@metasession.co/devaudit-cli 0.1.59 → 0.1.61

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.59",
3
+ "version": "0.1.61",
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.59",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.61",
37
37
  "ajv": "^8.20.0",
38
38
  "commander": "^12.1.0",
39
39
  "consola": "^3.2.3",
@@ -32,6 +32,11 @@
32
32
  # as `gateStatus`; unknown values are
33
33
  # silently dropped server-side.
34
34
  # DevAudit-Installer#96.
35
+ # --sdlc-stage <1-5> SDLC stage that produced this artefact:
36
+ # 1 plan, 2 implement/test, 3 compile-evidence,
37
+ # 4 submit-for-review, 5 deploy. Forwarded as
38
+ # `sdlcStage`; unknown to older portals (ignored
39
+ # server-side, no error).
35
40
  #
36
41
  # Required environment variables:
37
42
  # DEVAUDIT_BASE_URL e.g. https://meta-comply-production.up.railway.app
@@ -72,6 +77,7 @@ EVIDENCE_CATEGORY=""
72
77
  RELEASE_TITLE=""
73
78
  CHANGE_TYPE=""
74
79
  GATE_STATUS=""
80
+ SDLC_STAGE=""
75
81
  # Repeatable `--meta-key key=value` accumulator. Each pair gets merged
76
82
  # into the metadata JSON sent to the portal. Used by the screenshot
77
83
  # upload loop to pass `origin=feature|regression` from the per-PNG
@@ -96,6 +102,7 @@ while [ "$#" -gt 0 ]; do
96
102
  # ran-and-failed != never-ran. Unknown values dropped server-side.
97
103
  # DevAudit-Installer#96.
98
104
  --gate-status) GATE_STATUS="$2"; shift 2 ;;
105
+ --sdlc-stage) SDLC_STAGE="$2"; shift 2 ;;
99
106
  # --meta-key key=value (repeatable). Merged into the metadata JSON
100
107
  # before posting. Validates the `key=value` shape; rejects bare
101
108
  # keys without `=`.
@@ -119,6 +126,10 @@ if [ -n "$RELEASE_VERSION" ] && [ -z "$EVIDENCE_CATEGORY" ]; then
119
126
  echo "Error: --category is required when --release is specified (gate validation)"
120
127
  exit 1
121
128
  fi
129
+ if [ -n "$SDLC_STAGE" ] && ! [[ "$SDLC_STAGE" =~ ^[1-5]$ ]]; then
130
+ echo "Error: --sdlc-stage must be an integer 1-5 (got: $SDLC_STAGE)"
131
+ exit 1
132
+ fi
122
133
 
123
134
  if [ -z "${DEVAUDIT_BASE_URL:-}" ]; then
124
135
  echo "Error: DEVAUDIT_BASE_URL environment variable is required"
@@ -277,6 +288,7 @@ for FILE in "${FILES[@]}"; do
277
288
  [ -n "$RELEASE_TITLE" ] && CURL_ARGS+=(-F "releaseTitle=${RELEASE_TITLE}")
278
289
  [ -n "$CHANGE_TYPE" ] && CURL_ARGS+=(-F "changeType=${CHANGE_TYPE}")
279
290
  [ -n "$GATE_STATUS" ] && CURL_ARGS+=(-F "gateStatus=${GATE_STATUS}")
291
+ [ -n "$SDLC_STAGE" ] && CURL_ARGS+=(-F "sdlcStage=${SDLC_STAGE}")
280
292
 
281
293
  ATTEMPT=1
282
294
  BACKOFF=$INITIAL_BACKOFF_SECONDS
@@ -133,7 +133,7 @@ This is the **independent verification gate**. Tests run locally during developm
133
133
  | CI | Push to `develop` | TypeScript + SAST + dependency audit + E2E + build | Quality gates + independent verification |
134
134
  | Deploy | Merge to `main` | Auto-deploy to hosting platform | Production release |
135
135
 
136
- PRs to `main` do not trigger a separate CI run. Branch protection required status checks ensure the commit already passed Quality Gates on the develop push. This avoids duplicate CI runs.
136
+ PRs to the integration branch run `Quality Gates` before merge. PRs to `main` do not trigger a duplicate quality-gates run; branch protection required status checks ensure the commit already passed Quality Gates on the integration branch.
137
137
 
