@rasensio/aidlc-content 1.67.0 → 1.73.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,6 +55,35 @@ that acts on a record's *absence*. So the two provenance-dependent migrations co
55
55
  `complianceSectionState()` first and decline to run at all when the section is present but
56
56
  unreadable, rather than concluding a live pack was uninstalled.
57
57
 
58
+ ### Why a mechanical control's pattern is tested in the direction it is wrong
59
+
60
+ A control with `check_kind: mechanical` carries a `pattern`, and `aidlc compliance check` fails the
61
+ control when any added line matches it. That makes the pattern the whole control: there is no prose
62
+ for an agent to interpret and no second opinion.
63
+
64
+ The plain-HTTP control shipped for months with `http://(?!localhost|127\.0\.0\.1|\[::1\])`, and its
65
+ test asserted the two things the pattern got right — plain HTTP to `api.example.com` is flagged,
66
+ `http://localhost:3000` is not. Nothing asked about a host that merely *starts* with a loopback
67
+ name, and the lookahead had no host boundary, so `http://localhost-api.corp.net` and
68
+ `http://localhost@evil.example.com` passed a check whose report said it ran. A second pack then
69
+ copied the pattern as "already tested", and copied the blind spot with it.
70
+
71
+ Two rules came out of that, and they generalise to any pattern-backed control:
72
+
73
+ - **A pattern's test covers the cases it was written from, which are the cases its author already
74
+ had right.** The useful cases are the ones that distinguish a correct pattern from a plausible
75
+ one — a near miss on each side of the boundary. Pin the superseded pattern in the test and assert
76
+ that every new case was one it got wrong; otherwise a case that passes under both patterns reads
77
+ as coverage and is not.
78
+ - **One pattern in two packs is one pattern.** Two controls sharing a rule share the string, and a
79
+ test asserts they are equal. Divergence then fails a test rather than becoming two patterns
80
+ nobody compares.
81
+
82
+ The false-positive side is a deliberate trade. The pattern now flags `localhost.localdomain` and
83
+ `127.0.0.1.nip.io`, which really are loopback, because sparing them would need a host parser rather
84
+ than a regular expression — and a control that misses a real host is worse than one that asks about
85
+ an unusual alias.
86
+
58
87
  ## How to use it
59
88
 
60
89
  ```
@@ -104,7 +133,8 @@ entry's own recorded hash matches what is on disk. The record is tracked, so a c
104
133
  it. The hash used to be looked up by file *basename*, so a second entry named `victim.md` could
105
134
  vouch for `../../victim.md` and get a file outside the project deleted (security-review-findings).
106
135
 
107
- `compliance list` shows packs available and installed. `soc2` ships with the framework. `check` returns
136
+ `compliance list` shows packs available and installed. Two ship with the framework: `soc2` and
137
+ `iso27001` (ISO/IEC 27001:2022, Annex A only). `check` returns
108
138
  the controls applying to the current phase, each with its requirement, where to look, and its fail
109
139
  condition.
110
140
 
@@ -128,7 +158,8 @@ and read what it says the second time. Steady-state bugs are invisible on the fi
128
158
  - `packages/cli/src/doctor` — the checks and repairs. `migrations` holds the one-off repairs, including
129
159
  the nested-`.gitignore` coverage fix.
130
160
  - `packages/cli/src/compliance` — pack loading, control evaluation, and the evidence report.
131
- - `packages/content/packs` — the shipped packs; `soc2` is the only one today.
161
+ - `packages/content/packs` — the shipped packs, `soc2` and `iso27001`. A new directory there is a new
162
+ pack; nothing else registers it.
132
163
  - `packages/content/skills/80-review.md` — where the compliance findings stream is specified, including
133
164
  the two-places rule for every applicable control.
134
165
  - `packages/cli/src/operational/redact.ts` — redaction used when repo state is turned into something
package/docs/index.yaml CHANGED
@@ -91,7 +91,7 @@ entries:
91
91
  title: Skills and platforms
92
92
  file: skills-and-platforms.md
93
93
  source: packages/cli/src/compile
94
- commands: [add, update, docs, explain]
94
+ commands: [add, update, docs, explain, hook]
95
95
 
96
96
  - id: hygiene-and-compliance
97
97
  kind: topic
@@ -113,3 +113,10 @@ historical_paths:
113
113
  `knowledge-stale-sources` check: 15 graph entities described it for 17 days, and
114
114
  neither page can make that point without writing the path that no longer resolves.
115
115
  The entries were removed by stale-graph-entries; the story is what stays.
116
+ - path: .codex/hooks.json
117
+ reason: >-
118
+ Codex's project hook file, named in skills-and-platforms.md as where the Codex
119
+ session-start hook goes. It is written only when a user agrees to it
120
+ (hooks-carry-lifecycle-state/AC-18, AC-20), and nobody has agreed for this
121
+ repository, so it does not exist here — an unattended session cannot give that
122
+ consent on the user's behalf.
@@ -119,3 +119,34 @@ One implementation lesson worth carrying: a "preserve this unchanged" path that
119
119
  serializer does not preserve anything. Rebuilding the index must copy bytes, not re-emit parsed
120
120
  structures, or comment formatting and key order drift on every rebuild — 829 lines of diff versus 108
121
121
  on real data.
122
+
123
+ ## Why the index checks whether it is current
124
+
125
+ `index.db` is a cache, and for two months it was rebuilt only when it was missing or empty. That
126
+ covers the index you have never built. It does not cover the one you built in September and have been
127
+ pulling other people's commits into ever since — so facts arriving by `git pull`, a merge, a branch
128
+ switch or another worktree's commit never reached it, and `aidlc knowledge query` answered from
129
+ whatever state the file was first built in.
130
+
131
+ The tell was in `CLAUDE.md`. The `# Codebase Knowledge` block is generated from the index, so two
132
+ checkouts with differently-stale caches generated two different blocks, and one entry flipped between
133
+ its current and stale text ten times in a month. Six instances hit it, and all six reverted it by hand
134
+ as "unrelated churn" — which is the part worth remembering. A wrong answer that looks like noise gets
135
+ filed as noise. Nobody reported it as a defect until a retrospective counted the reverts.
136
+
137
+ So the index now records a stat hash of the sources it was built from — path, size and mtime, never
138
+ contents — and rebuilds whenever that record and the disk disagree. Three things about it are
139
+ deliberate:
140
+
141
+ - **Stat, not content.** Reading every file to decide whether to read every file buys nothing:
142
+ parsing this project's 62 source files costs 185ms and stat-ing them costs 1ms.
143
+ - **The hash is taken before the sources are read**, not after, so a file that changes mid-read leaves
144
+ the record stale and the next open rebuilds. Every failure mode is pointed the same way: a missing
145
+ or unreadable or unparseable fingerprint all mean *rebuild*. Forgetting to record one costs an extra
146
+ rebuild; forgetting to check one costs a month of wrong facts, and that asymmetry decides every
147
+ default in the design — including why `compact` and the write paths deliberately record nothing.
148
+ - **It lives inside `index.db`**, not in a sidecar, so `rm index.db` can never leave behind a
149
+ fingerprint claiming the cache is fresh. Deleting the file stays a complete repair.
150
+
151
+ The same shape guards the coverage cache in `src/traceability/cache.ts`, which is where the pattern
152
+ came from.
package/docs/roadmap.md CHANGED
@@ -168,6 +168,30 @@ Each item goes through these steps:
168
168
  error within 30 seconds of launch parks the item with `agent failed to launch (exit <code>):`
