@metasession.co/devaudit-cli 0.1.10 → 0.1.11

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.10",
3
+ "version": "0.1.11",
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.10",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.11",
37
37
  "commander": "^12.1.0",
38
38
  "consola": "^3.2.3",
39
39
  "env-paths": "^3.0.0",
@@ -15,6 +15,12 @@ Detailed workflow instructions are in this project's `SDLC/` directory. Read the
15
15
 
16
16
  When a workflow step requires detailed commands or templates, read the full workflow file rather than relying on the summary below.
17
17
 
18
+ ### Entry point: the `sdlc-implementer` skill
19
+
20
+ The default way to implement a tracked change is the **`sdlc-implementer`** skill (`.claude/skills/sdlc-implementer/SKILL.md`): give it one GitHub issue and it runs Stage 1 (classify risk, assign the next `REQ-XXX`, write the implementation plan, update `RTM.md`) through Stage 4 (PR + UAT review), delegating all end-to-end / visual test work to `e2e-test-engineer`. **Do NOT hand-roll implementation outside this flow** — every change starts from a requirement, which starts from an issue. The only exceptions are trivial housekeeping (docs, formatting, dependency bumps, CI tweaks).
21
+
22
+ **This is enforced, not just advised.** `feat` / `fix` / `refactor` / `perf` commits that cite no requirement (`[REQ-XXX]` in the subject or a `Ref: REQ-XXX` trailer) are **rejected** locally by the commit-msg hook (commitlint) and at PR CI by `validate-commits.sh` (which `--no-verify` cannot skip). So implementation work cannot reach `develop` without a requirement — which is also what keeps release labels correct (the version-deriver only falls back to a bare date for genuine housekeeping, never for real feature work). Housekeeping commit types remain exempt.
23
+
18
24
  ### Before ANY Code Change
19
25
 
20
26
  1. Ask: "Which GitHub Issue is this for?" before writing code. Fetch it with `gh issue view NNN`.
@@ -126,6 +126,8 @@ Write or update E2E tests **after** implementation. E2E tests need working UI/AP
126
126
 
127
127
  > **Skill available:** invoke the **`e2e-test-engineer`** skill for this step (at `.claude/skills/e2e-test-engineer/SKILL.md`). It derives scenarios from the requirement's acceptance criteria, reconciles with the existing test pack (flags obsoletes — but never deletes without confirmation), runs the suite, and files defects for failures or missed ACs. Framework-agnostic (Playwright, Cypress, pytest-playwright, etc.) and tracker-agnostic (GitHub, Linear, Jira, etc.). For projects with no e2e suite yet, the skill also covers bootstrapping one. See [`sdlc/SKILLS.md`](../sdlc/SKILLS.md) for the full list of available skills.
128
128
 
129
+ > **Run authenticated flows in CI.** Tests that need a logged-in session (admin forms, role-gated flows) belong in their own Playwright project that depends on `auth-setup`. Register that project name in `sdlc-config.json` `e2e_projects` and set `e2e_seed_command` / `e2e_env` so CI seeds fixtures and runs it as a **report-only** gate (continue-on-error — it surfaces failures as evidence without blocking the merge until proven stable). Prove each AC with an `evidenceShot(page, 'REQ-XXX', 'ACn-…')` so the PNG lands in `compliance/evidence/REQ-XXX/screenshots/`. This is what lets Stage 3 Step 10 reduce manual UAT to a light smoke instead of a full re-click.
130
+
129
131
  **4a. Review the test plan for E2E items:**
130
132
  ```bash
131
133
  cat compliance/evidence/REQ-XXX/test-plan.md
@@ -399,7 +399,7 @@ If it fails — typically a stale `devaudit.base_url`, a revoked `DEVAUDIT_API_K
399
399
  **Skip this step entirely if any of these are true:**
400
400
 
401
401
  - Project's `sdlc-config.json` has `uat.enabled: false` — meaning the project has no deployed UAT environment configured (internal services, retroactive-compliance pickups, etc.).
402
- - Requirement's risk class is **not** listed in project's `uat.required_risk_classes` (defaults: `payment`, `destructive_migration`, `realtime`, `physical_ux`). Text-only fixes, internal refactors, low-risk UI tweaks carry none of these and skip UAT-env verification.
402
+ - Requirement's risk class is **not** listed in project's `uat.required_risk_classes` (defaults: `payment`, `destructive_migration`, `realtime`, `physical_ux`). Text-only fixes, internal refactors, low-risk UI tweaks carry none of these and skip UAT-env verification. **Wildcard:** if `required_risk_classes` contains `"*"`, every requirement requires UAT-env verification regardless of risk class — use this for projects that deploy `develop` to a UAT environment and exercise every release there before promotion.
403
403
 
