Reverse-engineer a legacy codebase into ATDD-ready, traceable specifications
69
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
The Reviewer runs through this checklist before finalizing the confidence report. Every check is applied by meaning across whatever language doc_language selected — the rules are the same in en, pt-BR, or any other language. The mechanical hooks (doc-this-describe-only-gate.mjs, promote gate) cover en + pt-BR with regex; this checklist is the semantic safety net for everything regex misses.
These are the rules from ${CLAUDE_PLUGIN_ROOT}/skills/doc-this/references/describe-only-pact.md. Any failure REJECTS the offending content (removes it; the underlying gap, if any, becomes a 🔴 in questions.md). Log every rejection in confidence-report.md under "Pact violations rejected".
Alternatives considered unless every entry is a quoted citation from a cited sourceConsequences unless every entry is a quoted citation from a cited sourceSkip only when file-manifest.json does not exist (legacy run → recommend /doc-this --backfill-coverage).
class: source path appears in coverage-ledger.json files_analyzed (sorted-list comm -23 difference is empty); mismatch ⇒ REJECT naming the unread files.doc-this-sdd/**, judged by meaning in whatever language the file was produced in — any admission that sources were read by sampling, by outline, as N examples, or skimmed ⇒ REJECT + force re-readmarkup path has its own kind: "ui" entry in external-surface.json (controls: subkind: "control" + mounted_in); grouped "pages by module" entries ⇒ REJECTconfidence-report.md under "Total Source Coverage spot-check"Skip when doc_level = minimal (artifacts are embedded in code-analysis.md) or .doc-this/context/modules.json does not exist (legacy run). Otherwise, for each module in modules.json.modules[] — deterministic, keyed on COUNTS, never on prose:
entities[] is non-empty → <output_folder>/data-dictionary/[module].md exists and is non-empty. Missing ⇒ REJECT: name the module(s); the Code Analyst recorded entities only in modules.json and skipped the human-readable dictionary. Return for a Code-Analyst artifact pass (NOT a full re-read — see /doc-this --backfill-artifacts).functions[] or algorithms[] is non-empty → <output_folder>/flowcharts/[module].md exists and is non-empty. Missing ⇒ REJECT naming the module(s). (Keying on functions OR algorithms, never algorithms alone — algorithms[] is populated inconsistently; a module with real functions but empty algorithms[] still needs its flowchart.)flowcharts/[module]-[function].md. Missing ⇒ flag as moderate, not a hard REJECT (function-name slugging is not mechanically deterministic).data-dictionary/[module].md; function-less AND algorithm-less modules have NO flowcharts/[module].md (an empty stub is noise — flag spurious empties as cosmetic).doc-this-artifact-completeness-gate.mjs enforces this at the detective transition; re-verify here because --regenerate, backfills, and partial resumes can disturb artifact state after that gate passed (same reason A1 re-verifies coverage). Record the per-module artifact tally in confidence-report.md.
requirements.md, design.md, tasks.md)path:line citation; spot-check 5 random ones — verify they existEvidence: line under its Confidence marker; missing ⇒ add Evidence: static (specs generated before the field existed)Evidence: static + runtime cites a specific runtime artifact (log line with timestamp, span ID, HAR entry, event ID); aggregate or absence-based claims ⇒ rewrite to Evidence: static and log in confidence-report.mdEvidence: line appears under anything but a 🟢 markerdesign.md "Dependencies" section with import graphs)surface.json.modules has at least one corresponding unit (or explicit reason for omission)organization_suggestion.features has a corresponding unit (when granularity = feature)external-surface.json with visibility: public AND kind ∈ {http, grpc, websocket} has ≥ 1 @api scenario in some unitvisibility: private has an @api scenario (private = covered transitively)visibility: private entry is reachable from at least one @browser or @cli scenario's call graph; if no consumer found anywhere, flag as dead-code candidateexternal-surface.json entry with kind: ui has ≥ 1 @browser scenario@browser scenario references the route it exercises in its Given clause@api scenario has a paired @browser scenario in the same unit, OR carries an explicit @browser-exempt reason (e.g., "headless service consumed by partners only")@api @browser, both interfaces share the same Given/When/Then text — if they diverge, split into two scenarioskind: cli AND visibility: public has ≥ 1 @cli scenariokind: message AND visibility: public (publisher) has ≥ 1 @message scenario asserting topic + payload shapedatabase_ownership ∈ {external, mixed})kind: "database" AND visibility: external_dependency is referenced in ≥ 1 @database, @browser, or @cli scenario's call graph@database scenarios assert observable contract behavior (parameter shape, return, side effect on rows the app reads next), NOT internal procedure logic@database scenario cites the call site in consumed_bydatabase_ownership = owned)@database scenarios exist (DB is implementation detail; owned DBs are covered by @api/@browser/@cli scenarios end-to-end)@database scenario exists, flag as suspect and demote to 🔴 with reviewer note (record the underlying gap in questions.md)Applies to scenario step text only (Given/When/Then/And/But, pt-BR Dado/Quando/Então/E/Mas). The Realization map, design.md, and external/mixed @database scenarios are exempt — naming internals there is correct (the map and design.md document the how; an external @database proc is the contract the new system must keep honoring).
Flag a step that leaks any of these implementation classes — reframe to observable language per scenario-extraction-guide.md, and confirm the detail moved to the unit's Realization map (relocated, not deleted):
Service, Controller, Repository, Manager, Handler, Helper, Scheduler, Job, Worker, Consumer, Listener, Producer, Dispatcher, Factory, ProviderPascalCase.PascalCase(...) invocation syntax (e.g. AutoDispatch.SaveDispatch)@database step (project prefixes like TB_, VW_, plus bare UPPER_SNAKE columns asserted as the observable)P_*, DML_*, usp_*) when the DB is ownedUserId/PersonId in Session) or internal enum/model names (e.g. ECrateGrade.Premium, GrowerBatchModel)Grep starter (run, then interpret — config keys like Integration.X and external webhook payload fields like Document.Key are externally observable and stay; discard hits inside @database scenarios):
# Stage 1 isolates Gherkin step lines; stage 2 finds implementation tokens in them.
# Two greps, not one regex: a `.*` spanning a 1-char anchor (`E `) and the large
# alternation backtracks unreliably across grep flavors (verified failing on ugrep) —
# splitting is portable, and stage 1 also drops the Realization-map table rows (they
# never start with a step keyword, so the map is exempt mechanically, not by trust).
grep -rnE '^[[:space:]]*(Given|When|Then|And|But|Dado|Dada|Quando|Ent[ãa]o|E|Mas)\b' <output_folder>/*/requirements.md \
| grep -E '[A-Z][A-Za-z]+(Service|Controller|Repository|Manager|Handler|Helper|Scheduler|Job|Worker|Consumer|Listener|Producer|Dispatcher|Factory|Provider)\b|[A-Z][A-Za-z]+\.[A-Z][A-Za-z]+|\b(TB|VW|TBL)_[A-Z]|\bP_[A-Z]{3,}|\bDML_|\busp_'## Realization map, so the relocated detail is preserved with its citation@database step (when DB is owned)schema_versioning = unversioned AND no baseline DDL exists in .doc-this-sdd/database/schema.md or equivalent: refuse coverage completion. Add 🔴 GAP: "Capture baseline DDL before reimplementation can proceed; recommend snapshot via pg_dump --schema-only / mysqldump --no-data / SSMS export."When state.json.structural_extraction exists and preferred_source is "lsp" or "ua":
.understand-anything/ paths (UA knowledge graph is an internal tool artifact, not a citation source)function:src/auth/login.ts:login, file:src/models/User.ts)file:line the operation pointed tofile:line citations, not uncited assertionsLog violations in confidence-report.md under "Structural extraction citation issues".
code-spec-matrix.md has one row per class: source path in file-manifest.json — deterministic: compare the sorted manifest source slice against the sorted first-column paths (the coverage gate runs the same check before this phase; re-verify, don't assume)n/a correspond to modules.json.exclusions entries and carry the exclusion reason — any other n/a is a coverage holespec-impact-matrix.md reflects real dependencies (cross-check against design.md "Dependencies" sections)For each 🟢 claim spot-checked:
file:line supports the claim → leave 🟢file:line doesn't support the claim → either find a real citation and re-cite, or demote to 🔴 with a question in questions.md. Do not demote to 🟡 — 🟡 is retired.For any 🟡 claim found in any spec (these should not exist — their presence is a pact violation):
questions.mdconfidence-report.md under "Pact violations rejected"For each 🔴 claim:
questions.md per the question templateconfidence-report.md exists with overall % + per-unit breakdown (🟢 / 🔴 only)cross-review-result.md exists.tessl-plugin
hooks
skills
doc-this
references
scripts
doc-this-architect
references
doc-this-code-analyst
references
doc-this-data-master
doc-this-design-system
doc-this-detective
references
doc-this-help
doc-this-promote
doc-this-reviewer
doc-this-scout
doc-this-tracer
doc-this-viewer
doc-this-visor
doc-this-writer