@metasession.co/devaudit-cli 0.2.0 → 0.3.0

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.
@@ -409,6 +409,15 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
409
409
  - **Requirements deviation** (an AC is wrong, incomplete, or missing) — trigger the [requirements gap flow](#requirements-gap-flow-devaudit-installer212). Do NOT just note it as a plan deviation. The AC table must be updated, `requirements-aligner` must be re-invoked to re-check SRS alignment, and the RTM must be updated.
410
410
 
411
411
  The classification question: "Did the implementation deviate from the plan's approach (how to build it), or did the plan's requirements deviate from reality (what to build)?" If the former, note and continue. If the latter, trigger the requirements gap flow.
412
+
413
+ 4b. **Reconcile test-plan.md file paths with actual files (devaudit-installer#241).** After writing/updating tests (both unit and E2E), diff the actual test file paths against `compliance/evidence/REQ-XXX/test-plan.md`. The test plan was authored during Stage 1 with predicted file paths — during implementation, tests are often added to existing files instead of creating new ones. This is a natural drift, but it must be reconciled before committing so `validate-compliance-artifacts.sh` doesn't fail at PR time.
414
+
415
+ For each file path referenced in `test-plan.md`:
416
+ - If the file exists on disk → OK, no action needed.
417
+ - If the file does not exist → check whether a test covering the same AC was added to a different file. If so, update `test-plan.md` to reference the actual file path.
418
+ - If the file does not exist and no equivalent test was found → **HALT**: "test-plan.md references <file> but no test file exists and no equivalent test covering the same AC was found. Either create the test file, update test-plan.md to point to the actual test file, or remove the entry if the AC is no longer relevant."
419
+
420
+ Commit the updated `test-plan.md` alongside the test code. This is a file-path reconciliation — it does not change the AC table (that's the step 5b plan ↔ test-scope AC consistency check, which is separate and checks AC drift, not file-path drift).
412
421
  5. **Run gates locally, cheap-first.** The gates are not equivalent-cost — `npm run lint` is seconds, `npx playwright test` is 30–60 minutes. Iterate on the fast gates; spend the e2e cost once.
413
422
 
414
423
  **Fast gates** (run on every change, ideally pre-commit):
@@ -428,7 +437,9 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
428
437
  git diff --name-only "$INTEGRATION_BRANCH"...HEAD -- 'app/**/*.tsx' 'src/**/*.tsx' 'pages/**/*.tsx' 'app/**/*.jsx' 'src/**/*.jsx' 'pages/**/*.jsx'
429
438
  ```
430
439
 
431
- - **If UI-facing files are present:** check for `.e2e-gate-passed` sentinel file (written by `e2e-test-engineer` after a successful run) or `playwright-report/` directory with recent content. If neither exists, **HALT**: "E2E gate was not run. The change touches UI-facing files. Run `npx playwright test` (or invoke `e2e-test-engineer`) before committing. The pre-push hook will also block this push."
440
+ - **If UI-facing files are present:** check for `.e2e-gate-passed` sentinel file (written by `e2e-test-engineer` after a successful run) or `playwright-report/` directory with recent content. If neither exists, **HALT**: "E2E gate was not run. The change touches UI-facing files. Run `npx playwright test` (or invoke `e2e-test-engineer`) before committing. Do not defer to CI — install Playwright browsers with `npx playwright install` if needed. The pre-push hook will also block this push."
441
+
442
+ **Also check for `.e2e-evidence-wired` sentinel (devaudit-installer#226).** If `e2e/**/*.spec.ts` files were authored or modified, verify the `.e2e-evidence-wired` sentinel exists (written by `e2e-test-engineer` Phase 5½ after validating `tagTest()` and `evidenceShot()` calls). If missing, **HALT**: "Evidence wiring validation (Phase 5½) was not run. The change includes E2E spec files but no evidence wiring sentinel. Invoke `e2e-test-engineer` to validate `tagTest()` and `evidenceShot()` calls before committing. The pre-push hook will also block this push."
432
443
  - **If no UI-facing files (API-only, config, docs):** skip the check. Note the exemption in the commit body: "E2E gate skipped — no UI-facing files in this change."
433
444
  - **If `e2e-test-engineer` was invoked and determined e2e is not needed** (e.g. schema-only change): the skill writes `.e2e-gate-passed` with a `NOT_NEEDED` reason. The sentinel check passes. Note the exemption in the commit body: "E2E gate not needed — e2e-test-engineer assessed no UI surface (turn N)."
434
445
 
@@ -491,6 +502,14 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
491
502
  - The nil report uploads as `incident_report` evidence via `compliance-evidence.yml`'s `upload_incident_report` function, flipping `ISO29119.3.5.4` to COVERED for clean releases.
492
503
  - If incidents WERE closed, skip nil report generation — the populated incident report(s) from `incident-export.yml` serve as the evidence.
493
504
 
505
+ 5b. **Validate test-execution-summary.md gate states (devaudit-installer#240).** Before uploading evidence, verify that `compliance/evidence/REQ-XXX/test-execution-summary.md` does not contain invalid gate states. Run:
506
+
507
+ ```bash
508
+ bash scripts/validate-test-summary.sh origin/main
509
+ ```
510
+
511
+ If the validator fails, fix the summary before proceeding. E2E gate results must be one of: `PASS`, `FAIL`, `NOT_NEEDED` (with reason), or `SKIPPED` (with operator-approved rationale). The word "deferred" must never appear in `test-execution-summary.md` — not as a gate state, not in prose, not in final assessment. "Deferred to CI" and "Playwright browsers not installed locally" are environment issues, not gate states. The CI validator (`validate-test-summary.sh`) will reject any summary containing "deferred" or "browsers not installed" on PRs to main.
512
+
494
513
  6. **Organise artefacts** under `compliance/evidence/REQ-XXX/` with date-prefixed naming:
495
514
 
496
515
  ```
@@ -793,10 +793,35 @@ jobs:
793
793
  # specs exist on disk. If specs are found but weren't run in
794
794
  # this tier, emit a non-blocking warning instead of an error.
795
795
  SPECS_ON_DISK=$(grep -rl --include='*.spec.ts' -e "@requirement ${REQ}" -e "tagTest.*${REQ}" -e "'${REQ}'" e2e/ 2>/dev/null | wc -l)
796
+
797
+ # devaudit-installer#237 — also scan unit test files for
798
+ # @requirement REQ-XXX annotations. A REQ with thorough unit
799
+ # test coverage but no E2E specs (legitimate for API-only or
800
+ # backend-only changes) should not be hard-blocked.
801
+ UNIT_TESTS_ON_DISK=$(grep -rl --include='*.test.ts' --include='*.test.tsx' -e "@requirement ${REQ}" -e "'${REQ}'" e2e/ __tests__/ tests/ src/ 2>/dev/null | wc -l)
802
+
803
+ # devaudit-installer#237 — check for test-execution-summary.md
804
+ # as a secondary signal. This is a human-authored document and
805
+ # weaker than machine-generated evidence, so it only converts
806
+ # a hard error to a warning when combined with unit test files
807
+ # on disk — never alone.
808
+ HAS_SUMMARY=false
809
+ if [ -f "compliance/evidence/${REQ}/test-execution-summary.md" ]; then
810
+ HAS_SUMMARY=true
811
+ fi
812
+
796
813
  if [ "$SPECS_ON_DISK" -gt 0 ]; then
814
+ # Scenario B: E2E specs exist on disk but outside the smoke tier
797
815
  echo "::warning::Evidence completeness gate: ${REQ} has zero tagged tests in this smoke run and zero per-AC screenshots, but ${SPECS_ON_DISK} spec file(s) on disk reference it (outside the smoke project). Evidence exists but was not executed in this CI tier. Consider running --project=critical or --grep \"${REQ}\" to capture evidence."
816
+ elif [ "$UNIT_TESTS_ON_DISK" -gt 0 ] && [ "$HAS_SUMMARY" = "true" ]; then
817
+ # Scenario C: unit test files exist with @requirement annotations
818
+ # and a test-execution-summary.md documents coverage
819
+ echo "::warning::Evidence completeness gate: ${REQ} has zero E2E tagged tests and zero screenshots, but ${UNIT_TESTS_ON_DISK} unit test file(s) on disk reference it and a test-execution-summary.md exists. Unit test evidence found but execution was not verified in this run. If this is an API-only or backend-only change, this is expected."
798
820
  else
799
- echo "::error::Evidence completeness gate: ${REQ} has zero tagged tests AND zero per-AC screenshots. The release cannot proceed to UAT with no traceable evidence. Ensure specs carry @requirement ${REQ} annotations and evidenceShot() calls (skill Phase 5½, issue #170)."
821
+ # Scenario A: genuinely no evidence no E2E specs, no unit tests,
822
+ # no test-execution-summary. Hard error preserved (#237 Constraint 3).
823
+ echo "::error::Evidence completeness gate: ${REQ} has zero traceable evidence — no tagged E2E tests, no per-AC screenshots, no unit test files with @requirement annotations, and no test-execution-summary.md. The release cannot proceed to UAT with no traceable per-REQ evidence."
824
+ echo "::error::If E2E specs exist for this REQ, ensure they carry @requirement ${REQ} JSDoc annotations and tagTest() calls (e2e-test-engineer Phase 5½, issue #170). If unit tests exist, add @requirement ${REQ} annotations to the .test.ts files. If this is a pure config/docs change with no testable surface, document it in test-execution-summary.md."
800
825
  EVIDENCE_GAPS=$((EVIDENCE_GAPS + 1))
801
826
  fi
802
827
  else
@@ -30,5 +30,8 @@ jobs:
30
30
  - name: Validate compliance artifacts
31
31
  run: bash scripts/validate-compliance-artifacts.sh origin/main
32
32
 
33
+ - name: Validate test execution summaries
34
+ run: bash scripts/validate-test-summary.sh origin/main
35
+
33
36
  - name: Validate commit conventions
34
37
  run: bash scripts/validate-commits.sh origin/main
@@ -30,6 +30,8 @@ echo "Pre-push: TypeScript check passed."
30
30
  # Only fires if UI-facing files are in the push. Checks for either
31
31
  # playwright-report/ directory or .e2e-gate-passed sentinel (written by
32
32
  # e2e-test-engineer after a successful run).
33
+ # Also checks .e2e-evidence-wired sentinel if e2e spec files changed
34
+ # (written by e2e-test-engineer Phase 5½ after validating tagTest/evidenceShot).
33
35
  INTEGRATION_BRANCH=$(jq -r '.integration_branch // "develop"' sdlc-config.json 2>/dev/null || echo "develop")
34
36
 
35
37
  # Read stdin to get the pushed refs (husky pre-push protocol)
@@ -70,6 +72,23 @@ while read -r local_ref local_sha remote_ref remote_sha; do
70
72
  fi
71
73
  echo "Pre-push: E2E evidence check passed."
72
74
  fi
75
+
76
+ # Check for E2E spec file changes — require .e2e-evidence-wired sentinel
77
+ SPEC_FILES=$(git diff --name-only "$RANGE" -- 'e2e/**/*.spec.ts' 2>/dev/null || true)
78
+
79
+ if [ -n "$SPEC_FILES" ]; then
80
+ if [ ! -f .e2e-evidence-wired ]; then
81
+ echo ""
82
+ echo "ERROR: Evidence wiring validation (Phase 5½) was not run."
83
+ echo " E2E spec files changed in this push:"
84
+ echo "$SPEC_FILES" | sed 's/^/ /'
85
+ echo ""
86
+ echo " Invoke e2e-test-engineer to validate tagTest() and evidenceShot() calls."
87
+ echo " Bypass with --no-verify (last resort, not a habit)."
88
+ exit 1
89
+ fi
90
+ echo "Pre-push: E2E evidence wiring check passed."
91
+ fi
73
92
  done
74
93
 
75
94
  # ── 3. Skill-invocation sentinel (devaudit-installer#226) ────────────
package/sdlc/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devaudit-sdlc",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "DevAudit SDLC CLI Engine — cross-agent terminal-driven SDLC orchestrator.",
5
5
  "bin": {
6
6
  "devaudit-sdlc": "./src/bin/devaudit-sdlc.js"
@@ -174,6 +174,18 @@ If prerequisites are missing, do **not** start the full local suite. Run the tar
174
174
 
175
175
  **Do NOT proceed** until the scoped E2E/test-plan checks are complete and any local limitations are called out.
176
176
 
177
+ ### Step 4b: Reconcile Test Plan (devaudit-installer#241)
178
+
179
+ After writing/updating tests (both unit and E2E), verify that `test-plan.md` file paths still match reality. The test plan was authored during Stage 1 with predicted file paths — during implementation, tests are often added to existing files instead of creating new ones. This natural drift must be reconciled before committing so `validate-compliance-artifacts.sh` doesn't fail at PR time.
180
+
181
+ For each file path referenced in `test-plan.md`:
182
+
183
+ - If the file exists on disk → OK, no action needed.
184
+ - If the file does not exist → check whether a test covering the same AC was added to a different file. If so, update `test-plan.md` to reference the actual file path.
185
+ - If the file does not exist and no equivalent test was found → **STOP**: "test-plan.md references `<file>` but no test file exists and no equivalent test covering the same AC was found. Either create the test file, update test-plan.md to point to the actual test file, or remove the entry if the AC is no longer relevant."
186
+
187
+ Commit the updated `test-plan.md` alongside the test code. This is a file-path reconciliation — it does not change the AC table (the plan ↔ test-scope AC consistency check in the skill handles AC drift separately).
188
+
177
189
  ### Step 5: Stage Selectively
178
190
 
179
191
  ```bash
@@ -1,11 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(git init:*)",
5
- "Bash(git add:*)",
6
- "Bash(git branch:*)",
7
- "Bash(git commit:*)",
8
- "Bash(gh repo:*)"
9
- ]
10
- }
11
- }