@metasession.co/devaudit-cli 0.1.43 → 0.1.44

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.
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: risk-register-keeper
3
+ description: Maintain `compliance/risk-register.md` as the authoritative project-spanning record of risks across the SDLC lifecycle. Runs at Stage 1 (MEDIUM/HIGH risk classification — open RISK-NNN entries for risks the REQ introduces), at incident-close (residual risk after an incident), and at Stage 3 (per-REQ evidence pack). Owns the canonical risk row (description, inherent likelihood × impact, mitigations planned, residual likelihood × impact, owner, review-due, framework cross-references), allocates the next `RISK-NNN` per project, replaces the implementation plan's inline Risks/Considerations bullets with RISK-NNN reference list, and produces `compliance/evidence/REQ-XXX/risk-assessment.md` summarising which entries this REQ opened, mitigated, or accepted. Use when invoking on a single REQ ("draft a risk-register entry for REQ-XXX", "is the risk register up to date for this branch?"); when `sdlc-implementer` delegates at Stage 1 for MEDIUM/HIGH classifications or Stage 3 for the evidence artefact; when an incident closes and the residual-risk entry needs drafting; when a `solo_with_gap` approval mode requires the documented control-gap entry. Do NOT use for authoring canonical risk-treatment language (the operator owns the final wording); for periodic-review re-validation of accepted risks (deferred to Phase B); for full STRIDE/LINDDUN threat modelling (deferred to Phase B; consider folding into a separate `threat-modeller` skill if volume justifies); for framework-clause mapping of the `risk_assessment` evidence type (that's META-COMPLY's `framework-registry-auditor`).
4
+ ---
5
+
6
+ # Risk Register Keeper
7
+
8
+ Maintains `compliance/risk-register.md` as the authoritative record of project risks across the SDLC lifecycle. Sibling of [`requirements-aligner`](../requirements-aligner/SKILL.md) (owns `docs/SRS.md`) and [`adr-author`](../adr-author/SKILL.md) (owns `docs/ADR/`) in the SoT-alignment skill family.
9
+
10
+ The skill is **Phase A scope** (per [DevAudit-Installer#121](https://github.com/metasession-dev/DevAudit-Installer/issues/121) and the [#119 review](https://github.com/metasession-dev/DevAudit-Installer/issues/119#issuecomment-4631840651)): Stage 1 + post-incident + Stage 3 hooks. Periodic-review re-validation, audit-pack inclusion, and STRIDE/LINDDUN threat modelling all defer to Phase B.
11
+
12
+ ## What this skill owns
13
+
14
+ | Artefact | Lives at | Tier |
15
+ | -------------------------------------------------------------------------- | ------------------------------ | -------------------- |
16
+ | `compliance/risk-register.md` (the SoT, project-spanning) | Top-level compliance directory | 2 (project strategy) |
17
+ | `compliance/evidence/REQ-XXX/risk-assessment.md` (per-REQ Tier 3 evidence) | Per-REQ evidence directory | 3 (per-REQ) |
18
+
19
+ The skill does **not** own the canonical risk-treatment language (operator decision — risk acceptance has legal + audit consequences). It allocates `RISK-NNN` IDs, drafts canonical row stubs the operator edits, and cross-references the register entries from per-REQ artefacts.
20
+
21
+ ## Scope
22
+
23
+ **In scope**
24
+
25
+ - Phase 1 (Stage-1 hook, MEDIUM/HIGH only by default) — read implementation plan + diff → identify risks → allocate `RISK-NNN` → draft canonical rows → replace plan's Risks/Considerations bullets with RISK-NNN reference list.
26
+ - Phase 2 (post-incident hook) — read closed `incident`-labelled report → draft residual-risk entry → cross-link incident report ↔ register entry.
27
+ - Phase 3 (Stage-3 hook) — drop `compliance/evidence/REQ-XXX/risk-assessment.md` with this REQ's RISK-NNN summary.
28
+ - Phase 4 (`solo_with_gap` approval) — when project's `sdlc-config.json:approval.mode = 'solo_with_gap'`, refuse merge unless the documented control-gap RISK-NNN entry exists.
29
+ - Per-REQ ad-hoc audit (operator invocation).
30
+
31
+ **Out of scope**
32
+
33
+ - Authoring canonical risk-treatment prose — the skill drafts stubs; the operator owns final language. Risk acceptance has legal + audit consequences; the operator's sign-off is the audit value.
34
+ - Periodic-review re-validation — Phase B, paired with `governance-doc-author`'s periodic-review schedule.
35
+ - Audit-pack inclusion — Phase B, pairs with portal audit-pack export.
36
+ - STRIDE / LINDDUN threat modelling sub-domain — deferred; if volume justifies, graduates to a separate `threat-modeller` skill.
37
+ - Framework-clause mapping of the `risk_assessment` evidence type — that's META-COMPLY's `framework-registry-auditor`.
38
+ - CVSS-aware scoring — defaults to a `likelihood × impact` 3×3 matrix per `0-project-setup.md`. CVSS deferred.
39
+
40
+ ## The workflow
41
+
42
+ Six phases. Phase 0 routes; Phases 1–4 are the SDLC stage hooks; Phase 5 is the utility audit; Phase 6 reports.
43
+
44
+ ### Phase 0 — Route
45
+
46
+ Determine what's being assessed:
47
+
48
+ - **Stage-1 plan APPROVAL (MEDIUM/HIGH risk)** — `sdlc-implementer` (or operator) says _"draft risk-register entries for REQ-XXX"_ / _"this is HIGH risk, what goes in the register?"_ → Phase 1.
49
+ - **Incident close** — operator (or CI workflow) says _"incident-report-N.md just exported, draft the residual-risk entry"_ → Phase 2.
50
+ - **Stage-3 evidence pack** — `sdlc-implementer` (or operator) says _"drop the risk-assessment.md for REQ-XXX"_ → Phase 3.
51
+ - **`solo_with_gap` approval check** — operator says _"approval mode is solo_with_gap, is the control-gap entry on the register?"_ → Phase 4.
52
+ - **Per-REQ ad-hoc audit** — operator says _"is REQ-XXX's risk record complete?"_ / _"audit the register against this branch"_ → Phase 5.
53
+
54
+ The skill does not fire spontaneously. The parent skill (`sdlc-implementer`) invokes it at Stage 1 for MEDIUM/HIGH classifications + Stage 3 per the parent's SKILL.md delegation contract. `incident-export.yml` invokes it at incident close per its workflow definition.
55
+
56
+ ### Phase 1 — Stage-1 plan APPROVAL hook (MEDIUM/HIGH only)
57
+
58
+ Input: the REQ's `compliance/plans/REQ-XXX/implementation-plan.md` plus the working-tree diff. Triggered only when the orchestrator's risk classification is **MEDIUM or HIGH** by default (LOW skipped); configurable via `sdlc-config.json:risk_register_keeper.block_on_stage_1`.
59
+
60
+ **Step 1 — Read the implementation plan's Threat model + Security considerations section** (`Implementation_Plan_TEMPLATE.md` §4) and the diff scope.
61
+
62
+ **Step 2 — Identify discrete risks.** Each risk is something an auditor could examine independently:
63
+
64
+ - A specific attack surface the change exposes (e.g. "SQL injection via the order-id query param").
65
+ - A specific control gap the change introduces (e.g. "no rate limit on /api/auth/forgot-password").
66
+ - A specific dependency-introduced concern (e.g. "Redis adopted as cache — no encryption at rest by default").
67
+ - A specific data-handling decision (e.g. "payment card last-4 stored in app DB").
68
+
69
+ **Step 3 — For each risk, allocate `RISK-NNN` and draft the canonical row.** Scan `compliance/risk-register.md` for max-existing ID + 1. If the register doesn't exist yet, bootstrap it from `sdlc/files/_common/governance/risk-register.md.template`.
70
+
71
+ Format per row (markdown table inside the register):
72
+
73
+ ```markdown
74
+ ### RISK-NNN — <one-line title>
75
+
76
+ - **Status:** OPEN
77
+ - **Opened:** YYYY-MM-DD (REQ-XXX)
78
+ - **Owner:** <operator>
79
+ - **Description:** REPLACE — what the risk is, in operator-readable terms (2-3 sentences).
80
+ - **Inherent likelihood × impact:** REPLACE (low × medium = 2 / medium × medium = 4 / etc — per 3×3 matrix in 0-project-setup.md)
81
+ - **Mitigations applied in this REQ:** REPLACE — list controls landing in this PR
82
+ - **Residual likelihood × impact:** REPLACE (post-mitigation)
83
+ - **Framework cross-references:** REPLACE — ISO27001.A.X.Y / SOC2.CC3.2 / GDPR.Art-32 (as applicable)
84
+ - **Review due:** YYYY-MM-DD (default 365d for ACCEPTED + MITIGATED; OPEN reviews monthly)
85
+ - **Cross-links:** REQ-XXX implementation plan; ADR-NNN (if produced by adr-author); incident-report-N (if post-incident)
86
+ ```
87
+
88
+ **Step 4 — Replace the implementation plan's Risks/Considerations bullets with RISK-NNN references.** The plan's §4 (Threat model) gets a new sub-section:
89
+
90
+ ```markdown
91
+ ### Risk register entries
92
+
93
+ This REQ opens / touches the following entries in `compliance/risk-register.md`:
94
+
95
+ - **RISK-NNN — <title>** — Status: OPEN. Opened by `risk-register-keeper`. Operator edits the canonical row + signs off the residual rating before plan APPROVAL.
96
+ - **RISK-NNN — <title>** — Status: MITIGATED. Controls landing in this PR close the residual.
97
+ ```
98
+
99
+ For **deferred** risks (the operator decides the surface doesn't merit a register entry — typically LOW-impact + LOW-likelihood combination), the row carries `@risk-deferred: <reason>` so the deferral is visible.
100
+
101
+ **Step 5 — Block plan APPROVAL** (configurable) until each MEDIUM/HIGH risk has either a RISK-NNN entry OR an explicit `@risk-deferred` annotation with rationale.
102
+
103
+ ### Phase 2 — Post-incident hook
104
+
105
+ Triggered when `incident-export.yml` exports a closed `incident`-labelled GitHub issue to `compliance/governance/incident-report-N.md` (DevAudit-Installer v0.1.31 WS4+).
106
+
107
+ **Step 1 — Read the incident report.** Severity classification, root cause, controls applied, residual concern.
108
+
109
+ **Step 2 — Draft a residual-risk entry.** Status branches:
110
+
111
+ | Outcome of incident | Status | What the entry records |
112
+ | ----------------------------------------------------------------------------- | --------- | ----------------------------------------------------------------------- |
113
+ | Controls landed alongside the fix; residual risk now LOW | MITIGATED | What was wrong, what landed, what's checked going forward |
114
+ | Controls deferred (fix-forward shipped but follow-up work tracked) | OPEN | Same, plus follow-up issue reference + deadline |
115
+ | Risk judged tolerable post-incident (e.g. one-off external dependency outage) | ACCEPTED | What was wrong, why acceptance is defensible, when re-validation is due |
116
+
117
+ **Step 3 — Cross-link both directions.** The register entry references `incident-report-N.md`; the incident report file's frontmatter gets a `risk_register_entry: RISK-NNN` line so the audit trail is bidirectional.
118
+
119
+ ### Phase 3 — Stage-3 evidence pack hook
120
+
121
+ Input: the REQ's implementation plan (post-approval) and the working-tree diff.
122
+
123
+ **Step 1 — Generate `compliance/evidence/REQ-XXX/risk-assessment.md`.** Format:
124
+
125
+ ```markdown
126
+ ---
127
+ req: REQ-XXX
128
+ generated_by: risk-register-keeper
129
+ generated_at: <ISO timestamp>
130
+ ---
131
+
132
+ # Risk assessment — REQ-XXX
133
+
134
+ ## Summary
135
+
136
+ This REQ opened / mitigated / accepted the following entries in `compliance/risk-register.md`:
137
+
138
+ | RISK-NNN | Title | Status this cycle | Residual L × I |
139
+ | -------- | ------- | ------------------------------------------------------ | -------------- |
140
+ | RISK-NNN | <title> | OPEN (opened in this REQ) | medium × low |
141
+ | RISK-NNN | <title> | MITIGATED (controls landed in this REQ) | low × low |
142
+ | RISK-NNN | <title> | ACCEPTED (re-validated, no change required this cycle) | low × medium |
143
+
144
+ ## Framework cross-references
145
+
146
+ Risks above map to the following framework clauses:
147
+
148
+ - ISO27001.A.X.Y — RISK-NNN
149
+ - SOC2.CC3.2 — RISK-NNN (Risk identification and assessment)
150
+ - GDPR.Art-32 — RISK-NNN (Security of processing) — if applicable
151
+
152
+ ## Operator sign-off
153
+
154
+ I have reviewed the risk register entries above and confirm:
155
+
156
+ - [ ] Each entry's residual rating is defensible given the controls landing in this REQ.
157
+ - [ ] No risk was downgraded without evidence (control demonstrated effective via tests).
158
+ - [ ] OPEN entries have follow-up tracking (issue / deadline / next-review-due).
159
+
160
+ **Reviewer:** <operator-name>
161
+ **Date:** <YYYY-MM-DD>
162
+ ```
163
+
164
+ **Step 2 — Tag for upload.** The CI's `compliance-evidence.yml` uploads this file as `evidence_type=risk_assessment` (added to META-COMPLY's `EVIDENCE_TYPE_REGISTRY` in the paired sub-PR). The framework-coverage matrix attribution depends on `framework-registry-auditor`'s review — see the META-COMPLY-side PR for final clause closures.
165
+
166
+ **Step 3 — Hand-off back to `sdlc-implementer`.** The skill's job ends at the artefact + operator sign-off.
167
+
168
+ ### Phase 4 — `solo_with_gap` approval check
169
+
170
+ When `sdlc-config.json:approval.mode = 'solo_with_gap'` and a release is about to be approved, the skill verifies the documented control-gap RISK-NNN entry exists in the register.
171
+
172
+ **Step 1 — Read `sdlc-config.json:approval.mode`.** If not `solo_with_gap`, exit (no check needed).
173
+
174
+ **Step 2 — Grep the register for a control-gap entry.** Look for an entry whose Framework cross-references include `SOC2.CC8.1` and whose description references `solo_with_gap` or equivalent ("self-approval", "single-actor release").
175
+
176
+ **Step 3 — If absent, draft one.** Status: ACCEPTED (operator-acknowledged trade-off). Description: "Project operates in solo_with_gap approval mode — release submitter approves their own release. This is a documented control gap relative to SOC2 CC8.1 four-eyes ideal. Compensating controls: <list — typically: CI gates green, MFA on release operator, monthly audit log review>."
177
+
178
+ **Step 4 — Refuse approval until the entry is signed off** by the operator. The control gap must be deliberately acknowledged, not silently inherited.
179
+
180
+ ### Phase 5 — Per-REQ ad-hoc audit
181
+
182
+ Same logic as Phase 1's Step 2 + Step 3, but produces a markdown report rather than blocking. Useful when an operator asks _"is REQ-XXX's risk record complete?"_ outside the SDLC orchestration flow.
183
+
184
+ ### Phase 6 — Report
185
+
186
+ - For Phase 1 — the plan's injected sub-section + the block/allow decision.
187
+ - For Phase 2 — the new register entry + cross-link confirmation.
188
+ - For Phase 3 — the artefact path + summary line.
189
+ - For Phase 4 — the gap-entry confirmation + approval-blocking decision.
190
+ - For Phase 5 — markdown report per REQ.
191
+
192
+ ## Configuration (sdlc-config.json)
193
+
194
+ ```json
195
+ {
196
+ "risk_register_keeper": {
197
+ "enabled": true,
198
+ "block_on_stage_1": false,
199
+ "block_on_stage_3": true,
200
+ "scoring": "likelihood-impact",
201
+ "auto_open_on_high_risk_req": true,
202
+ "auto_open_on_closed_incident": true,
203
+ "stage_1_min_risk_class": "MEDIUM"
204
+ }
205
+ }
206
+ ```
207
+
208
+ Per the [#119 review](https://github.com/metasession-dev/DevAudit-Installer/issues/119#issuecomment-4631840651) defaults:
209
+
210
+ - `block_on_stage_1: false` — advisory at Stage 1 by default. Flip to `true` once the project's register is populated enough that the check is reliably surfacing real risks (not false-positives on sparse coverage).
211
+ - `block_on_stage_3: true` — per-REQ `risk-assessment.md` artefact is the hard gate.
212
+ - `scoring: 'likelihood-impact'` — default 3×3 matrix per `0-project-setup.md`. CVSS-aware scoring (Phase B) deferred.
213
+ - `stage_1_min_risk_class: 'MEDIUM'` — LOW REQs skip the Stage-1 hook (the orchestrator's classification already decided no register entry is warranted). MEDIUM/HIGH trigger.
214
+ - `auto_open_on_closed_incident: true` — fire Phase 2 on every `incident-export.yml` close. Set to `false` for projects with high incident volume + dedicated risk-management process.
215
+
216
+ ## Principles
217
+
218
+ **Don't author canonical risk-treatment language.** The skill drafts stubs; the operator owns the final wording. Risk acceptance has legal + audit consequences; the operator's sign-off carries the audit value. Inventing canonical risk-treatment prose without operator review is exactly the kind of silent acceptance this skill exists to prevent.
219
+
220
+ **Calibrate, don't over-trigger.** Not every change introduces a register-worthy risk. A typo fix doesn't. A CSS tweak doesn't. The `stage_1_min_risk_class` default skips LOW REQs precisely for this reason. False-positive register entries (drafting noise the team has to edit-and-delete) dilute the register's audit value.
221
+
222
+ **The negative case is audit evidence too.** An `@risk-deferred: <rationale>` annotation in the plan's Risks-register-entries sub-section proves the operator considered the surface and decided no entry was needed. Auditors examine the negative case as well as the positive — empty/silent is the failure mode, not "considered + deferred with rationale".
223
+
224
+ **Status semantics are load-bearing.** OPEN = active and unmitigated. MITIGATED = controls landed and demonstrated effective. ACCEPTED = operator-acknowledged trade-off with periodic re-validation. CLOSED = no longer relevant. Don't flip OPEN → CLOSED to make the register green for an audit — auditors check the audit log.
225
+
226
+ **Sibling-skill awareness.** When this skill opens a RISK-NNN that maps to an SRS item, cross-link the SRS-ID (from `requirements-aligner`). When the risk relates to an architectural decision, cross-link the ADR-NNN (from `adr-author`). The three SoT-alignment skills work together; each produces its own per-REQ Tier 3 artefact but they share the per-REQ context.
227
+
228
+ **`solo_with_gap` is a deliberate trade-off, not a silent override.** The framework supports solo-dev projects via `solo_with_gap` approval mode — but only on the explicit basis that the control gap is documented in the risk register. Phase 4 enforces this; the alternative is silently inheriting a SOC 2 CC8.1 gap that an auditor will flag.
229
+
230
+ ## References
231
+
232
+ - [DevAudit-Installer#121](https://github.com/metasession-dev/DevAudit-Installer/issues/121) — the issue this skill closes, with the case study + locked Phase A scope.
233
+ - `sdlc-implementer/SKILL.md` Phase 1 + Phase 3 — the parent-skill invocation contract.
234
+ - `sdlc/files/_common/governance/risk-register.md.template` — starter template installed via `devaudit bootstrap-governance`.
235
+ - `sdlc/files/_common/Implementation_Plan_TEMPLATE.md` — §4 Threat model gets a new "Risk register entries" sub-section in this PR (companion change).
236
+ - `sdlc/files/_common/1-plan-requirement.md` — stage-1 doc updated to point at the skill (companion change).
237
+ - `sdlc/files/_common/skills/requirements-aligner/SKILL.md` — sibling skill (same SoT-alignment family); see for the symmetric shape.
238
+ - `sdlc/files/_common/skills/adr-author/SKILL.md` — sibling skill (same family).
239
+ - `sdlc/files/_common/skills/governance-doc-author/SKILL.md` — Phase 0 routing cross-links to this skill ("register a new risk" vs "draft a ROPA / DPIA / incident-report").
240
+ - Meta-reviewer (META-COMPLY): `framework-registry-auditor` reviews the `risk_assessment` evidence type's clause mappings before the META-COMPLY sub-PR opens.
241
+ - Approval mode reference: `sdlc-config.example.json:approval.mode` — `dual_actor` vs `solo_with_gap` vs `auto_low_risk`.
@@ -68,9 +68,10 @@ Runs **first**, before any `REQ-XXX` is assigned. It decides which of the six ch
68
68
  4. Body heuristics — acceptance criteria, or risk signals (auth, payments, RBAC, data egress, AI decisioning) → tracked, and raise the risk class.
69
69
 
70
70
  Map the result to one of the six paths in `change-workflows.md`.
71
+
71
72
  3. **Announce a "Workflow Decision" block** (template below): change-type, commit-type, whether a `REQ-XXX` is needed, risk class, which stages/gates run, which approvals the **operator** must perform (UAT four-eyes, Production approval), and what is **skipped**.
72
73
  4. **Pause policy — pause-when-it-matters.** Pause for explicit confirmation on **tracked / heavier** paths, or when classification is **ambiguous**; **announce-and-auto-proceed** on trivial / housekeeping. The operator can always reclassify ("treat this as housekeeping" / "this is HIGH risk").
73
- 5. **Route — and stay on to completion.** A route is a choice of *which workflow to drive*, never a hand-off that abandons the operator. Whatever the path, the skill keeps guiding step by step until no further action is required (typically: merged).
74
+ 5. **Route — and stay on to completion.** A route is a choice of _which workflow to drive_, never a hand-off that abandons the operator. Whatever the path, the skill keeps guiding step by step until no further action is required (typically: merged).
74
75
  - **tracked** (feature / bug fix / refactor / perf) → continue into Phase 1 below (full Stages 1–5).
75
76
  - **housekeeping / trivial** → drive the **Lightweight path** below to completion. No `REQ-XXX`, no RTM row, no evidence pack, no portal release approvals — but the skill still branches, runs the gates, opens the PR, and walks the operator through review → merge.
76
77
  - **compliance-doc-only** → drive the same Lightweight path as a docs push (or PR, per the project's flow) referencing the **existing** `REQ-XXX`: no new requirement and no quality-gate ceremony, but driven through to merge.
@@ -79,6 +80,7 @@ Runs **first**, before any `REQ-XXX` is assigned. It decides which of the six ch
79
80
  **"Workflow Decision" announcement template**
80
81
 
81
82
  > **Workflow decision — #N**
83
+ >
82
84
  > - **Change type:** \<Feature | Bug fix | Refactor/Perf | Housekeeping | Trivial | Compliance-doc-only\>
83
85
  > - **Commit type:** \<feat | fix | refactor | chore | docs | …\>
84
86
  > - **Requirement:** \<REQ-XXX assigned | none\>
@@ -87,13 +89,13 @@ Runs **first**, before any `REQ-XXX` is assigned. It decides which of the six ch
87
89
  > - **Gates/evidence:** \<…\>
88
90
  > - **Your approvals:** \<UAT four-eyes + Production approval | PR review only\>
89
91
  > - **Skipped:** \<…\>
90
- > Proceed? *(or reclassify)*
92
+ > Proceed? _(or reclassify)_
91
93
 
92
94
  Only the **tracked** route continues into Phase 1; the others run the Lightweight path below. The off-ramps are deliberate — dragging housekeeping through tracked-change machinery it doesn't need is exactly the failure mode this step exists to prevent — but they are still **driven to completion**, never dumped as a checklist for the operator to run alone.
93
95
 
94
96
  **Worked examples** (one per change-type the skill keeps mis-routing without one):
95
97
 
96
- *Tracked feature — REQ-XXX assigned*
98
+ _Tracked feature — REQ-XXX assigned_
97
99
 
98
100
  > - **Change type:** Feature
99
101
  > - **Commit type:** feat
@@ -104,7 +106,7 @@ Only the **tracked** route continues into Phase 1; the others run the Lightweigh
104
106
  > - **Your approvals:** UAT four-eyes + Production approval
105
107
  > - **Skipped:** none
106
108
 
107
- *Test fix surfaced by suite drift*
109
+ _Test fix surfaced by suite drift_
108
110
 
109
111
  > - **Change type:** Housekeeping (test maintenance)
110
112
  > - **Commit type:** test
@@ -115,7 +117,7 @@ Only the **tracked** route continues into Phase 1; the others run the Lightweigh
115
117
  > - **Your approvals:** PR review only
116
118
  > - **Skipped:** RTM, evidence pack, UAT four-eyes, Production approval
117
119
 
118
- *Workflow tweak (CI artifact upload, gate timeout bump, etc.)*
120
+ _Workflow tweak (CI artifact upload, gate timeout bump, etc.)_
119
121
 
120
122
  > - **Change type:** Housekeeping (CI maintenance)
121
123
  > - **Commit type:** ci
@@ -128,14 +130,14 @@ Only the **tracked** route continues into Phase 1; the others run the Lightweigh
128
130
 
129
131
  ### Lightweight path (housekeeping / trivial / compliance-doc-only)
130
132
 
131
- Reached from Phase 0 for non-tracked change-types. The skill drives this end-to-end; the only difference from the tracked cycle is the absence of *ceremony*, not the absence of *guidance*. It pauses only where a human is genuinely required (PR review, merge).
133
+ Reached from Phase 0 for non-tracked change-types. The skill drives this end-to-end; the only difference from the tracked cycle is the absence of _ceremony_, not the absence of _guidance_. It pauses only where a human is genuinely required (PR review, merge).
132
134
 
133
135
  1. **Branch off `$INTEGRATION_BRANCH`** with a housekeeping prefix — `chore/…`, `docs/…`, `ci/…`, `build/…`, `test/…`, or `compliance/…` for a doc-only change against an existing REQ.
134
136
  2. **Make the change**, single-purpose. If it turns out to touch runtime behaviour in `app/` / `lib/`, stop and reclassify as tracked — the commit-type rule is the backstop.
135
137
  3. **Run all gates locally** (`npm run lint`, `npx tsc --noEmit`, the test suite, `semgrep`, `npm audit` — or the stack-adapter equivalents). Trivial ≠ unverified; never `--no-verify`.
136
138
  4. **Commit** with a housekeeping type and **no** `REQ-XXX` — `docs:` / `chore:` / `ci:` / `build:` / `test:` / `revert:` are exempt from the `[REQ-XXX]` rule; a `compliance:` doc-only change references the existing REQ. `Co-Authored-By: Claude` if AI-assisted.
137
139
  5. **Push and open the PR** into `$INTEGRATION_BRANCH` (`gh pr create --base "$INTEGRATION_BRANCH" --head <branch>`). CI runs the same quality gates; `compliance-validation.yml` finds no `REQ-XXX` and skips artifact validation.
138
- 6. **For `ci:` changes, verify-via-dispatch before merging.** `gh workflow run <workflow.yml> --ref <branch>` fires the modified workflow against the PR branch. If the change broke a step, the dispatch run fails loudly and you fix-forward *before* the merge ships the broken gate to `$INTEGRATION_BRANCH`. This is the cheapest insurance against silent CI regressions — a `ci:` change that breaks a gate is most damaging *after* it lands.
140
+ 6. **For `ci:` changes, verify-via-dispatch before merging.** `gh workflow run <workflow.yml> --ref <branch>` fires the modified workflow against the PR branch. If the change broke a step, the dispatch run fails loudly and you fix-forward _before_ the merge ships the broken gate to `$INTEGRATION_BRANCH`. This is the cheapest insurance against silent CI regressions — a `ci:` change that breaks a gate is most damaging _after_ it lands.
139
141
  7. **Report honest status** — wait for CI, name any failing check, fix and re-push. Never announce "ready" while a required check is red.
140
142
  8. **Guide review → merge.** A human still reviews the PR (separation of duties). There is **no** portal release approval, no UAT four-eyes, no Production gate, and no close-out. Merge once CI is green and the reviewer approves.
141
143
  9. **Done.** A housekeeping push produces at most a bare-date release (`vYYYY.MM.DD`) with no approval gate; a doc-only push attaches its docs to the existing `REQ-XXX` release. No further action required — report completion and stop.
@@ -150,21 +152,23 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
150
152
  4. **Detect over-scoping.** If the issue spans clearly distinct deliverables (e.g. "build SAML SSO + reorganise the admin dashboard + migrate from Postgres 14 to 16"), halt with a clear message asking the user to split the issue into separate ones. Do not proceed past Phase 1.
151
153
  5. **Write the implementation plan.** Create `compliance/plans/REQ-XXX/implementation-plan.md` from `sdlc/files/_common/Implementation_Plan_TEMPLATE.md` (synced into the consumer's `SDLC/` directory at install). The template's shape is load-bearing — it carries the **Framework attribution** section that closes four framework clauses on upload:
152
154
 
153
- | Clause | What the plan must contain |
154
- |---|---|
155
- | **ISO 29119 §3.4** Test Plan | Acceptance criteria + verification strategy per AC. |
156
- | **ISO 27001 A.8.25** Secure SDLC | Threat model + secrets / dependency considerations. |
157
- | **GDPR Art. 25** Data protection by design | Per-purpose data flows + lawful basis + retention. Explicit "no personal data" callout if not applicable. |
158
- | **EU AI Act Art. 11** Technical documentation | Model provenance + oversight path when AI is in scope. Explicit "no AI in scope" callout if not. |
155
+ | Clause | What the plan must contain |
156
+ | --------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
157
+ | **ISO 29119 §3.4** Test Plan | Acceptance criteria + verification strategy per AC. |
158
+ | **ISO 27001 A.8.25** Secure SDLC | Threat model + secrets / dependency considerations. |
159
+ | **GDPR Art. 25** Data protection by design | Per-purpose data flows + lawful basis + retention. Explicit "no personal data" callout if not applicable. |
160
+ | **EU AI Act Art. 11** Technical documentation | Model provenance + oversight path when AI is in scope. Explicit "no AI in scope" callout if not. |
159
161
 
160
162
  For HIGH/CRITICAL also include: threat model (against STRIDE categories applicable to the touched surfaces), four-eyes attestation slot, rollback plan — the template has slots for all of these.
161
163
 
162
164
  **Don't delete sections** — mark with `N/A — <reason>` if a clause genuinely doesn't apply (e.g. UI-only change with no personal-data scope). Empty stubs commit-then-upload as placeholder evidence and break the audit trail.
165
+
163
166
  6. **Invoke `requirements-aligner` to populate the SRS-ID column on the AC table.** The plan's "Acceptance criteria" table carries an SRS-ID column per AC; `requirements-aligner` fuzzy-matches each AC against `docs/SRS.md` and proposes new `REQ-AREA-NNN` stubs, flags stale items, or annotates `@srs-deferred`. Don't author the SRS-ID column inline — call via the standard Claude Code Skill mechanism (`Skill(name: "requirements-aligner", …)`). Block plan APPROVAL until every AC has a resolved SRS-ID per the skill's Phase 1 contract (configurable via `sdlc-config.json:requirements_aligner.block_on_stage_1`; ramp-up mode default-on for legacy projects).
164
- 7. **Invoke `adr-author` to decide ADR-worthiness + draft the ADR if needed.** The plan's "Architecture decisions" section is no longer authored inline as bullets — `adr-author` applies its decision tree (new third-party dependency / new database/cache/queue / new external service / pattern change spanning >3 files / HIGH-CRITICAL risk class / file-path signals from `sdlc-config.json:adr_author.file_paths_signal_architecture`), allocates the next `ADR-NNN`, drafts a Context/Decision/Consequences/Alternatives/Status stub at `docs/ADR/ADR-NNN-<slug>.md`, and injects either *"Produced ADR-NNN: <title>"* or *"No ADR needed — <rationale>"* into the plan's section. Call via the standard Claude Code Skill mechanism (`Skill(name: "adr-author", …)`). Configurable via `sdlc-config.json:adr_author.block_on_stage_1`; advisory by default in v1.
165
- 8. **Update `compliance/RTM.md`** with the new entry: REQ-XXX, title, risk class, linked issue, linked test cases (placeholder).
166
- 9. **Post plan summary as an issue comment.** Format: TL;DR; Risk class + signals; Acceptance criteria (with SRS-IDs); Architectural decisions (ADR-NNN reference or no-ADR rationale); Technical approach (one paragraph); Dependencies; Test scope.
167
- 10. **Checkpoint** pause for human approval **iff** risk class is HIGH or CRITICAL. LOW and MEDIUM pass through to Phase 2 automatically. The checkpoint can be forced on for all classes via the `--require-plan-approval` flag (or `DEVAUDIT_REQUIRE_PLAN_APPROVAL=1` env var) for orgs that want it always-on.
167
+ 7. **Invoke `adr-author` to decide ADR-worthiness + draft the ADR if needed.** The plan's "Architecture decisions" section is no longer authored inline as bullets — `adr-author` applies its decision tree (new third-party dependency / new database/cache/queue / new external service / pattern change spanning >3 files / HIGH-CRITICAL risk class / file-path signals from `sdlc-config.json:adr_author.file_paths_signal_architecture`), allocates the next `ADR-NNN`, drafts a Context/Decision/Consequences/Alternatives/Status stub at `docs/ADR/ADR-NNN-<slug>.md`, and injects either _"Produced ADR-NNN: <title>"_ or _"No ADR needed — <rationale>"_ into the plan's section. Call via the standard Claude Code Skill mechanism (`Skill(name: "adr-author", …)`). Configurable via `sdlc-config.json:adr_author.block_on_stage_1`; advisory by default in v1.
168
+ 8. **Invoke `risk-register-keeper` for MEDIUM/HIGH risk classifications.** The plan's "Threat model" / Risks section is no longer authored as orphan bullets — when risk class is MEDIUM or HIGH (LOW skipped by default per `sdlc-config.json:risk_register_keeper.stage_1_min_risk_class`), `risk-register-keeper` reads the plan + diff, identifies discrete risks the change introduces, allocates `RISK-NNN` per project, drafts canonical rows in `compliance/risk-register.md`, and injects the RISK-NNN reference list into the plan's "Risk register entries" sub-section. The skill also enforces the `solo_with_gap` control-gap entry exists for projects in that approval mode. Call via the standard Claude Code Skill mechanism (`Skill(name: "risk-register-keeper", …)`). Configurable via `sdlc-config.json:risk_register_keeper.block_on_stage_1`; advisory by default in v1.
169
+ 9. **Update `compliance/RTM.md`** with the new entry: REQ-XXX, title, risk class, linked issue, linked test cases (placeholder).
170
+ 10. **Post plan summary as an issue comment.** Format: TL;DR; Risk class + signals; Acceptance criteria (with SRS-IDs); Architectural decisions (ADR-NNN reference or no-ADR rationale); Risk register entries (RISK-NNN list); Technical approach (one paragraph); Dependencies; Test scope.
171
+ 11. **Checkpoint** — pause for human approval **iff** risk class is HIGH or CRITICAL. LOW and MEDIUM pass through to Phase 2 automatically. The checkpoint can be forced on for all classes via the `--require-plan-approval` flag (or `DEVAUDIT_REQUIRE_PLAN_APPROVAL=1` env var) for orgs that want it always-on.
168
172
 
169
173
  ### Phase 2 — Implement and test (SDLC stage 2)
170
174
 
@@ -185,8 +189,9 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
185
189
  - `semgrep scan --config auto`
186
190
  - `npm audit --audit-level=high` (or stack-adapter equivalent)
187
191
 
188
- **E2E gate** — run *once*, after the fast gates are clean:
192
+ **E2E gate** — run _once_, after the fast gates are clean:
189
193
  - `npx playwright test` (delegated to `e2e-test-engineer`, which has its own focused-iteration discipline for within-e2e fix-and-verify loops)
194
+
190
195
  6. **On gate failure**, iterate up to N=3 attempts. Each iteration: read the failure output, propose a fix, apply, re-run. On exhausted attempts, halt with the full failure output and surface to the human — never use `--no-verify`, `eslint-disable`, `@ts-expect-error`, `xfail`, or any other bypass.
191
196
  7. **Commit** using Conventional Commits with `Ref: REQ-XXX` trailer and `Co-Authored-By: Claude` trailer. One commit per logical step; never amend a commit that's already been pushed.
192
197
  8. **Land the work on `$INTEGRATION_BRANCH`.** Push the feature branch, then:
@@ -196,15 +201,18 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
196
201
  ### Phase 3 — Compile evidence (SDLC stage 3)
197
202
 
198
203
  1. **Invoke `requirements-aligner` to drop the per-REQ SRS-alignment artefact.** The skill's Phase 2 produces `compliance/evidence/REQ-XXX/srs-alignment.md` — the per-REQ trace from each AC to its SRS item, with an operator sign-off block. The artefact uploads with `evidence_type=srs_alignment` (visible in Documents tab + audit-pack export; v1 orphan-by-design per META-COMPLY framework-registry-auditor). Call via the standard Skill mechanism; don't inline the alignment logic.
199
- 2. **Invoke `adr-author` to drop the per-REQ architecture-decision artefact.** The skill's Phase 2 produces `compliance/evidence/REQ-XXX/architecture-decision.md` — either *"Produced ADR-NNN: <title>"* with the file pointer, or *"No ADR needed — <rationale>"*. Operator sign-off block at the bottom. The artefact uploads with `evidence_type=architecture_decision`; clause attribution per the META-COMPLY framework-registry-auditor review. Call via the standard Skill mechanism.
200
- 3. **Re-run the full test pack** with artefact capture:
204
+ 2. **Invoke `adr-author` to drop the per-REQ architecture-decision artefact.** The skill's Phase 2 produces `compliance/evidence/REQ-XXX/architecture-decision.md` — either _"Produced ADR-NNN: <title>"_ with the file pointer, or _"No ADR needed — <rationale>"_. Operator sign-off block at the bottom. The artefact uploads with `evidence_type=architecture_decision`; clause attribution per the META-COMPLY framework-registry-auditor review. Call via the standard Skill mechanism.
205
+ 3. **Invoke `risk-register-keeper` to drop the per-REQ risk-assessment artefact.** The skill's Phase 3 produces `compliance/evidence/REQ-XXX/risk-assessment.md` — a summary table of RISK-NNN entries this REQ opened / mitigated / accepted, framework cross-references, and an operator sign-off block. The artefact uploads with `evidence_type=risk_assessment`; clause attribution per the META-COMPLY framework-registry-auditor review. Call via the standard Skill mechanism.
206
+ 4. **Re-run the full test pack** with artefact capture:
201
207
  - `npm run test:e2e -- --reporter=html` (produces `playwright-report/`)
202
208
  - `npx vitest run --coverage` (produces `coverage/`)
203
- 4. **Organise artefacts** under `compliance/evidence/REQ-XXX/` with date-prefixed naming:
209
+ 5. **Organise artefacts** under `compliance/evidence/REQ-XXX/` with date-prefixed naming:
210
+
204
211
  ```
205
212
  compliance/evidence/REQ-XXX/
206
213
  ├── srs-alignment.md ← produced in step 1 by requirements-aligner
207
214
  ├── architecture-decision.md ← produced in step 2 by adr-author
215
+ ├── risk-assessment.md ← produced in step 3 by risk-register-keeper
208
216
  ├── YYYY-MM-DD_e2e-results.json
209
217
  ├── YYYY-MM-DD_playwright-report/
210
218
  ├── YYYY-MM-DD_traces/ ← per-test trace.zip + error-context.md
@@ -212,8 +220,9 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
212
220
  └── YYYY-MM-DD_screenshots/*.png
213
221
  ```
214
222
 
215
- Copy Playwright's `test-results/` folder verbatim into `YYYY-MM-DD_traces/` so trace-by-test-name is available for audit without walking the HTML report's hash-name index. For HIGH/CRITICAL releases the traces are part of the audit trail — *"what state was the page in when test X failed and was overridden?"* answers in one `ls` instead of an HTML-report walk.
216
- 5. **Upload each artefact to the portal**:
223
+ Copy Playwright's `test-results/` folder verbatim into `YYYY-MM-DD_traces/` so trace-by-test-name is available for audit without walking the HTML report's hash-name index. For HIGH/CRITICAL releases the traces are part of the audit trail — _"what state was the page in when test X failed and was overridden?"_ answers in one `ls` instead of an HTML-report walk.
224
+
225
+ 6. **Upload each artefact to the portal**:
217
226
  ```bash
218
227
  devaudit push <project-slug> REQ-XXX <evidence-type> <file> \
219
228
  --release "v$(date +%Y.%m.%d)" --create-release-if-missing \
@@ -221,9 +230,9 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
221
230
  --git-sha "$(git rev-parse HEAD)" \
222
231
  --branch "$(git rev-parse --abbrev-ref HEAD)"
223
232
  ```
224
- Evidence types: `screenshot`, `e2e_result`, `test_report`, `audit_log`, `compliance_document`, `manual_upload`, `srs_alignment` (from step 1), `architecture_decision` (from step 2).
225
- 6. **Verify uploads landed.** `gh api` or `curl` against `https://devaudit.metasession.co/projects/<slug>/requirements/REQ-XXX/evidence` should show every artefact.
226
- 7. **Update `compliance/RTM.md`** with portal links for each evidence row.
233
+ Evidence types: `screenshot`, `e2e_result`, `test_report`, `audit_log`, `compliance_document`, `manual_upload`, `srs_alignment` (from step 1), `architecture_decision` (from step 2), `risk_assessment` (from step 3).
234
+ 7. **Verify uploads landed.** `gh api` or `curl` against `https://devaudit.metasession.co/projects/<slug>/requirements/REQ-XXX/evidence` should show every artefact.
235
+ 8. **Update `compliance/RTM.md`** with portal links for each evidence row.
227
236
 
228
237
  ### Phase 4 — Submit for UAT review (SDLC stage 4)
229
238
 
@@ -240,9 +249,11 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
240
249
  - For HIGH/CRITICAL: Rollback plan: reference to `compliance/plans/REQ-XXX/implementation-plan.md` §Rollback
241
250
  - Test plan
242
251
  - SDLC checklist
252
+
243
253
  2. **Verify the UAT reviewer ≠ skill-trigger user** for HIGH/CRITICAL. If they match, halt with a configuration error: "HIGH/CRITICAL risk requires an independent UAT reviewer; the configured reviewer matches the trigger user — fix the four-eyes attestation slot in the implementation plan and re-run."
244
254
 
245
- **Solo-operator teams.** On a one-person team, the literal "reviewer ≠ submitter" check is structurally unsatisfiable. The supported interpretation is *actor type, not human identity* — AI tooling (the skill-trigger) and the human operator (the portal-approver) are distinct actors. Document this on the release ticket under `## Sign-off (dual-actor)` with the explicit interpretation, and ensure the human operator has independently reviewed the diff before clicking *Approve Production* in the portal. Without this attestation the four-eyes claim is performative.
255
+ **Solo-operator teams.** On a one-person team, the literal "reviewer ≠ submitter" check is structurally unsatisfiable. The supported interpretation is _actor type, not human identity_ — AI tooling (the skill-trigger) and the human operator (the portal-approver) are distinct actors. Document this on the release ticket under `## Sign-off (dual-actor)` with the explicit interpretation, and ensure the human operator has independently reviewed the diff before clicking _Approve Production_ in the portal. Without this attestation the four-eyes claim is performative.
256
+
246
257
  3. **Apply labels** — `awaiting-uat-review`, `risk:<class>`.
247
258
  4. **Comment on the issue**: "Implementation complete. PR #M opened. Evidence on portal: <link>. UAT review requested. Resume with `resume REQ-XXX` once UAT approval is granted on the portal."
248
259
  5. **Hard stop.** Phase 4 ends here. Do not proceed to merge; the human's next action is reviewing on the portal.
@@ -261,7 +272,6 @@ Invoked separately by the user after UAT activity on the portal. Trigger: "resum
261
272
  1. **Read portal state.** `curl` `https://devaudit.metasession.co/api/projects/<slug>/releases/<version>` and inspect the approval status.
262
273
 
263
274
  2. **Branch on state:**
264
-
265
275
  - **UAT approved** → run stage 5:
266
276
  - `gh pr merge <M> --merge` (merge commit; `--squash` and `--rebase` are blocked by branch protection on SDLC repos and would break the audit trail).
267
277
  - Watch `post-deploy-prod.yml` via `gh run watch` — block until the workflow reaches a terminal state.
@@ -71,7 +71,12 @@
71
71
  "uat": {
72
72
  "enabled": false,
73
73
  "url": "",
74
- "required_risk_classes": ["payment", "destructive_migration", "realtime", "physical_ux"]
74
+ "required_risk_classes": [
75
+ "payment",
76
+ "destructive_migration",
77
+ "realtime",
78
+ "physical_ux"
79
+ ]
75
80
  },
76
81
 
77
82
  "_comment_approval": "Four-eyes release approval policy (Stage 3 Step 11). dual_actor = DevAudit enforces approver ≠ release_creator. solo_with_gap = self-approval allowed with documented control gap in compliance/risk-register.md. auto_low_risk = LOW-risk auto-approved by CI, MEDIUM/HIGH require human.",
@@ -106,5 +111,16 @@
106
111
  "prisma/schema.prisma",
107
112
  "infra/"
108
113
  ]
114
+ },
115
+
116
+ "_comment_risk_register_keeper": "risk-register-keeper skill toggles (DevAudit-Installer#121, v0.1.44+). The skill maintains compliance/risk-register.md as the project-spanning risk SoT. At Stage 1 (MEDIUM/HIGH risk classifications only by default — LOW skipped) it identifies risks the change introduces, allocates RISK-NNN per project, drafts canonical rows, and injects the reference list into the implementation plan. On incident close it drafts the residual-risk entry. At Stage 3 it drops compliance/evidence/REQ-XXX/risk-assessment.md. For solo_with_gap approval projects it enforces the documented control-gap entry. block_on_stage_1=false (default) means advisory in v1. block_on_stage_3=true means the per-REQ risk-assessment.md artefact is the hard gate. scoring='likelihood-impact' = default 3x3 matrix per 0-project-setup.md (CVSS deferred). stage_1_min_risk_class='MEDIUM' = LOW REQs skip the Stage-1 hook (orchestrator's classification already decided no register entry is warranted).",
117
+ "risk_register_keeper": {
118
+ "enabled": true,
119
+ "block_on_stage_1": false,
120
+ "block_on_stage_3": true,
121
+ "scoring": "likelihood-impact",
122
+ "auto_open_on_high_risk_req": true,
123
+ "auto_open_on_closed_incident": true,
124
+ "stage_1_min_risk_class": "MEDIUM"
109
125
  }
110
126
  }