169
169
  and the first line it printed, so a flag the agent no longer accepts names itself instead of
170
170
  reading as a failed build.
171
+
172
+ **The agent reports a typed result.** With one of the Claude Code or Codex presets, autopilot
173
+ asks the agent how it ended: Claude Code runs with `--output-format json` and an outcome schema,
174
+ Codex with `--json`, `--output-schema` and `-o`, and the agent finishes by reporting `shipped`,
175
+ `paused`, `parked` or `blocked`, with its reason. When the agent exits, that result decides what
176
+ happens next before the instance's phase does, so a parked item says why it stopped — the cost
177
+ cap, a turn limit, a failed session, or the agent's own reason, followed by the first tool call
178
+ the scoped preset refused. Each session also leaves a summary in the item's log: how it ended,
179
+ what it cost, its turns, its session id, and each refused tool call and failed command.
180
+
181
+ **A stopped session is resumed once.** An item stopped by a dropped connection is resumed with
182
+ its own session id at the next pass. One stopped by a session limit waits for the reset time
183
+ its message names — an hour when it names none, parked at once when the reset is more than six
184
+ hours away — launches no other agent meanwhile, and is then resumed once. Stopping the same way
185
+ again parks it with the session id. A command you typed yourself is launched exactly as you
186
+ wrote it and handled as before.
187
+
188
+ **A session that ended before the release boundary is resumed once too.** Under `claude -p`
189
+ the end of the agent's turn is the end of its session, so an agent that ends its turn to wait
190
+ for its test suite is gone, and the suite with it. When a session ends short of the release
191
+ boundary with no outcome, `blocked`, or a `shipped` or `paused` its phase does not bear out,
192
+ it is resumed at the next pass, with a prompt to run the command again and wait for it inside
193
+ the turn. A second early ending parks the item with the session id. Every resume releases the
194
+ instance's claim first, so the resumed session can take it.
171
195
  3. **Your review, after each paused phase.** When a phase in `pause_after` is complete and
172
196
  unapproved, the item waits as `awaiting-review` — not parked. Read the artifact in the item's
173
197
  worktree, then `aidlc autopilot approve <instance>`; the next pass waits at the next paused
@@ -186,9 +210,16 @@ Each item goes through these steps:
186
210
  6. **Up to date with main**, for an item autopilot merges itself. Before merging, it merges
187
211
  `origin/main` into the branch in the
188
212
  item's worktree — locally, so the repository's `merge=union` rules apply — pushes, and waits for
189
- CI on the new head. A conflict goes back to the item's agent to resolve, twice at most, then the
190
- item is parked. A pull request with no checks that GitHub reports as conflicting is handled the
191
- same way: GitHub runs no checks on a conflicting PR, so waiting for them would wait forever.
213
+ CI on the new head. Just before that merge it commits the worktree's two cost ledgers,
214
+ `.aidlc/cost/unattributed.ndjson` and the instance's `costs.ndjson`, and nothing else: the cost
215
+ hook keeps writing to them after the agent's last commit, and git refuses to merge over an
216
+ uncommitted change to a file main also changed. A conflict — a merge that leaves unmerged
217
+ files — goes back to the item's agent to resolve, twice at most, then the item is parked. A merge
218
+ git refuses without one, because some other local change would be overwritten, is not a
219
+ conflict: it halts the queue as a failed update with git's message, and `aidlc autopilot run`
220
+ resumes it once you have dealt with the change. A pull request with no checks that GitHub reports
221
+ as conflicting is handled the same way: GitHub runs no checks on a conflicting PR, so waiting for
222
+ them would wait forever.
192
223
  7. **Merge and release**, one at a time, never while a release workflow is running: merge the exact
193
224
  commit CI passed (`--match-head-commit`), pull `main`, run the release step when the item's stop
194
225
  is `release`, then `aidlc transition` to close the instance. A failure halts the queue. Running
@@ -209,7 +240,12 @@ six questions on its own. Each is a list with one choice marked recommended:
209
240
  it is never picked for you: with no terminal, setup needs `--agent <preset>` or
210
241
  `--non-interactive`.
211
242
  - **How many items build at once** — two (recommended) or one.
212
- - **A cost cap per item** — an item past it is stopped and parked.
243
+ - **A cost cap per item** — an item past it is stopped and parked. Claude Code is given the cap as
244
+ its budget (`--max-budget-usd`), less what the item already spent and a 10% margin, because it
245
+ checks its budget only after each turn. Codex has no budget flag, so autopilot prices its token
246
+ usage as it runs and stops it at the cap less the same margin. That needs a rate for its model
247
+ under `cost.rates` in `.aidlc/config.yaml`; without one autopilot says so once, and only
248
+ `aidlc cost` holds the run to the cap.
213
249
  - **Which phases to pause after for your review** — after requirements and design (recommended),
214
250
  after design only, or no pauses. These are the two phases whose output decides the shape of the
215
251
  code.
@@ -93,6 +93,59 @@ reviewer cannot write, it replies with its findings files and the session that s
93
93
  unchanged. Claude Code reads `.claude/agents/` at session start, so an `update` that adds the agent
94
94
  takes effect in the next session.
95
95
 
96
+ **Skill metadata** is the other thing a skill declares for the harnesses rather than for the reader.
97
+ Four optional keys sit in a content skill's frontmatter, and each adapter translates them; none of
98
+ them reaches the shared copy under `.aidlc/skills/`, and a bad value fails the parse rather than
99
+ quietly meaning the default.
100
+
101
+ - `arguments` — a one-line hint, such as `<instance> <artifact>` on the review. Claude Code shows it
102
+ as `argument-hint` when you type `/aidlc-review`.
103
+ - `invocation` — who may start the skill. `auto`: the model, on a matching request. `routed`: reached
104
+ through another skill or by name. `user`: only you, by name. On Claude Code `user` becomes
105
+ `disable-model-invocation: true`, which the two autopilot skills carry so a loose sentence never
106
+ launches background work; `routed` changes nothing there, because a description match is how Claude
107
+ Code routes. On Codex, `agents/openai.yaml` beside each skill sets `allow_implicit_invocation`, true
108
+ only for `aidlc` and `aidlc-continue`. That keeps Codex's listing — 2% of the context window, with
109
+ descriptions shortened first when over it — to two skills. `aidlc-continue` stays implicit because
110
+ autopilot names it in plain words, and the sub-agents line one-agent-per-task depends on is in the
111
+ Codex skill file only, not in the shared copy.
112
+ - `tier` — `reasoning` (ideation, requirements, design), `standard` (implementation, maintenance) or
113
+ `mechanical` (testing, deployment). See below.
114
+ - `activation: none` — the skill takes none of its phase's capability lines. The overview is declared
115
+ `phase: ideation`, so before this it opened with "enter plan mode" although it writes nothing.
116
+ Getting-started, first-activation, the review and the two autopilot skills declare it too.
117
+ `aidlc-continue` must not: it is the route an unattended run takes into implementation.
118
+
119
+ A Claude Code shim also gets `when_to_use` from the skill's `trigger`. Both managed blocks — the one in
120
+ `CLAUDE.md` and the one in `AGENTS.md` — say where to read a skill the agent is not offered, so the
121
+ entry skill's "follow the aidlc-autopilot skill" still works when the model cannot pick that skill
122
+ itself.
123
+
124
+ There is no tool profile, on purpose. Claude Code's `disallowed-tools` lasts until your next message,
125
+ and an unattended run is a single message, so a read-only skill loaded anywhere in it would take Edit
126
+ and Write away for the rest of the run. The review, the one skill that must not write, already gets
127
+ that from its agent.
128
+
129
+ **Model and effort per tier** are off until you set them, in `.aidlc/config.yaml`:
130
+
131
+ ```yaml
132
+ skill_tiers:
133
+ mechanical:
134
+ model: sonnet
135
+ effort: low
136
+ reasoning:
137
+ effort: high
138
+ ```
139
+
140
+ Each value is written as `model` or `effort` into the Claude Code shims of the skills in that tier;
141
+ `inherit`, or no entry, writes nothing. `effort` takes `low`, `medium`, `high`, `xhigh` or `max`. A
142
+ `model` must be one name of letters, digits and `. _ - : / [ ]` — a value that is not is warned about and
143
+ left out, which is also what stops a config value from adding a header line of its own. Two limits are
144
+ Claude Code's, not AIDLC's. The override lasts until your next message, and it applies only when the
145
+ phase skill itself is invoked, as `/aidlc-testing`; `aidlc-continue` reads a phase's body directly, so
146
+ an unattended run is not routed. Codex gets neither value: it would need a custom agent or a profile per
147
+ tier, which is not built.
148
+
96
149
  Those files also carry a **top-level `questions:` key**, outside the phase-keyed `capabilities:` map, and