138
138
  ### GitHub Actions Workflow File
139
139
 
@@ -218,7 +218,7 @@ _Workflow tweak (CI artifact upload, gate timeout bump, etc.)_
218
218
 
219
219
  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).
220
220
 
221
- **CI trigger shape — read once before step 7.** The DevAudit-Installer-generated `ci.yml.template` defaults to **post-merge-only** triggers (`push: branches: [<integration>]`, no `pull_request:` trigger). On these projects there will be **no PR-time checks** to wait for review + merge is the gate, and the post-merge CI run on the integration branch is the actual quality gate. A consumer who has explicitly added a `pull_request:` trigger has PR-time CI in addition. The skill must adapt step 7's wording to whichever shape the project uses; never poll a PR for checks that the template doesn't trigger.
221
+ **CI trigger shape — read once before step 7.** DevAudit-Installer-generated `ci.yml.template` runs `Quality Gates` on PRs to the integration branch and on pushes to the integration branch. Older consumers may still have post-merge-only CI (`push: branches: [<integration>]`, no `pull_request:` trigger) until they re-run `devaudit update`. The skill must adapt step 7's wording to whichever shape the project uses; never poll a PR for checks that won't arrive on that consumer yet.
222
222
 
223
223
  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.
224
224
  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.
@@ -227,8 +227,8 @@ Reached from Phase 0 for non-tracked change-types. The skill drives this end-to-
227
227
  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.
228
228
  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.
229
229
  7. **Report honest status — adapt to the project's CI trigger shape (devaudit-installer#145).** Check whether `.github/workflows/ci.yml` has a `pull_request:` trigger.
230
- - **PR-time CI present** — wait for CI to settle, name any failing check, fix and re-push. Never announce "ready" while a required check is red.
231
- - **Post-merge-only CI (the DevAudit-Installer default — `push: branches: [<integration>]` with no `pull_request:` trigger)** — say so explicitly in the LAST/NEXT sticky: _"no PR-time checks will fire; review + merge is the gate; CI runs post-merge on `$INTEGRATION_BRANCH`."_ Don't poll the PR for checks that won't arrive. The post-merge run (CI Pipeline + Compliance Evidence Upload on the integration branch) is the actual gate; address it via fix-forward if it fails.
230
+ - **PR-time CI present (current DevAudit default)** — wait for `gh pr checks <PR>` to report `Quality Gates`, name any failing check, fix and re-push. Never announce "ready" while a required check is red. Release registration and evidence upload still happen on the post-merge push to `$INTEGRATION_BRANCH`.
231
+ - **Post-merge-only CI (older generated workflows — `push: branches: [<integration>]` with no `pull_request:` trigger)** — say so explicitly in the LAST/NEXT sticky: _"no PR-time checks will fire; review + merge is the gate; CI runs post-merge on `$INTEGRATION_BRANCH`."_ Don't poll the PR for checks that won't arrive. The post-merge run (CI Pipeline + Compliance Evidence Upload on the integration branch) is the actual gate; address it via fix-forward if it fails.
232
232
 
233
233
  Either way, never bypass a gate (no `--no-verify`, no `--admin` merge of a red required check); the only difference is **where** you wait for the gate to fire — before merge vs. after merge.
234
234
  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.
@@ -1,4 +1,4 @@
1
- # CI Pipeline — all gates on every code push to develop
1
+ # CI Pipeline — all gates on PRs to develop and code pushes to develop
2
2
  #
3
3
  # Generated by `devaudit install` / `devaudit update` from sdlc-config.json.
4
4
  # Do not edit manually — re-run the CLI (`devaudit update`) to regenerate.
@@ -6,13 +6,16 @@
6
6
  # Single consolidated job — on a self-hosted runner, parallel jobs run
7
7
  # sequentially anyway. One checkout + one cached npm ci = fast.
8
8
  #
9
- # PRs to main inherit commit status via branch protection.
9
+ # PRs to develop run Quality Gates before integration. PRs to main inherit
10
+ # commit status via branch protection.
10
11
  # Compliance validation runs separately on PRs (compliance-validation.yml).