404
404
  When skipped, proceed directly to Step 11.
405
405
 
@@ -407,6 +407,8 @@ When skipped, proceed directly to Step 11.
407
407
 
408
408
  When this step DOES apply, the develop branch's auto-deploy to UAT must complete first. **Wait for the deployment to complete**, then verify the change works in the UAT environment.
409
409
 
410
+ > **Automated e2e shrinks this step — it does not delete it.** When a requirement's acceptance criteria are covered by **passing CI e2e tests** authored with the `e2e-test-engineer` skill (each AC proven by an `evidenceShot`, run via the report-only authenticated-e2e gate — see `sdlc-config.json` `e2e_projects` / `e2e_seed_command`), those ACs are already exercised against the running app on every push. For those ACs, this step is **not** a full manual re-click of every criterion: it reduces to a **light manual smoke** on the deployed UAT environment — confirm the build is live, the changed area loads, and spot-check anything the e2e couldn't reach (real third-party integrations, environment-specific config, payment sandboxes). Record which ACs were discharged by automated e2e vs. exercised manually. ACs **not** covered by a passing e2e test still need full manual verification here.
411
+
410
412
  #### WAIT CHECKPOINT: Confirm CI + Deployment Complete
411
413
 
412
414
  Before UAT verification, confirm BOTH CI and deployment are complete:
@@ -52,6 +52,28 @@ while IFS= read -r sha; do
52
52
  continue
53
53
  fi
54
54
 
55
+ # Requirement traceability: implementation commits (feat/fix/refactor/perf)
56
+ # MUST cite a requirement — [REQ-XXX] in the subject or a Ref: REQ-XXX
57
+ # trailer. Housekeeping types (docs/chore/ci/build/test/compliance/revert)
58
+ # are exempt. Mirrors the commitlint rule; this is the PR-CI half that
59
+ # `--no-verify` can't skip. Work starts from a requirement (which starts
60
+ # from an issue) — use the sdlc-implementer skill to assign one.
61
+ TYPE=$(echo "$SUBJECT" | grep -oE '^[a-z]+' || true)
62
+ case "$TYPE" in
63
+ feat|fix|refactor|perf)
64
+ if ! echo "$SUBJECT" | grep -qP '\[REQ-\d{3,}\]' \
65
+ && ! echo "$BODY" | grep -qiP 'Ref:\s*REQ-\d{3,}'; then
66
+ echo "ERROR [$SHORT]: '$TYPE' is an implementation commit but cites no requirement."
67
+ echo " Add [REQ-XXX] to the subject or a 'Ref: REQ-XXX' trailer. Start work"
68
+ echo " from a requirement via the sdlc-implementer skill (it assigns the REQ"
69
+ echo " from the originating issue in Phase 1)."
70
+ FAILED=$((FAILED + 1))
71
+ EXIT_CODE=1
72
+ continue
73
+ fi
74
+ ;;
75
+ esac
76
+
55
77
  # Check Co-Authored-By on commits that touch code files
56
78
  CODE_FILES=$(git diff-tree --no-commit-id --name-only -r "$sha" -- '*.ts' '*.tsx' '*.js' '*.jsx' '*.py' 2>/dev/null || true)
57
79
  if [ -n "$CODE_FILES" ]; then
@@ -150,7 +150,7 @@ jobs:
150
150
  PLAYWRIGHT_HTML_REPORTER_OPEN: never
151
151
  PLAYWRIGHT_JSON_OUTPUT_NAME: e2e-results.json
152
152
  run: npx playwright test --project={{E2E_PROJECT}} --reporter=json,html
153
-
153
+ {{E2E_AUTHENTICATED_STEP}}
154
154
  # ── Gate 5: Build ──
155
155
 
156
156
  - name: Build Check
@@ -169,6 +169,7 @@ jobs:
169
169
  sast-results.json
170
170
  dependency-audit.json
171
171
  e2e-results.json
172
+ e2e-auth-results.json
172
173
  playwright-report/
173
174
  coverage/coverage-summary.json
174
175
  retention-days: 90
@@ -20,6 +20,7 @@
20
20
  name: Compliance Evidence Upload
21
21
 
22
22
  on:
23
+ workflow_dispatch:
23
24
  push:
24
25
  branches: [develop]
25
26
  paths:
@@ -98,9 +99,16 @@ jobs:
98
99
  if: steps.resolve.outputs.skip != 'true'
99
100
  run: |
100
101
  chmod +x scripts/upload-evidence.sh 2>/dev/null || true
