Skip to content

v1.17.0 ·

An unassessed control is never a pass

AIDLC already produces audit evidence and does not know it. A finished piece of work leaves numbered acceptance criteria, a design, tasks that name the criteria they satisfy, review findings with a severity and a status, a timestamped log of every phase change, and a deployment record with a rollback. An auditor would call that a change-management trail, a better one than most teams keep by hand.

But nothing in it names a control. Ask "show me your change-management control and the evidence it was applied" and what you get is a directory of markdown files and a person explaining them from memory. Evidence you have to narrate is not evidence you can hand over.

What changed

This release adds compliance packs, opt-in per project, starting with SOC 2. With none installed, nothing changes. aidlc compliance has list, add, remove, upgrade, check and report. A pack carries four things: rules for implementation time, installed through the existing guidance seam; controls, each with a phase, where to look, a fail condition and a severity; which artifact records which control decision; and metadata.

The review skill gains one dimension per control that applies to the phase under review, and findings are tagged with the control id. aidlc compliance report renders the evidence trail by control id from files already on disk. check assesses a diff without running a phase, and an unassessed control is never a pass.

The pack lives in packages/content/packs/soc2/, the code in packages/cli/src/compliance/.

Why this way

The cheap version was one more guidance file. It would have taken an afternoon and read like a style guide: prose an agent applies on best effort, no control ids, nothing afterwards saying which controls were checked. That is worse than shipping nothing, because it invites a buyer to believe something was established. I kept it only as the fallback if the structured version proved too big.

The bet in the structured version is that the report comes from existing artifacts. If it had needed new bookkeeping from developers, it would have collapsed into the cheap version, and I wanted to know that early. I also left out a registry, licence keys, signed packs and an industry catalog. A licence server is weeks of work before anyone has validated any pack content.

Removal was the hard half. There was no uninstall at all, and install leaves a locally edited layer alone, which is right. So remove has to tell "our file, safe to delete" from "the project's file now". It compares against the hashes recorded at install.

Codex now gets the same skills as Claude Code and Kiro. The adapter emits one SKILL.md under the .agents/skills folder, named for the skill per lifecycle skill with the full body, so Codex picks a skill by matching its description. Only SKILL.md is emitted, since a committed skill directory with scripts would be an auto-loading surface for anyone who clones the repo. Across 17 skills the previews use 2,583 of 5,168 characters.

Along the way I fixed a live defect: claude-code and codex both wrote the canonical skill copy to the same path in different formats, so on a two-platform project the result depended on adapter order. All five adapters now share one formatter.

An instance now has one owning platform, derived from the session log. A Codex session on a Claude-pinned instance would otherwise be priced at Claude rates. When two platforms touched one instance, its cost reports as unmeasured and names both, from a single seam that aidlc cost, aidlc metrics --json and blog frontmatter all read. A Codex cost provider reads the last-usage block and de-overlaps the counters, since cached input sits inside input tokens. A straight mapping priced one observed turn at 206,483 input-side tokens against a true 122,167.

The third piece is aidlc constitution. import reads a vision document into a vision-source file under .aidlc/context, and check reports which statements moved since and which constitution entries cite one that is gone.

Only SOC 2 ships, and packs come bundled with the CLI and are looked up by exact name. There is no registry to fetch from.