11
12
 
12
13
  name: CI Pipeline
13
14
 
14
15
  on:
15
16
  workflow_dispatch:
17
+ pull_request:
18
+ branches: [develop]
16
19
  push:
17
20
  branches: [develop]
18
21
  paths-ignore:
@@ -232,6 +235,10 @@ jobs:
232
235
  register-release:
233
236
  name: Register Release
234
237
  runs-on: {{RUNNER}}
238
+ # PRs to develop should report Quality Gates without mutating DevAudit
239
+ # releases or evidence. Release registration remains a develop-push /
240
+ # manual-dispatch side effect.
241
+ if: ${{ github.event_name != 'pull_request' }}
235
242
  outputs:
236
243
  version: ${{ steps.version.outputs.version }}
237
244
  env:
@@ -405,6 +412,7 @@ jobs:
405
412
  FLAGS="--git-sha ${{ github.sha }} --ci-run-id ${{ github.run_id }} --branch ${{ github.ref_name }}"
406
413
  FLAGS="${FLAGS} --release ${{ needs.register-release.outputs.version }} --create-release-if-missing"
407
414
  FLAGS="${FLAGS} --environment uat"
415
+ FLAGS="${FLAGS} --sdlc-stage 2"
408
416
 
409
417
  # Track failures across all uploads so we can fail the job at the
410
418
  # end with the full picture. Previously each upload used
@@ -237,7 +237,7 @@ jobs:
237
237
  # untagged docs commit must not sweep every in-scope REQ into a date
238
238
  # release. Note: upload-evidence.sh keeps the LAST --release seen.
239
239
  FLAGS="--git-sha ${{ github.sha }} --ci-run-id ${{ github.run_id }} --branch ${{ github.ref_name }}"
240
- FLAGS="${FLAGS} --create-release-if-missing --environment uat"
240
+ FLAGS="${FLAGS} --create-release-if-missing --environment uat --sdlc-stage 3"
241
241
  DERIVED_RELEASE="${{ steps.version.outputs.version }}"
242
242
 
243
243
  # Derive change_type for the bare-date (housekeeping) DERIVED_RELEASE:
@@ -586,9 +586,9 @@ jobs:
586
586
  PRIOR_EVENT="${{ github.event.workflow_run.event }}"
587
587
  PRIOR_BRANCH="${{ github.event.workflow_run.head_branch }}"
588
588
  case "$PRIOR_EVENT" in
589
- pull_request) TIER=critical ;;
590
- push) TIER=regression ;;
591
- *) TIER="${PRIOR_EVENT}" ;;
589
+ pull_request) TIER=critical; STAGE=2 ;;
590
+ push) TIER=regression; STAGE=5 ;;
591
+ *) TIER="${PRIOR_EVENT}"; STAGE="" ;;
592
592
  esac
593
593
 
594
594
  # Common flags for upload-evidence.sh. Branch + SHA come from
@@ -597,6 +597,7 @@ jobs:
597
597
  --git-sha ${{ github.event.workflow_run.head_sha }} \
598
598
  --ci-run-id ${{ github.event.workflow_run.id }} \
599
599
  --branch ${PRIOR_BRANCH}"
600
+ [ -n "$STAGE" ] && FLAGS="${FLAGS} --sdlc-stage ${STAGE}"
600
601
 
601
602
  # In-scope REQs from pending release tickets at the triggering
602
603
  # SHA. Fall back to `_compliance-docs` if no tickets present so
@@ -634,10 +635,13 @@ jobs:
634
635
  # facing artefact (the formatted run summary). Skipped if
635
636
  # the report directory is missing (e.g. an upstream
636
637
  # infrastructure failure aborted before reporting).
637
- if [ -f e2e-artifacts/playwright-report/index.html ]; then
638
+ if [ -d e2e-artifacts/playwright-report ]; then
639
+ (cd e2e-artifacts && zip -qr playwright-report.zip playwright-report/) 2>/dev/null || true
640
+ fi
641
+ if [ -f e2e-artifacts/playwright-report.zip ]; then
638
642
  if bash scripts/upload-evidence.sh \