102
+ # Common flags WITHOUT --release. Each upload appends its OWN
103
+ # --release so per-requirement artifacts land in their own release
104
+ # record (version = REQ-ID) instead of all collapsing into whichever
105
+ # single version the triggering commit derived. DevAudit #135 follow-
106
+ # up: this fixes release *attribution* (not just duplication) — an
107
+ # untagged docs commit must not sweep every in-scope REQ into a date
108
+ # release. Note: upload-evidence.sh keeps the LAST --release seen.
101
109
  FLAGS="--git-sha ${{ github.sha }} --ci-run-id ${{ github.run_id }} --branch ${{ github.ref_name }}"
102
- FLAGS="${FLAGS} --release ${{ steps.version.outputs.version }} --create-release-if-missing"
103
- FLAGS="${FLAGS} --environment uat"
110
+ FLAGS="${FLAGS} --create-release-if-missing --environment uat"
111
+ DERIVED_RELEASE="${{ steps.version.outputs.version }}"
104
112
 
105
113
  # Upload compliance docs (planning category)
106
114
  for DOC in compliance/RTM.md compliance/test-plan.md compliance/test-cases.md compliance/test-summary-report.md; do
@@ -108,7 +116,7 @@ jobs:
108
116
  echo "Uploading: $(basename "$DOC")"
109
117
  bash scripts/upload-evidence.sh \
110
118
  {{PROJECT_SLUG}} _compliance-docs compliance_document "$DOC" \
111
- --category planning ${FLAGS} || echo "Warning: Failed to upload $(basename "$DOC")"
119
+ --category planning ${FLAGS} --release "${DERIVED_RELEASE}" || echo "Warning: Failed to upload $(basename "$DOC")"
112
120
  fi
113
121
  done
114
122
 
@@ -116,10 +124,20 @@ jobs:
116
124
  if [ -d "compliance/pending-releases" ]; then
117
125
  for TICKET in compliance/pending-releases/*.md; do
118
126
  [ -f "$TICKET" ] || continue
119
- echo "Uploading: $(basename "$TICKET")"
127
+ # A RELEASE-TICKET-REQ-XXX.md belongs to that requirement's
128
+ # release record; any other ticket rides the derived release.
129
+ TICKET_BASE=$(basename "$TICKET" .md)
130
+ case "$TICKET_BASE" in
131
+ RELEASE-TICKET-REQ-*)
132
+ TICKET_REQ="${TICKET_BASE#RELEASE-TICKET-}"
133
+ TICKET_OWNER="$TICKET_REQ"; TICKET_RELEASE="$TICKET_REQ" ;;
134
+ *)
135
+ TICKET_OWNER="_compliance-docs"; TICKET_RELEASE="$DERIVED_RELEASE" ;;
136
+ esac
137
+ echo "Uploading: $(basename "$TICKET") -> release ${TICKET_RELEASE}"
120
138
  bash scripts/upload-evidence.sh \
121
- {{PROJECT_SLUG}} _compliance-docs compliance_document "$TICKET" \
122
- --category release_artifact ${FLAGS} || echo "Warning: Failed to upload $(basename "$TICKET")"
139
+ {{PROJECT_SLUG}} "${TICKET_OWNER}" compliance_document "$TICKET" \
140
+ --category release_artifact ${FLAGS} --release "${TICKET_RELEASE}" || echo "Warning: Failed to upload $(basename "$TICKET")"
123
141
  done
124
142
  fi
125
143
 
@@ -152,7 +170,7 @@ jobs:
152
170
  echo "Uploading: ${REQ_ID}/$(basename "$ARTIFACT")"
153
171
  bash scripts/upload-evidence.sh \
154
172
  {{PROJECT_SLUG}} "${REQ_ID}" compliance_document "$ARTIFACT" \
155
- --category planning ${FLAGS} || echo "Warning: Failed to upload $(basename "$ARTIFACT")"
173
+ --category planning ${FLAGS} --release "${REQ_ID}" || echo "Warning: Failed to upload $(basename "$ARTIFACT")"
156
174
  done
157
175
  done
158
176
  fi
@@ -32,6 +32,11 @@
32
32
  "e2e_project": "chromium",
33
33
  "e2e_start_command": "npm run dev",
34
34
 
35
+ "_comment_e2e_authenticated": "Optional report-only authenticated e2e gate (continue-on-error, never blocks the merge). e2e_projects = Playwright project names that need a logged-in session (auth-setup runs automatically as their dependency); e2e_seed_command seeds admins/fixtures before the run; e2e_env maps repo secrets onto the seed + e2e steps. Author these specs with the e2e-test-engineer skill (evidenceShot per AC). Leave empty to run only the blocking smoke project above.",
36
+ "e2e_seed_command": "",
37
+ "e2e_projects": [],
38
+ "e2e_env": {},
39
+
35
40
  "paths_ignore": [
36
41
  ".github/workflows/**",
37
42
  "SDLC/**",
@@ -53,7 +58,7 @@
53
58
  "api_key_secret": "DEVAUDIT_API_KEY"
54
59
  },
55
60
 
56
- "_comment_uat": "UAT-environment verification (Stage 3 Step 10). Opt-in: enabled=false skips Step 10 entirely. When enabled, only requirements whose risk class is listed in required_risk_classes go through UAT-env verification.",
61
+ "_comment_uat": "UAT-environment verification (Stage 3 Step 10). Opt-in: enabled=false skips Step 10 entirely. When enabled, only requirements whose risk class is listed in required_risk_classes go through UAT-env verification; use [\"*\"] to require it for every requirement (projects that UAT every release).",
57
62
  "uat": {
58
63
  "enabled": false,
59
64
  "url": "",
@@ -2,15 +2,24 @@
2
2
  * Commitlint configuration for Metasession SDLC.
3
3
  *
4
4
  * Enforces:
5
- * - Conventional Commits format (feat, fix, docs, test, refactor, chore, compliance, security)
6
- * - Co-Authored-By tag presence (warning not every commit is AI-generated)
7
- * - Ref: REQ-XXX trailer presence (warning trivial commits skip requirements)
5
+ * - Conventional Commits format (feat, fix, docs, test, refactor, chore, ).
6
+ * - Requirement traceability: **implementation** commits (feat / fix /
7
+ * refactor / perf) MUST cite a requirement via `[REQ-XXX]` in the subject
8
+ * or a `Ref: REQ-XXX` trailer (ERROR). Housekeeping types (docs, chore, ci,
9
+ * build, test, compliance, revert) are exempt. This is the local half of
10
+ * the "no implementation without a requirement" rule; `validate-commits.sh`
11
+ * enforces the same at PR CI (which `--no-verify` can't skip). Work starts
12
+ * from a requirement, which starts from an issue — run the `sdlc-implementer`
13
+ * skill, whose Phase 1 assigns the REQ from the originating issue.
14
+ * - Co-Authored-By trailer (warning — not every commit is AI-generated).
8
15
  *
9
16
  * Install:
10
17
  * npm install --save-dev @commitlint/cli @commitlint/config-conventional
11
18
  * cp this file to your project root as commitlint.config.mjs
12
19
  */
