Skip to content

/sdlc:entities-audit

Generated from solutions/ontological/skills/entities-audit/SKILL.md.

Audit every entity instance under docs/planning// against the current entity schemas in the plugin. Reports schema_version drift, frontmatter validation errors, depends_on graph issues, and prose-section drift (missing template H2s). Read-only: catalogues drift, applies no fixes. Mechanical fixes are /sdlc:entities-migrate’s job (see also).

  • Bash

Usage:

  • /sdlc:entities-audit — audit every active entity type, markdown report. Closed entities are skipped by default.
  • /sdlc:entities-audit --types task — restrict to one entity type.
  • /sdlc:entities-audit --json — JSON output (for piping into other tooling).
  • /sdlc:entities-audit --include-archive — also audit files under docs/planning/<plural>/archive/.
  • /sdlc:entities-audit --include-closed — also drift-check entities whose status is closed. Default skips them.

Project context (don’t re-derive every run):

  • The plugin keeps one schema per entity type at ${CLAUDE_PLUGIN_ROOT}entities/<type>/schema.ts. Each schema now carries a top-level version (integer). Instance frontmatter carries a schema_version (numeric string) to record which version it conforms to.
  • Canonical instance dirs are docs/planning/<plural>/ under the project root (taskdocs/planning/tasks/).
  • The audit is read-only: it catalogues drift. Mechanical fixes (auto_fixable=true drift) are the job of /sdlc:entities-migrate.
  1. Run the op from the project root:

    ${CLAUDE_PLUGIN_ROOT}cli/sdlc entities audit

    The default output is the markdown report. Append any flags the user passed (--types, --include-archive). If the user passed --json, append --json — the op then emits the JSON payload instead.

  2. Print the op’s output verbatim. The markdown report is already shaped for the user — don’t paraphrase or summarize unless asked.

  3. If the user invoked the skill with --json, pass that through unchanged so the output can be piped. Under --json the drift signal is the payload’s serious boolean — a JSON consumer reads that field rather than the process exit code.

  4. Note the exit code (default markdown output):

    • 0 — no structural drift. Prose drift is reported but doesn’t fail the audit.
    • 1 — structural drift (schema_version, frontmatter, or parse errors) detected on at least one entity.
    • 2 — op error (missing dirs, malformed schema). Show the stderr to the user.

The audit tags every drift entry with a kind and an auto_fixable flag:

kindauto_fixablemeaning
schema_versiontrueFrontmatter is missing schema_version. Migrator stamps the schema’s current version. Only reported for closed entities when --include-closed is set.
schema_versiontrueschema_version is older than the schema’s current version AND a transform module exists at entities/<type>/migrations/v<file>-to-v<current>.ts. Migrator imports the transform and applies it.
schema_versionfalseschema_version is older than the schema’s current version (and not the 0 sentinel), but no matching transform module is on disk. Needs a real migration written first.
frontmatterfalsejsonschema validation error (wrong enum value, missing required field, etc.). Manual.
depends_onfalseCross-file check on the task depends_on graph: either a cycle (A → B → A) or a broken link (target does not resolve to a known entity under docs/planning/ — resolution spans the whole cross-entity corpus, so a task may depend on a decision, standard, etc.). Manual fix — edit the offending file.
prosefalseTemplate ## Section heading not present in the instance body. Reported but not enforced.
parsefalseFile could not be parsed (no frontmatter, malformed YAML, unreadable).

The audit also tags each file with closed: bool (in JSON output) and a [closed] suffix (in markdown). By default, closed entities are skipped — no drift checks run against them at all — so they always render as OK in the report. Pass --include-closed to drift-check closed entities like active ones (the companion /sdlc:entities-migrate accepts the same flag and forwards it). The 0 sentinel (schema_version: 0) means “intentionally pre-SDLC-managed”: audit treats it as not-drift rather than “older than current”.

  • Prose drift is informational. Templates declare every H2 they ship with, but several are explicitly optional (“delete this section if scope is obvious”). The audit reports every missing H2 as drift; it does not fail the run on prose drift. (A later iteration could let templates declare which H2s are required, so the report can separate must-have from nice-to-have prose sections.)
  • Archive subdirs are skipped by default. Anything under docs/planning/<plural>/archive/ (or archived/) is excluded unless --include-archive is set.
  • Type filter. --types is repeatable; restrict to a subset when iterating on a single entity type’s drift.
  • Safe as a summary step. Being read-only, this skill can be wired into other skills (e.g. /sdlc:setup) as a closing summary step.