propagate — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited propagate (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 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.
When this skill is loaded, you MUST immediately begin executing the Workflow below — do not wait, do not summarize, do not ask "what should I do now". Skills are operational manuals, not reference documents. Read Step 1 (Determine Source Doc), perform it, then Steps 2, 3, 4, ... in order, until the workflow completes or you reach an AskUserQuestion checkpoint.
If the harness shows you Successfully loaded skill · N tools allowed, that message means the SKILL.md content was injected into your context — it does NOT mean the skill has run. Skills do not "run" autonomously; you run them by executing the Detailed Steps below.
If you find yourself about to say "the skill didn't produce output", "skill 仍未输出", "falling back to manual propagation", "回退到手动 propagate", or anything similar, STOP. You have misunderstood how skills work. Go directly to Step 1 and start executing.
The first user-visible action of this skill should be either (a) the output of Step 1 (resolved source doc + change scope), or (b) an AskUserQuestion if Step 1 needs disambiguation. Never an apology, never a fallback, never silence.
Walk a doc change downstream and keep the whole chain consistent.
EVERY UPSTREAM CHANGE PROPAGATES OR FAILS LOUDLY. Partial propagation is worse than no propagation — it creates the illusion of consistency where there is none.
/spec-forge:prd or another generator that modified an existing doc in place--since {git-ref}, to catch accumulated drift across recent commitsspec-forge:analyze or spec-forge:audit flags inconsistencies between upstream and downstream docsThis skill is the symmetric counterpart to code-forge:fix --review (which propagates code review findings into code changes). Where code-forge:fix walks up from a bug to the spec, spec-forge:propagate walks down from a spec change to the docs and code that depend on it.
/spec-forge:propagate [@source-doc.md] [--since git-ref] [--scope all|docs|code] [--dry-run] [--save]| Argument / Flag | Default | Description |
|---|---|---|
@source-doc.md | — | The upstream doc whose changes should propagate. If omitted, auto-detect from git diff HEAD (uncommitted changes) or git diff HEAD~1 HEAD (last commit). |
--since {git-ref} | — | Compute the diff between {git-ref} and HEAD instead of using uncommitted changes. Useful for catching drift across multiple commits. |
--scope | docs | What to propagate into. docs = downstream documentation only. code = also flag code that references changed requirement IDs. all = both. |
--dry-run | off | Generate the impact report and per-downstream proposed changes, but do NOT apply any edits. The user reviews the report and re-runs without --dry-run to apply. |
--save | off | Save the propagation report to docs/propagate-report-{timestamp}.md in addition to displaying it. |
Step 1 (Determine Source) → Step 2 (Extract Changed Concepts) → Step 3 (Discover Downstream Refs)
→ Step 4 (Per-Downstream Impact Analysis) → Step 5 (Interactive Review) → Step 6 (Apply)
→ Step 7 (Verify) → Step 8 (Report)#### 1.1 Resolve the Source
Parse $ARGUMENTS:
.md files in docs/ that changed between {ref} and HEAD. Use git diff --name-only {ref}...HEAD -- 'docs/**/*.md' '*.md' to enumerate.git status --porcelain -- 'docs/**/*.md' '*.md' to find uncommitted doc changes.git diff --name-only HEAD~1 HEAD -- 'docs/**/*.md' '*.md' (the last commit's doc changes).No doc changes detected. Provide an explicit @source-doc.md or use --since {ref}. and stop.If the source is auto-detected, display the resolved file list and use AskUserQuestion:
AskUserQuestion listing nearby docs#### 1.2 Compute Change Scope
For each source file, compute the diff:
git diff HEAD -- {file}git diff {ref}...HEAD -- {file}git diff HEAD~1 HEAD -- {file}Display the diff summary:
Source documents:
docs/core/prd.md +24 -8
docs/core/srs.md +12 -3
Total: 2 files, +36 -11 linesStore the per-file diffs in memory for Step 2.
Offload to a sub-agent so the diff content stays out of the main context.
Spawn an Agent tool call:
subagent_type: "general-purpose"description: "Extract changed concepts from doc diff"Sub-agent prompt must include:
Sub-agent must return:
CONCEPTS_REPORT
ADDED:
- type: {requirement_id|term|component|api|metric|decision|threshold|other}
name: {concept name}
defined_at: {source_file:line}
summary: {one-sentence description}
MODIFIED:
- type: {...}
name: {...}
defined_at: {source_file:line}
what_changed: {one-sentence description of the change}
REMOVED:
- type: {...}
name: {...}
was_defined_at: {source_file:line in the OLD version}
reason: {one-sentence why it was removed, if inferrable}
RENAMED:
- type: {...}
old_name: {...}
new_name: {...}
defined_at: {source_file:line}
SEARCH_TERMS:
- {keyword 1}
- {keyword 2}
- {... grep-friendly strings to find downstream references — include literal IDs, exact term names, and at least one variant for each rename}Main context retains: Only this report (~3-5KB).
Offload to a sub-agent so the grep output stays out of the main context.
Spawn an Agent tool call:
subagent_type: "general-purpose"description: "Discover downstream references"Sub-agent prompt must include:
CONCEPTS_REPORT from Step 2 (paste verbatim)docs, code, or all)Sub-agent must return:
DOWNSTREAM_REPORT
DOC_REFERENCES:
- file: {downstream_file_path}
type: {prd|srs|tech-design|feature-spec|test-cases|test-plan|readme|adr|other}
references:
- concept: {concept name}
kind: {ADDED|MODIFIED|REMOVED|RENAMED}
lines: [{line numbers where mentioned}]
uses_old_name: {true|false} # only for RENAMED
uses_new_name: {true|false} # only for RENAMED
CODE_REFERENCES: # only if scope = code or all
- file: {code_file_path}
language: {python|typescript|...}
references:
- concept: {concept name}
kind: {...}
lines: [{...}]
ORPHANED:
- {concepts marked REMOVED in CONCEPTS_REPORT that are still referenced somewhere — these are the most urgent fixes}
SUMMARY:
total_downstream_docs: {N}
total_downstream_code_files: {N}
most_referenced_concept: {name and ref count}Main context retains: Only this report (~5-10KB depending on project size).
For each entry in DOWNSTREAM_REPORT.DOC_REFERENCES (and optionally CODE_REFERENCES), spawn a sub-agent to determine what specific changes the downstream needs. Use parallel Agent tool calls — one per downstream file — but cap at 8 parallel sub-agents at a time to avoid overwhelming the orchestrator.
Each sub-agent receives:
CONCEPTS_REPORT (only the concepts this downstream references)DOWNSTREAM_REPORT (only this file's references)Sub-agent prompt:
You are analyzing whether {downstream_file} needs to be updated in response to upstream
spec changes.
Read {downstream_file} from disk. For each referenced concept, decide whether and how
the downstream needs to change.
Decision rules:
- ADDED concept: usually no change needed unless the downstream is the natural place
to consume the new concept (e.g., a new requirement should be referenced from the
test-cases doc). If the downstream should reference the new concept, propose where.
- MODIFIED concept: the downstream's mention of this concept may now be stale. Read
the surrounding context, compare against the new upstream definition, and decide:
STALE (needs update), STILL_VALID (the change doesn't affect this mention), or
AMBIGUOUS (human judgment needed).
- REMOVED concept: the downstream still references something that no longer exists.
Either the reference must be deleted, or replaced with a pointer to the replacement
(if there is one — check the surrounding context for hints).
- RENAMED concept: any mention of the old name is stale. Replace with the new name.
For each needed change, produce a unified-diff-style proposed edit that the orchestrator
can apply directly. Be precise about the line range and the exact replacement text.
Do NOT make subjective improvements unrelated to the propagation — only address the
upstream changes.
Return structured output:
DOWNSTREAM_IMPACT for {downstream_file}
CHANGES_NEEDED:
- concept: {concept name}
decision: STALE | STILL_VALID | AMBIGUOUS | REMOVE_REFERENCE | ADD_REFERENCE
current_text:
line {N}: {current line content}
proposed_text:
line {N}: {proposed replacement}
rationale: {one sentence why this change is needed}
confidence: HIGH | MEDIUM | LOW # HIGH = mechanical replacement, LOW = needs human review
NO_CHANGE_NEEDED:
- concept: {concept name}
reason: {one sentence}
AMBIGUOUS:
- concept: {concept name}
question: {what the human needs to decide}After all sub-agents complete, aggregate into a single IMPACT_REPORT keyed by downstream file.
Walk the IMPACT_REPORT with the user. For each downstream file with CHANGES_NEEDED, display the proposed changes and use AskUserQuestion to choose:
Downstream: docs/core/srs.md
Proposed changes (3):
[1] FR-AUTH-005 (RENAMED → FR-USER-005)
Current L42: - The system shall enforce FR-AUTH-005 (password complexity)
Proposed L42: - The system shall enforce FR-USER-005 (password complexity)
Confidence: HIGH
[2] threshold "5 attempts" (MODIFIED → "3 attempts")
Current L88: - Account locks after 5 failed attempts
Proposed L88: - Account locks after 3 failed attempts
Confidence: HIGH
[3] component "AuthService" (REMOVED, replaced by "UserAuthFlow" + "SessionManager")
Current L120: - AuthService validates credentials and issues tokens
Proposed L120: <AMBIGUOUS — needs human decision>
Confidence: LOW
Question: How should this sentence be split between UserAuthFlow and SessionManager?
How would you like to proceed?
- Apply all HIGH-confidence changes, ask me about LOW/AMBIGUOUS
- Apply all proposed changes (including AMBIGUOUS — I'll review the diff after)
- Show me the full diff for this file before deciding
- Skip this file entirely
- Stop and let me handle this manuallyFor each AMBIGUOUS change, follow up with a focused AskUserQuestion per concept.
If --dry-run was set: skip the interactive choices, collect everything as "would apply" / "would skip", and jump to Step 8 (Report).
For each accepted change from Step 5:
Edit (specific line range, exact text replacement)git diff -- {file} and store the diffHard rule: Use Edit for surgical changes. Never rewrite the entire file. Never use Write to overwrite. The downstream file may have content unrelated to the propagation — that content must not be touched.
Hard rule: Apply changes file by file, not concept by concept. This keeps each file's edits atomic and easy to revert.
After all changes are applied:
CONCEPTS_REPORT that still appears in any downstream file is a propagation gap — display it as STILL_STALE and ask the user to address it manually.Display the propagation report:
Propagate Complete
Source documents: {N}
- docs/core/prd.md (+24 -8)
- docs/core/srs.md (+12 -3)
Concepts changed:
ADDED: {N} MODIFIED: {N} REMOVED: {N} RENAMED: {N}
Downstream files analyzed: {N}
Updated: {N}
Skipped: {N}
Ambiguous: {N} (left for manual)
Code references: {N} (scope = {scope})
Verification:
Stale references remaining: {N}
{if any: list them}
Tests after propagation: {pass/fail/skipped}
Files modified:
docs/core/srs.md 3 changes
docs/core/tech-design.md 5 changes
docs/features/auth.md 2 changes
README.md 1 change
Next steps:
Review changes: git diff
Commit: git add <files> && git commit -m "docs: propagate changes from prd.md"
Re-run audit: /spec-forge:audit
{if --save was used:}
Report saved: docs/propagate-report-{timestamp}.mdIf --dry-run was set: prefix the entire report with DRY RUN — no changes were applied. and append:
To apply the proposed changes, re-run without --dry-run:
/spec-forge:propagate {original args minus --dry-run}Edit is the only safe tool. Never Write.docs, the skill must not modify any code files even if they reference stale concepts. Code-side updates are out of scope.--since against a clean ref.analyze periodically; use propagate after each upstream change.propagate run, an audit confirms the propagation didn't break anything.propagate walks doc changes forward into downstream docs.propagate is the within-doc-chain version.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.