13
20
 
21
+ const IMPLEMENTATION_TYPES = ['feat', 'fix', 'refactor', 'perf'];
22
+
14
23
  export default {
15
24
  extends: ['@commitlint/config-conventional'],
16
25
  rules: {
@@ -35,20 +44,29 @@ export default {
35
44
  ],
36
45
  // Warn (not error) when body is missing — some commits are one-liners
37
46
  'body-empty': [1, 'never'],
47
+ // Implementation commits must trace to a requirement (ERROR)
48
+ 'requirement-ref-for-impl': [2, 'always'],
49
+ // AI-authored commits should be attributed (warning)
50
+ 'trailer-co-authored-by': [1, 'always'],
38
51
  },
39
52
  plugins: [
40
53
  {
41
54
  rules: {
42
- 'trailer-ref-requirement': ({ raw }) => {
43
- // Warn if Ref: REQ-XXX is missing trivial commits don't need it
44
- const hasRef = /Ref:\s*REQ-\d+/i.test(raw);
55
+ 'requirement-ref-for-impl': ({ type, raw }) => {
56
+ // Only implementation work is requirement-gated; housekeeping is exempt.
57
+ if (!IMPLEMENTATION_TYPES.includes(type)) return [true];
58
+ const hasRef =
59
+ /\[REQ-\d{3,}\]/i.test(raw) || /Ref:\s*REQ-\d{3,}/i.test(raw);
45
60
  return [
46
61
  hasRef,
47
- 'Commit should include "Ref: REQ-XXX" for tracked requirements',
62
+ `"${type}" is an implementation commit and must cite a requirement: ` +
63
+ `add [REQ-XXX] to the subject or a "Ref: REQ-XXX" trailer. Work must ` +
64
+ `start from a requirement (which starts from an issue) — run the ` +
65
+ `sdlc-implementer skill to assign one. Housekeeping types ` +
66
+ `(docs/chore/ci/build/test/compliance/revert) are exempt.`,
48
67
  ];
49
68
  },
50
69
  'trailer-co-authored-by': ({ raw }) => {
51
- // Warn if Co-Authored-By is missing — not every commit is AI-generated
52
70
  const hasCoAuthor = /Co-Authored-By:/i.test(raw);
53
71
  return [
54
72
  hasCoAuthor,
@@ -58,7 +76,5 @@ export default {
58
76
  },
59
77
  },
60
78
  ],
61
- // Apply custom rules as warnings (level 1), not errors
62
- // Override in your project if you want stricter enforcement
63
79
  helpUrl: 'https://www.conventionalcommits.org/',
64
80
  };