97
150
  the reason it sits outside is not cosmetic. The shared capability resolution returns exactly one
98
151
  activation string per phase, and three platforms already occupy `requirements` and `design` — the two
@@ -122,6 +175,32 @@ an adapter to emit a file, check which of those two shapes you have first.
122
175
  If you are adding an operational skill of your own, reuse this seam rather than writing platform files
123
176
  directly.
124
177
 
178
+ **Lifecycle hooks** carry state the skills cannot: where the agent is after a session was compacted,
179
+ cleared or resumed. `aidlc hook session-start` prints at most three lines — the instance claimed in
180
+ this checkout, its phase and its next step, the lowest open task in implementation — and nothing
181
+ when nothing is claimed here. A claim counts when it was recorded from this working directory, stale
182
+ or not: claims renew only at phase transitions, and one phase outlasts the 60-minute window, so a
183
+ live-only rule would go quiet on a compaction deep into implementation, the case the hook is for. It
184
+ reads no stdin, writes nothing, and reads only the claimed instance's files — `aidlc status --json`
185
+ reads every instance and ledger and is far too slow for a hook. `aidlc init` installs it for Claude
186
+ Code in `.claude/settings.json`, beside the cost hooks, under its own `#aidlc-lifecycle-hook` marker so
187
+ neither installer counts or removes the other's entries; existing projects run `aidlc hook install`.
188
+ Both hooks run through the cost-capture shim, never a `PATH` lookup. For Codex, init asks first,
189
+ defaulting to no, and writes the project's `.codex/hooks.json` only on a yes (or on
190
+ `aidlc hook install --platform codex`): Codex runs a project hook only after the user trusts it with
191
+ `/hooks`, keyed on its content, and AIDLC never writes that trust — which is also why install rewrites
192
+ the file only when its text would change.
193
+
194
+ **The phase guard** is the opt-in other half: `aidlc hook install --guard` adds a `PreToolUse` hook on
195
+ `Edit`, `Write`, `MultiEdit` and `NotebookEdit` that **asks** before a project file outside `.aidlc/`
196
+ is edited while the claimed instance is in ideation, requirements or design. It never denies and never
197
+ allows, and on anything it cannot read it says nothing, so the normal permission flow decides. That is
198
+ the reviewer guard's contract inverted on purpose: the reviewer guard is a security boundary and fails
199
+ closed; this one enforces a process rule, and a hook that blocks legitimate work is the failure it
200
+ must not have. Files written through `Bash` are not seen — a guardrail, not a boundary. Codex has no
201
+ guard, because its `PreToolUse` can deny or rewrite a call but not ask. `aidlc hook remove --guard`
202
+ takes it away again.
203
+
125
204
  **Unattended mode.** Every skill assumes a person is there to answer. With `AIDLC_UNATTENDED=1`, an
126
205
  agent follows `.aidlc/resources/rules/unattended.md` instead: each place a skill would ask, wait or
127
206
  confirm has one written outcome — take the named default and log it to the instance's
@@ -141,10 +220,16 @@ would be a cost every future change pays.
141
220
  through `90-retrospective.md`). This is the only place instructions are authored.
142
221
  - `packages/content/capabilities` — per-platform capability declarations, plus each platform's
143
222
  `questions:` rendering.
223
+ - `packages/cli/src/compile/skill-metadata.ts` — the allowed values of the four skill metadata keys
224
+ and the `skill_tiers` check, in one place so the parser, the adapters and the config cannot disagree.
144
225
  - `packages/cli/src/compile/question-rendering.ts` — emits `.aidlc/resources/questions/rendering.md`, the
145
226
  one file holding how each configured platform puts a question in front of the user. The protocol it
146
227
  serves is in `packages/content/resources/rules/question-protocol.md` and names no platform tool
147
228
  anywhere; that split is what stops the question shape from being written for one platform's UI.
229
+ - `packages/cli/src/hooks` — the lifecycle hooks: `lifecycle-context.ts` reads claims and the claimed
230
+ instance's state without writing (it does not open the claim store, which creates directories and
231
+ migrates legacy claims), `guard.ts` decides the phase guard's `ask`, and `install.ts` merges both
232
+ platforms' hook files. `commands/hook.ts` is the `aidlc hook` command.
148
233
  - `packages/content/resources/rules` — the six rules skills send readers to (the context rule, the
149
234
  always-read rule, the constitution rule, the Question Protocol, Creating an Instance, Lifecycle or
150
235
  Skill?), one file each. `packages/cli/src/compile/rules.ts` emits them to `.aidlc/resources/rules/`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc-content",
