doccraft-close-2ef3ed — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited doccraft-close-2ef3ed (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
Managed by doccraft —doccraft updateregenerates this file. Local edits will be overwritten. Seedoccraft.jsonto override project-specific vocabulary and paths without touching this file.
have the planning surface end up consistent — not just the story file.
done, or a non-promotingterminal like done-no-promote, abandoned, absorbed.
shipped the retry flow", or similar.
Not for: authoring or re-scoping a story (use doccraft-story), a general "what's unblocked / fix the queue" sweep with no specific story to close (use doccraft-queue-audit), or recording a decision (use doccraft-adr).
Closing a story is a multi-file transaction. The story file is only step one; the backlog row, the queue row, and (with epics) the parent epic table all describe the same work and drift the moment one is updated without the others. This skill owns the whole transition so a close never lands halfway.
Read doccraft.json at invocation. Every key below has a default in this body, so a missing config file is a soft fallback, not an error.
docsDir — root folder for all docs. Default: docs. Stories, queue, andbacklog live at {docsDir}/stories/, {docsDir}/queue.md, {docsDir}/backlog.md.
story.status — the allowed status: values. The terminal values arewhichever of these mean "no longer active work" — done always, plus any the project adds (done-no-promote, abandoned, absorbed). Read this list rather than assuming done is the only terminal state; a story closed as absorbed is just as closed as one marked done.
queue.tables.suggestedOrder, queue.tables.platformSpikes — heading textused to locate the queue tables. Defaults: Suggested order, Platform spikes. Matched on heading text, not row position.
For monorepo projects (a Known package roots block appears above when packages are declared), a story lives under a specific scope — the project root or a declared package's docs/. For single-root projects no block appears and everything operates on the project-root docs/.
Resolve the target's scope before touching anything:
pkg/STR-NNNN names the package directly — operate inthat package's docs/. An unprefixed id is project-root scoped.
package path, default to that package.
Close the story in its own scope: its story file, its package docs/queue.md, and its package docs/backlog.md. Then refresh the root cross-package aggregate (see step 5) so the closed story stops showing up there.
Reads:
id, status, epic, depends_on,roadmap_ref) and the project's story.status vocabulary.
docs/queue.md and docs/backlog.md.epic: is set and the epics extension is active.Writes (Agent mode only):
status only (and updated).docs/backlog.md — the matching Status cell.docs/queue.md — remove the closed row, renumber.close.epic-update injection (see below).Same contract as doccraft-queue-audit, set by the environment, not by user enthusiasm:
and reconcile in the same turn, then report what changed.
exact diff you would apply (which files, which cells, which rows) and stop. NEVER write in Ask mode even if asked; the user applies it themselves.
Run these in order. If any step cannot be completed unambiguously, stop and report (see Stop and report) rather than leaving a partial close.
namespaced id / active file. If zero or more than one match, stop and ask — never guess which story to close.
done. It MUST be one of the project's story.status terminal values. Set the story's status and bump updated to today. Do not touch other frontmatter.
docs/backlog.md, find therow for this story (by roadmap_ref / id) and set its Status cell to the project's established "closed" phrasing for that terminal state. NEVER mark a backlog row closed when the story file is still todo / in_progress — the backlog follows the story, never leads it.
docs/queue.md, remove the closedstory's row from the Suggested order table and renumber the rows below it. A closed story never stays in the pick-next list.
close.epic-update fragment below — mark the story's row in the parent epic's table and roll the epic to a terminal status when its last open child closes. Absent the extension this is a no-op.
doccraft-queue-audit invariants over the affectedscope (graph checks, queue-order checks, backlog-drift checks) so closing this story did not strand a dependent or leave a stale row elsewhere. In a monorepo, also regenerate the root cross-package aggregate so the closed story is dropped from it. Do not restate the audit rules here — apply the same ones doccraft-queue-audit defines, so the two skills can never reconcile a queue differently.
NEVER guess through these — report and let the user decide:
in story.status. List the valid terminal values.
only path forward was this story and whose other prerequisites are unfinished — surface it; the close is still valid, but the user should see the downstream impact.
write. Report the plan; never overwrite in-progress work.
Before writing anything in Agent mode, MUST complete these checks:
determined. If not, stop and ask.
story.status terminal set.
its Status cell; if no row exists, note it rather than inventing one.
renumbering.
defer to the user.
status and stopping — leaves the backlog, queue, andepic stale. The whole point of this skill is the full transition.
todo / in_progress — status flows story → backlog/epic, never the reverse.
story.status — extend the vocabulary indoccraft.json first (via doccraft-config).
depends_on edge on a dependent to "unblock" it after a close —never; surface the stranded dependent and let the user decide.
The task is complete when:
status is set to the intended terminal value andupdated is bumped.
docs/backlog.md Status cell reflects the closure.docs/queue.md row is removed and rows renumbered.(via close.epic-update).
doccraft-queue-audit reconcile has run over the affected scope (andthe root aggregate refreshed in a monorepo) with no unreported drift.
doccraft-queue-audit — the reconcile invariants this skill defers to.doccraft-story — the frontmatter contract and terminal status vocab.docs/queue.md, docs/backlog.md — the surfaces reconciled.Project-specific vocabulary (terminalstatusvalues, queue-table headings, docs dir) lives indoccraft.json— the Configuration section lists the keys this skill reads. The defaults in this body apply when no config is present.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.