639
643
  {{PROJECT_SLUG}} "$REQ" test_report \
640
- e2e-artifacts/playwright-report/index.html \
644
+ e2e-artifacts/playwright-report.zip \
641
645
  --category test_report ${FLAGS} --release "${DERIVED_RELEASE}" \
642
646
  --meta-key "tier=${TIER}"
643
647
  then
@@ -0,0 +1,88 @@
1
+ # Feature-branch in-scope E2E (DEVAUDIT-003, issue #174)
2
+ #
3
+ # Generated by `devaudit install` / `devaudit update` from sdlc-config.json.
4
+ # Runs the E2E specs tagged with the branch's REQ on PRs to the integration
5
+ # branch, so regression-tier bugs surface during the feature cycle instead of
6
+ # at the release gate. Uploads the report as stage-2, origin=feature evidence
7
+ # so it does NOT co-mingle with the stage-3/5 regression runs and is NOT
8
+ # counted as release/UAT evidence by the portal.
9
+ name: Feature In-Scope E2E
10
+
11
+ on:
12
+ pull_request:
13
+ branches: [develop]
14
+
15
+ jobs:
16
+ detect-req:
17
+ name: Detect REQ from branch
18
+ runs-on: {{RUNNER}}
19
+ outputs:
20
+ req_id: ${{ steps.detect.outputs.req_id }}
21
+ has_tests: ${{ steps.detect.outputs.has_tests }}
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+ - name: Parse REQ from branch name
25
+ id: detect
26
+ run: |
27
+ BRANCH="${{ github.head_ref }}"
28
+ if [[ $BRANCH =~ (REQ-[0-9]+) ]]; then
29
+ REQ_ID="${BASH_REMATCH[1]}"
30
+ echo "req_id=$REQ_ID" >> "$GITHUB_OUTPUT"
31
+ if grep -rl "@requirement $REQ_ID" e2e/ --include="*.spec.ts" >/dev/null 2>&1; then
32
+ echo "has_tests=true" >> "$GITHUB_OUTPUT"
33
+ else
34
+ echo "has_tests=false" >> "$GITHUB_OUTPUT"
35
+ fi
36
+ else
37
+ echo "req_id=none" >> "$GITHUB_OUTPUT"
38
+ echo "has_tests=false" >> "$GITHUB_OUTPUT"
39
+ fi
40
+
41
+ run-feature-e2e:
42
+ name: Run in-scope E2E
43
+ needs: detect-req
44
+ if: needs.detect-req.outputs.has_tests == 'true'
45
+ runs-on: {{RUNNER}}
46
+ env:
47
+ DEVAUDIT_BASE_URL_VAR: ${{ vars.DEVAUDIT_BASE_URL }}
48
+ DEVAUDIT_API_KEY: ${{ secrets.DEVAUDIT_API_KEY }}
49
+ steps:
50
+ - uses: actions/checkout@v6
51
+ with:
52
+ fetch-depth: 0
53
+ - uses: actions/setup-node@v4
54
+ with:
55
+ node-version: '20'
56
+ - run: npm ci
57
+ - run: npx playwright install --with-deps
58
+ - name: Run in-scope E2E
59
+ run: |
60
+ REQ_ID="${{ needs.detect-req.outputs.req_id }}"
61
+ npx playwright test --grep "$REQ_ID"
62
+ - name: Upload feature E2E evidence (stage 2, origin=feature)
63
+ if: always()
64
+ run: |
65
+ REQ_ID="${{ needs.detect-req.outputs.req_id }}"
66
+ CONFIG_URL=""
67
+ if [ -f sdlc-config.json ]; then
68
+ CONFIG_URL=$(jq -r '.devaudit.base_url // empty' sdlc-config.json 2>/dev/null || true)
69
+ fi
70
+ BASE="${CONFIG_URL:-$DEVAUDIT_BASE_URL_VAR}"
71
+ if [ -z "$BASE" ] || [ -z "$DEVAUDIT_API_KEY" ]; then
72
+ echo "::warning::DevAudit not configured — skipping feature E2E upload."
73
+ exit 0
74
+ fi
75
+ export DEVAUDIT_BASE_URL="${BASE%/}"
76
+ if [ -d playwright-report ]; then
77
+ zip -qr playwright-report.zip playwright-report/ 2>/dev/null || true
78
+ fi
79
+ if [ -f playwright-report.zip ]; then
80
+ bash scripts/upload-evidence.sh \
81
+ {{PROJECT_SLUG}} "$REQ_ID" test_report playwright-report.zip \
82
+ --category test_report --release "$REQ_ID" --create-release-if-missing \
83
+ --environment uat --sdlc-stage 2 \
84
+ --git-sha "${{ github.event.pull_request.head.sha }}" \
85
+ --ci-run-id "${{ github.run_id }}" --branch "${{ github.head_ref }}" \
86
+ --meta-key "origin=feature" \
87
+ || echo "::warning::feature E2E report upload failed"
88
+ fi
@@ -164,7 +164,7 @@ jobs:
164
164
  bash scripts/upload-evidence.sh \