3
- "version": "1.67.0",
3
+ "version": "1.73.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,574 @@
1
+ # ISO/IEC 27001:2022 — Annex A controls only.
2
+ #
3
+ # Ids are written A<theme>.<n>: `A8.25` is Annex A control 8.25. The pack validator
4
+ # accepts that shape and rejects `A.8.25` and `8.25`, and the A prefix keeps every id
5
+ # distinct from the SOC 2 pack's CC ids, which matters because `aidlc compliance
6
+ # check` keys agent outcomes by control id across all installed packs
7
+ # (iso-27001-pack/AC-4, AC-24).
8
+ #
9
+ # Clauses 4-10 — the information security management system itself — are not
10
+ # controls and are not listed here. Certification is of that system, and nothing a
11
+ # code tool reads can speak to it. The constraint layer says so.
12
+ #
13
+ # The text below paraphrases the standard in this pack's own words and cites control
14
+ # numbers only. ISO's text is copyrighted; obtain the standard from ISO.
15
+ #
16
+ # `kind` says what the AIDLC artifact trail can establish:
17
+ #
18
+ # evidenced the trail genuinely demonstrates the control
19
+ # checked-only the control operates over a running system, so no document
20
+ # evidences it; the pack supplies a fail condition an agent
21
+ # applies, and the trail records only that the check happened
22
+ #
23
+ # `check_kind` says who applies the fail condition: `mechanical` controls carry a
24
+ # pattern the diff check evaluates itself, `agent` controls need a review session.
25
+ #
26
+ # Five controls are `evidenced`. Seven are `checked-only`. Eighty-one Annex A
27
+ # controls are not covered at all, each listed below with its reason.
28
+ #
29
+ # `references` points at the guidance layer whose rule a control restates, so the
30
+ # duplication is traceable. The pack's own constraint layer does not restate those
31
+ # rules.
32
+
33
+ controls:
34
+ # -------------------------------------------------------------------------
35
+ # Evidenced: the lifecycle trail is real evidence for these controls. Most of
36
+ # them sit in the 8.25-8.33 run of software-development controls.
37
+ # -------------------------------------------------------------------------
38
+ - id: A5.8
39
+ kind: evidenced
40
+ check_kind: agent
41
+ severity: major
42
+ phases:
43
+ - requirements
44
+ - design
45
+ requires: >-
46
+ Information security is built into how projects are run, whatever kind of
47
+ project it is: security risks are identified early and handled as part of the
48
+ project's own work rather than afterwards.
49
+ look_at: >-
50
+ design.md for the security considerations of the change — the risks it names
51
+ and how each is handled — and requirements.md for the non-functional security
52
+ requirements the design answers to.
53
+ fails_when: >-
54
+ design.md is absent, or names no security consideration for the change: neither
55
+ a risk with how it is handled, nor an explicit statement that the change carries
56
+ none.
57
+ evidence_artifact: design.md
58
+
59
+ - id: A8.25
60
+ kind: evidenced
61
+ check_kind: agent
62
+ severity: major
63
+ phases:
64
+ - requirements
65
+ - design
66
+ - implementation
67
+ - testing
68
+ - deployment
69
+ requires: >-
70
+ Rules for developing software and systems securely are set and are actually
71
+ applied to the development work.
72
+ look_at: >-
73
+ transitions.log for the recorded passage of the change through each lifecycle
74
+ phase its template requires, and the guidance layers each phase read — the
75
+ secure-defaults layer above all — as the development rules applied.
76
+ fails_when: >-
77
+ The instance has no transitions.log, or the log shows the change skipping a
78
+ phase its template requires, so the change did not pass through the defined
79
+ development lifecycle.
80
+ evidence_artifact: transitions.log
81
+
82
+ - id: A8.26
83
+ kind: evidenced
84
+ check_kind: agent
85
+ severity: major
86
+ phases:
87
+ - requirements
88
+ - design
89
+ requires: >-
90
+ The security requirements of an application are identified, specified and
91
+ approved when it is developed or acquired.
92
+ look_at: >-
93
+ requirements.md: the acceptance criteria and the non-functional security
94
+ section, read against what the change handles — sensitive data,
95
+ authentication, access control, external input.
96
+ fails_when: >-
97
+ A change that handles sensitive data, authentication or access control reaches
98
+ design with no acceptance criterion in requirements.md stating the security
99
+ requirement it must meet.
100
+ evidence_artifact: requirements.md
101
+
102
+ - id: A8.29
103
+ kind: evidenced
104
+ check_kind: agent
105
+ severity: major
106
+ phases:
107
+ - testing
108
+ requires: >-
109
+ Security testing is defined and carried out as part of the development
110
+ lifecycle, before a change is accepted.
111
+ look_at: >-
112
+ test-results.md for the outcome of the testing phase, and the tests that
113
+ reference each security acceptance criterion in requirements.md.
114
+ fails_when: >-
115
+ test-results.md is absent or names no outcome, or a security acceptance
116
+ criterion in requirements.md has no test referencing it.
117
+ evidence_artifact: test-results.md
118
+
119
+ - id: A8.32
120
+ kind: evidenced
121
+ check_kind: agent
122
+ severity: critical
123
+ phases:
124
+ - requirements
125
+ - design
126
+ - implementation
127
+ - testing
128
+ - deployment
129
+ requires: >-
130
+ Changes to information processing facilities and systems go through change
131
+ management: each is planned, assessed for impact, authorised, tested and
132
+ accepted before release, with a way back if it fails.
133
+ look_at: >-
134
+ requirements.md for numbered acceptance criteria authorising the change;
135
+ design.md for what the change touches; tasks.md for the link from each task to
136
+ its criteria; test-results.md for the test outcome; transitions.log for the
137
+ recorded phase progression; and deployment-record.md for the release and its
138
+ rollback.
139
+ fails_when: >-
140
+ A change reached deployment without each of these on record: numbered criteria
141
+ in requirements.md, a design.md naming what the change touches, a
142
+ test-results.md naming an outcome, and a deployment-record.md naming what
143
+ shipped and how to roll it back.
144
+ evidence_artifact: deployment-record.md
145
+
146
+ # -------------------------------------------------------------------------
147
+ # Checked-only: these operate over a running system or its surroundings. The
148
+ # pack gives you a fail condition to apply; the trail records that you applied
149
+ # it, never that the control operates.
150
+ # -------------------------------------------------------------------------
151
+ - id: A8.4
152
+ kind: checked-only
153
+ check_kind: agent
154
+ severity: major
155
+ phases:
156
+ - implementation
157
+ - deployment
158
+ requires: >-
159
+ Read and write access to source code, development tools and software
160
+ libraries is managed appropriately.
161
+ look_at: >-
162
+ Repository access configuration touched by the change: CI workflow
163
+ permissions and secret access, code-ownership rules, branch-protection
164
+ settings, and any token or deploy key the change introduces.
165
+ fails_when: >-
166
+ The change widens write access to the repository or its pipelines with no
167
+ stated reason — a CI job gains write permissions or access to secrets, an
168
+ ownership rule for a path is removed, or a token with repository write scope is
169
+ added.
170
+ references: secure-defaults#least-privilege-and-defense-in-depth
171
+
172
+ - id: A8.8
173
+ kind: checked-only
174
+ check_kind: agent
175
+ severity: major
176
+ phases:
177
+ - implementation
178
+ - deployment
179
+ - maintenance
180
+ requires: >-
181
+ Information about technical vulnerabilities in the systems in use is obtained,
182
+ the organisation's exposure is evaluated, and suitable measures are taken.
183
+ look_at: >-
184
+ Dependency manifests and lockfiles in the change, and whether the build or CI
185
+ runs a vulnerability audit over the dependency set.
186
+ fails_when: >-
187
+ A dependency is added without a lockfile entry, a dependency range is left
188
+ unpinned, or the project runs no dependency vulnerability audit in its build or
189
+ CI.
190
+ references: secure-defaults#dependency-security
191
+
192
+ - id: A8.9
193
+ kind: checked-only
194
+ check_kind: agent
195
+ severity: major
196
+ phases:
197
+ - implementation
198
+ - deployment
199
+ requires: >-
200
+ Configurations of hardware, software, services and networks, security
201
+ configurations included, are established, documented, implemented, monitored
202
+ and reviewed.
203
+ look_at: >-
204
+ Configuration and infrastructure-as-code changes in the diff: TLS and
205
+ certificate settings, CORS and security headers, debug and feature flags, and
206
+ network rules defined as code.
207
+ fails_when: >-
208
+ A configuration change relaxes a security setting with no stated reason — TLS
209
+ verification turned off, a wildcard CORS origin, a security header removed, or
210
+ debug mode enabled in a production configuration.
211
+ references: secure-defaults#transport-and-data-protection
212
+
213
+ - id: A8.15
214
+ kind: checked-only
215
+ check_kind: agent
216
+ severity: major
217
+ phases:
218
+ - implementation
219
+ - deployment
220
+ - maintenance
221
+ requires: >-
222
+ Logs recording activities, exceptions, faults and other relevant events are
223
+ produced, stored, protected and analysed.
224
+ look_at: >-
225
+ Error handling and logging in the change: whether failures and
226
+ security-relevant events are recorded with enough context to investigate, and
227
+ whether anything sensitive is written to a log.
228
+ fails_when: >-
229
+ A failure path swallows an error without logging it, a security-relevant event
230
+ such as a failed authentication or a denied access goes unlogged, or a log
231
+ statement records a secret or personal data.
232
+ references: secure-defaults#error-handling-and-logging
233
+
234
+ - id: A8.24
235
+ kind: checked-only
236
+ check_kind: mechanical
237
+ severity: major
238
+ phases:
239
+ - implementation
240
+ - deployment
241
+ requires: >-
242
+ Rules for the effective use of cryptography, key management included, are
243
+ defined and implemented.
244
+ look_at: Network client configuration and request targets in the change.
245
+ fails_when: >-
246
+ An added line targets a plain-HTTP URL whose host is not exactly localhost,
247
+ 127.0.0.1 or [::1], so information would be transmitted without transport
248
+ encryption.
249
+ # The same string as SOC 2 CC6.7, kept equal by plain-http-pattern.test.ts; the
250
+ # reasoning for its shape is beside that control.
251
+ pattern: "[hH][tT][tT][pP]://(?!(?:[lL][oO][cC][aA][lL][hH][oO][sS][tT]|127\\.0\\.0\\.1|\\[::1\\])(?::\\d+)?(?![\\w:@%~-]|\\.[\\w-]))"
252
+ references: secure-defaults#transport-and-data-protection
253
+
254
+ - id: A8.28
255
+ kind: checked-only
256
+ check_kind: agent
257
+ severity: critical
258
+ phases:
259
+ - design
260
+ - implementation
261
+ requires: >-
262
+ Secure coding principles are applied when software is developed.
263
+ look_at: >-
264
+ Every place external input crosses into the system in the change — request
265
+ handlers, message consumers, file uploads and any parser reached from them —
266
+ and any credential handling.
267
+ fails_when: >-
268
+ External input reaches a parser, query, filesystem path or command without
269
+ validation at the boundary, or a credential, key or token appears in source.
270
+ references: secure-defaults#input-validation
271
+
272
+ - id: A8.31
273
+ kind: checked-only
274
+ check_kind: agent
275
+ severity: major
276
+ phases:
277
+ - implementation
278
+ - deployment
279
+ requires: >-
280
+ Development, testing and production environments are kept separate and each is
281
+ secured.
282
+ look_at: >-
283
+ Environment configuration, test setup and fixtures in the change: which
284
+ endpoints, databases and credentials each environment's code and configuration
285
+ points at.
286
+ fails_when: >-
287
+ Development or test code or configuration points at a production endpoint,
288
+ database or credential, or a production configuration enables a feature meant
289
+ only for development.
290
+ references: secure-defaults#secrets-management
291
+
292
+ # ---------------------------------------------------------------------------
293
+ # Not covered. Eighty-one of the ninety-three Annex A controls.
294
+ #
295
+ # organizational a tool that reads code cannot speak to the control: it is
296
+ # about the organisation's governance, people, premises or the
297
+ # operation of its infrastructure
298
+ # not-yet-built a code lifecycle could say something here, and this pack does
299
+ # not yet
300
+ #
301
+ # Every theme 7 and theme 8 exclusion carries a note, because `organizational`
302
+ # alone misdescribes a physical or infrastructure control (iso-27001-pack/AC-10).
303
+ # ---------------------------------------------------------------------------
304
+ excluded:
305
+ # 5 — Organizational controls.
306
+ - id: A5.1
307
+ reason: organizational
308
+ - id: A5.2
309
+ reason: organizational
310
+ - id: A5.3
311
+ reason: not-yet-built
312
+ note: >-
313
+ Segregation of duties has a real lifecycle angle. The trail records who wrote a
314
+ change and who reviewed it, but nothing checks that they are different people,
315
+ so this pack does not claim it.
316
+ - id: A5.4
317
+ reason: organizational
318
+ - id: A5.5
319
+ reason: organizational
320
+ - id: A5.6
321
+ reason: organizational
322
+ - id: A5.7
323
+ reason: organizational
324
+ - id: A5.9
325
+ reason: organizational
326
+ - id: A5.10
327
+ reason: organizational
328
+ - id: A5.11
329
+ reason: organizational
330
+ - id: A5.12
331
+ reason: organizational
332
+ - id: A5.13
333
+ reason: organizational
334
+ - id: A5.14
335
+ reason: organizational
336
+ note: >-
337
+ Rules and agreements for transferring information are the organisation's. A
338
+ plain-HTTP target added in a change is flagged under A8.24, which is one input
339
+ here, not the control.
340
+ - id: A5.15
341
+ reason: organizational
342
+ - id: A5.16
343
+ reason: organizational
344
+ - id: A5.17
345
+ reason: organizational
346
+ note: >-
347
+ Allocating and managing authentication information is the organisation's
348
+ process. A credential committed to source is flagged under A8.28; that is not
349
+ this control.
350
+ - id: A5.18
351
+ reason: organizational
352
+ - id: A5.19
353
+ reason: organizational
354
+ - id: A5.20
355
+ reason: organizational
356
+ - id: A5.21
357
+ reason: not-yet-built
358
+ note: >-
359
+ The ICT supply chain has a real code angle — dependency inventory, lockfiles
360
+ and vulnerability audit. Those rules exist in the secure-defaults guidance
361
+ layer and A8.8 checks them, but this pack does not claim them here: a
362
+ dependency audit is one input to supply-chain risk management, not the control
363
+ itself.
364
+ - id: A5.22
365
+ reason: organizational
366
+ - id: A5.23
367
+ reason: organizational
368
+ - id: A5.24
369
+ reason: organizational
370
+ - id: A5.25
371
+ reason: organizational
372
+ - id: A5.26
373
+ reason: organizational
374
+ - id: A5.27
375
+ reason: organizational
376
+ - id: A5.28
377
+ reason: organizational
378
+ note: >-
379
+ This control is about evidence of security events gathered for legal or
380
+ disciplinary use. The lifecycle trail is a different kind of evidence and does
381
+ not serve it.
382
+ - id: A5.29
383
+ reason: organizational
384
+ - id: A5.30
385
+ reason: organizational
386
+ - id: A5.31
387
+ reason: organizational
388
+ - id: A5.32
389
+ reason: organizational
390
+ - id: A5.33
391
+ reason: organizational
392
+ - id: A5.34
393
+ reason: organizational
394
+ note: >-
395
+ Identifying and meeting privacy obligations is the organisation's. Personal
396
+ data written to a log is flagged under A8.15, which is one input here, not the
397
+ control.
398
+ - id: A5.35
399
+ reason: organizational
400
+ - id: A5.36
401
+ reason: organizational
402
+ - id: A5.37
403
+ reason: organizational
404
+
405
+ # 6 — People controls. Screening, employment terms, awareness, discipline,
406
+ # confidentiality, remote working and event reporting are all about people.
407
+ - id: A6.1
408
+ reason: organizational
409
+ - id: A6.2
410
+ reason: organizational
411
+ - id: A6.3
412
+ reason: organizational
413
+ - id: A6.4
414
+ reason: organizational
415
+ - id: A6.5
416
+ reason: organizational
417
+ - id: A6.6
418
+ reason: organizational
419
+ - id: A6.7
420
+ reason: organizational
421
+ - id: A6.8
422
+ reason: organizational
423
+
424
+ # 7 — Physical controls.
425
+ - id: A7.1
426
+ reason: organizational
427
+ note: Physical security of premises is outside a code tool's reach entirely.
428
+ - id: A7.2
429
+ reason: organizational
430
+ note: Physical entry to premises is outside a code tool's reach entirely.
431
+ - id: A7.3
432
+ reason: organizational
433
+ note: Securing offices, rooms and facilities is outside a code tool's reach entirely.
434
+ - id: A7.4
435
+ reason: organizational
436
+ note: Physical security monitoring is outside a code tool's reach entirely.
437
+ - id: A7.5
438
+ reason: organizational
439
+ note: Protection against physical and environmental threats is outside a code tool's reach entirely.
440
+ - id: A7.6
441
+ reason: organizational
442
+ note: Working in secure areas is outside a code tool's reach entirely.
443
+ - id: A7.7
444
+ reason: organizational
445
+ note: Clear desks and clear screens are outside a code tool's reach entirely.
446
+ - id: A7.8
447
+ reason: organizational
448
+ note: Siting and protecting equipment is outside a code tool's reach entirely.
449
+ - id: A7.9
450
+ reason: organizational
451
+ note: Assets kept off the premises are outside a code tool's reach entirely.
452
+ - id: A7.10
453
+ reason: organizational
454
+ note: Storage media handling is outside a code tool's reach entirely.
455
+ - id: A7.11
456
+ reason: organizational
457
+ note: Supporting utilities such as power are outside a code tool's reach entirely.
458
+ - id: A7.12
459
+ reason: organizational
460
+ note: Cabling security is outside a code tool's reach entirely.
461
+ - id: A7.13
462
+ reason: organizational
463
+ note: Equipment maintenance is outside a code tool's reach entirely.
464
+ - id: A7.14
465
+ reason: organizational
466
+ note: Disposal and re-use of equipment is outside a code tool's reach entirely.
467
+
468
+ # 8 — Technological controls not covered above.
469
+ - id: A8.1
470
+ reason: organizational
471
+ note: >-
472
+ User endpoint devices are managed by the organisation's device management, not
473
+ by anything in a code change.
474
+ - id: A8.2
475
+ reason: organizational
476
+ note: >-
477
+ Allocating and restricting privileged access is the organisation's
478
+ access-management process. Code that grants a privilege is not the control.
479
+ - id: A8.3
480
+ reason: not-yet-built
481
+ note: >-
482
+ Restricting access to information has a real code angle: whether every read or
483
+ write of a protected record passes an authorization check on the same path.
484
+ The secure-defaults layer states the rule, but this pack carries no fail
485
+ condition for it yet.
486
+ - id: A8.5
487
+ reason: not-yet-built
488
+ note: >-
489
+ Secure authentication has a real code angle — password hashing, rate limits on
490
+ authentication endpoints, token lifetimes — and the secure-defaults layer
491
+ states the rules. This pack does not yet carry a fail condition for them.
492
+ - id: A8.6
493
+ reason: organizational
494
+ note: Capacity management is an operations activity over running systems.
495
+ - id: A8.7
496
+ reason: organizational
497
+ note: >-
498
+ Protection against malware is detection software on endpoints and servers plus
499
+ user awareness. Nothing in a diff establishes it.
500
+ - id: A8.10
501
+ reason: not-yet-built
502
+ note: >-
503
+ Deleting information when it is no longer needed has a code angle: a change
504
+ that stores a new kind of personal data could be checked for a deletion path.
505
+ This pack does not check it yet.
506
+ - id: A8.11
507
+ reason: not-yet-built
508
+ note: >-
509
+ Data masking has a code angle in what an application outputs. Personal data
510
+ written to a log is already checked under A8.15; masking in other outputs is not
511
+ checked yet.
512
+ - id: A8.12
513
+ reason: organizational
514
+ note: Data leakage prevention runs as monitoring over systems, networks and endpoints.
515
+ - id: A8.13
516
+ reason: organizational
517
+ note: Backups are taken and tested by operations, not by a code change.
518
+ - id: A8.14
519
+ reason: organizational
520
+ note: Redundancy of processing facilities is an infrastructure property.
521
+ - id: A8.16
522
+ reason: organizational
523
+ note: >-
524
+ Monitoring networks and systems for anomalous behaviour is an operations
525
+ activity. The logging a change adds is checked under A8.15.
526
+ - id: A8.17
527
+ reason: organizational
528
+ note: Clock synchronisation is an infrastructure property.
529
+ - id: A8.18
530
+ reason: organizational
531
+ note: Restricting privileged utility programs is an operations control over running systems.
532
+ - id: A8.19
533
+ reason: organizational
534
+ note: Controlling software installed on operational systems is an operations process.
535
+ - id: A8.20
536
+ reason: organizational
537
+ note: >-
538
+ Network security is an infrastructure control. Where network rules are defined
539
+ as code, a change to them is checked as configuration under A8.9.
540
+ - id: A8.21
541
+ reason: organizational
542
+ note: >-
543
+ Security of network services is agreed with and monitored at the provider.
544
+ Where a service's settings are defined as code, a change to them is checked as
545
+ configuration under A8.9.
546
+ - id: A8.22
547
+ reason: organizational
548
+ note: >-
549
+ Segregating networks is an infrastructure control. Where segments are defined
550
+ as code, a change to them is checked as configuration under A8.9.
551
+ - id: A8.23
552
+ reason: organizational
553
+ note: Web filtering is an infrastructure control over users' access to external sites.
554
+ - id: A8.27
555
+ reason: not-yet-built
556
+ note: >-
557
+ Secure architecture and engineering principles have a lifecycle angle: design.md
558
+ is where they would be applied. But design.md records one design, not the
559
+ organisation's established and maintained principles, so this pack does not
560
+ claim the control.
561
+ - id: A8.30
562
+ reason: organizational
563
+ note: >-
564
+ Directing and monitoring outsourced development is supplier management. An
565
+ outsourced team working inside this lifecycle leaves the same trail as anyone
566
+ else, but that does not evidence the oversight.
567
+ - id: A8.33
568
+ reason: not-yet-built
569
+ note: >-
570
+ Protecting test information has a code angle: fixtures copied from production
571
+ data could be flagged. This pack does not check it yet.
572
+ - id: A8.34
573
+ reason: organizational
574
+ note: Protecting systems during audit testing is planned between auditor and management.
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: iso27001-constraints
3
+ description: ISO/IEC 27001:2022 Annex A constraints that apply while code is being written
4
+ ---
5
+ # ISO 27001 Constraints
6
+
7
+ **This pack's control text has not been reviewed by a compliance practitioner.**
8
+ It was written by an engineer reading the standard. Treat it as a working draft: useful
9
+ for applying controls while you write code, not as an opinion on whether your controls
10
+ are adequate. Nothing here makes a project ISO 27001 certified, attested, or
11
+ audit-ready.
12
+
13
+ The control text paraphrases the standard in this pack's own words and cites control
14
+ numbers only. It quotes nothing: ISO's text is copyrighted, and the standard itself is
15
+ obtained from ISO.
16
+
17
+ ## Edition and numbering
18
+
19
+ This pack targets **ISO/IEC 27001:2022** only. The 2013 edition's certificates expired on
20
+ 2025-10-31, and its numbering — A.14 and the rest — does not apply here.
21
+
22
+ Control ids are written `A<theme>.<n>`: `A8.25` means Annex A control 8.25. Annex A has
23
+ 93 controls in four themes — 5 organizational, 6 people, 7 physical, 8 technological.
24
+
25
+ ## What this pack does not cover
26
+
27
+ It covers **Annex A controls only**. Clauses 4–10 of the standard — the information
28
+ security management system: its scope, the risk assessment, the Statement of
29
+ Applicability, internal audit and management review — are not covered, and a code tool
30
+ cannot speak to them. Certification is of the management system, not of a codebase or
31
+ its development process, so no output of this pack bears on whether an organisation
32
+ would be certified.
33
+
34
+ Of the 93 Annex A controls, 12 are covered. The other 81 are listed in the pack's
35
+ `controls.yaml` under `excluded:` with a reason: `organizational` where nothing a code
36
+ tool reads can speak to the control, `not-yet-built` where a code lifecycle could say
37
+ something and this pack does not yet.
38
+
39
+ ## Which controls apply, and when
40
+
41
+ | Phase | Controls to have in mind |
42
+ |---|---|
43
+ | Requirements | A5.8, A8.25, A8.26, A8.32 |
44
+ | Design | A5.8, A8.25, A8.26, A8.28, A8.32 |
45
+ | Implementation | A8.4, A8.8, A8.9, A8.15, A8.24, A8.25, A8.28, A8.31, A8.32 |
46
+ | Testing | A8.25, A8.29, A8.32 |
47
+ | Deployment | A8.4, A8.8, A8.9, A8.15, A8.24, A8.25, A8.31, A8.32 |
48
+ | Maintenance | A8.8, A8.15 |
49
+
50
+ Run `aidlc compliance check` for each control's exact fail condition. Apply the fail
51
+ condition as written rather than your reading of the control — that is what makes two
52
+ reviews of the same change agree.
53
+
54
+ ## Five controls are evidenced. Seven are only checked.
55
+
56
+ **A5.8, A8.25, A8.26, A8.29 and A8.32 are evidenced.** They are controls over how
57
+ software is developed and changed, and this lifecycle *is* a development and change
58
+ process, so the artifact trail demonstrates them.
59
+
60
+ **A8.4, A8.8, A8.9, A8.15, A8.24, A8.28 and A8.31 are checked only.** They operate over a
61
+ running system or its surroundings. No document establishes that your logs are analysed
62
+ or that your environments stay separate — so the pack gives you a fail condition to
63
+ apply, and the trail records that you applied it. A report will say which is which.
64
+ Never present a checked-only control as evidence.
65
+
66
+ ## What the evidenced controls ask of you while you build
67
+
68
+ Make sure each of these leaves a record, because the record is the evidence:
69
+
70
+ - **A5.8, security in project work.** `design.md` names the change's security
71
+ considerations — each risk and how it is handled — or says plainly that there are none.
72
+ - **A8.25, a secure development life cycle.** The change passes through every phase its
73
+ template requires, and `transitions.log` shows it.
74
+ - **A8.26, application security requirements.** When the change handles sensitive data,
75
+ authentication or access control, `requirements.md` carries an acceptance criterion
76
+ stating the security requirement.
77
+ - **A8.29, security testing.** `test-results.md` names an outcome, and every security
78
+ criterion has a referencing test.
79
+ - **A8.32, change management.** Numbered criteria authorise the change, `design.md` names
80
+ what it touches, `test-results.md` records the test, and `deployment-record.md` records
81
+ what shipped and how to roll it back.
82
+
83
+ ## What A8.32 does not evidence here
84
+
85
+ The trail shows a change passed through requirements, design, testing and deployment, and
86
+ a requirement changed after its phase closed is recorded when it goes through
87
+ `aidlc amend`, which walks the impact and reopens the phases it invalidates. An artifact
88
+ edited directly after its phase closed — without `aidlc amend` — is **not** detected:
89
+ every gate still passes. So the trail does **not** establish that `requirements.md` and
90
+ the shipped code still agree. Do not represent this pack's A8.32 output as evidence of
91
+ that agreement.
92
+
93
+ ## Security rules live in one place, not here
94
+
95
+ This pack does not restate the project's security rules. Read
96
+ `.aidlc/guidance/secure-defaults.md` and apply it. The seven checked-only controls
97
+ reference its sections — least privilege, dependency security, transport and data
98
+ protection, error handling and logging, input validation, secrets management — so there
99
+ is exactly one place to change when a rule changes.
@@ -0,0 +1,29 @@
1
+ id: iso27001
2
+ # The edition is part of the name on purpose. The report prints this string as its
3
+ # section heading, and the control numbers only mean something against the 2022
4
+ # edition: the 2013 edition's certificates expired on 2025-10-31 and its A.14-style
5
+ # numbering is gone. A ragged column in `aidlc compliance list` is the accepted cost
6
+ # (iso-27001-pack/AC-2).
7
+ regime: ISO 27001:2022
8
+ version: 0.1.0
9
+
10
+ # ISO/IEC 27001 is a management-system standard any organisation can certify
11
+ # against, so like SOC 2 it is not industry-scoped.
12
+ industries:
13
+ - any
14
+
15
+ entitlement: unrestricted
16
+
17
+ # Null on purpose. The control text in this pack was written by an engineer reading
18
+ # the standard, not by a compliance practitioner. Nulling this field obliges the
19
+ # constraint layer to say so, obliges every report to say so, and makes a doctor
20
+ # check watch for someone editing the statement out.
21
+ reviewed_by: null
22
+
23
+ layers:
24
+ - name: iso27001-constraints
25
+ file: iso27001-constraints.md
26
+ # Pack layers are delivered as a read-instruction whatever their size. A small
27
+ # layer that got inlined would put pack text inside an emitted skill, which is
28
+ # forbidden outright.
29
+ always_pointer: true
@@ -102,9 +102,14 @@ controls:
102
102
  transmission, movement or removal.
103
103
  look_at: Network client configuration and request targets in the change.
104
104
  fails_when: >-
105
- An added line targets a plain-HTTP URL, so protected information could be
106
- transmitted without transport encryption.
107
- pattern: "http://(?!localhost|127\\.0\\.0\\.1|\\[::1\\])"
105
+ An added line targets a plain-HTTP URL whose host is not exactly localhost,
106
+ 127.0.0.1 or [::1], so protected information could be transmitted without
107
+ transport encryption.
108
+ # Case is spelled out letter by letter because the check compiles patterns with no
109
+ # flags. The trailing lookahead is the host boundary: localhost-api.corp.net and
110
+ # localhost@evil.example.com are not loopback (plain-http-check-misses-loopback-lookalikes).
111
+ # ISO 27001 A8.24 ships the same string, and plain-http-pattern.test.ts keeps them equal.
112
+ pattern: "[hH][tT][tT][pP]://(?!(?:[lL][oO][cC][aA][lL][hH][oO][sS][tT]|127\\.0\\.0\\.1|\\[::1\\])(?::\\d+)?(?![\\w:@%~-]|\\.[\\w-]))"
108
113
  references: secure-defaults#transport-and-data-protection
109
114
 
110
115
  - id: CC6.8
@@ -15,6 +15,10 @@ A situation no entry below covers is a hard stop. Guessing is what this mode exi
15
15
 
16
16
  Append one entry per default or hard stop to `.aidlc/state/<instance>/unattended-stops.md`: a `## <n>. <title> — <slug>` heading, then **Source:** (skill and section, or rule), **Instruction:** (the exact text), **Decided:** (the default, or "hard stop"), **Why:** (why it is safe, or which hard-stop class). A Question Protocol answer also carries `(unattended default)` in its `[Answer]:` — how a reviewer finds every choice nobody made.
17
17
 
18
+ ## Waiting for a command
19
+
20
+ Unattended, the end of the turn is the end of the session, and a command still running dies with it. Run a long command in the foreground, or poll it inside the turn until it ends. Never end the turn while it runs, or to wait for a wakeup or a notification.
21
+
18
22
  ## Hard stop
19
23
 
20
24
  Always a hard stop:
@@ -3,6 +3,8 @@ name: aidlc-overview
3
3
  description: Framework overview and state protocol for the AI Development Lifecycle
4
4
  phase: ideation
5
5
  priority: 100
6
+ invocation: routed
7
+ activation: none
6
8
  ---
7
9
  # AIDLC Framework Overview
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-getting-started
3
3
  description: Helps users get started with AIDLC — responds to onboarding questions, suggests templates, and guides first steps
4
4
  phase: ideation
5
5
  priority: 95
