@metasession.co/devaudit-cli 0.1.40 → 0.1.42

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-cli",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^0.8.2",
36
- "@metasession.co/devaudit-plugin-sdk": "^0.1.40",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.42",
37
37
  "commander": "^12.1.0",
38
38
  "consola": "^3.2.3",
39
39
  "env-paths": "^3.0.0",
@@ -58,6 +58,38 @@ Both `ci.yml` and `compliance-evidence.yml` call the same helper, so a feature s
58
58
 
59
59
  If you need a separate release container for a sub-piece of work — e.g. carving REQ-038 out of an in-flight feature — give it its own REQ-ID and tag the commits accordingly.
60
60
 
61
+ ## Two release shapes
62
+
63
+ A release is classified by its version pattern. **Most of this doc walks the tracked path** (a REQ-XXX-tagged release for a single requirement). For develop pushes that don't carry a REQ tag — typically `docs:`, `chore:`, `ci:`, `build:`, `test:`, `compliance:`, `revert:` — the version-deriver falls back to a bare date and the release is **housekeeping**.
64
+
65
+ | Shape | Version pattern | Triggered by | Per-REQ ceremony |
66
+ |---|---|---|---|
67
+ | **Tracked** | `REQ-037`, `REQ-046-FIX`, etc. | A `feat`/`fix`/`refactor`/`perf` commit (REQ tag required by commitlint) | Yes — full Steps 1-9 |
68
+ | **Housekeeping** | `v2026.06.04` (bare date, optionally `.N`) | A push containing only REQ-exempt commit types | **No** per-REQ artefacts; the portal auto-skips test-scope, test-plan, implementation-plan, and test-execution-summary completeness checks |
69
+
70
+ ### Housekeeping releases — what's required
71
+
72
+ Housekeeping releases **skip** the per-requirement evidence (no REQ → no `compliance/evidence/REQ-XXX/` folder) but **still produce two release-scoped artefacts**:
73
+
74
+ | Artefact | Tracked path | Housekeeping path | Auto-generated by CI? |
75
+ |---|---|---|---|
76
+ | Release ticket | `compliance/pending-releases/RELEASE-TICKET-REQ-XXX.md` (Step 8) | `compliance/pending-releases/RELEASE-TICKET-<version>.md` (e.g. `RELEASE-TICKET-v2026.06.04.md`) | **Yes** — `generate-housekeeping-release-ticket.sh` runs after `derive-release-version.sh` and emits a stub the operator reviews + signs off |
77
+ | Security summary | `compliance/evidence/REQ-XXX/security-summary.md` (Step 4) | `compliance/security-summary-<version>.md` at the compliance root (release-scoped, not REQ-scoped) | **Yes** — `generate-security-summary.sh` scrapes the SAST + dep-audit gate JSON and emits a stub with an operator sign-off block |
78
+
79
+ **The portal evidence check is lenient on filename.** Any file whose name (case-insensitive) starts with `release-ticket` satisfies the release-ticket check, and any file named exactly `security-summary.md` satisfies the security-summary check. The version-suffixed conventions above are recommended for **searchability + audit trail** when a project has many housekeeping releases stacked up — they keep the artefacts distinct per release without needing folder scoping.
80
+
81
+ **What housekeeping operators do, end to end:**
82
+
83
+ 1. Push the `docs:` / `chore:` / `ci:` commits to develop. CI runs the four gates as usual.
84
+ 2. CI's `compliance-evidence.yml` workflow auto-opens a PR (`chore/housekeeping-release-<version>`) containing the two stubs.
85
+ 3. Review the stubs — confirm the commit-summary list in the release ticket is sensible, confirm the SAST + dep-audit summary reads correctly, fill in the operator sign-off block on each.
86
+ 4. Merge that PR. The next CI run picks up the artefacts and the portal's release-completeness checklist flips both items to ✓.
87
+ 5. Submit for UAT review on the portal. The approval flow is identical to the tracked path — same four-eyes rules (per project risk tier), same `draft → uat_review → uat_approved → prod_review → prod_approved → released` state machine.
88
+
89
+ **No auto-approval.** Housekeeping releases still require operator action to advance through the gates. The CI-generated stubs replace the operator's authoring effort, not the operator's review.
90
+
91
+ > **Versions of the framework before 2026-06 produced housekeeping stubs by hand.** Older release records may have `security-summary.md` under a REQ-XXX-shaped folder or no release ticket at all — leave those in DRAFT for the audit trail; backfilling isn't required.
92
+
61
93
  ## Steps
62
94
 
63
95
  ### Step 0: Confirm CI Is Green
@@ -233,6 +265,20 @@ cat compliance/evidence/REQ-XXX/test-scope.md
233
265
  # If not, complete the outstanding items before proceeding
234
266
  ```
235
267
 
268
+ The test-scope artefact carries an **SRS-ID cross-reference table** so each test maps back to the requirement (SoT) it pins. Format:
269
+
270
+ ```markdown
271
+ ## SRS coverage
272
+
273
+ | Test (file) | AC | SRS item |
274
+ |---|---|---|
275
+ | e2e/admin-order-flow.spec.ts | AC1 | REQ-ORDER-005 |
276
+ | services/order-service.test.ts | AC2 | REQ-INV-010 |
277
+ | e2e/incident-dashboard.spec.ts | AC9 | REQ-OPS-001 |
278
+ ```
279
+
280
+ The SRS-ID column populates from the implementation plan's SRS-ID column (populated by the `requirements-aligner` skill at Stage 1). Stage 3 cross-checks consistency: every AC's SRS item should resolve to a real entry in `docs/SRS.md`, every test should pin at least one AC. The skill also drops a `srs-alignment.md` per-REQ artefact alongside this one (Tier 3 evidence with `evidence_type=srs_alignment`).
281
+
236
282
  For MEDIUM/HIGH risk, verify the implementation plan exists and matches what was built:
237
283
 
238
284
  ```bash
