Skip to content

v1.10.2 ·

The skills were lying: six places the instructions and the code disagreed

A skill is what an agent obeys. When a skill names a file, a format or a command that the code does not support, the agent does what the skill says and the gate rejects it. The failure looks like the agent forgot something. The instructions were wrong.

I found six places where they were. Three had already cost me detours in a single session on 2026-08-25.

What was wrong

Four skills named a fixed artifact file that the templates do not require. The ideation skill said ideation.md, but the feature templates want idea.md and a spike wants research-question.md. Testing said testing.md where the templates want test-results.md. Deployment said deployment.md where they want deployment-record.md. Maintenance said maintenance.md where they want maintenance-plan.md, a mismatch nobody had hit yet. An agent followed the skill, wrote a file the gate could not see, and the gate then reported a missing artifact that nobody had told it to write.

Two skills documented commands that do not work. aidlc cost report <instance> has no report subcommand, and the working form is aidlc cost <instance>. aidlc gate deployment puts a phase name where an instance name goes.

The code hid the same class of mismatch in three places. The traceability gate read coverage claims from testing.md only, in packages/cli/src/traceability/gate-criterion.ts, so the escape hatch for indirect coverage was unreachable for anyone following the template. And the review gate could not parse what aidlc review itself writes. A review done exactly as documented parsed to zero findings, and the gate blocked with "no findings exist" while the file sat there full of them.

What changed

The skills now describe an artifact by its role and point at the template: the artifacts your template's ideation phase lists in required_artifacts, with idea.md and research-question.md as examples. I did not just fix the filenames, because no single name is right for both a feature and a spike. Renaming the template artifacts so they all agree was worse: it would break every finished instance on disk to fix a documentation error.

For the review gate I had planned to add a parser for the bullet form. Then I found packages/cli/src/commands/review.ts already had a tested one, exported, with fifteen passing tests. The gate was wired to a weaker second parser. So the fix was a deletion, and parseFindingsFromMarkdown in packages/cli/src/commands/transition.ts is gone.

That showed a worse bug. The shared parser matched status against an exact list, and 185 of the 229 status lines already on disk carry trailing prose, like resolved (requirements.md rev 2, 2026-08-18). Under exact matching a critical open finding could not block the gate it exists to block. Status and severity now match the leading word and keep the rest as a note. An unknown status counts as open and an unknown severity as critical. When the input is unclear, the safe direction is to block.

Two guards followed. The review scaffold is now parseable, so an untouched placeholder could pass for a review. Two separate markers flag it, and a test fails if someone rewords the scaffold. The gate also checks each required artifact on its own, because one real finding anywhere used to unblock every unreviewed artifact. For coverage, the template's file wins over a legacy testing.md, and the ignored file is named in a warning. I rejected merging the two, because a stale claim in the old file would keep a criterion marked covered after the new one dropped it.

What keeps it fixed

packages/cli/test/skill-code-contract.test.ts runs in the normal suite. It fails if a skill names an artifact no template requires, if an aidlc command in a skill does not exist on the built program, or if a documented file format does not parse with the real parsers.