@metasession.co/devaudit-cli 0.1.44 → 0.1.47

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.44",
3
+ "version": "0.1.47",
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.44",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.47",
37
37
  "commander": "^12.1.0",
38
38
  "consola": "^3.2.3",
39
39
  "env-paths": "^3.0.0",
@@ -184,13 +184,33 @@ fi
184
184
  # Issue: devaudit#263.
185
185
  SUCCEEDED=0
186
186
  FAILED=0
187
+ # devaudit#133 — central stub guard. Any file still carrying the
188
+ # DevAudit starter banner ("STARTER TEMPLATE — REPLACE BEFORE
189
+ # COMMITTING" / "...BEFORE GOING TO PRODUCTION" — both phrasings)
190
+ # is skipped before the upload attempt so unedited placeholders
191
+ # can't flip a clause to COVERED off a stub. The check is binary-
192
+ # safe (-a) so it doesn't choke on PNGs or other non-text files.
193
+ SKIPPED=0
187
194
  TOTAL_SIZE=0
188
195
  UPLOAD_URL="${DEVAUDIT_BASE_URL}/api/evidence/upload"
189
196
  MAX_ATTEMPTS=${UPLOAD_MAX_ATTEMPTS:-5}
190
197
  INITIAL_BACKOFF_SECONDS=${UPLOAD_INITIAL_BACKOFF_SECONDS:-1}
191
198
 
199
+ is_unedited_starter_stub() {
200
+ # Match BOTH banner phrasings the SDLC has shipped (v0.1.36 changed
201
+ # the wording from "...GOING TO PRODUCTION" to "...COMMITTING").
202
+ # -a forces binary→text so we don't error on PNGs/PDFs; the regex
203
+ # won't match either of those formats by accident.
204
+ grep -aqE 'STARTER TEMPLATE.+REPLACE BEFORE' "$1"
205
+ }
206
+
192
207
  for FILE in "${FILES[@]}"; do
193
208
  FILENAME=$(basename "$FILE")
209
+ if is_unedited_starter_stub "$FILE"; then
210
+ echo "SKIPPED ${FILENAME} — unedited starter stub (replace the STARTER TEMPLATE banner to upload)"
211
+ SKIPPED=$((SKIPPED + 1))
212
+ continue
213
+ fi
194
214
  FILE_SIZE=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
195
215
  echo -n "Uploading ${FILENAME}... "