@@ -36,9 +36,14 @@ Each section below maps to one (or more) of these clauses. Don't delete sections
36
36
 
37
37
  - **Goal:** REPLACE — one sentence describing what this REQ delivers, no jargon.
38
38
  - **Acceptance criteria:**
39
- - AC1 — REPLACE
40
- - AC2 REPLACE
41
- - …
39
+
40
+ | AC | Description | SRS item it traces to |
41
+ |---|---|---|
42
+ | AC1 | REPLACE — one-line behavioural description | REQ-AREA-NNN (existing) / REQ-AREA-NNN (new — propose stub) / `@srs-deferred: <reason>` |
43
+ | AC2 | REPLACE | REPLACE |
44
+ | … | | |
45
+
46
+ > **SRS-ID column populated by the `requirements-aligner` skill** at Stage 1 plan APPROVAL. The skill fuzzy-matches each AC against `docs/SRS.md`, proposes new `REQ-AREA-NNN` stubs for behaviour the SRS doesn't yet describe, and flags stale items. Plan APPROVAL blocks (configurable per `sdlc-config.json:requirements_aligner.block_on_stage_1`, ramp-up mode default-on for legacy projects) until every AC has either an existing SRS item, a new SRS-ID stub added in this cycle, or an explicit `@srs-deferred` annotation. See [`requirements-aligner` skill](../skills/requirements-aligner/SKILL.md).
42
47
 
43
48
  ## 2. Scope
44
49
 
@@ -45,7 +45,7 @@ A worked end-to-end example for a zero-risk change (a typo, a dependency bump, a
45
45
  3. **Commit with a housekeeping type.** `docs:` / `chore:` / `ci:` / `build:` / `test:` / `revert:` are **exempt** from the `[REQ-XXX]` rule — e.g. `git commit -m "docs: fix typo in README"`. A `feat` / `fix` / `refactor` / `perf` subject without a `[REQ-XXX]` or `Ref: REQ-XXX` is **rejected** by commitlint and `validate-commits.sh` — if that fires, you picked the wrong type and the change isn't trivial.
46
46
  4. **Run the gates locally — not optional.** `npx tsc --noEmit`, lint, and the test suite must pass before you push. Trivial ≠ unverified.
47
47
  5. **Push and open a PR.** CI runs the same quality gates. `compliance-validation.yml` finds no `REQ-XXX` and **skips** artifact validation; no release ticket, no RTM row, no evidence pack is required.
48
- 6. **Merge once CI is green** and a reviewer approves the PR. There's **no** portal release record to approve, no UAT/Production gate, and no close-out a housekeeping push produces at most a bare-date release (`vYYYY.MM.DD`), which carries no approval gate. (Contrast the tracked-change flow below, which produces a `REQ-XXX` release that goes through four-eyes.)
48
+ 6. **Merge once CI is green** and a reviewer approves the PR. A housekeeping push **does** produce a portal release record a bare-date release (`vYYYY.MM.DD`) and it **does** go through the same UAT → production four-eyes flow as a tracked release. What the portal **auto-skips for housekeeping** is the four per-REQ completeness items (test-scope / test-plan / implementation-plan / test-execution-summary) — those have nothing to evaluate without a `REQ-XXX`. What's still required: all four CI gates green, a release ticket (`compliance/pending-releases/RELEASE-TICKET-<version>.md`), and a security summary (`compliance/security-summary-<version>.md`). **CI auto-generates both stubs as an operator-sign-off PR** (DevAudit-Installer v0.1.41+, scripts `generate-housekeeping-release-ticket.sh` + `generate-security-summary.sh`). Review the stubs + replace the `REPLACE — …` markers + merge → next CI run uploads them → matrix flips both items to ✓ → submit for UAT review on the portal. See [stage-3 housekeeping section](./3-compile-evidence.md) for the full walkthrough.
49
49
 
50
50
  If at any step it stops feeling trivial — it changes behaviour, touches auth/payments/data, or an auditor would ask about it — switch to a tracked change and run `sdlc-implementer`. When unsure, it's not trivial.
51
51
 
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bash
2
+ # generate-housekeeping-release-ticket.sh
3
+ #
4
+ # Writes a housekeeping release-ticket stub for a bare-date release
5
+ # (`v2026.06.04` etc.). Synced into the consumer's `scripts/` by
6
+ # `devaudit update`; invoked from `compliance-evidence.yml` after
7
+ # `derive-release-version.sh` when the version pattern is bare-date AND
8
+ # no ticket file already exists.
9
+ #
10
+ # Usage:
11
+ # bash scripts/generate-housekeeping-release-ticket.sh <version> > <out>
12
+ #
13
+ # Where <version> is the bare-date version (e.g. `v2026.06.04`) and
14
+ # <out> is the target path (typically `compliance/pending-releases/
15
+ # RELEASE-TICKET-<version>.md`).
16
+ #
17
+ # The stub carries:
18
+ # - Frontmatter with version + generated_at + last_reviewed_at (defaults
19
+ # to today; operator updates on sign-off)
20
+ # - Commit summaries since the previous release tag (or last 20 commits
21
+ # if no prior tag exists)
22
+ # - An operator sign-off block with `REPLACE — …` markers the operator
23
+ # must fill in before merging the auto-PR
24
+ #
25
+ # Companion to `generate-security-summary.sh`. Both are invoked together
26
+ # by the CI workflow.
27
+ #
28
+ # DevAudit-Installer#116 WS3.
29
+
30
+ set -euo pipefail
31
+
32
+ VERSION="${1:-}"
33
+ if [ -z "$VERSION" ]; then
34
+ echo "usage: $(basename "$0") <version>" >&2
35
+ exit 2
36
+ fi
37
+
38
+ # Validate bare-date pattern (matches `classifyReleaseShape` in META-COMPLY).
39
+ if ! [[ "$VERSION" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
40
+ echo "error: '$VERSION' is not a bare-date version (expected vYYYY.MM.DD[.N])" >&2
41
+ exit 2
42
+ fi
43
+
44
+ TODAY=$(date -u +%Y-%m-%d)
45
+
46
+ # Last 20 commits with subject lines. Skip the version-deriver fallback
47
+ # from itself (avoid recursion if this script is re-run on a branch
48
+ # that already includes its own auto-commit).
49
+ COMMIT_LINES=$(git log -20 --pretty=format:'- `%h` %s' 2>/dev/null \
50
+ | grep -v 'chore: housekeeping release-ticket stub' \
51
+ | head -15)
52
+ if [ -z "$COMMIT_LINES" ]; then
53
+ COMMIT_LINES="- _(no commits found in `git log` — this stub was generated outside a git context)_"
54
+ fi
55
+
56
+ cat <<EOF
57
+ ---
58
+ version: "$VERSION"
59
+ release_shape: housekeeping
60
+ generated_at: "$TODAY"
61
+ last_reviewed_at: "$TODAY"
62
+ generated_by: "generate-housekeeping-release-ticket.sh (DevAudit-Installer#116)"
63
+ ---
64
+
65
+ > ⚠️ **AUTO-GENERATED STUB — REPLACE BEFORE MERGE**
66
+ >
67
+ > This release ticket was auto-generated by CI when develop received a
68
+ > housekeeping push (no \`REQ-XXX\` in commit subjects, version derived
69
+ > as bare-date \`$VERSION\`).
70
+ >
71
+ > **The operator must:**
72
+ > 1. Confirm the **Summary** below describes the actual intent of these
73
+ > commits — replace the placeholder if the auto-summary is generic.
74
+ > 2. Fill in the **Sign-off** block with the operator's name + date +
75
+ > risk assessment.
76
+ > 3. Merge this PR. The next \`compliance-evidence.yml\` run will upload
77
+ > this file as \`release_artifact\` evidence, satisfying the
78
+ > portal's release-ticket completeness check.
79
+
80
+ # Release Ticket: $VERSION (housekeeping)
81
+
82
+ **Status:** TESTED - PENDING SIGN-OFF
83
+ **Date:** $TODAY
84
+ **Release Shape:** Housekeeping (bare-date, no REQ tag)
85
+ **Version:** $VERSION
86
+
87
+ ---
88
+
89
+ ## Summary
90
+
91
+ REPLACE — one or two sentences describing what these housekeeping commits delivered. Examples: *"Documentation refresh for the v0.1.39 governance changes; no code paths touched."* / *"Dependency bumps (vitest 4.0.5 → 4.0.6, prettier 4.3.0 → 4.3.1) caught by Dependabot; no behavioural change."* / *"CI workflow housekeeping: retry-on-flake threshold raised, runner image pinned."*
92
+
93
+ ## Commits in this release
94
+
95
+ $COMMIT_LINES
96
+
97
+ ## Risk Assessment
98
+
99
+ REPLACE — confirm risk class for this release (typically LOW for housekeeping):
100
+
101
+ - [ ] **LOW** — documentation, dependency bumps, CI tweaks, internal refactors. No user-visible behaviour change.
102
+ - [ ] **MEDIUM** — touches code paths an end-user reaches; user-visible change is small and well-contained.
103
+ - [ ] **HIGH** — should not be a housekeeping release. If this is checked, **stop and re-tag the commits with \`REQ-XXX\`** so the release is tracked properly.
104
+
105
+ ## Test Evidence
106
+
107
+ | Test Type | Status | Source |
108
+ |---|---|---|
109
+ | TypeScript | $(test -f gate-outcomes.json && echo "see gate-outcomes.json" || echo "REPLACE — green / N/A") | CI \`typecheck\` gate |
110
+ | SAST | $(test -f gate-outcomes.json && echo "see gate-outcomes.json" || echo "REPLACE — green / N/A") | CI \`SAST\` gate |
111
+ | Dependency audit | $(test -f gate-outcomes.json && echo "see gate-outcomes.json" || echo "REPLACE — green / N/A") | CI \`dependency_audit\` gate |
112
+ | E2E | $(test -f gate-outcomes.json && echo "see gate-outcomes.json" || echo "REPLACE — green / N/A") | CI \`e2e\` gate |
113
+ | Test reports | $(test -f gate-outcomes.json && echo "see gate-outcomes.json" || echo "REPLACE — green / N/A") | CI \`test_report\` gate |
114
+
115
+ > Companion artefact: \`compliance/security-summary-$VERSION.md\` (auto-generated by \`generate-security-summary.sh\` in the same workflow run; contains the SAST + dep-audit findings detail).
116
+
117
+ ## Acceptance Criteria
118
+
119
+ - [x] All four compliance gates green on the CI run that produced this stub
120
+ - [x] No \`REQ-XXX\`-tagged commits in this release (housekeeping by definition)
121
+ - [ ] Operator-reviewed and signed off — see Sign-off block below
122
+
123
+ ## Post-Deploy Actions
124
+
125
+ | Type | Script / Command | Target | Required | Notes |
126
+ |------|-----------------|--------|----------|-------|
127
+ | — | None | — | — | Housekeeping releases typically have no post-deploy actions |
128
+
129
+ <!-- Replace the "None" row above if this release requires post-deploy work. -->
130
+
131
+ ---
132
+
133
+ ## Sign-off
134
+
135
+ | Role | Name | Date | Notes |
136
+ |---|---|---|---|
137
+ | Submitter | REPLACE | $TODAY | Auto-generated by CI; reviewed + edited |
138
+ | Reviewer (independent if project risk_tier ≠ low) | REPLACE | REPLACE | REPLACE |
139
+
140
+ ## Audit Trail
141
+
142
+ | Date | Action | Actor | Notes |
143
+ |------|--------|-------|-------|
144
+ | $TODAY | Stub auto-generated | devaudit-bot | Bare-date version $VERSION |
145
+ | REPLACE | Operator sign-off | REPLACE | REPLACE |
146
+ | REPLACE | Submitted for UAT review | REPLACE | Via portal |
147
+ EOF
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env bash
2
+ # generate-security-summary.sh
3
+ #
4
+ # Writes a security-summary stub for a release. Resolves the dangling
5
+ # reference in META-COMPLY's release-checklist (the UI hint mentioned a
6
+ # generator script that didn't exist).
7
+ #
8
+ # Usage:
9
+ # bash scripts/generate-security-summary.sh <version> > <out>
10
+ #
11
+ # - For housekeeping releases (bare-date version), the canonical
12
+ # <out> is `compliance/security-summary-<version>.md` at the
13
+ # compliance root.
14
+ # - For tracked releases (REQ-XXX version), the canonical <out> is
15
+ # `compliance/evidence/REQ-XXX/security-summary.md`. The script
16
+ # outputs the same body shape; only the caller decides the path.
17
+ #
18
+ # Scrapes:
19
+ # - `sast-results.json` (Semgrep) — high/critical findings count
20
+ # - `dependency-audit.json` (npm audit / pip-audit) — high/critical
21
+ # vulnerability count
22
+ # - `gate-outcomes.json` (DevAudit-Installer v0.1.29) — per-gate
23
+ # pass/fail/skip status
24
+ #
25
+ # Each source is optional — the stub gracefully reports "not found"
26
+ # rather than erroring out. The operator fills in any missing detail
27
+ # in the sign-off block before merging the auto-PR.
28
+ #
29
+ # DevAudit-Installer#116 WS4.
30
+
31
+ set -euo pipefail
32
+
33
+ VERSION="${1:-}"
34
+ if [ -z "$VERSION" ]; then
35
+ echo "usage: $(basename "$0") <version>" >&2
36
+ exit 2
37
+ fi
38
+
39
+ TODAY=$(date -u +%Y-%m-%d)
40
+
41
+ # Detect release shape from the version.
42
+ SHAPE="unknown"
43
+ if [[ "$VERSION" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
44
+ SHAPE="housekeeping"
45
+ elif [[ "$VERSION" =~ ^REQ- ]]; then
46
+ SHAPE="tracked"
47
+ fi
48
+
49
+ # Helper: scrape Semgrep JSON for high/critical counts. Soft-fails when
50
+ # the file is absent or jq isn't available.
51
+ sast_summary() {
52
+ if [ ! -f sast-results.json ]; then
53
+ echo "REPLACE — \`sast-results.json\` not present at CWD; check that the SAST gate ran on this commit"
54
+ return
55
+ fi
56
+ if ! command -v jq >/dev/null 2>&1; then
57
+ echo "REPLACE — \`jq\` not available; manually inspect \`sast-results.json\`"
58
+ return
59
+ fi
60
+ local HIGH CRITICAL TOTAL
61
+ HIGH=$(jq -r '[.results[]? | select(.extra.severity == "WARNING" or .extra.severity == "ERROR")] | length' sast-results.json 2>/dev/null || echo "?")
62
+ CRITICAL=$(jq -r '[.results[]? | select(.extra.severity == "ERROR")] | length' sast-results.json 2>/dev/null || echo "?")
63
+ TOTAL=$(jq -r '[.results[]?] | length' sast-results.json 2>/dev/null || echo "?")
64
+ echo "$TOTAL total finding(s) · $HIGH high/warning · $CRITICAL critical/error"
65
+ }
66
+
67
+ # Helper: scrape npm audit JSON. Tolerant of both `npm audit --json`
68
+ # shape (vulnerabilities object) and pip-audit shape (vulnerabilities
69
+ # array).
70
+ dep_audit_summary() {
71
+ if [ ! -f dependency-audit.json ]; then
72
+ echo "REPLACE — \`dependency-audit.json\` not present at CWD; check that the dependency-audit gate ran on this commit"
73
+ return
74
+ fi
75
+ if ! command -v jq >/dev/null 2>&1; then
76
+ echo "REPLACE — \`jq\` not available; manually inspect \`dependency-audit.json\`"
77
+ return
78
+ fi
79
+ # npm audit shape: .vulnerabilities is an object keyed by package
80
+ # name with .severity per row.
81
+ local HIGH CRITICAL TOTAL
82
+ HIGH=$(jq -r '[.vulnerabilities | (if type == "object" then to_entries[] | .value else .[]? end) | select(.severity == "high")] | length' dependency-audit.json 2>/dev/null || echo "?")
83
+ CRITICAL=$(jq -r '[.vulnerabilities | (if type == "object" then to_entries[] | .value else .[]? end) | select(.severity == "critical")] | length' dependency-audit.json 2>/dev/null || echo "?")
84
+ TOTAL=$(jq -r '[.vulnerabilities | (if type == "object" then to_entries[] | .value else .[]? end)] | length' dependency-audit.json 2>/dev/null || echo "?")
85
+ echo "$TOTAL total vulnerability/ies · $HIGH high · $CRITICAL critical"
86
+ }
87
+
88
+ # Helper: gate-outcomes.json (DevAudit-Installer v0.1.29 onwards).
89
+ gate_outcomes_summary() {
90
+ if [ ! -f gate-outcomes.json ]; then
91
+ echo "REPLACE — \`gate-outcomes.json\` not present at CWD"
92
+ return
93
+ fi
94
+ if ! command -v jq >/dev/null 2>&1; then
95
+ echo "REPLACE — \`jq\` not available; manually inspect \`gate-outcomes.json\`"
96
+ return
97
+ fi
98
+ jq -r 'to_entries[] | "- **\(.key)** — \(.value // "?")"' gate-outcomes.json 2>/dev/null \
99
+ || echo "REPLACE — could not parse gate-outcomes.json"
100
+ }
101
+
102
+ SAST_SUMMARY=$(sast_summary)
103
+ DEP_SUMMARY=$(dep_audit_summary)
104
+ GATES=$(gate_outcomes_summary)
105
+
106
+ cat <<EOF
107
+ ---
108
+ version: "$VERSION"
109
+ release_shape: $SHAPE
110
+ generated_at: "$TODAY"
111
+ last_reviewed_at: "$TODAY"
112
+ generated_by: "generate-security-summary.sh (DevAudit-Installer#116)"
113
+ ---
114
+
115
+ > ⚠️ **AUTO-GENERATED STUB — REVIEW BEFORE MERGE**
116
+ >
117
+ > This security summary was auto-generated by CI from the SAST and
118
+ > dependency-audit gate JSON. The operator should:
119
+ >
120
+ > 1. Confirm the **findings summary** matches what they saw on the
121
+ > gate panel for this release.
122
+ > 2. Replace any \`REPLACE — …\` markers below (typically the access-
123
+ > control + audit-log assessment, which the gates can't infer).
124
+ > 3. Sign off in the **Sign-off** block before this PR merges.
125
+
126
+ # Security Summary — $VERSION
127
+
128
+ **Release shape:** $SHAPE
129
+ **Generated:** $TODAY
130
+ **Source data:** \`sast-results.json\` + \`dependency-audit.json\` + \`gate-outcomes.json\` (this CI run)
131
+
132
+ ## SAST findings (Semgrep)
133
+
134
+ $SAST_SUMMARY
135
+
136
+ > **Policy:** the SAST gate fails the build at \`high\` or \`critical\` severity. If this release shipped, both are zero.
137
+
138
+ ## Dependency vulnerabilities
139
+
140
+ $DEP_SUMMARY
141
+
142
+ > **Policy:** the dependency-audit gate fails the build at \`high\` or \`critical\` severity. If this release shipped, both are zero.
143
+
144
+ ## Gate outcomes (per CI run)
145
+
146
+ $GATES
147
+
148
+ ## Access control + audit log
149
+
150
+ | Check | Result | Notes |
151
+ |---|---|---|
152
+ | Access control unchanged | REPLACE — yes/no | If yes, no further work. If no, document the auth/RBAC delta and confirm it landed an audit event. |
153
+ | Audit log append-only invariant preserved | REPLACE — yes/no | If yes, no further work. If no, document why and confirm the change has independent review. |
154
+ | Sensitive data exposure | REPLACE — yes/no | If yes, escalate to the GDPR triage in \`compliance/governance/dpia.md\` before merging. |
155
+
156
+ ## Risk Assessment
157
+
158
+ REPLACE — one paragraph summarising the security posture of this release. For housekeeping releases the typical wording is *"No code paths touched; security posture unchanged from the previous release."* For tracked releases name the touched modules + threat model assessment.
159
+
160
+ ---
161
+
162
+ ## Sign-off
163
+
164
+ | Role | Name | Date | Notes |
165
+ |---|---|---|---|
166
+ | Author | devaudit-bot (auto-generated) | $TODAY | Stub generated from CI gate JSON |
167
+ | Reviewer | REPLACE | REPLACE | REPLACE |
168
+
169
+ Once reviewed + signed off, this file is uploaded as evidence by the next \`compliance-evidence.yml\` run; the portal's release-completeness checklist flips the security-summary item to ✓.
170
+ EOF
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: requirements-aligner
3
+ description: Catch drift between docs/SRS.md (the requirements source-of-truth) and the in-flight implementation. Runs at Stage 1 (plan APPROVAL) and Stage 3 (evidence pack) of the SDLC. Parses each REQ's acceptance criteria, fuzzy-matches each AC against existing SRS items, proposes new `REQ-AREA-NNN` stubs for behaviour the SRS doesn't yet describe, flags potentially-stale SRS items whose source-of-truth file was modified without the SRS prose being updated, and produces a per-REQ `compliance/evidence/REQ-XXX/srs-alignment.md` artefact that traces the audit back from code to spec. Use when invoking on a single REQ ("align SRS for REQ-066", "what SRS items did this REQ need?", "is the SRS in sync with this branch?"); when `sdlc-implementer` delegates at Stage 1 plan-approval or Stage 3 evidence-compilation; when running a branch-wide audit ("audit SRS drift across this PR's commits"). Do NOT use for SRS authoring from scratch (the operator drafts new items; this skill proposes the IDs and stubs); for changing the SRS prose conventions themselves (those are operator decisions); for framework-clause mapping of the `srs_alignment` evidence type (that's META-COMPLY's `framework-registry-auditor`).
4
+ ---
5
+
6
+ # Requirements Aligner
7
+
8
+ Catches the class of drift the wawagardenbar-app REQ-066 cycle surfaced: code, tests, and screenshots shipped across 10 ACs in 6 PRs while `docs/SRS.md` stayed untouched. Seven new SRS items + one stale item were filed retroactively after release. This skill catches them at Stage 1 or Stage 3, before merge.
9
+
10
+ The skill is **Phase A scope** (per [DevAudit-Installer#119](https://github.com/metasession-dev/DevAudit-Installer/issues/119) review): Stage 1 + Stage 3 hooks only. Stage 2 (commit-time advisory) + Stage 5 (post-release audit) + automatic follow-up issue filing all defer to Phase B/C — the v1 surface is the safest enforcement points.
11
+
12
+ ## What this skill owns
13
+
14
+ | Artefact | Lives at | Tier |
15
+ |---|---|---|
16
+ | `docs/SRS.md` (the SoT, project-spanning) | Top-level project docs | 2 (project strategy) |
17
+ | `compliance/evidence/REQ-XXX/srs-alignment.md` (per-REQ Tier 3 evidence) | Per-REQ evidence directory | 3 (per-REQ) |
18
+
19
+ The skill does **not** own the SRS prose conventions (operator decision). It does propose new `REQ-AREA-NNN` IDs + Given/When/Then stubs the operator then edits.
20
+
21
+ ## Scope
22
+
23
+ **In scope**
24
+
25
+ - Phase 1 (Stage-1 hook) — parse plan AC table → fuzzy-match against `docs/SRS.md` → propose new IDs / flag stale → inject into plan's "SRS items proposed/touched" section.
26
+ - Phase 2 (Stage-3 hook) — drop `compliance/evidence/REQ-XXX/srs-alignment.md` with the per-REQ trace from AC to SRS item.
27
+ - Per-REQ alignment audit (operator invocation).
28
+ - Branch-wide alignment audit (operator invocation — walks every REQ touched on the branch).
29
+
30
+ **Out of scope**
31
+
32
+ - Drafting SRS prose from scratch — the skill proposes stubs; the operator authors final language.
33
+ - Stage 2 (commit-time advisory) — deferred to Phase B.
34
+ - Stage 5 (post-release audit) — deferred to Phase B.
35
+ - Automatic follow-up issue filing — deferred to Phase C (default OFF per [#119 review](https://github.com/metasession-dev/DevAudit-Installer/issues/119#issuecomment-4631840651)).
36
+ - Threat modelling, ADR drafting, risk-register entries — adjacent skills (`adr-author`, `risk-register-keeper`).
37
+ - Framework-clause mapping of the `srs_alignment` evidence type — that's META-COMPLY's `framework-registry-auditor`.
38
+
39
+ ## The workflow
40
+
41
+ Five phases. Phase 0 routes; Phases 1–2 are the SDLC stage hooks; Phases 3–4 are utilities; Phase 5 reports.
42
+
43
+ ### Phase 0 — Route
44
+
45
+ Determine what's being aligned:
46
+
47
+ - **Stage-1 plan APPROVAL** — `sdlc-implementer` (or operator) says *"align SRS for REQ-XXX before approving the plan"* → Phase 1.
48
+ - **Stage-3 evidence pack** — `sdlc-implementer` (or operator) says *"drop the srs-alignment.md for REQ-XXX"* → Phase 2.
49
+ - **Per-REQ ad-hoc audit** — operator says *"is the SRS in sync with REQ-XXX?"* / *"what SRS items did this REQ need?"* → Phase 3.
50
+ - **Branch-wide audit** — operator says *"audit SRS drift across this branch"* / *"every REQ on develop since main needs an SRS check"* → Phase 4.
51
+
52
+ The skill does not fire spontaneously. The parent skill (`sdlc-implementer`) invokes it at Stages 1 + 3 per the parent's SKILL.md delegation contract.
53
+
54
+ ### Phase 1 — Stage-1 plan APPROVAL hook
55
+
56
+ Input: the REQ's `compliance/plans/REQ-XXX/implementation-plan.md` plus the working-tree diff.
57
+
58
+ **Step 1 — Parse the AC table.** The implementation plan template carries an "Acceptance Criteria" or equivalent section listing AC1, AC2, … with one-line descriptions of each behavioural change.
59
+
60
+ **Step 2 — Fuzzy-match each AC against `docs/SRS.md`.** For each AC, search the SRS for items whose:
61
+ - *Title* phrase appears in the AC description, OR
62
+ - *Implementation source-of-truth* footnote names a file the AC's diff touches, OR
63
+ - *Given/When/Then* prose semantically aligns with the AC (use the AC's verbs + nouns as the match-key).
64
+
65
+ **Step 3 — Categorise each AC:**
66
+
67
+ | AC ⇒ SRS state | Action |
68
+ |---|---|
69
+ | **Exact match** — AC traces 1:1 to an existing SRS item, no behavioural delta | Record the mapping; no SRS edit needed |
70
+ | **Match + drift** — existing SRS item covers the AC's surface but the behaviour has shifted (e.g. new field, new edge case, new error path) | Flag the item as *potentially stale*; the plan must mark it for update in this cycle OR justify why the SRS prose still covers it |
71
+ | **No match** — AC introduces behaviour the SRS doesn't yet describe | Propose new `REQ-AREA-NNN` (next free ID per area — see Step 4) with a Given/When/Then stub the operator edits |
72
+ | **Reverse drift** — an SRS item points at code that's been removed in this REQ | Propose deprecation: the SRS item is now obsolete |
73
+
74
+ **Step 4 — Allocate new SRS-IDs.** Scan `docs/SRS.md` for the max-existing ID per `REQ-AREA` prefix (`REQ-ORDER`, `REQ-INV`, `REQ-OPS`, etc.) and propose `+1` for each new item. The skill does NOT support cross-branch ID coordination — if two parallel branches both consume the same next-free ID, git merge on `docs/SRS.md` is the canonical conflict signal. Re-run the skill post-merge to re-allocate.
75
+
76
+ **Step 5 — Inject into the implementation plan.** The plan's "SRS items proposed/touched" section (added to `Implementation_Plan_TEMPLATE.md` alongside this skill's introduction) carries a table:
77
+
78
+ ```markdown
79
+ ## SRS items proposed/touched
80
+
81
+ | AC | SRS item | Status | Notes |
82
+ |---|---|---|---|
83
+ | AC1 | REQ-ORDER-005 (existing) | unchanged | Trace-only |
84
+ | AC2 | REQ-INV-010 (new — proposed) | stub | <one-line behaviour description> |
85
+ | AC3 | REQ-INV-011 (new — proposed) | stub | <one-line> |
86
+ | AC4 | REQ-ORDER-002 (existing) | stale — update needed | <one-line: what's drifted> |
87
+ ```
88
+
89
+ For **deferred** items (the operator decides the AC genuinely doesn't need an SRS entry), the row carries `@srs-deferred: <reason>` so the deferral is visible.
90
+
91
+ **Step 6 — Block plan APPROVAL** until each AC has either:
92
+ - (a) an existing SRS item it traces to, with no drift, OR
93
+ - (b) a new SRS-ID stub added in this cycle, OR
94
+ - (c) an explicit `@srs-deferred: <reason>` annotation in the AC row.
95
+
96
+ The block is configurable via `sdlc-config.json` — see *Configuration* below. For projects with sparse SRS, the **ramp-up mode** defaults to audit-only for the first N runs (default 5) so operators get used to the surface before it starts blocking.
97
+
98
+ ### Phase 2 — Stage-3 evidence pack hook
99
+
100
+ Input: the REQ's implementation plan (post-approval) and the working-tree diff.
101
+
102
+ **Step 1 — Generate `compliance/evidence/REQ-XXX/srs-alignment.md`.** Format:
103
+
104
+ ```markdown
105
+ ---
106
+ req: REQ-XXX
107
+ generated_by: requirements-aligner
108
+ generated_at: <ISO timestamp>
109
+ ---
110
+
111
+ # SRS alignment — REQ-XXX
112
+
113
+ ## ACs traced
114
+
115
+ | AC | SRS item | Action this cycle |
116
+ |---|---|---|
117
+ | AC1 | REQ-ORDER-005 | unchanged |
118
+ | AC2 | REQ-INV-010 | added (new — see Phase 1 stub) |
119
+ | AC3 | REQ-INV-011 | added (new) |
120
+ | AC4 | REQ-ORDER-002 | updated (drift) |
121
+
122
+ ## Operator sign-off
123
+
124
+ I have reviewed the AC-to-SRS-item traces above and confirm:
125
+ - [ ] Each AC has a defensible SRS item.
126
+ - [ ] New SRS items have been edited from stubs to canonical Given/When/Then prose.
127
+ - [ ] Stale items have been brought current.
128
+
129
+ **Reviewer:** <operator-name>
130
+ **Date:** <YYYY-MM-DD>
131
+ ```
132
+
133
+ **Step 2 — Tag for upload.** The CI's `compliance-evidence.yml` uploads this file as `evidence_type=srs_alignment` (added to META-COMPLY's `EVIDENCE_TYPE_REGISTRY` in the paired sub-PR). The framework-coverage matrix then closes `ISO29119.3.4` (Test Plan — requirements traceability) and `SOC2.CC2.1` (Communication of policies — when paired with INSTRUCTIONS.md) for this REQ.
134
+
135
+ **Step 3 — Hand-off back to `sdlc-implementer`.** The skill's job ends at the artefact + the operator sign-off. The parent orchestrator continues with the rest of Stage 3 (security summary, evidence upload, release ticket).
136
+
137
+ ### Phase 3 — Per-REQ ad-hoc audit
138
+
139
+ 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 SRS coverage healthy?"* outside the SDLC orchestration flow.
140
+
141
+ ### Phase 4 — Branch-wide audit
142
+
143
+ For each REQ that has commits on the current branch (or in a specified range), run Phase 3. Produces an aggregated report listing per-REQ alignment status across the branch.
144
+
145
+ ### Phase 5 — Report
146
+
147
+ - For Phase 1 — the plan's injected table + the block/allow decision.
148
+ - For Phase 2 — the artefact path + summary line.
149
+ - For Phase 3 / 4 — markdown report (one per REQ, or aggregated for branch audit).
150
+
151
+ ## Configuration (sdlc-config.json)
152
+
153
+ ```json
154
+ {
155
+ "requirements_aligner": {
156
+ "enabled": true,
157
+ "block_on_stage_1": false,
158
+ "block_on_stage_3": true,
159
+ "auto_file_followup_issue": false,
160
+ "ramp_up_runs": 5
161
+ }
162
+ }
163
+ ```
164
+
165
+ Per the [#119 review](https://github.com/metasession-dev/DevAudit-Installer/issues/119#issuecomment-4631840651) defaults:
166
+
167
+ - `block_on_stage_1: false` — advisory at Stage 1 by default. Operators flip to `true` once the SRS is populated enough that the skill is reliably catching real drift, not false-positives on sparse coverage.
168
+ - `block_on_stage_3: true` — the per-REQ evidence pack is the hard gate (the Stage 3 artefact is what actually lands as evidence; missing it leaks).
169
+ - `auto_file_followup_issue: false` — the skill never opens GitHub issues automatically. If gaps are detected at Stage 1 and the operator chooses to defer, the operator files the follow-up issue manually (or asks the skill to draft one, then confirms before filing).
170
+ - `ramp_up_runs: 5` — on projects whose SRS is sparse, the first 5 invocations are audit-only regardless of `block_on_stage_1`. After 5 successful runs the configured blocking kicks in.
171
+
172
+ ## Principles
173
+
174
+ **Don't author the SRS prose.** The skill proposes IDs + stubs the operator edits. Inventing canonical SRS language without operator review is exactly the kind of silent-drift this skill exists to prevent.
175
+
176
+ **Fuzzy-match, don't presume.** When an AC matches an SRS item with low confidence, the skill surfaces the candidate and asks. False-positive matches (linking an unrelated SRS item to an AC) are worse than no match — they hide the gap they were trying to surface.
177
+
178
+ **Block at Stage 3, advise at Stage 1.** The implementation plan can carry `@srs-deferred` annotations and ship. The evidence pack cannot — the per-REQ `srs-alignment.md` artefact must exist before Stage 3 completes. This is the asymmetric enforcement the [#119 review](https://github.com/metasession-dev/DevAudit-Installer/issues/119#issuecomment-4631840651) recommended.
179
+
180
+ **Sibling-skill awareness.** When this skill proposes a new SRS-ID for an AC that documents an architectural decision, cross-link the proposed `adr-author` ADR (and vice versa). When it proposes an SRS-ID covering a HIGH-risk behaviour, cross-link the proposed `risk-register-keeper` RISK entry. The three SoT-alignment skills work together; each produces its own per-REQ Tier 3 artefact but they share the per-REQ context.
181
+
182
+ **Ramp-up is the kindness.** Projects whose `docs/SRS.md` is sparse will trip every check on first contact. Audit-only first 5 runs gives operators time to populate the SoT before the blocking enforces.
183
+
184
+ ## References
185
+
186
+ - [DevAudit-Installer#119](https://github.com/metasession-dev/DevAudit-Installer/issues/119) — the issue this skill closes, with the case study (wawagardenbar-app REQ-066) + the locked Phase A scope.
187
+ - `sdlc-implementer/SKILL.md` Phase 1 + Phase 3 — the parent-skill invocation contract.
188
+ - `sdlc/files/_common/Implementation_Plan_TEMPLATE.md` — carries the "SRS items proposed/touched" section this skill populates (companion change in this PR).
189
+ - `sdlc/files/_common/3-compile-evidence.md` — the test-scope template gains an SRS-ID cross-reference table (companion change in this PR).
190
+ - Sibling skills (forthcoming): `adr-author` (DevAudit-Installer#120), `risk-register-keeper` (DevAudit-Installer#121).
191
+ - Meta-reviewer (META-COMPLY): `framework-registry-auditor` reviewed the `srs_alignment` evidence type's clause mappings before the META-COMPLY sub-PR opened. Per #119 sequencing.
192
+ - Memory cross-link: `project_srs_supersedes_requirements` (docs/SRS.md is the requirements SoT — REQ-AREA-NNN; RTM uses REQ-XXX); `feedback_check_git_before_filing_from_umbrella` (Phase 5 post-release audit must grep git before claiming SRS-IDs are missing — deferred to Phase B but worth noting).