6
+ invocation: routed
7
+ activation: none
6
8
  trigger: When the user asks how to get started, how to use the framework, or asks about fixing bugs, adding features, or beginning work
7
9
  ---
8
10
  # Getting Started with AIDLC
@@ -3,6 +3,8 @@ name: aidlc-first-activation
3
3
  description: Auto-discovers a brownfield project on first activation — scans codebase, asks about extra context folders, writes context docs
4
4
  phase: ideation
5
5
  priority: 98
6
+ invocation: routed
7
+ activation: none
6
8
  trigger: When AIDLC is installed but `.aidlc/context/` does not exist or contains no files
7
9
  ---
8
10
  # First Activation — Project Discovery
@@ -3,6 +3,7 @@ name: aidlc
3
3
  description: Entry point for AIDLC — reads lifecycle state and offers the next actions (continue an instance, start new work, check status, review an artifact)
4
4
  phase: ideation
5
5
  priority: 99
6
+ invocation: auto
6
7
  trigger: When the user invokes the aidlc skill directly or asks what lifecycle actions are available
7
8
  native_mode_hint:
8
9
  claude-code: >-
@@ -3,6 +3,8 @@ name: aidlc-roadmap
3
3
  description: Captures roadmap items into .aidlc/roadmap/inbox/ at any moment — no instance, claim, or phase required — and browses, triages, promotes, or drops them