196
216
  CURL_ARGS=(
@@ -267,8 +287,10 @@ done
267
287
  # --- Summary ---
268
288
  echo ""
269
289
  echo "=== Upload Summary ==="
270
- echo "Files: ${SUCCEEDED} succeeded, ${FAILED} failed (${#FILES[@]} total)"
290
+ echo "Files: ${SUCCEEDED} succeeded, ${FAILED} failed, ${SKIPPED} skipped (${#FILES[@]} total)"
271
291
  echo "Total size: $((TOTAL_SIZE / 1024)) KB"
292
+ # Skipped stubs are intentional (devaudit#133) — they don't fail the
293
+ # run. Only true upload failures bump the exit code.
272
294
  if [ "$FAILED" -gt 0 ]; then
273
295
  exit 1
274
296
  fi
package/sdlc/SKILLS.md CHANGED
@@ -93,18 +93,39 @@ node scripts/validate-adapter.cjs sdlc/files/_common/skills/<name>/SKILL.md
93
93
 
94
94
  ## Skills currently shipped
95
95
 
96
- | Skill | Location | Triggers (paraphrased) | Additional emissions |
97
- | ----------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
98
- | `e2e-test-engineer` | `_common/skills/` | "add e2e tests", "bootstrap an e2e suite", "update the test pack", "are any tests obsolete", "run e2e tests and file issues" | `e2e/helpers/evidence.ts` + `evidence-shot-core.ts` (node-stack consumers) |
99
- | `sdlc-implementer` | `_common/skills/` | "implement issue #N under the SDLC", "run the SDLC for issue #N", "automate REQ-XXX from issue to release", "resume REQ-XXX" | — (orchestrator; invokes `e2e-test-engineer` + `governance-doc-author`) |
100
- | `governance-doc-author` | `_common/skills/` | "create / refresh the RoPA", "write a DPIA", "update the AI disclosure", "set up the periodic review schedule", "GDPR.Art-30 is MISSING on the matrix" (v0.1.37+) | `references/incident-classification.md` (shared with `e2e-test-engineer`) |
96
+ | Skill | Location | Triggers (paraphrased) | Additional emissions |
97
+ | ----------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | `e2e-test-engineer` | `_common/skills/` | "add e2e tests", "bootstrap an e2e suite", "update the test pack", "are any tests obsolete", "run e2e tests and file issues" | `e2e/helpers/evidence.ts` + `evidence-shot-core.ts` (node-stack consumers) |
99
+ | `sdlc-implementer` | `_common/skills/` | "implement issue #N under the SDLC", "run the SDLC for issue #N", "automate REQ-XXX from issue to release", "resume REQ-XXX" | — (orchestrator; invokes `e2e-test-engineer`, `governance-doc-author`, and the three SoT-alignment skills) |
100
+ | `governance-doc-author` | `_common/skills/` | "create / refresh the RoPA", "write a DPIA", "update the AI disclosure", "set up the periodic review schedule", "GDPR.Art-30 is MISSING on the matrix" (v0.1.37+) | `references/incident-classification.md` (shared with `e2e-test-engineer`) |
101
+ | `requirements-aligner` | `_common/skills/` | "align SRS for REQ-XXX", "what SRS items did this REQ need?", "is the SRS in sync with this branch?" (v0.1.42+). Auto-invoked by `sdlc-implementer` at Stage 1 plan-APPROVAL + Stage 3 evidence-pack. | Maintains `docs/SRS.md`; drops `compliance/evidence/REQ-XXX/srs-alignment.md` per cycle. |
102
+ | `adr-author` | `_common/skills/` | "draft an ADR for REQ-XXX", "does this REQ need an ADR?", "is the architectural decision documented?" (v0.1.43+). Auto-invoked by `sdlc-implementer` at Stage 1 + Stage 3. | Maintains `docs/ADR/ADR-NNN-<slug>.md`; drops `compliance/evidence/REQ-XXX/architecture-decision.md` per cycle. Closes `ISO27001.A.8.25`. |
103
+ | `risk-register-keeper` | `_common/skills/` | "draft a risk-register entry for REQ-XXX", "is the risk register up to date for this branch?", "incident-report-N just exported, draft the residual-risk entry" (v0.1.44+). Auto-invoked by `sdlc-implementer` at Stage 1 (MEDIUM/HIGH) + Stage 3, and by `incident-export.yml` at incident close. | Maintains `compliance/risk-register.md` + the `governance/risk-register.md.template` starter; drops `compliance/evidence/REQ-XXX/risk-assessment.md`. Closes `SOC2.CC3.2`. |
101
104
 
102
105
  `sdlc-implementer` is the **default entry point for a tracked change** — an **orchestration skill** that drives Claude Code's native tools (`gh`, shell, `devaudit` CLI, portal API) through the full 5-stage flow against a single GitHub issue, pausing only at the UAT-review gate (and at the plan checkpoint for HIGH/CRITICAL risk). It is synced into every consumer (`.claude/skills/sdlc-implementer/`) by `devaudit update`. It replaces an earlier roadmap of five atomic skills (`risk-classifier`, `commit-message-author`, `compliance-evidence-author`, `sast-triager`, `release-ticket-author`) that were deprioritised — Claude Code's innate capabilities already cover what those atomic skills wrapped; the value-add is end-to-end orchestration with framework-compliant pauses, not five discoverable helpers a human still has to compose.
103
106
 
104
- **Sub-skill invocation requirement.** During its Phase 2 (Implement & test), the orchestrator **MUST** invoke `e2e-test-engineer` for any end-to-end or visual-regression test work — both scenario derivation from the implementation plan and execution of the resulting suite. The orchestrator does NOT author e2e tests directly. (Unit tests stay with the orchestrator until a unit-test counterpart skill ships.) The invocation pattern is documented in [docs/adding-a-skill.md §Orchestrator skills](../docs/adding-a-skill.md#orchestrator-skills-calling-other-skills); this is a hard contract — the orchestrator's SKILL.md fails review if it inlines `e2e-test-engineer`'s procedure.
107
+ **Sub-skill invocation contract.** The orchestrator delegates at every phase rather than authoring inline:
108
+
109
+ - **Phase 1 (Plan)** — invoke `requirements-aligner` to populate the AC table's SRS-ID column; invoke `adr-author` to decide ADR-worthiness + draft the ADR when warranted; invoke `risk-register-keeper` (MEDIUM/HIGH only by default) to draft RISK-NNN entries.
110
+ - **Phase 2 (Implement & test)** — invoke `e2e-test-engineer` for ALL end-to-end or visual-regression test work. The orchestrator does NOT author e2e tests directly. (Unit tests stay with the orchestrator until a unit-test counterpart skill ships.)
111
+ - **Phase 3 (Compile evidence)** — invoke each of `requirements-aligner`, `adr-author`, `risk-register-keeper` to drop their per-REQ Tier 3 traceability artefacts (`srs-alignment.md`, `architecture-decision.md`, `risk-assessment.md`).
112
+
113
+ These delegations are hard contracts — the orchestrator's SKILL.md fails review if it inlines a specialist skill's procedure. The invocation pattern is documented in [docs/adding-a-skill.md §Orchestrator skills](../docs/adding-a-skill.md#orchestrator-skills-calling-other-skills).
105
114
 
106
115
  `sdlc-implementer` is **not** used for trivial / housekeeping changes (docs, formatting, dependency bumps, CI tweaks) — those skip the requirement and the ceremony. See [the change-type matrix](../docs/change-workflows.md) and the [trivial-change walkthrough](./files/_common/implementing-an-sdlc-issue.md#trivial-change-walkthrough).
107
116
 
117
+ ### The SoT-alignment skill family
118
+
119
+ `requirements-aligner`, `adr-author`, and `risk-register-keeper` form the **SoT-alignment family** (v0.1.42 → v0.1.44). They share a uniform shape: each owns one persistent Tier 2 source-of-truth document, fires at Stage 1 plan-APPROVAL (advisory by default, configurable to block) and Stage 3 evidence-pack (hard gate on the per-REQ Tier 3 artefact), and produces a per-REQ traceability evidence file the CI uploads to the portal. The family closes the silent-drift gap between shipped code and the project's three SoT documents at edit time.
120
+
121
+ | Skill | Tier 2 SoT it maintains | Tier 3 per-REQ artefact | Closes framework clause |
122
+ | ---------------------- | ----------------------------- | ------------------------------------ | ------------------------------------------------------------------- |
123
+ | `requirements-aligner` | `docs/SRS.md` | `srs-alignment.md` (per REQ) | none in v1 (orphan-by-design per framework-registry-auditor review) |
124
+ | `adr-author` | `docs/ADR/ADR-NNN-<slug>.md` | `architecture-decision.md` (per REQ) | `ISO27001.A.8.25` Secure development life cycle |
125
+ | `risk-register-keeper` | `compliance/risk-register.md` | `risk-assessment.md` (per REQ) | `SOC2.CC3.2` Risk identification and assessment |
126
+
127
+ Each skill is **configurable per project** via `sdlc-config.json` (`requirements_aligner`, `adr_author`, `risk_register_keeper` blocks) — `block_on_stage_1: false` is the default in v1 so the skill advises but doesn't block plan APPROVAL; flip to `true` once calibrated.
128
+
108
129
  ## Skills on the roadmap
109
130
 
110
131
  No concrete candidates are queued. A `unit-test-engineer` counterpart to `e2e-test-engineer` is the most likely next skill, but it lands only when day-to-day work repeatedly surfaces the pain and the orchestrator demonstrably needs it as a separable component. Tracking: [`metasession-dev/DevAudit-Installer#29`](https://github.com/metasession-dev/DevAudit-Installer/issues/29).
@@ -29,9 +29,9 @@ last_reviewed_at: "REPLACE — YYYY-MM-DD"
29
29
 
30
30
  ## Uploading this artefact
31
31
 
32
- - **File path:** `compliance/governance/incident-report.md` (the template) or `compliance/governance/incident-report-<id>.md` (per-incident — recommended; the `incident-export.yml` workflow auto-produces these from closed GitHub issues labelled `incident`)
33
- - **Upload trigger:** automatic — on every push to `develop` that touches `compliance/**`, `compliance-evidence.yml` uploads this file as `incident_report` evidence via the `upload_governance` helper.
34
- - **Verify after merge:** open `/projects/<slug>/compliance`. `ISO29119.3.5.4` always flips to COVERED (baseline). `SOC2.CC7.2`, `GDPR.Art-33`, `GDPR.Art-34` flip only when the relevant attribution sections below are non-stub.
32
+ - **File path:** `compliance/governance/incident-report-<id>.md` (per-incident — recommended; the `incident-export.yml` workflow auto-produces these from closed GitHub issues labelled `incident`). The bare `incident-report.md` is the unedited starter — kept on disk as a reference but **skipped by the uploader** until you replace the STARTER TEMPLATE banner.
33
+ - **Upload trigger:** automatic — on every push to `develop` that touches `compliance/**`, `compliance-evidence.yml` globs `incident-report*.md` under both layouts and uploads each non-stub file as `incident_report` evidence via the `upload_governance` helper. The starter stub is filtered out centrally by `upload-evidence.sh` (devaudit#133).
34
+ - **Verify after merge:** open `/projects/<slug>/compliance`. `ISO29119.3.5.4` flips to COVERED only when a non-stub `incident-report*.md` lands. `SOC2.CC7.2`, `GDPR.Art-33`, `GDPR.Art-34` flip only when the relevant attribution sections below are non-stub.
35
35
  - **Refresh cadence:** none — incidents are point-in-time. Authoring is event-driven.
36
36
 
37
37
  ## Framework attribution — which clauses THIS incident closes
@@ -40,9 +40,13 @@ jobs:
40
40
  # doesn't yet have its stub release-ticket on disk. Without these
41
41
  # the github-actions[bot] token gets HTTP 403 on the push + on the PR
42
42
  # create, and the auto-housekeeping path silently leaves a red badge
43
- # on every docs-only / chore push. DEVAUDIT_USER_TOKEN remains optional
44
- # for orgs with restricted Actions permissions — but is no longer
45
- # required for the default-config flow. See DevAudit-Installer#122.
43
+ # on every docs-only / chore push.
44
+ #
45
+ # `DEVAUDIT_USER_TOKEN` is no longer consulted by this workflow (the
46
+ # auto-stub step now uses `github.token` directly — see the env block
47
+ # on that step). The permissions below grant everything `gh pr create`
48
+ # needs; preferring a (potentially stale) PAT was the cause of the
49
+ # 2026-06-07 401 chain on this issue.
46
50
  permissions:
47
51
  contents: write # push the auto-PR branch
48
52
  pull-requests: write # gh pr create
@@ -129,7 +133,19 @@ jobs:
129
133
  - name: Auto-generate housekeeping stubs (if needed)
130
134
  if: steps.resolve.outputs.skip != 'true'
131
135
  env:
132
- GH_TOKEN: ${{ secrets.DEVAUDIT_USER_TOKEN || github.token }}
136
+ # Use the workflow's GITHUB_TOKEN directly. The `permissions:`
137
+ # block on the job grants `contents: write` + `pull-requests:
138
+ # write`, which is everything `gh pr create` + `git push` need
139
+ # here. The earlier `secrets.DEVAUDIT_USER_TOKEN || github.token`
140
+ # fallback became a foot-gun once that permissions block landed
141
+ # — when an operator had set `DEVAUDIT_USER_TOKEN` historically
142
+ # (to work around the missing permissions) and the PAT later
143
+ # expired, every `gh pr create` 401'd as the workflow preferred
144
+ # the stale PAT over the live bot token. See DevAudit-Installer#122
145
+ # 2026-06-07 escalation. Orgs with policy that blocks the bot
146
+ # token from creating PRs can override per-workflow on their
147
+ # own; the canonical default no longer prefers a PAT.
148
+ GH_TOKEN: ${{ github.token }}
133
149
  VERSION: ${{ steps.version.outputs.version }}
134
150
  run: |
135
151
  # Guard: only fire for bare-date (housekeeping) versions.
@@ -274,8 +290,19 @@ jobs:
274
290
  # (operator's choice — both layouts are common).
275
291
  upload_governance compliance/periodic-review.md periodic_review
276
292
  upload_governance compliance/governance/periodic-review.md periodic_review
277
- upload_governance compliance/incident-report.md incident_report
278
- upload_governance compliance/governance/incident-report.md incident_report
293
+ # Incident reports: glob `incident-report*.md` so per-incident
294
+ # files (e.g. `incident-report-2026-001.md`, written by
295
+ # incident-export.yml from labelled GitHub issues) all
296
+ # upload as real evidence. The unedited starter
297
+ # `incident-report.md` matches the glob too but is skipped
298
+ # by upload-evidence.sh's central stub guard — so the stub
299
+ # can never flip ISO29119.3.5.4 to COVERED on its own
300
+ # (devaudit#133). `*.md` does not match `*.md.template`.
301
+ shopt -s nullglob
302
+ for f in compliance/incident-report*.md compliance/governance/incident-report*.md; do
303
+ upload_governance "$f" incident_report
304
+ done
305
+ shopt -u nullglob
279
306
 
280
307
  # ── Audit-log export (DevAudit-Installer#98 WS2) ──────────────
281
308
  # Snapshot the portal's audit log for the rolling 90-day window