165
165
  "${PROJECT_SLUG}" "${VERSION}" test_report prod-smoke-results.json \
166
166
  --release "${VERSION}" --create-release-if-missing --environment production \
167
- --category test_report --git-sha "${GIT_SHA}" --ci-run-id "${CI_RUN}" --branch main \
167
+ --category test_report --sdlc-stage 5 --git-sha "${GIT_SHA}" --ci-run-id "${CI_RUN}" --branch main \
168
168
  || echo "Warning: smoke upload failed for ${VERSION}"
169
169
  fi
170
170
  # Carry the release ticket into the production environment so the
@@ -179,7 +179,7 @@ jobs:
179
179
  bash scripts/upload-evidence.sh \
180
180
  "${PROJECT_SLUG}" "${VERSION}" compliance_document "$TICKET" \
181
181
  --release "${VERSION}" --create-release-if-missing --environment production \
182
- --category release_artifact --git-sha "${GIT_SHA}" --ci-run-id "${CI_RUN}" --branch main \
182
+ --category release_artifact --sdlc-stage 5 --git-sha "${GIT_SHA}" --ci-run-id "${CI_RUN}" --branch main \
183
183
  || echo "Warning: ticket upload failed for ${VERSION}"
184
184
  else
185
185
  echo "No RELEASE-TICKET-${VERSION}.md found — skipping ticket (date-versioned or archived)."
@@ -1,17 +1,20 @@
1
- # CI Pipeline — all gates on every code push to develop (Python stack)
1
+ # CI Pipeline — all gates on PRs to develop and code pushes to develop (Python stack)
2
2
  #
3
3
  # Generated by `devaudit install` / `devaudit update` from sdlc-config.json + stacks/python/adapter.json.
4
4
  # Do not edit manually — re-run the CLI (`devaudit update`) to regenerate.
5
5
  #
6
6
  # Single consolidated job. Order: install → ruff → mypy → semgrep → pip-audit → pytest → build.
7
7
  #
8
- # PRs to main inherit commit status via branch protection.
8
+ # PRs to develop run Quality Gates before integration. PRs to main inherit
9
+ # commit status via branch protection.
9
10
  # Compliance validation runs separately on PRs (compliance-validation.yml).
10
11
 
11
12
  name: CI Pipeline
12
13
 
13
14
  on:
14
15
  workflow_dispatch:
16
+ pull_request:
17
+ branches: [develop]
15
18
  push:
16
19
  branches: [develop]
17
20
  paths-ignore:
@@ -184,7 +187,10 @@ jobs:
184
187
  register-release:
185
188
  name: Register Release
186
189
  runs-on: {{RUNNER}}
187
- if: ${{ vars.DEVAUDIT_BASE_URL != '' }}
190
+ # PRs to develop should report Quality Gates without mutating DevAudit
191
+ # releases or evidence. Release registration remains a develop-push /
192
+ # manual-dispatch side effect.
193
+ if: ${{ github.event_name != 'pull_request' && vars.DEVAUDIT_BASE_URL != '' }}
188
194
  outputs:
189
195
  version: ${{ steps.version.outputs.version }}
190
196
  env: