forge-1b7bff — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited forge-1b7bff (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Create .claude/rules/ files that are specific, scoped, and quality-scored. Language: Rule drafting and scoring is English-only.
If arguments are provided, treat them as the rule topic: $ARGUMENTS
AskUserQuestion shape constraints — apply to every invocation in this skillEvery decision point in this skill that presents a fixed, option-shaped answer space MUST use AskUserQuestion — plain-text questions like "Want me to do X, or Y?" break the button-driven flow and users may not notice them.
{ questions: [{ question, header, multiSelect, options }] }. The questions: [...] array wrapper is required — flat-form inputs without it are rejected by the tool schema. Each field list below describes the contents of the single entry inside that array.header MUST be ≤12 characters (tool-enforced; longer values truncate silently).options MUST contain 2–4 entries. The harness auto-injects an "Other" escape when needed — do NOT add a 5th option manually.label and description. Omitting description produces bare buttons with no guidance.multiSelect: true ONLY when selections are logically independent (e.g. multiple test scopes). Default to false.Bash invocation MUST include a short description field (5–10 words) naming its purpose.Build runs in one of two contexts, and each uses a different task-tracking strategy. Before doing anything else, check whether .rulesense-tmp/audit.json exists in the project root — that is the assay→forge bridge marker (same check as Phase 1 Step 1 below; doing it here lets the task-list decision precede the first user-visible tool call).
The user invoked /rulesense:forge directly. Build owns the task list for this session. Create it via TaskCreate (fall back to TodoWrite in non-interactive / SDK sessions). Every task MUST carry paired content (imperative) and activeForm (progressive) fields — content renders when pending or completed, activeForm renders while in_progress, and they are NOT interchangeable.
Initial tasks (create all of these up front, with both forms):
{ content: "Detect audit→build bridge marker", activeForm: "Detecting audit→build bridge marker" } — Phase 1 Step 1{ content: "Capture the user's intent", activeForm: "Capturing the user's intent" } — Phase 1 Steps 2–3{ content: "Analyze the project", activeForm: "Analyzing the project" } — Phase 2{ content: "Scope the rules via questionnaire", activeForm: "Scoping the rules" } — Phase 2b{ content: "Draft the rule set", activeForm: "Drafting the rule set" } — Phase 3 Step 1{ content: "Score the draft rules", activeForm: "Scoring the draft rules" } — Phase 3 Step 2{ content: "Write the rule files", activeForm: "Writing the rule files" } — Phase 4{ content: "Clean up temp files", activeForm: "Cleaning up temp files" } — Phase 4 final stepMark each task in_progress via TaskUpdate immediately before starting it and completed immediately upon finishing. Do not batch completions — update the list as each step resolves.
The assay skill delegated here from its Phase 3c Step 7 "Fix coverage gaps" branch. The assay skill already appended a single gap-umbrella task (inserted before "Clean up temp files" — see ../assay/references/gap-fill.md) and marked it in_progress before invoking forge. Forge MUST NOT call `TaskCreate` or `TodoWrite` in this context — appending the eight Phase-1-to-4 tasks would pollute the assay list with duplicated names (e.g. two "Clean up temp files" entries, one from assay's Phase 4 and one from forge's Phase 4) and produce the "chaotic list" users have reported.
Instead, in Context B:
TaskCreate / TodoWrite call entirely.draft_* temp files), return control to the assay skill without touching its task list. The assay skill mutates the umbrella's activeForm between gaps and marks it completed after the final gap per ../assay/references/gap-fill.md.First, check whether .rulesense-tmp/audit.json exists in the project root.
"Fix coverage gaps" branch. The topic and project context are already available. Skip Phase 1 Steps 2-3 and go directly to Phase 2 with the gap topic as the scoping input. Say: "I'll draft rules for [gap topic] based on your project. Let me ask a couple of questions to get the scope right."Ask one question as plain prose (this is the one intentional exception to the AskUserQuestion discipline — the answer space is open-ended and free-text is required):
"What do you want me to do (or stop doing) in this project?"
Expect anything from a specific request ("always use Vitest for tests") to a vague wish ("help me write better TypeScript"). Both are valid starting points. Every subsequent clarification MUST use AskUserQuestion per the shape constraints at the top of this file.
If the request is vague, narrow scope by invoking AskUserQuestion (do NOT ask in prose — the option set is fixed and mutually exclusive):
"Which area do you care about most?""Rule area"false{ label: "Testing", description: "Test placement, coverage expectations, mocking discipline" }{ label: "Code style", description: "Naming, imports, file organization, formatting" }{ label: "Architecture", description: "Layer boundaries, module isolation, API contracts" }{ label: "Workflow / process", description: "Git discipline, PR conventions, commit hygiene" }If the user picks "Other" and supplies free text, treat that text as the topic and proceed.
paths: frontmatter; rules that apply everywhere do not.Before writing anything, understand what exists:
.claude/rules/*.md and CLAUDE.md. Count current rules.Heavy-context escape: if the project has more than ~200 source files in the relevant subsystem, or the subsystem is unfamiliar territory (e.g. you've never touched the framework before), do NOT read samples in main context. Dispatch Agent with the full parameter shape:
"Explore""Sample testing conventions in src/api")false (you need the summary before drafting)model — inherit from the parent sessionUse the returned summary to inform Phase 3 drafting. Do not re-load the raw files into main context.
See references/rule-templates.md for common rule types and scoping patterns.
After analyzing the project, narrow scope with at most 3 questions, tailored to the topic. Every question whose answer space is a fixed enumerable set MUST be asked via AskUserQuestion — do NOT ask these in prose. Only genuinely open-ended questions ("Is there a style guide or reference project I should match?", "Which directories are the focus?") may stay as plain text.
Pattern — adapt to the topic, don't use the option labels verbatim. Substitute concrete labels drawn from the project analysis in Phase 2 (real directories, real frameworks).
For the per-topic AskUserQuestion option sets (testing / code style / architecture), see references/questionnaire-patterns.md.
Rules for the questionnaire:
AskUserQuestion is binding. If a category has more than 4 candidates, pick the 4 most-likely-from-Phase-2 and rely on the harness's auto-injected "Other" escape for the rest.Based on the user's request, project analysis, and questionnaire answers, design a coherent set of rules covering the topic from multiple angles.
Generate 3-8 rules that together cover the topic. Organize them into logical groups:
Based on the project analysis, here are [N] rules for [topic]:
**[Group 1 name]:**
1. "[Rule text]"
2. "[Rule text]"
**[Group 2 name]:**
3. "[Rule text]"
4. "[Rule text]"
**[Group 3 name]:**
5. "[Rule text]"
These would go in .claude/rules/[filename].md
[scoped to [pattern] if applicable].
Want me to adjust any of these, or should I score them?Before presenting, apply the rule-writing checklist and full-set drafting guidance from references/writing-principles.md: each rule must have a concrete trigger (WHEN), explicit action (WHAT), brief intent clause (WHY), exactly one interpretation, and self-contained ambiguity resolution; the set must cover different angles, mix structural / quality / process rules, draw concrete examples from the real project, and surface hook / linter alternatives when enforcement belongs there.
After presenting the proposed rules, invoke AskUserQuestion with:
"Here are [N] rules for [topic]. What would you like to do?" (substitute count and topic)"Draft review"false{ label: "Score them", description: "Check each rule for quality and flag any that need work" }{ label: "Adjust", description: "Pick which rules to modify, add, or remove" }{ label: "Start over", description: "Discard and return to the scope questionnaire" }If "Adjust", iterate until the user picks "Score them". Each re-present is a new decision point — fire AskUserQuestion again, not prose.
Execute the scoring pipeline in this order:
SCRIPTS, PYTHON_CMD, PYTHONIOENCODING)..rulesense-tmp/draft_rules.json via the Write tool.Bash with description: "Score draft rules mechanically" to run --score-draft.--score-draft output JSON has status: "needs_revision", the script detected rules that would fragment when written to markdown and re-extracted on the next audit. Do NOT present the fragmentation warnings to the user as scoring failures — they are a silent guardrail, not a quality judgment. Silently revise the flagged rules per references/writing-principles.md (the "Extractor self-check" section), overwrite .rulesense-tmp/draft_rules.json with the revised text, and re-run --score-draft. Repeat until status == "ok" (cap at 3 revision passes; if a rule still fragments after 3 passes, collapse it to its single most important directive). Only when the status is ok does the judgment phase begin.../assay/references/factor-rubrics.md..rulesense-tmp/draft_judgments.json via a temp Python script (the draft_ prefix prevents collision with the audit pipeline's all_judgments.json on the gap bridge).Bash with description: "Finalize draft scoring" to run --finalize-draft.For the full command-line payloads, JSON/Python templates, rubric level boundaries, and the scoring-results presentation format, see references/scoring-mechanics.md.
After presenting scoring results, invoke AskUserQuestion. The shape depends on whether any rules fell below the quality floor — pick ONE of the two branches below:
Branch A — all rules passed:
"All [N] rules passed. What next?" (substitute the count)"After score"false{ label: "Write them", description: "Write the rule file(s) into .claude/rules/" }{ label: "Adjust rules", description: "Edit the draft set, then re-score" }{ label: "Skip scoring", description: "Write the rules as-is without further scoring" }Branch B — some rules scored below the quality floor:
"[N] drafts passed, [M] drafts need work. What next?" (substitute both counts; the word "drafts" disambiguates this from the assay skill's Phase 3c question about pre-existing rules)"After score"false{ label: "Improve [M] drafts", description: "Suggest stronger rewrites for the [M] weak drafts, re-score, show before/after" } (substitute [M]){ label: "Write them", description: "Write all drafts as-is; I'll flag which ones are weak" }{ label: "Adjust drafts", description: "Edit the draft set, then re-score" }{ label: "Skip scoring", description: "Write as-is without further scoring" }Read on demand, not upfront. The workflow steps above are self-contained; these references add depth for specific phases.
references/rule-templates.md. The same file's "Advanced: High-stakes rule scaffold" section lists the 8 structural elements (severity marker, rationale, ±examples, bright-line threshold, precedence, self-check) for rules important enough to justify more tokens.references/questionnaire-patterns.md.paths: scoping guidance (Phase 3 Step 1), see references/writing-principles.md.references/scoring-mechanics.md.references/quality-gates.md.After all rules pass the quality floor (or are accepted by the user):
.claude/rules/<topic>.md filepaths: frontmatter.claude/rules/ file -> append to that file instead of creating a new onepaths: (if scoped) and default-category: (if not mandate)- Rule text here)## Created
.claude/rules/<topic>.md — [N] rules, scoped to [pattern]
Mean quality: A (0.84)
All rules meet the quality bar
The project now has [N] total rules across [M] files.After writing the file(s), invoke AskUserQuestion with:
"Created [file] with [N] rules. What next?" (substitute filename and count)"Next step"false{ label: "Run assay", description: "Run /rulesense:assay to see how new rules fit with existing ones" }{ label: "More rules", description: "Start a new build session for another topic" }{ label: "Done", description: "Finish and clean up" }Check whether .rulesense-tmp/audit.json exists (the audit-bridge marker from Phase 1 Step 1).
scored_semi.json, all_judgments.json, audit.json) must survive for the remaining audit phases. Invoke Bash with description: "Remove draft-specific temp files": rm -f .rulesense-tmp/draft_*.json .rulesense-tmp/draft_*.md .rulesense-tmp/_draft_*.json .rulesense-tmp/draft_rules.jsonBash with description: "Remove entire temp directory": rm -rf .rulesense-tmp~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.