@metasession.co/devaudit-cli 0.1.69 → 0.1.71
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/dist/index.js +12 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/upload-evidence.sh +10 -1
- package/sdlc/CLAUDE.md +25 -2
- package/sdlc/SKILLS.md +1 -1
- package/sdlc/ai-rules/INSTRUCTIONS-SDLC.md +21 -5
- package/sdlc/files/_common/3-compile-evidence.md +63 -2
- package/sdlc/files/_common/4-submit-for-review.md +2 -1
- package/sdlc/files/_common/5-deploy-main.md +1 -0
- package/sdlc/files/_common/Test_Plan_TEMPLATE.md +1 -1
- package/sdlc/files/_common/Test_Strategy.md +1 -1
- package/sdlc/files/_common/governance/nil-incident-report.md.template +38 -0
- package/sdlc/files/_common/scripts/derive-release-version.sh +7 -0
- package/sdlc/files/_common/scripts/generate-bundled-changes.sh +88 -0
- package/sdlc/files/_common/scripts/generate-bundled-changes.test.sh +183 -0
- package/sdlc/files/_common/scripts/validate-compliance-artifacts.sh +13 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +12 -2
- package/sdlc/files/_common/skills/requirements-aligner/SKILL.md +6 -1
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +138 -25
- package/sdlc/files/_common/skills/sdlc-implementer/references/call-graph.md +1 -1
- package/sdlc/files/_common/skills/sdlc-implementer/references/change-request-loop.md +27 -2
- package/sdlc/files/ci/ci.yml.template +112 -13
- package/sdlc/files/ci/compliance-evidence.yml.template +353 -53
- package/sdlc/files/ci/feature-e2e.yml.template +3 -2
- package/sdlc/files/ci/incident-export.yml.template +306 -8
- package/sdlc/files/ci/label-retention.yml.template +144 -0
- package/sdlc/files/ci/post-deploy-prod.yml.template +80 -3
- package/sdlc/files/ci/python/ci.yml.template +60 -16
- package/sdlc/files/sdlc-config.example.json +1 -1
- package/sdlc/.claude/settings.local.json +0 -11
|
@@ -294,11 +294,40 @@ jobs:
|
|
|
294
294
|
chmod +x scripts/upload-evidence.sh 2>/dev/null || true
|
|
295
295
|
# Create the release in DevAudit (no evidence yet — just registration)
|
|
296
296
|
bash scripts/upload-evidence.sh \
|
|
297
|
-
{{PROJECT_SLUG}} _compliance-docs
|
|
297
|
+
{{PROJECT_SLUG}} _compliance-docs release_registration README.md \
|
|
298
298
|
--release ${{ steps.version.outputs.version }} --create-release-if-missing \
|
|
299
299
|
--environment uat --category planning \
|
|
300
300
|
--git-sha ${{ github.sha }} --branch ${{ github.ref_name }} || true
|
|
301
301
|
|
|
302
|
+
- name: Generate and upload bundled changes (REQ releases only)
|
|
303
|
+
if: env.DEVAUDIT_BASE_URL != ''
|
|
304
|
+
run: |
|
|
305
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
306
|
+
# Only generate bundled changes for REQ-tagged releases —
|
|
307
|
+
# housekeeping (bare-date) releases don't bundle other housekeeping.
|
|
308
|
+
if [[ "$VERSION" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
|
|
309
|
+
echo "Version ${VERSION} is housekeeping — skipping bundled changes."
|
|
310
|
+
exit 0
|
|
311
|
+
fi
|
|
312
|
+
chmod +x scripts/generate-bundled-changes.sh 2>/dev/null || true
|
|
313
|
+
chmod +x scripts/upload-evidence.sh 2>/dev/null || true
|
|
314
|
+
# Find the previous release tag to scan from. Fall back to last 50
|
|
315
|
+
# commits if no prior tag exists.
|
|
316
|
+
SINCE_REF=$(git tag --sort=-creatordate | head -1 || true)
|
|
317
|
+
if [ -z "$SINCE_REF" ]; then
|
|
318
|
+
SINCE_REF="HEAD~50"
|
|
319
|
+
fi
|
|
320
|
+
echo "Scanning bundled changes since ${SINCE_REF} for ${VERSION}"
|
|
321
|
+
BUNDLED_FILE="compliance/pending-releases/BUNDLED-CHANGES-${VERSION}.md"
|
|
322
|
+
mkdir -p compliance/pending-releases
|
|
323
|
+
bash scripts/generate-bundled-changes.sh "$SINCE_REF" "$VERSION" > "$BUNDLED_FILE"
|
|
324
|
+
# Upload as bundled_changes evidence against the REQ release.
|
|
325
|
+
bash scripts/upload-evidence.sh \
|
|
326
|
+
{{PROJECT_SLUG}} _compliance-docs bundled_changes "$BUNDLED_FILE" \
|
|
327
|
+
--release "$VERSION" \
|
|
328
|
+
--environment uat --category planning \
|
|
329
|
+
--git-sha ${{ github.sha }} --branch ${{ github.ref_name }} || true
|
|
330
|
+
|
|
302
331
|
- name: Sync known requirements from RTM
|
|
303
332
|
if: env.DEVAUDIT_BASE_URL != ''
|
|
304
333
|
env:
|
|
@@ -413,6 +442,7 @@ jobs:
|
|
|
413
442
|
FLAGS="${FLAGS} --release ${{ needs.register-release.outputs.version }} --create-release-if-missing"
|
|
414
443
|
FLAGS="${FLAGS} --environment uat"
|
|
415
444
|
FLAGS="${FLAGS} --sdlc-stage 2"
|
|
445
|
+
FLAGS="${FLAGS} --test-cycle ${{ github.run_id }}"
|
|
416
446
|
|
|
417
447
|
# Track failures across all uploads so we can fail the job at the
|
|
418
448
|
# end with the full picture. Previously each upload used
|
|
@@ -451,7 +481,7 @@ jobs:
|
|
|
451
481
|
STATUS_DEPAUDIT=$(gate_status "$(jq -r '.dependency_audit // "skipped"' ci-evidence/gate-outcomes.json)")
|
|
452
482
|
STATUS_BUILD=$(gate_status "$(jq -r '.build // "skipped"' ci-evidence/gate-outcomes.json)")
|
|
453
483
|
upload gate-outcomes.json \
|
|
454
|
-
{{PROJECT_SLUG}} _compliance-docs
|
|
484
|
+
{{PROJECT_SLUG}} _compliance-docs gate_outcome ci-evidence/gate-outcomes.json \
|
|
455
485
|
--category ci_pipeline ${FLAGS}
|
|
456
486
|
fi
|
|
457
487
|
|
|
@@ -488,28 +518,34 @@ jobs:
|
|
|
488
518
|
--category security_scan --gate-status "$STATUS_DEPAUDIT" ${FLAGS}
|
|
489
519
|
fi
|
|
490
520
|
|
|
491
|
-
# Upload E2E test results (
|
|
521
|
+
# Upload E2E test results (e2e_result category)
|
|
492
522
|
if [ -f ci-evidence/e2e-results.json ]; then
|
|
493
523
|
upload e2e-results.json \
|
|
494
524
|
{{PROJECT_SLUG}} _compliance-docs e2e_result ci-evidence/e2e-results.json \
|
|
495
|
-
--category
|
|
525
|
+
--category e2e_result ${FLAGS}
|
|
496
526
|
fi
|
|
497
527
|
|
|
498
|
-
# Upload Playwright HTML report (
|
|
528
|
+
# Upload Playwright HTML report (e2e_report — run context, NOT
|
|
529
|
+
# a test completion report). Uses evidence_type=e2e_report so
|
|
530
|
+
# the portal can distinguish it from per-REQ test-execution-
|
|
531
|
+
# summary.md (DevAudit-Installer#207).
|
|
499
532
|
if [ -d ci-evidence/playwright-report ]; then
|
|
500
533
|
(cd ci-evidence && zip -qr playwright-report.zip playwright-report/) 2>/dev/null || true
|
|
501
534
|
if [ -f ci-evidence/playwright-report.zip ]; then
|
|
502
535
|
upload playwright-report.zip \
|
|
503
|
-
{{PROJECT_SLUG}} _compliance-docs
|
|
504
|
-
--category
|
|
536
|
+
{{PROJECT_SLUG}} _compliance-docs e2e_report ci-evidence/playwright-report.zip \
|
|
537
|
+
--category e2e_report ${FLAGS}
|
|
505
538
|
fi
|
|
506
539
|
fi
|
|
507
540
|
|
|
508
|
-
# Upload Jest coverage summary (
|
|
541
|
+
# Upload Jest coverage summary (coverage_report category).
|
|
542
|
+
# Uses evidence_type=coverage_report (NOT test_report) so the
|
|
543
|
+
# portal can distinguish run-context coverage data from per-REQ
|
|
544
|
+
# test completion reports (DevAudit-Installer#207).
|
|
509
545
|
if [ -f ci-evidence/coverage/coverage-summary.json ]; then
|
|
510
546
|
upload coverage-summary.json \
|
|
511
|
-
{{PROJECT_SLUG}} _compliance-docs
|
|
512
|
-
--category
|
|
547
|
+
{{PROJECT_SLUG}} _compliance-docs coverage_report ci-evidence/coverage/coverage-summary.json \
|
|
548
|
+
--category coverage_report ${FLAGS}
|
|
513
549
|
fi
|
|
514
550
|
|
|
515
551
|
# Upload project-level Test Summary Report as a baseline
|
|
@@ -526,6 +562,56 @@ jobs:
|
|
|
526
562
|
--category planning ${FLAGS}
|
|
527
563
|
fi
|
|
528
564
|
|
|
565
|
+
# devaudit-installer#200 Fix 4 — Per-REQ gate evidence fan-out.
|
|
566
|
+
# The gate evidence above was uploaded to the single commit-derived
|
|
567
|
+
# release (FLAGS carries --release <derived>). When multiple REQs
|
|
568
|
+
# have pending release tickets, only that one REQ gets gate evidence
|
|
569
|
+
# on the portal — other in-scope REQs show "no gate evidence" and
|
|
570
|
+
# "no tests tagged with this REQ" even though the gates ran and
|
|
571
|
+
# passed. Fan out gate-outcomes.json + e2e-results.json to each
|
|
572
|
+
# in-scope REQ's release so the portal's per-REQ test parser can
|
|
573
|
+
# extract REQ-tagged tests from the e2e-results.json associated with
|
|
574
|
+
# that REQ's release. Heavy run-context artefacts (SAST, dep-audit,
|
|
575
|
+
# playwright zip, coverage) remain on the commit-derived release
|
|
576
|
+
# only — they are run-level, not per-REQ.
|
|
577
|
+
COMMIT_REQ="${{ needs.register-release.outputs.version }}"
|
|
578
|
+
FANOUT_REQS=()
|
|
579
|
+
if [ -d compliance/pending-releases ]; then
|
|
580
|
+
for TICKET in compliance/pending-releases/RELEASE-TICKET-REQ-*.md; do
|
|
581
|
+
[ -f "$TICKET" ] || continue
|
|
582
|
+
REQ_ID=$(basename "$TICKET" .md | sed 's/^RELEASE-TICKET-//')
|
|
583
|
+
# #192 — skip REQs already in a terminal release directory.
|
|
584
|
+
if compgen -G "compliance/approved-releases/RELEASE-TICKET-${REQ_ID}.md" > /dev/null 2>&1 \
|
|
585
|
+
|| compgen -G "compliance/superseded-releases/RELEASE-TICKET-${REQ_ID}.md" > /dev/null 2>&1; then
|
|
586
|
+
continue
|
|
587
|
+
fi
|
|
588
|
+
# Skip the commit-derived REQ — it already has the evidence.
|
|
589
|
+
if [ "$REQ_ID" = "$COMMIT_REQ" ]; then
|
|
590
|
+
continue
|
|
591
|
+
fi
|
|
592
|
+
FANOUT_REQS+=("$REQ_ID")
|
|
593
|
+
done
|
|
594
|
+
fi
|
|
595
|
+
if [ "${#FANOUT_REQS[@]}" -gt 0 ]; then
|
|
596
|
+
echo "Fanning out gate evidence to in-scope REQs: ${FANOUT_REQS[*]}"
|
|
597
|
+
for REQ_ID in "${FANOUT_REQS[@]}"; do
|
|
598
|
+
FANOUT_FLAGS="--git-sha ${{ github.sha }} --ci-run-id ${{ github.run_id }} --branch ${{ github.ref_name }}"
|
|
599
|
+
FANOUT_FLAGS="${FANOUT_FLAGS} --release ${REQ_ID} --create-release-if-missing"
|
|
600
|
+
FANOUT_FLAGS="${FANOUT_FLAGS} --environment uat --sdlc-stage 2"
|
|
601
|
+
FANOUT_FLAGS="${FANOUT_FLAGS} --test-cycle ${{ github.run_id }}"
|
|
602
|
+
if [ -f ci-evidence/gate-outcomes.json ]; then
|
|
603
|
+
upload "gate-outcomes.json -> ${REQ_ID}" \
|
|
604
|
+
{{PROJECT_SLUG}} "${REQ_ID}" gate_outcome ci-evidence/gate-outcomes.json \
|
|
605
|
+
--category ci_pipeline ${FANOUT_FLAGS}
|
|
606
|
+
fi
|
|
607
|
+
if [ -f ci-evidence/e2e-results.json ]; then
|
|
608
|
+
upload "e2e-results.json -> ${REQ_ID}" \
|
|
609
|
+
{{PROJECT_SLUG}} "${REQ_ID}" e2e_result ci-evidence/e2e-results.json \
|
|
610
|
+
--category e2e_result ${FANOUT_FLAGS}
|
|
611
|
+
fi
|
|
612
|
+
done
|
|
613
|
+
fi
|
|
614
|
+
|
|
529
615
|
# Upload per-AC e2e evidence screenshots, scoped to each in-scope
|
|
530
616
|
# requirement so they render under "Evidence by requirement" in the
|
|
531
617
|
# portal. These are the per-assertion `evidenceShot(page, REQ, 'ACn-…')`
|
|
@@ -627,7 +713,7 @@ jobs:
|
|
|
627
713
|
|
|
628
714
|
if bash scripts/upload-evidence.sh \
|
|
629
715
|
{{PROJECT_SLUG}} "$REQ" screenshot "$NAMED" \
|
|
630
|
-
--category
|
|
716
|
+
--category screenshot ${FLAGS} --release "$REQ" \
|
|
631
717
|
"${REQ_META[@]}" \
|
|
632
718
|
"${ORIGIN_META[@]}"
|
|
633
719
|
then
|
|
@@ -679,8 +765,21 @@ jobs:
|
|
|
679
765
|
" 2>/dev/null || echo "0")
|
|
680
766
|
fi
|
|
681
767
|
if [ "$TAGGED_COUNT" -eq 0 ]; then
|
|
682
|
-
|
|
683
|
-
|
|
768
|
+
# devaudit-installer#195 — before failing, scan spec files on
|
|
769
|
+
# disk for the REQ ID. CI runs --project=smoke (a fast subset),
|
|
770
|
+
# so specs outside e2e/smoke/ (e2e/realtime/, e2e/critical/,
|
|
771
|
+
# e2e/admin/, etc.) never appear in e2e-results.json. A REQ
|
|
772
|
+
# whose tests live there would be falsely flagged as having
|
|
773
|
+
# "zero traceable evidence" even though well-written, REQ-tagged
|
|
774
|
+
# specs exist on disk. If specs are found but weren't run in
|
|
775
|
+
# this tier, emit a non-blocking warning instead of an error.
|
|
776
|
+
SPECS_ON_DISK=$(grep -rl --include='*.spec.ts' -e "@requirement ${REQ}" -e "tagTest.*${REQ}" -e "'${REQ}'" e2e/ 2>/dev/null | wc -l)
|
|
777
|
+
if [ "$SPECS_ON_DISK" -gt 0 ]; then
|
|
778
|
+
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."
|
|
779
|
+
else
|
|
780
|
+
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)."
|
|
781
|
+
EVIDENCE_GAPS=$((EVIDENCE_GAPS + 1))
|
|
782
|
+
fi
|
|
684
783
|
else
|
|
685
784
|
echo "${REQ} has zero screenshots but ${TAGGED_COUNT} tagged test(s) — evidence-completeness gate passed (screenshot gap is non-blocking)"
|
|
686
785
|
fi
|