Skip to content

v1.68.0 ·

Not every buyer asks for SOC 2

The problem

packages/content/packs/ holds one pack, soc2. Buyers outside the US ask their suppliers for ISO/IEC 27001, not SOC 2, and an ISO auditor works in Annex A control numbers. Today a team that wants the lifecycle to apply and evidence ISO 27001 controls has nothing to install.

Read from the code on 2026-10-07: packs are found by directory (resolver.ts:53), so a new directory is a new pack. The validator (schema.ts:70) accepts control ids shaped like CC8.1 — A8.25 passes, 8.25 and A.8.25 do not. check.ts:116 keys agent outcomes by control id across every installed pack, so ISO ids must not equal SOC 2 ids. Nothing in packages/cli/src names SOC 2 outside comments, so the report, check, gate and install paths need no change for a second pack. The no-claims guard (compliance-no-claims.test.ts:37) matches "is SOC 2 compliant" but not "is ISO 27001 certified".

ISO/IEC 27001:2022 Annex A has 93 controls in four themes: 5.1–5.37 organizational, 6.1–6.8 people, 7.1–7.14 physical, 8.1–8.34 technological.

How it could be solved

Three decisions, each about claiming no more than the pack can stand behind.

The first was whether the tool should bend to the standard's usual numbering. It does not. Auditors are used to seeing control 8.25 written "A.8.25" or plain "8.25". The pack writes "A8.25", which reads a little oddly, and says once what it means. In return the change stayed content only, with nothing in the tool touched. The pack's name carries the edition, "ISO 27001:2022", because the control numbers belong to that edition and the report heading should say so. The cost is one column sitting out of line in a terminal list.

The second was where to draw the line on coverage. A control counts as evidenced only where the lifecycle already writes the record an auditor would ask for: the requirements, the design, the test results, the phase log, the release record. Controls about a running system are checked while the code is written, but never offered as evidence. Eight of the excluded controls do have a code angle, such as authentication or deleting personal data. Calling them organizational would hide the gap, and covering them would go beyond what was asked, so they are marked as not built yet. Only one control is checked automatically. A second automatic check, for weak hashes, was turned down: SHA-1 has honest uses, such as naming git objects, and a check that fires on correct code teaches people to ignore it.

The third was what the tests should hold in place. Coverage is checked against all 93 controls typed out in the test, not read from the pack, so a dropped control fails loudly. The table that tells each phase which controls apply is checked against the controls themselves, and every pointer into the shared security rules must name a heading that exists. The SOC 2 pack checks neither. None of this says whether the text is right, only that it is consistent and does not overclaim. That takes a practitioner, and until one reads it the pack stays a draft.

How AIDLC solves it

iso-27001-pack

A second bundled compliance pack, iso27001, for ISO/IEC 27001:2022 Annex A, beside soc2. aidlc compliance add iso27001 installs it; check, report, the gate and the init wizard pick it up with no CLI change, because packs are found by directory.

  • Twelve controls, ids written A<theme>.<n> (A8.25 is Annex A control 8.25). Evidenced by the lifecycle trail: A5.8, A8.25, A8.26, A8.29, A8.32. Checked only: A8.4, A8.8, A8.9, A8.15, A8.24, A8.28, A8.31. A8.24 is the one mechanical check — it flags an added plain-HTTP URL other than loopback, the same pattern as SOC 2's CC6.7.
  • Eighty-one exclusions, each with a reason; eight are not-yet-built with a note on what a code lifecycle could check there.
  • One constraint layer, iso27001-constraints. It says the text is unreviewed by a compliance practitioner, paraphrases the standard and cites numbers only, covers Annex A and not clauses 4–10 (the management system), and that edits outside aidlc amend are not detected.

Minor, not patch: a new pack a user can install. Nothing changes for a project that does not add it; a project with soc2 sees no difference until it does, and both can be installed together.

Changes

  • packages/content/packs/iso27001/ — pack.yaml, controls.yaml, guidance/iso27001-constraints.md (new).
  • packages/content/docs/hygiene-and-compliance.md, README.md, packages/cli/README.md (regenerated) — name both packs.
  • Tests: iso27001-pack-content.test.ts, iso27001-pack-cli.test.ts (new); one case in compliance-wizard.test.ts; compliance-no-claims.test.ts widened to ISO 27001 phrasing.
  • .aidlc/knowledge/ — decision iso27001-control-id-format, module iso27001-pack and its uses edge to compliance-module.
  • No file under packages/cli/src/ changed. No dependency added or changed.

hooks-carry-lifecycle-state