4
4
  phase: ideation
5
5
  priority: 90
6
+ arguments: "[idea text]"
7
+ invocation: routed
6
8
  trigger: When the user says "idea:", asks to capture/record an idea or roadmap item, wants to browse the roadmap, or wants to triage, promote, or drop an item, or asks to start a roadmap item in a new worktree
7
9
  native_mode_hint:
8
10
  claude-code: >-
@@ -3,6 +3,8 @@ name: aidlc-constitution
3
3
  description: Turns a product vision document into the repo's constitution — what this repo is for and what it must never become — and keeps it in step when the vision is updated
4
4
  phase: ideation
5
5
  priority: 88
6
+ arguments: "[path to the vision document]"
7
+ invocation: routed
6
8
  trigger: When the user points at a product vision document, asks what this repo is or is not allowed to do, asks to create or update a project constitution, or when the vision document has changed
7
9
  native_mode_hint:
8
10
  claude-code: >-
@@ -3,6 +3,8 @@ name: aidlc-ideation
3
3
  description: Guides the Ideation phase — exploring the problem space, defining goals and constraints
4
4
  phase: ideation
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: reasoning
6
8
  ---
7
9
  # Ideation Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-requirements
3
3
  description: Guides the Requirements phase — defining acceptance criteria and user stories
4
4
  phase: requirements
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: reasoning
6
8
  ---
7
9
  # Requirements Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-design
3
3
  description: Guides the Design phase — architecture decisions, interfaces, and data flow
4
4
  phase: design
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: reasoning
6
8
  ---
7
9
  # Design Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-implementation
3
3
  description: Guides the Implementation phase — writing code following the design and project conventions
4
4
  phase: implementation
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: standard
6
8
  ---
7
9
  # Implementation Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-testing
3
3
  description: Guides the Testing phase — verifying implementation against requirements
4
4
  phase: testing
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: mechanical
6
8
  ---
7
9
  # Testing Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-deployment
3
3
  description: Guides the Deployment phase — release preparation, validation, and execution
4
4
  phase: deployment
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: mechanical
6
8
  ---
7
9
  # Deployment Phase
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-maintenance
3
3
  description: Guides the Maintenance phase — monitoring, iteration, and documentation upkeep
4
4
  phase: maintenance
5
5
  priority: 50
6
+ invocation: routed
7
+ tier: standard
6
8
  ---
7
9
  # Maintenance Phase
8
10
 
@@ -4,6 +4,9 @@ description: Performs adversarial review of lifecycle artifacts — examining fo
4
4
  phase: requirements
5
5
  trigger: Activated when a review is requested for any artifact or phase
6
6
  priority: 60
7
+ arguments: "<instance> <artifact>"
8
+ invocation: routed
9
+ activation: none
7
10
  agent: aidlc-reviewer
8
11
  ---
9
12
  # Adversarial Review
@@ -3,6 +3,8 @@ name: aidlc-continue
3
3
  description: Resumes a lifecycle instance from the next incomplete step with minimal context loading
4
4
  phase: implementation
5
5
  priority: 70
6
+ arguments: "[instance]"
7
+ invocation: auto
6
8
  ---
7
9
  # Lifecycle Continuation
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-add-action
3
3
  description: Translates natural language automation descriptions into lifecycle action declarations
4
4
  phase: implementation
5
5
  priority: 55
6
+ arguments: "<what should happen, and when>"
7
+ invocation: routed
6
8
  ---
7
9
  # AI-Assisted Action Authoring
8
10
 
@@ -3,6 +3,8 @@ name: aidlc-add-skill
3
3
  description: Turns a described repeatable operation into an app-owned operational skill with built-in verification
4
4
  phase: implementation
5
5
  priority: 54
6
+ arguments: "<the operation to automate>"
7
+ invocation: routed
6
8
  ---
7
9
  # Operational Skill Authoring
8
10
 
@@ -3,6 +3,9 @@ name: aidlc-autopilot
3
3
  description: Works the next backlog items in the background — "do the next 3 items" or "do all the items" — pauses and resumes that run, and reports how to watch and stop
4
4
  phase: implementation
5
5
  priority: 60
6
+ arguments: "[<n> | all | pause | resume]"
7
+ invocation: user
8
+ activation: none
6
9
  trigger: When the user asks to do, work, build or ship the next n backlog items, or all of them, without supervising each one — or to pause or resume that run
7
10
  ---
8
11
  # Autopilot
@@ -3,6 +3,8 @@ name: aidlc-autopilot-stop
3
3
  description: Stops the background autopilot run — nothing further is started, merged or released
4
4
  phase: implementation
5
5
  priority: 60
6
+ invocation: user
7
+ activation: none
6
8
  trigger: When the user asks to stop or halt autopilot or the background backlog run
7
9
  ---
8
10
  # Stop Autopilot
@@ -3,6 +3,8 @@ name: aidlc-retrospective
3
3
  description: Runs the completion retrospective — captures lessons into the guidance layer, and consolidates the lessons file on demand
4
4
  phase: maintenance
5
5
  priority: 55
6
+ arguments: "[instance]"
7
+ invocation: routed
6
8
  trigger: When an instance reaches its completion moment, a retro-pending marker exists, or the user asks for a retrospective or lessons consolidation
7
9
  ---
8
10
  # Retrospective