spec-kit-sync-artifacts
Skill6 starsChanged 2 months agoApache-2.0View on GitHub
Detect drift between spec.md/plan.md/tasks.md and their recorded state.json fingerprints — mechanical hash comparison plus best-effort structural localization by stable ID — and recommend which upstream spec-kit skill to re-invoke, one hop at a time. Never edits spec.md, plan.md, or tasks.md itself; that stays each generating skill's own "Updating an Existing X" procedure. Invocable standalone after editing a source document, or as the Fase 0 staleness check inside spec-kit-generate-plan, spec-kit-generate-tasks, and spec-kit-execute-tasks. When a drift-watcher agent is requested, generates compatible definitions for both Kiro CLI and Claude Code.
In this repository22 other files it gives its agents.
- backend-api-standardsSkill
- brain-orchestratorSkill
- brand-guidelinesSkill
- code-architecture-explainerSkill
- code-documentationSkill
- create-pull-requestSkill
- frontend-architectureSkill
- frontend-designSkill
- gh-stackSkill
- git-commitsSkill
- latex-academic-reportsSkill
- pre-pr-reviewSkill
- project-intelligenceSkill
- project-setupSkill
- spec-kit-amend-artifactsSkill
- spec-kit-analyze-consistencySkill
- spec-kit-establish-constitutionSkill
- spec-kit-execute-tasksSkill
- spec-kit-generate-planSkill
- spec-kit-generate-specSkill
- spec-kit-generate-tasksSkill
- verify-before-implementSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 8 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 30
Always consider the complete user message and any files or attachments available in the current conversation, even when $ARGUMENTS appears …
- Distinctive: line 42
After a source changes, recommend regenerating the *directly* dependent artifact first (the spec that cites it).
- Distinctive: line 59
Only recommend a full multi-hop cascade upfront if the user explicitly asked for it (e.g.
- Very specific: line 73
Never silently touch a completed task: If drift potentially affects a story whose [CIERRE] task (or any task) is already marked [x], flag …
- Very specific: line 77
Generate portable agent pairs: If this workflow creates a drift-watcher (or other support agent), it must generate and validate both a Kiro …
- Distinctive: line 98
Do not invent a different name or redefine it for another purpose.
- Very specific: line 116
If logging is off (RUN_LOG: off), continue normally.
- Distinctive: line 122
If the user gave an explicit feature directory, use it.
- Distinctive: line 124
If neither resolves, stop and ask:
- Very specific: line 131
If .speckit/specs/<feature-dir>/state.json does not exist, stop and report:
- Distinctive: line 136
Do not proceed past this point when state is missing (Rule 8).
- Very specific: line 142
Read state.json completely: schema_version, artifacts.spec/artifacts.plan/artifacts.tasks (whichever exist), and source_documents.
- Very specific: line 170
Before reporting it, apply the convention's Legacy tasks.md hashes rule — a hash recorded before normalization existed is not drift when …
- Distinctive: line 173
Every comparison is reported, matched or not — a full "everything matches" result is a valid report (Rule 6).
- Very specific: line 187
Spec→plan drift: if the previous spec.md version is available (git history, or the prior content implied by plan.md's own traceability …
- Very specific: line 206
If any task in an affected story is already [x], flag it explicitly per Rule 10.
- Distinctive: line 207
Ask for confirmation before recommending more than one hop, unless the user already asked for the full cascade.
- Very specific: line 209
If the user explains that the edit is an already-decided change (a review finding, a decision they made), recommend …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Sync Artifacts — Drift Detection Skill
Purpose
Answer, with evidence, the question this whole kit exists to answer for the user: did something this specification/plan/tasks depended on change since it was generated, and if so, what needs to be regenerated? This is the mechanism behind "if the file a spec was generated from changes importantly, the plan and tasks should be able to update accordingly."
This skill is deliberately narrow: it detects and reports, using the Content Fingerprint
Convention (spec-kit-shared/artifact-conventions.md). It does not regenerate anything itself
— that stays spec-kit-generate-spec's, spec-kit-generate-plan's, or spec-kit-generate-tasks's own "Updating an Existing
X" procedure, each already written to propagate a change through only the sections it actually
touches. spec-kit-sync-artifacts is the shared, canonical definition of the mechanical comparison those
skills' own Fase 0 steps already rely on — they reference this file instead of each re-describing
hashing/comparison logic independently.
User Input
$ARGUMENTSAlways consider the complete user message and any files or attachments available in the current
conversation, even when $ARGUMENTS appears literally or is empty. The most common inputs are: a
feature directory to check, or an explicit note that a specific source document was just edited.
Core Principle
Detection is mechanical. Classification is semantic and stays with whoever regenerates. Propagation is one hop at a time, and never silent.
- A hash mismatch means "something changed" — not "this is a material change requiring a
cascade." The consuming skill (
spec-kit-generate-spec,spec-kit-generate-plan,spec-kit-generate-tasks) makes that judgment when it re-invokes its own "Updating an Existing X" procedure. - After a source changes, recommend regenerating the directly dependent artifact first (the spec that cites it). Do not presume what the plan or tasks will need until the spec's actual, regenerated content is known — a cascade is a sequence of confirmed hops, not one leap.
- A task already marked
[x]is never silently touched by anything this skill triggers — it is flagged for review instead.
Non-Negotiable Rules
- Detection is purely mechanical. Compare a current content hash/fingerprint against the
value recorded in
state.json. Report match or mismatch — do not judge whether a mismatch is "important" beyond the best-effort structural localization in Phase 3. - Read-only on
spec.md/plan.md/tasks.md. This skill never edits any of them. Its only possible writes are the twostate.jsonbookkeeping exceptions in § Writing state.json. - Use the Content Fingerprint Convention exactly as defined in
spec-kit-shared/artifact-conventions.md— never invent a different hashing rule or apply it inconsistently between a first check and a later one. - One hop at a time by default. Recommend re-invoking the nearest downstream skill first. Only recommend a full multi-hop cascade upfront if the user explicitly asked for it (e.g. "sync everything").
- Recommend, never force. This skill does not invoke
spec-kit-generate-spec/spec-kit-generate-plan/spec-kit-generate-taskson the user's behalf without explicit confirmation — it reports and asks, the same wayspec-kit-generate-spec's Extension Hooks distinguish mandatory from optional actions. - Report clean results too. "Nothing changed" is a valid, useful, explicitly stated outcome — never silently produce no output when there's nothing to report.
- Every finding cites the exact artifact/source ID and both fingerprint values. No vague "something seems out of date."
- If
state.jsondoesn't exist for the target feature, say so and stop — there is nothing to compare against; this is not the same as "no drift," and must not be reported as such. - Structural localization (§ Phase 3) is best-effort, not a guarantee. If a change can't be reliably localized to specific stable IDs (e.g. a source document spec-kit-sync-artifacts can't parse into a section structure), say so plainly rather than guessing which IDs are affected.
- Never silently touch a completed task. If drift potentially affects a story whose
[CIERRE]task (or any task) is already marked[x], flag it explicitly as "closed work potentially affected by this change — needs review," and let the human orspec-kit-generate-tasks's own update procedure decide, rather than un-checking or editing it. - Generate portable agent pairs. If this workflow creates a
drift-watcher(or other support agent), it must generate and validate both a Kiro CLI and a Claude Code definition per the shared portability contract.
Shared Files
spec-kit-shared/… paths resolve against <skills-root>, the parent of this skill's own
directory: .claude/skills/ or the host's equivalent once installed, the repository root in a
checkout of the kit. Run shared scripts from the project root as
node <skills-root>/spec-kit-shared/scripts/<script>.mjs, with <skills-root> written out as an
absolute path; a bare spec-kit-shared/… script path resolves against the project and fails.
Cross-Platform Agent Compatibility
The complete portability contract lives in spec-kit-shared/agent-portability.md. Before
generating, validating, or reporting on the drift-watcher role — or any other agent this skill
materializes — read that file completely and follow it exactly. If the active host cannot resolve
the reference, follow its fallback section.
drift-watcher is the standard role for this skill: running a standalone drift check in
isolation, read-only, without the rest of a spec-kit-generate-plan/spec-kit-generate-tasks invocation's context.
Do not invent a different name or redefine it for another purpose.
Artifact Conventions
The .speckit/ layout (including .speckit/specs/<feature-dir>/), state.json schema, and Content Fingerprint
Convention live in spec-kit-shared/artifact-conventions.md. Read it before Phase 1 below — this
skill's entire mechanism is built directly on that document's schema.
Run Log
Record this run per spec-kit-shared/artifact-conventions.md § Run Log (<dir> is the feature directory): start with
node <skills-root>/spec-kit-shared/scripts/log-event.mjs <dir> run.start --skill spec-kit-sync-artifacts mode=<mode> and pass the printed RUN_ID to every
later call; end with a run.end event (status, reason when it stops, next), also when the run stops early.
Pass --log <RUN_ID> --skill spec-kit-sync-artifacts to fingerprint.mjs --state so they record their own results.
Record these decisions, each with a one- or two-sentence rationale citing its IDs:
drift— one per drifted artifact or source: what changed (localized IDs) and the recommended next hop
If logging is off (RUN_LOG: off), continue normally.
Input Contract
Resolving the Target Feature
- If the user gave an explicit feature directory, use it.
- Otherwise, read
.speckit/feature.jsonfor the active feature directory. If neither resolves, stop and ask:
Provide the feature directory to check for drift. If you just edited a source document, name it and the feature it feeds.
Missing State
If .speckit/specs/<feature-dir>/state.json does not exist, stop and report:
No recorded state for this feature — nothing to compare against yet. This is expected before a first
plan.md/tasks.mdexists; it is not the same as confirming there's no drift.
Do not proceed past this point when state is missing (Rule 8).
Workflow
Phase 1 — Load State
Read state.json completely: schema_version, artifacts.spec/artifacts.plan/artifacts.tasks
(whichever exist), and source_documents. Apply artifact-conventions.md § Schema Versions and
Migrations: a version newer than the contract stops the check (report it — comparing with rules
this kit does not know would be guesswork); a version-1 file is compared with the version-1
meaning, and this skill reports it as SCHEMA_VERSION: 1 (migrates on next write) without
migrating it.
Phase 2 — Recompute Fingerprints and Compare
For every entry in state.json, recompute its current fingerprint using the Content Fingerprint
Convention and compare. Compute artifact hashes with
node <skills-root>/spec-kit-shared/scripts/fingerprint.mjs --state <feature-dir> (or its documented shell
equivalent) — never by estimating, and never with a hashing rule of your own:
- Each
source_documents.<ID>: recompute per its recorded type (versioned file → current commit SHA touching that path; non-versioned file/pasted text/URL/attachment → current content hash). Compare to the recordedfingerprint. If the source no longer exists or can't be re-read, report that explicitly — a vanished source is itself a finding, not a silent skip. artifacts.spec.content_hash: recomputespec.md's current hash. A mismatch here (with no corresponding update inplan.md'sbased_on_spec_hash) meansspec.mdwas hand-edited or regenerated since the plan was built.artifacts.plan.based_on_spec_hashvs.artifacts.spec.content_hash(current): the direct spec→plan staleness checkspec-kit-generate-plan's own Fase 0 relies on.artifacts.tasks.based_on_plan_hashvs.artifacts.plan.content_hash(current): the direct plan→tasks staleness checkspec-kit-generate-tasks's own Fase 0 relies on.artifacts.tasks.content_hash: recomputetasks.md's current progress-insensitive hash (checkboxes normalized, per the convention). Marking tasks[x]never produces a mismatch here; a mismatch meanstasks.mdwas edited outsidespec-kit-generate-tasks/spec-kit-amend-artifacts. Before reporting it, apply the convention's Legacytasks.mdhashes rule — a hash recorded before normalization existed is not drift when the only difference is checkbox state.
Every comparison is reported, matched or not — a full "everything matches" result is a valid report (Rule 6).
Phase 3 — Structural Localization (best-effort)
For every mismatch found in Phase 2, attempt to localize which stable IDs are involved. When the
recorded entry has sections, localization is mechanical: fingerprint.mjs --state prints the
changed, added, and removed IDs for each drifted artifact — report those and stop there for that
artifact (an edit outside every ID block is reported as such). The best-effort rules below apply
only to entries without sections:
- Source drift: which
[S#]/[P#]row inspec.md's Evidence Catalog cites this source, and whichR-G##/R-FR##/R-AC##/etc. cite that same ID in turn (a simple citation-graph lookup, not a semantic reading of what changed in the source's prose). - Spec→plan drift: if the previous
spec.mdversion is available (git history, or the prior content implied byplan.md's own traceability citations), identify whichR-FR##/R-AC##/E-##/R-QR##IDs' surrounding text differs; otherwise, report "spec.md changed, could not localize which sections — recommendspec-kit-generate-planreview the full spec diff." - Plan→tasks drift: same approach against
PL-O##/PL-D##/RS-##/Safe Deferral entries (or a legacy plan'sO-0#/A-D0#, per the convention's Stable ID Namespaces).
State plainly when localization isn't possible (Rule 9) rather than asserting an ID list you aren't confident in.
Phase 4 — Drift Report and Cascade Recommendation
For each mismatch, in dependency order (source → spec → plan → tasks):
- State what changed (fingerprints, and localized IDs when available).
- Recommend the nearest downstream skill to re-invoke (Rule 4) — e.g. a source mismatch
recommends
spec-kit-generate-spec(update mode) first, notspec-kit-generate-plandirectly, even ifplan.mdalso looks stale — that staleness is a consequence to re-check after the spec is actually updated, not a parallel action to take now. - If any task in an affected story is already
[x], flag it explicitly per Rule 10. - Ask for confirmation before recommending more than one hop, unless the user already asked for the full cascade.
- If the user explains that the edit is an already-decided change (a review finding, a decision
they made), recommend
spec-kit-amend-artifactsinstead: it applies a decided change from its lowest affected layer downward in one confirmed pass, which is the multi-hop path this skill deliberately does not take on its own.
Writing state.json
Each generating skill (spec-kit-generate-spec, spec-kit-generate-plan, spec-kit-generate-tasks) already writes its own
artifact's hash entries in state.json when it finishes regenerating. spec-kit-sync-artifacts does not
duplicate that write. The one exception: if the user asks spec-kit-sync-artifacts to simply acknowledge
a source change without regenerating anything yet (e.g. "yes, the PRD changed, but don't update
the spec right now") — in that case, and only with explicit confirmation, it may refresh
source_documents.<ID>.fingerprint and read_at to the current value, so the next check doesn't
re-report an already-acknowledged change as new. State plainly when this happens, since it means
the spec is now knowingly stale against its own source until someone regenerates it.
A second, mechanical exception: a legacy tasks.md hash (recorded before checkbox
normalization) that the convention's Legacy rule shows to differ only in checkbox state may be
rewritten to the normalized hash, with no confirmation needed because no content changed. Report
it as LEGACY_HASH_UPGRADED: tasks.
Drift Report
# Drift Report: [Feature Name]
**Checked**: [timestamp]
**state.json**: found / not found (stop here if not found)
## Source Documents
| ID | Path | Recorded Fingerprint | Current Fingerprint | Status |
| --- | --- | --- | --- | --- |
| S1 | ... | sha256:... | sha256:... | MATCH / DRIFT |
## Artifact Chain
| Artifact | Recorded Hash | Current Hash | Based-On Reference | Status |
| --- | --- | --- | --- | --- |
| spec.md | ... | ... | — | MATCH / DRIFT |
| plan.md | ... | ... | based_on_spec_hash: ... vs current spec: ... | MATCH / DRIFT |
| tasks.md | ... | ... | based_on_plan_hash: ... vs current plan: ... | MATCH / DRIFT |
## Findings
### F1 — [Source drift / Spec→Plan drift / Plan→Tasks drift]
**Evidence**: [fingerprints compared]
**Localized to**: [IDs, or "could not localize — recommend full diff review"]
**Closed work potentially affected**: [task IDs already [x], or "none"]
**Recommended next step**: [exact skill + mode, one hop]
## Verdict
**DRIFT_DETECTED**: YES / NO
**RECOMMENDED_NEXT_HOP**: [skill name, or "none — everything matches"]How Other spec-kit Skills Use This
spec-kit-generate-plan's and spec-kit-generate-tasks's own Fase 0 sections read this file's Phase 1/2 procedure
and apply it against their own specific based_on_* field — they do not re-describe the hashing
mechanism independently. If either skill's Fase 0 finds drift, it follows its own
"Updating an Existing Plan"/"Updating an Existing Task List" section to propagate the change — this
skill's job ends at the report and recommendation.
Completion Report
Report:
RUN_ID: this run's log ID, oroff.SPECIFY_FEATURE_DIRECTORY: resolved feature directory.STATE_FOUND:true/false.SCHEMA_VERSION: the version found, and whether it migrates on the next write.SOURCES_CHECKED/SOURCES_DRIFTED: counts.ARTIFACT_CHAIN_STATUS: spec/plan/tasks each MATCH/DRIFT/absent.CLOSED_WORK_FLAGGED: task IDs already[x]potentially affected, or "none".DRIFT_DETECTED:YES/NO.RECOMMENDED_NEXT_HOP: the single nearest skill to re-invoke, or "none".LEGACY_HASH_UPGRADED:tasksif a legacy rawtasks.mdhash was rewritten, otherwise omitted.AGENTS:none, or every generated Kiro/Claude path with validation and parity status.
Done When
- The run was logged from
run.starttorun.end(or logging is off). - The target feature's
state.jsonwas located, or its absence was reported and the skill stopped there. - Every
source_documentsentry and every artifact hash was recomputed and compared. - Every mismatch attempted structural localization, or explicitly reported that localization wasn't possible.
- Every finding cites concrete fingerprints and IDs.
- Any closed (
[x]) task potentially affected by a finding was explicitly flagged. - The recommendation followed the one-hop-at-a-time rule unless the user asked for the full cascade.
- No content was written to
spec.md,plan.md, ortasks.md. - Every generated support agent has a validated Kiro/Claude pair, or
AGENTS: noneis reported.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