After a session is compacted, cleared or resumed, the agent is told where it is.

  • aidlc hook session-start prints at most three plain lines — the instance claimed in this checkout with its template and scope, its phase (with the phase skill's path), and its next step, which in implementation is the lowest open task in tasks.md. One line when several instances are claimed here; nothing when none is. It reads no stdin, writes nothing, starts one git, and exits 0 on every path. Median 253 ms in this repository, where aidlc status --json takes 3.8 s.
  • aidlc hook guard (opt-in, Claude Code only) answers a PreToolUse call on Edit, Write, MultiEdit or NotebookEdit with ask when a project file outside .aidlc/ is about to be edited while the claimed instance is in ideation, requirements or design. It never denies, never allows, and is silent on anything it cannot read.
  • aidlc hook install [--guard] [--platform codex] / aidlc hook remove [--guard] write and remove them under a #aidlc-lifecycle-hook marker that the cost hooks never match. Both hooks run through the existing cost-capture shim, never a PATH lookup.
  • aidlc init installs the Claude Code session-start hook beside the cost hooks (--no-lifecycle-hooks skips it). With Codex configured, an interactive init asks first — default no — and says Codex runs it only after the user trusts it in /hooks; every other path prints aidlc hook install --platform codex instead of writing. The guard is never installed by init. AIDLC never writes a Codex trust hash, and no doctor migration installs a lifecycle hook.

Visible to users on upgrade: nothing, until they act. aidlc update and aidlc doctor add no hook. A new aidlc init — or a re-run in an existing project — adds one SessionStart entry to .claude/settings.json (a tracked file: it shows in git status; commit it). Existing projects opt in with aidlc hook install. aidlc doctor's missing-cost-shim now also regenerates the shim for a project that has the lifecycle hook but declined cost capture.

Changes

23 files under packages/ and .claude/, +2,609 / −6. 21 files under .aidlc/ (state, knowledge), +1,323. 11 commits; each code commit carries its Task: trailers.

  • packages/cli/src/hooks/lifecycle-context.ts, guard.ts, install.ts (new); packages/cli/src/commands/hook.ts (new), registered in cli.ts, excluded from the menu in menu/roster.ts.
  • concurrency/claim-store.ts (readClaims, read-only), concurrency/common-dir.ts (gitDirs, one spawn), cost/hooks/arm.ts (counts Claude Code lifecycle hooks), commands/init.ts (installLifecycleHooksAtInit, --no-lifecycle-hooks).
  • .claude/settings.json — this repository's own session-start hook.
  • packages/content/docs/skills-and-platforms.md, docs/index.yaml; regenerated packages/website/src/data/cli-reference.json.
  • Tests: six new files and a fixture, 98 tests; the command-count pins in cli-entrypoint.test.ts and the website's cli-reference.test.ts.
  • .aidlc/knowledge/ — decisions lifecycle-hooks-run-through-shim, lifecycle-hooks-read-only-claims, phase-guard-fails-open-ask-only, codex-lifecycle-hook-consent; module lifecycle-hooks-module.

help-text-truncates-cli-reference

The website's CLI reference shows each command's whole description. Six were cut off mid-sentence, because commander wraps a long description at 80 columns and the generator kept only the first line. Those six are autopilot setup, cross-check, doctor, roadmap, roadmap next and roadmap rank. The generator now joins the wrapped lines with one space.

A CLI test catches it next time. packages/cli/test/cli-reference-descriptions.test.ts compares every command and option in the committed reference with the text it was registered with, and names the command and both texts when they differ.

Nothing published to npm changes. No file under packages/cli/src or packages/content is touched; the CLI package gains one test file.

Changes

  • scripts/generate-cli-reference.mjs: parseHelp joins the description lines (T1, eab3cab2).
  • packages/website/src/data/cli-reference.json: regenerated. Six description fields change and nothing else (T1).
  • packages/cli/test/cli-reference-descriptions.test.ts: new, AC-2 to AC-5 (T2, c9f2750b).
  • packages/website/src/test/cli-reference.test.ts: one comment. No assertion changed (T2).
  • .aidlc/roadmap/inbox/20261007-help-epilog-parsed-as-options.md: the sibling defect, captured for later (2027a5ad).
  • Spec delta: ADDED cli-reference: Command descriptions are carried whole (requirements.md).

No tasks were deferred.

autopilot-reads-agent-result

Autopilot asks a preset agent how its session ended, and acts on the answer.

  • A typed result. The Claude Code presets run with --output-format json and an outcome schema. The Codex preset runs with --json, --output-schema and -o. The agent finishes by reporting shipped, paused, parked or blocked, with its reason. When the agent exits, that result decides what happens next before the instance's phase does.
  • Park reasons that name the cause. A parked item says why it stopped: the cost cap, a turn limit, a failed session, or the agent's own reason. The first tool call the scoped preset refused follows the reason.
  • The cost cap inside the run. Claude Code gets the cap as --max-budget-usd, less what the item already spent and less a 10% margin. Codex has no budget flag, so autopilot prices its token usage as it runs and stops it at the same line. Pricing needs a rate for the Codex model under cost.rates; without one, autopilot says so once and only the aidlc cost poll holds the cap. That poll is kept for every agent.
  • One resume. A session stopped by a dropped connection is resumed with its own session id at the next pass. One stopped by a session limit waits for the reset its message names, launching no other agent meanwhile, and is then resumed. A reset more than six hours away parks the item. A session is resumed once; stopping the same way again parks the item with its session id.
  • A session summary in the item's log. How the session ended, its cost, turns and session id, each refused tool call and each failed Codex command.

Visible to users on upgrade. Machines already set up with a preset get all of this with no setup run: the flags are added at launch, and config.json is unchanged. A custom agent command is launched exactly as configured and handled as before. Park reasons read differently for typed launches, and item logs gain [autopilot] summary lines.

Changes

12 files under packages/, +3,484 / −41, in 12 commits: one per task T1–T11, each with its Task: trailer, plus c8d0771a for the testing review's fixes.

  • packages/cli/src/autopilot/typed.ts (new) — what autopilot sends.
  • packages/cli/src/autopilot/result.ts (new) — what it reads back.
  • packages/cli/src/autopilot/driver.ts — the launch, the end of a session, the decision, the cap inside a Codex run, the resume, and the launch gate.
  • packages/cli/src/autopilot/run.ts, state.ts, presets.ts — the ctx seams and the new state fields; presets.ts gains a comment only.
  • packages/cli/src/cost/providers/codex.ts — rolloutModel; isCount is now exported.
  • packages/content/docs/roadmap.md — the Build step and the cost-cap answer.
  • Tests: autopilot-typed.test.ts, autopilot-result.test.ts and autopilot-agent-result.test.ts (154 new tests). autopilot-codex-preset.test.ts changes one assertion (design D4).
  • .aidlc/knowledge/ — module autopilot-typed-result and three decisions.

native-skill-metadata

The skill files AIDLC writes for Claude Code and Codex now carry each harness's own metadata, declared once per skill in the content package.

  • Argument hints. /aidlc-review shows <instance> <artifact>, /aidlc-continue shows [instance], and six other skills show theirs (argument-hint on Claude Code).
  • Autopilot starts only when asked by name. The two autopilot skills carry disable-model-invocation: true on Claude Code, so a loose sentence never launches background work. Every skill's trigger also reaches Claude Code as when_to_use.
  • Codex picks two skills on its own. Each Codex skill gains agents/openai.yaml; allow_implicit_invocation is true only for aidlc and aidlc-continue. AGENTS.md says so, and says where to read a skill Codex has not offered.
  • No plan-mode line on skills that write no artifact. The overview, getting-started and first-activation shims no longer open with "enter plan mode"; the autopilot skills lose the implementation lines on Codex. Continue and implementation keep their sub-agents line.
  • Opt-in model and effort per phase tier. skill_tiers: in .aidlc/config.yaml maps reasoning, standard and mechanical to a model and effort, written into the Claude Code shims of the phase skills in that tier. Absent — the default — writes nothing.

Visible to users on upgrade: after aidlc update, Claude Code shims gain the new header keys and CLAUDE.md gains a ## Skills line; Codex projects gain one agents/openai.yaml per skill and a reworded Phase Skills paragraph. On Claude Code, aidlc-autopilot and aidlc-autopilot-stop disappear from the model's skill list — type /aidlc-autopilot to use them. On Codex, phase skills are no longer picked by matching your words; the entry skill routes, or name one with $aidlc-<name>. Nothing changes for Kiro, Cursor, Windsurf or Copilot.

Changes

38 files under packages/, +1,292 / −33; 37 generated files, +86 / −21. Ten commits, one per task where possible, each with a Task: trailer (T4 and T5 share one).

  • packages/cli/src/compile/skill-metadata.ts (new) — allowed values, strict parse, skill_tiers check.
  • packages/cli/src/core/types.ts, compile/loaders.ts — SkillMeta fields, parse.
  • packages/cli/src/compile/adapters/claude-code.ts, adapters/codex.ts — what each harness gets.
  • packages/cli/src/commands/init.ts, commands/update.ts — skill_tiers wiring.
  • packages/content/skills/*.md — frontmatter declarations on all 20 skills; no body changed.
  • packages/content/docs/skills-and-platforms.md — "Skill metadata", "Model and effort per tier".
  • Tests: five new files (skill-metadata*.test.ts, 91 tests); five existing files updated where they counted Codex files or pinned the review shim's control — reasons in code-complete.md.
  • .aidlc/knowledge/ — decision skill-metadata-strict-new-keys; module compile-adapters updated.