@metasession.co/devaudit-cli 0.3.11 → 0.3.13
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 +94 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/upload-evidence.sh +55 -1
- package/sdlc/ai-rules/SDLC_RULES.md +27 -7
- package/sdlc/files/_common/0-project-setup.md +13 -7
- package/sdlc/files/_common/Periodic_Security_Review_Schedule.md +5 -5
- package/sdlc/files/_common/README_TEMPLATE.md +8 -8
- package/sdlc/files/_common/Test_Architecture.md +15 -15
- package/sdlc/files/_common/Test_Plan_TEMPLATE.md +13 -13
- package/sdlc/files/_common/Test_Policy.md +2 -2
- package/sdlc/files/_common/Test_Strategy.md +10 -10
- package/sdlc/files/_common/governance/ai-disclosure.md.template +3 -3
- package/sdlc/files/_common/governance/dpia.md.template +3 -3
- package/sdlc/files/_common/governance/incident-report.md.template +3 -3
- package/sdlc/files/_common/governance/nil-incident-report.md.template +1 -1
- package/sdlc/files/_common/governance/periodic-review.md.template +3 -3
- package/sdlc/files/_common/governance/risk-register.md.template +1 -1
- package/sdlc/files/_common/governance/ropa.md.template +2 -2
- package/sdlc/files/_common/joining-an-existing-project.md +4 -4
- package/sdlc/files/_common/scripts/check-host-deployment.sh +107 -0
- package/sdlc/files/_common/scripts/check-host-deployment.test.sh +119 -0
- package/sdlc/files/_common/scripts/check-release-pr-scope.sh +95 -0
- package/sdlc/files/_common/scripts/check-release-pr-scope.test.sh +137 -0
- package/sdlc/files/_common/scripts/close-out-release.sh +175 -54
- package/sdlc/files/_common/scripts/close-out-release.test.sh +90 -0
- package/sdlc/files/_common/scripts/extract-release-metadata.sh +65 -0
- package/sdlc/files/_common/scripts/extract-release-metadata.test.sh +38 -0
- package/sdlc/files/_common/scripts/generate-bundled-changes.sh +307 -58
- package/sdlc/files/_common/scripts/generate-bundled-changes.test.sh +128 -78
- package/sdlc/files/_common/scripts/generate-housekeeping-release-ticket.sh +18 -9
- package/sdlc/files/_common/scripts/generate-housekeeping-release-ticket.test.sh +66 -0
- package/sdlc/files/_common/scripts/generate-security-summary.sh +14 -5
- package/sdlc/files/_common/scripts/generate-security-summary.test.sh +57 -0
- package/sdlc/files/_common/scripts/prepare-release-pr.sh +44 -4
- package/sdlc/files/_common/scripts/render-test-cycles.sh +227 -0
- package/sdlc/files/_common/scripts/render-test-cycles.test.sh +107 -0
- package/sdlc/files/_common/scripts/report-test-cycle.sh +344 -0
- package/sdlc/files/_common/scripts/submit-bundle-manifest.sh +100 -0
- package/sdlc/files/_common/scripts/submit-bundle-manifest.test.sh +138 -0
- package/sdlc/files/_common/scripts/upload-evidence.sh +55 -1
- package/sdlc/files/_common/scripts/upload-evidence.test.sh +119 -0
- package/sdlc/files/_common/scripts/validate-compliance-artifacts.sh +169 -2
- package/sdlc/files/_common/scripts/validate-compliance-artifacts.test.sh +169 -0
- package/sdlc/files/_common/scripts/validate-test-summary.test.sh +4 -4
- package/sdlc/files/_common/skills/adr-author/SKILL.md +2 -2
- package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +2 -2
- package/sdlc/files/_common/skills/e2e-test-engineer/references/bootstrap.md +5 -5
- package/sdlc/files/_common/skills/governance-doc-author/references/incident-classification.md +1 -1
- package/sdlc/files/_common/skills/requirements-aligner/SKILL.md +4 -4
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +57 -3
- package/sdlc/files/_common/skills/sdlc-implementer/references/change-request-loop.md +1 -1
- package/sdlc/files/_common/skills/sdlc-implementer/references/compliance-constraints.md +7 -14
- package/sdlc/files/ci/check-release-approval.yml.template +18 -28
- package/sdlc/files/ci/ci.yml.template +95 -35
- package/sdlc/files/ci/close-out-release.yml.template +7 -4
- package/sdlc/files/ci/compliance-evidence.yml.template +234 -49
- package/sdlc/files/ci/feature-e2e.yml.template +84 -1
- package/sdlc/files/ci/post-deploy-prod.yml.template +59 -4
- package/sdlc/files/ci/python/ci.yml.template +60 -12
- package/sdlc/files/ci/quality-gates-provenance.yml.template +123 -28
- package/sdlc/package.json +1 -1
- package/sdlc/src/bin/devaudit-sdlc.js +44 -2
- package/sdlc/src/blueprints/1-plan-requirement.raw.md +6 -1
- package/sdlc/src/blueprints/2-implement-and-test.raw.md +1 -1
- package/sdlc/src/blueprints/3-compile-evidence.raw.md +102 -20
- package/sdlc/src/blueprints/4-submit-for-review.raw.md +3 -3
- package/sdlc/src/blueprints/5-deploy-main.raw.md +2 -2
|
@@ -126,6 +126,7 @@ make_fixture "$WORKDIR/case3" "Ref: REQ-030"
|
|
|
126
126
|
mkdir -p compliance/evidence/REQ-030
|
|
127
127
|
echo "scope" > compliance/evidence/REQ-030/test-scope.md
|
|
128
128
|
echo "plan" > compliance/evidence/REQ-030/test-plan.md
|
|
129
|
+
echo "summary" > compliance/evidence/REQ-030/test-execution-summary.md
|
|
129
130
|
touch compliance/pending-releases/RELEASE-TICKET-REQ-030.md
|
|
130
131
|
git add . && git commit -q --amend --no-edit
|
|
131
132
|
run_validator
|
|
@@ -147,6 +148,7 @@ make_fixture "$WORKDIR/case4" "Ref: REQ-031"
|
|
|
147
148
|
mkdir -p compliance/evidence/REQ-031
|
|
148
149
|
echo "scope" > compliance/evidence/REQ-031/test-scope.md
|
|
149
150
|
echo "plan" > compliance/evidence/REQ-031/test-plan.md
|
|
151
|
+
echo "summary" > compliance/evidence/REQ-031/test-execution-summary.md
|
|
150
152
|
# Only the superseded location — neither pending- nor approved-releases.
|
|
151
153
|
touch compliance/superseded-releases/RELEASE-TICKET-REQ-031.md
|
|
152
154
|
git add . && git commit -q --amend --no-edit
|
|
@@ -252,8 +254,175 @@ assert_grep "no evidence-dir ERROR for prose-only REQ-002" 'ERROR: Evidence dire
|
|
|
252
254
|
assert_exit "validator exits 0 when future REQ is only prose-mentioned" 0
|
|
253
255
|
cd "$WORKDIR"
|
|
254
256
|
|
|
257
|
+
# --- case 8: tracked REQ without test-execution-summary fails ---
|
|
258
|
+
#
|
|
259
|
+
# Regression for devaudit-installer#341: tracked releases must not pass
|
|
260
|
+
# validation without the per-release test report that satisfies the
|
|
261
|
+
# portal's Test Reports gate.
|
|
262
|
+
|
|
263
|
+
echo "Case 8: tracked REQ missing test-execution-summary fails"
|
|
264
|
+
make_fixture "$WORKDIR/case8" "Ref: REQ-341"
|
|
265
|
+
{
|
|
266
|
+
echo '# RTM'
|
|
267
|
+
echo
|
|
268
|
+
echo '| ID | Description | Status |'
|
|
269
|
+
echo '| --- | --- | --- |'
|
|
270
|
+
echo '| REQ-341 | Missing test summary | TESTED - PENDING SIGN-OFF |'
|
|
271
|
+
} > compliance/RTM.md
|
|
272
|
+
mkdir -p compliance/evidence/REQ-341
|
|
273
|
+
echo "scope" > compliance/evidence/REQ-341/test-scope.md
|
|
274
|
+
echo "plan" > compliance/evidence/REQ-341/test-plan.md
|
|
275
|
+
touch compliance/pending-releases/RELEASE-TICKET-REQ-341.md
|
|
276
|
+
git add . && git commit -q --amend --no-edit
|
|
277
|
+
run_validator
|
|
278
|
+
assert_grep "missing-summary ERROR emitted" 'ERROR: Test execution summary missing: compliance/evidence/REQ-341/test-execution-summary.md' 1
|
|
279
|
+
assert_exit "validator exits 1 when tracked REQ lacks test-execution-summary" 1
|
|
280
|
+
cd "$WORKDIR"
|
|
281
|
+
|
|
255
282
|
# --- summary ---
|
|
256
283
|
|
|
284
|
+
# --- case 9: bundled release context missing from canonical artefacts fails ---
|
|
285
|
+
echo "Case 9: bundled release artefacts without context headings fail"
|
|
286
|
+
make_fixture "$WORKDIR/case9" "Ref: REQ-344"
|
|
287
|
+
{
|
|
288
|
+
echo '# RTM'
|
|
289
|
+
echo
|
|
290
|
+
echo '| ID | Description | Status |'
|
|
291
|
+
echo '| --- | --- | --- |'
|
|
292
|
+
echo '| REQ-344 | Bundled release context missing | TESTED - PENDING SIGN-OFF |'
|
|
293
|
+
} > compliance/RTM.md
|
|
294
|
+
mkdir -p compliance/evidence/REQ-344
|
|
295
|
+
echo "scope" > compliance/evidence/REQ-344/test-scope.md
|
|
296
|
+
echo "plan" > compliance/evidence/REQ-344/test-plan.md
|
|
297
|
+
echo "summary" > compliance/evidence/REQ-344/test-execution-summary.md
|
|
298
|
+
echo "security" > compliance/evidence/REQ-344/security-summary.md
|
|
299
|
+
echo "ai note" > compliance/evidence/REQ-344/ai-use-note.md
|
|
300
|
+
cat > compliance/pending-releases/RELEASE-TICKET-REQ-344.md <<'EOF'
|
|
301
|
+
# Release Ticket — REQ-344
|
|
302
|
+
|
|
303
|
+
## Summary
|
|
304
|
+
Tracked release without bundle section.
|
|
305
|
+
EOF
|
|
306
|
+
echo "## Bundled Changes" > compliance/pending-releases/BUNDLED-CHANGES-REQ-344.md
|
|
307
|
+
git add . && git commit -q --amend --no-edit
|
|
308
|
+
run_validator
|
|
309
|
+
assert_grep "missing bundled manifest is reported" "ERROR: Bundled release evidence exists but BUNDLED-CHANGES-REQ-344.json is missing" 1
|
|
310
|
+
assert_grep "missing structured fields on bundled evidence are reported" "ERROR: Bundled release evidence is missing bundled field '\\*\\*Core tracked release:\\*\\*'" 1
|
|
311
|
+
assert_grep "missing structured fields on ticket are reported" "ERROR: Release ticket is missing bundled field '\\*\\*Core tracked release:\\*\\*'" 1
|
|
312
|
+
assert_grep "missing bundled section on ticket is reported" "ERROR: Bundled release evidence exists but the release ticket is missing" 1
|
|
313
|
+
assert_grep "missing bundled section on summary is reported" "ERROR: Bundled release evidence exists but test-execution-summary.md is missing" 1
|
|
314
|
+
assert_grep "missing bundled section on security summary is reported" "ERROR: Bundled release evidence exists but security-summary.md is missing" 1
|
|
315
|
+
assert_grep "missing bundled section on ai note is reported" "ERROR: Bundled release evidence exists but ai-use-note.md is missing" 1
|
|
316
|
+
assert_exit "validator exits 1 when bundled artefacts lack required headings" 1
|
|
317
|
+
cd "$WORKDIR"
|
|
318
|
+
|
|
319
|
+
# --- case 10: bundled release context present in canonical artefacts passes ---
|
|
320
|
+
echo "Case 10: bundled release artefacts with context headings pass"
|
|
321
|
+
make_fixture "$WORKDIR/case10" "Ref: REQ-345"
|
|
322
|
+
{
|
|
323
|
+
echo '# RTM'
|
|
324
|
+
echo
|
|
325
|
+
echo '| ID | Description | Status |'
|
|
326
|
+
echo '| --- | --- | --- |'
|
|
327
|
+
echo '| REQ-345 | Bundled release context present | TESTED - PENDING SIGN-OFF |'
|
|
328
|
+
} > compliance/RTM.md
|
|
329
|
+
mkdir -p compliance/evidence/REQ-345
|
|
330
|
+
echo "scope" > compliance/evidence/REQ-345/test-scope.md
|
|
331
|
+
echo "plan" > compliance/evidence/REQ-345/test-plan.md
|
|
332
|
+
cat > compliance/evidence/REQ-345/test-execution-summary.md <<'EOF'
|
|
333
|
+
# Test Execution Summary — REQ-345
|
|
334
|
+
|
|
335
|
+
## Bundled Release Context
|
|
336
|
+
- **Core tracked release:** REQ-345
|
|
337
|
+
- **Absorbed predecessor releases:** None
|
|
338
|
+
- **Absorbed non-release work:** housekeeping syncs only
|
|
339
|
+
- **Why bundled here:** housekeeping consolidation
|
|
340
|
+
- **Evidence impact:** core REQ proof unchanged; gate evidence covers full develop state
|
|
341
|
+
- **Reviewer impact:** reviewer is approving the tracked REQ plus absorbed housekeeping context
|
|
342
|
+
- **Security / risk impact:** None beyond core REQ
|
|
343
|
+
- **Reference:** compliance/pending-releases/BUNDLED-CHANGES-REQ-345.md
|
|
344
|
+
EOF
|
|
345
|
+
cat > compliance/evidence/REQ-345/security-summary.md <<'EOF'
|
|
346
|
+
# Security Summary — REQ-345
|
|
347
|
+
|
|
348
|
+
## Bundled Release Context
|
|
349
|
+
- **Core tracked release:** REQ-345
|
|
350
|
+
- **Absorbed predecessor releases:** None
|
|
351
|
+
- **Absorbed non-release work:** housekeeping syncs only
|
|
352
|
+
- **Why bundled here:** housekeeping consolidation
|
|
353
|
+
- **Evidence impact:** no extra security evidence beyond the shared gate outputs
|
|
354
|
+
- **Reviewer impact:** reviewer should treat the shared gate results as covering the absorbed housekeeping work too
|
|
355
|
+
- **Security / risk impact:** None beyond core REQ
|
|
356
|
+
- **Reference:** compliance/pending-releases/BUNDLED-CHANGES-REQ-345.md
|
|
357
|
+
EOF
|
|
358
|
+
cat > compliance/evidence/REQ-345/ai-use-note.md <<'EOF'
|
|
359
|
+
# AI Use Record — REQ-345
|
|
360
|
+
|
|
361
|
+
## Bundled Release Context
|
|
362
|
+
- **Core tracked release:** REQ-345
|
|
363
|
+
- **Absorbed predecessor releases:** None
|
|
364
|
+
- **Absorbed non-release work:** housekeeping syncs only
|
|
365
|
+
- **Why bundled here:** housekeeping consolidation
|
|
366
|
+
- **Evidence impact:** no AI-generated evidence split beyond the shared bundle context
|
|
367
|
+
- **Reviewer impact:** reviewer should read the bundle note as part of the approval scope
|
|
368
|
+
- **Security / risk impact:** None beyond core REQ
|
|
369
|
+
- **Reference:** compliance/pending-releases/BUNDLED-CHANGES-REQ-345.md
|
|
370
|
+
EOF
|
|
371
|
+
cat > compliance/pending-releases/RELEASE-TICKET-REQ-345.md <<'EOF'
|
|
372
|
+
# Release Ticket — REQ-345
|
|
373
|
+
|
|
374
|
+
## Summary
|
|
375
|
+
Tracked release with bundle section.
|
|
376
|
+
|
|
377
|
+
## Bundled Changes
|
|
378
|
+
- **Core tracked release:** REQ-345
|
|
379
|
+
- **Absorbed predecessor releases:** None
|
|
380
|
+
- **Absorbed non-release work:** housekeeping syncs only
|
|
381
|
+
- **Why bundled here:** housekeeping consolidation
|
|
382
|
+
- **Evidence impact:** gate evidence and release reports include the absorbed housekeeping changes
|
|
383
|
+
- **Reviewer impact:** approval scope is the tracked REQ plus the absorbed housekeeping context
|
|
384
|
+
- **Security / risk impact:** None beyond core REQ
|
|
385
|
+
- **Reference:** compliance/pending-releases/BUNDLED-CHANGES-REQ-345.md
|
|
386
|
+
EOF
|
|
387
|
+
cat > compliance/pending-releases/BUNDLED-CHANGES-REQ-345.md <<'EOF'
|
|
388
|
+
## Bundled Changes
|
|
389
|
+
|
|
390
|
+
- **Core tracked release:** `REQ-345`
|
|
391
|
+
- **Bundle manifest:** `BUNDLED-CHANGES-REQ-345.json`
|
|
392
|
+
- **Manifest hash:** `sha256:test-bundle-hash`
|
|
393
|
+
- **Absorbed predecessor releases:** None
|
|
394
|
+
- **Absorbed non-release work:** housekeeping syncs only
|
|
395
|
+
- **Why bundled here:** housekeeping consolidation
|
|
396
|
+
- **Evidence impact:** gate evidence and release reports include the absorbed housekeeping changes
|
|
397
|
+
- **Reviewer impact:** approval scope is the tracked REQ plus the absorbed housekeeping context
|
|
398
|
+
- **Security / risk impact:** None beyond core REQ
|
|
399
|
+
- **Reference:** commit range `abc123..HEAD`
|
|
400
|
+
|
|
401
|
+
### Absorbed Non-Release Work
|
|
402
|
+
|
|
403
|
+
- `abc123` chore: sync templates
|
|
404
|
+
EOF
|
|
405
|
+
cat > compliance/pending-releases/BUNDLED-CHANGES-REQ-345.json <<'EOF'
|
|
406
|
+
{
|
|
407
|
+
"schemaVersion": 1,
|
|
408
|
+
"approvalRelease": { "version": "REQ-345" },
|
|
409
|
+
"coreRelease": { "version": "REQ-345" },
|
|
410
|
+
"members": [],
|
|
411
|
+
"nonReleaseWorkItems": [],
|
|
412
|
+
"manifestHash": "sha256:test-bundle-hash"
|
|
413
|
+
}
|
|
414
|
+
EOF
|
|
415
|
+
git add . && git commit -q --amend --no-edit
|
|
416
|
+
run_validator
|
|
417
|
+
assert_grep "bundled manifest accepted" "OK: Bundled release manifest present: compliance/pending-releases/BUNDLED-CHANGES-REQ-345.json" 1
|
|
418
|
+
assert_grep "bundled ticket section accepted" "OK: Release ticket documents bundled release context" 1
|
|
419
|
+
assert_grep "bundled test summary section accepted" "OK: test-execution-summary.md documents bundled release context" 1
|
|
420
|
+
assert_grep "bundled security summary section accepted" "OK: security-summary.md documents bundled release context" 1
|
|
421
|
+
assert_grep "bundled ai note section accepted" "OK: ai-use-note.md documents bundled release context" 1
|
|
422
|
+
assert_grep "structured bundled evidence accepted" "OK: Bundled release evidence carries the required structured fields" 1
|
|
423
|
+
assert_exit "validator exits 0 when bundled artefacts carry required headings" 0
|
|
424
|
+
cd "$WORKDIR"
|
|
425
|
+
|
|
257
426
|
echo
|
|
258
427
|
echo "=== validate-compliance-artifacts.test.sh: $PASS passed, $FAIL failed ==="
|
|
259
428
|
[ "$FAIL" -eq 0 ]
|
|
@@ -182,7 +182,7 @@ make_fixture "$D6" "REQ-006" << 'EOF'
|
|
|
182
182
|
## Accepted skips
|
|
183
183
|
|
|
184
184
|
| Spec | Test | REQ/AC | Classification | Resolution attempted | Approved by | Rationale |
|
|
185
|
-
|
|
185
|
+
| ------ | ------ | -------- | --------------- | --------------------- | ------------- | ---------- |
|
|
186
186
|
| e2e/foo.spec.ts | "AC1: bar dialog" | REQ-006/AC1 | intentional_non_applicability | N/A — API-only change | operator | API-only change, no UI surface |
|
|
187
187
|
|
|
188
188
|
**Final assessment:** All gates passed. E2E skipped — API-only change.
|
|
@@ -279,7 +279,7 @@ make_fixture "$D12" "REQ-012" << 'EOF'
|
|
|
279
279
|
## Accepted skips
|
|
280
280
|
|
|
281
281
|
| Spec | Test | REQ/AC | Classification | Resolution attempted | Approved by | Rationale |
|
|
282
|
-
|
|
282
|
+
| ------ | ------ | -------- | --------------- | --------------------- | ------------- | ---------- |
|
|
283
283
|
| e2e/foo.spec.ts | "AC3: bar dialog" | REQ-012/AC3 | intentional_non_applicability | N/A — API-only change | operator | API-only change, no UI surface |
|
|
284
284
|
|
|
285
285
|
**Final assessment:** All gates passed. E2E skipped — API-only change.
|
|
@@ -317,7 +317,7 @@ make_fixture "$D14" "REQ-014" << 'EOF'
|
|
|
317
317
|
## Accepted skips
|
|
318
318
|
|
|
319
319
|
| Spec | Test | REQ/AC | Classification | Resolution attempted | Approved by | Rationale |
|
|
320
|
-
|
|
320
|
+
| ------ | ------ | -------- | --------------- | --------------------- | ------------- | ---------- |
|
|
321
321
|
|
|
322
322
|
**Final assessment:** All gates passed. E2E skipped — API-only change.
|
|
323
323
|
EOF
|
|
@@ -338,7 +338,7 @@ make_fixture "$D15" "REQ-015" << 'EOF'
|
|
|
338
338
|
## Accepted skips
|
|
339
339
|
|
|
340
340
|
| Spec | Test | REQ/AC | Classification | Resolution attempted | Approved by | Rationale |
|
|
341
|
-
|
|
341
|
+
| ------ | ------ | -------- | --------------- | --------------------- | ------------- | ---------- |
|
|
342
342
|
| e2e/foo.spec.ts | "AC3: bar dialog" | REQ-015/AC3 | intentional_non_applicability | N/A — API-only change | | API-only change, no UI surface |
|
|
343
343
|
|
|
344
344
|
**Final assessment:** All gates passed. E2E skipped — API-only change.
|
|
@@ -12,7 +12,7 @@ The skill is **Phase A scope** (per [DevAudit-Installer#120](https://github.com/
|
|
|
12
12
|
## What this skill owns
|
|
13
13
|
|
|
14
14
|
| Artefact | Lives at | Tier |
|
|
15
|
-
|
|
15
|
+
| --- | --- | --- |
|
|
16
16
|
| `docs/ADR/ADR-NNN-<slug>.md` (the SoT, project-spanning) | Top-level project docs | 2 (project strategy) |
|
|
17
17
|
| `compliance/evidence/REQ-XXX/architecture-decision.md` (per-REQ Tier 3 evidence) | Per-REQ evidence directory | 3 (per-REQ) |
|
|
18
18
|
|
|
@@ -57,7 +57,7 @@ Input: the REQ's `compliance/plans/REQ-XXX/implementation-plan.md` plus the work
|
|
|
57
57
|
**Step 2 — Apply the ADR-worthiness decision tree.** The skill judges *architectural significance* via these signals — any one matching ⇒ ADR warranted:
|
|
58
58
|
|
|
59
59
|
| Signal | Examples | Verdict |
|
|
60
|
-
|
|
60
|
+
| --- | --- | --- |
|
|
61
61
|
| New third-party runtime dependency | adding `redis`, `bull`, a new ORM, a new auth provider package | ADR |
|
|
62
62
|
| New external service | introducing Stripe, Twilio, a new SaaS integration | ADR |
|
|
63
63
|
| New database / cache / queue tier | adding Redis alongside Postgres, swapping MongoDB for Postgres | ADR |
|
|
@@ -136,7 +136,7 @@ For each scenario, write a one-line description. Present the full grouped list t
|
|
|
136
136
|
When designing each scenario, also pick the tier it'll live in. Three tiers map to MoSCoW priority + gating point (see `Test_Strategy.md` § *E2E gating model*):
|
|
137
137
|
|
|
138
138
|
| Tier | File location | Picks this when… |
|
|
139
|
-
|
|
139
|
+
| --- | --- | --- |
|
|
140
140
|
| **smoke** | `e2e/smoke/*.spec.ts` | Cross-cutting sanity that proves the app is up: login, basic nav, one canonical CRUD per main domain. Runs on every push to the integration branch. Keep small — total smoke wall-clock target is ~3–5 min. |
|
|
141
141
|
| **critical** | `e2e/critical/*.spec.ts` | Must-priority SRS item that breaks a headline flow if it regresses. Examples: payment authorisation, order completion, admin permission editing, RBAC enforcement on financial surfaces. Runs on PR-to-release-branch. Total critical wall-clock target ~10–15 min (includes smoke). |
|
|
142
142
|
| **regression** | `e2e/<area>/*.spec.ts` | Should/Could-priority SRS item, edge cases, less-load-bearing flows. Runs nightly + post-merge + dispatch. Total full pack can be 30+ min; that's the point of the tier. |
|
|
@@ -365,7 +365,7 @@ Every defect filed from Phase 6 becomes `incident_report` evidence when (a) the
|
|
|
365
365
|
Classify the defect against this table when filing — the canonical version lives at `governance-doc-author/references/incident-classification.md`, mirrored here for the e2e workflow:
|
|
366
366
|
|
|
367
367
|
| Defect characteristic | Frameworks/clauses attributed |
|
|
368
|
-
|
|
368
|
+
| --- | --- |
|
|
369
369
|
| **Any test failure / defect** (baseline — always) | `ISO29119.3.5.4` Test incident report |
|
|
370
370
|
| **Ops impact** (downtime, persistent errors, perf regression, data corruption) | + `SOC2.CC7.2` System monitoring and incident response |
|
|
371
371
|
| **Security vulnerability** (auth bypass, injection, data exposure) | + `SOC2.CC7.2` + relevant ISO 27001 controls |
|
|
@@ -20,7 +20,7 @@ Recommend a primary, mention the runner-up, get user confirmation before install
|
|
|
20
20
|
### Web apps — JavaScript / TypeScript
|
|
21
21
|
|
|
22
22
|
| Stack | Primary | Runner-up | Rationale |
|
|
23
|
-
|
|
23
|
+
| --- | --- | --- | --- |
|
|
24
24
|
| React / Next.js / Remix | **Playwright** | Cypress | Fast, parallel by default, multi-browser, first-party TS, built-in visual regression, excellent trace viewer. |
|
|
25
25
|
| Vue / Nuxt | **Playwright** | Cypress | Same reasons. |
|
|
26
26
|
| Angular | **Playwright** | Cypress | Playwright has overtaken Cypress as the Angular community default; Cypress still common in established Angular shops. |
|
|
@@ -32,7 +32,7 @@ Recommend a primary, mention the runner-up, get user confirmation before install
|
|
|
32
32
|
### Mobile
|
|
33
33
|
|
|
34
34
|
| Stack | Primary | Runner-up | Rationale |
|
|
35
|
-
|
|
35
|
+
| --- | --- | --- | --- |
|
|
36
36
|
| React Native | **Detox** | Appium | Native, fast, integrates with RN test infra. |
|
|
37
37
|
| Native iOS / Android cross-platform | **Appium** | Maestro | Industry standard; Maestro is gaining popularity for simpler flows. |
|
|
38
38
|
| Mobile web | **Playwright** (mobile emulation) | Appium (for real-device need) | Playwright covers viewport + UA emulation; Appium for real-device touch interactions. |
|
|
@@ -40,14 +40,14 @@ Recommend a primary, mention the runner-up, get user confirmation before install
|
|
|
40
40
|
### Desktop
|
|
41
41
|
|
|
42
42
|
| Stack | Primary | Runner-up | Rationale |
|
|
43
|
-
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
44
|
| Electron | **Playwright** | WebdriverIO + Electron service | Playwright has first-party Electron support. |
|
|
45
45
|
| Tauri | **WebdriverIO** + Tauri driver | — | Official path. |
|
|
46
46
|
|
|
47
47
|
### Backend-rendered / non-JS web apps
|
|
48
48
|
|
|
49
49
|
| Stack | Primary | Runner-up | Rationale |
|
|
50
|
-
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
51
|
| Python (Django, Flask, FastAPI with templates) | **pytest-playwright** | Selenium + pytest | Same Playwright engine, idiomatic for Python test suites. |
|
|
52
52
|
| Ruby on Rails | **Capybara + Cuprite** | Capybara + Selenium | Cuprite uses CDP, faster than Selenium. |
|
|
53
53
|
| Java (Spring etc.) | **Playwright for Java** | Selenium + JUnit/TestNG | Playwright Java is mature; Selenium still dominant in enterprise Java. |
|
|
@@ -67,7 +67,7 @@ Recommend a primary, mention the runner-up, get user confirmation before install
|
|
|
67
67
|
Only add visual regression if the user asked for it or the originating issue is visually significant. Default off for greenfield bootstrap unless explicitly requested.
|
|
68
68
|
|
|
69
69
|
| Need | Recommendation | Notes |
|
|
70
|
-
|
|
70
|
+
| --- | --- | --- |
|
|
71
71
|
| Default for Playwright | **`toHaveScreenshot()` built-in** | Zero extra deps; baselines stored in repo. Configure `threshold` and `maxDiffPixels`. |
|
|
72
72
|
| Default for Cypress | **`cypress-image-snapshot`** | Or `cypress-visual-regression`. Both store baselines in repo. |
|
|
73
73
|
| Default for WebdriverIO | **`@wdio/visual-service`** | Maintained, image-comparison-based. |
|
package/sdlc/files/_common/skills/governance-doc-author/references/incident-classification.md
CHANGED
|
@@ -7,7 +7,7 @@ Used by both `e2e-test-engineer` (when filing defects) and `governance-doc-autho
|
|
|
7
7
|
Every `incident_report` evidence row closes `ISO29119.3.5.4` (baseline). Additional clauses depend on the incident's scope.
|
|
8
8
|
|
|
9
9
|
| Defect / incident characteristic | Frameworks/clauses attributed |
|
|
10
|
-
|
|
10
|
+
| --- | --- |
|
|
11
11
|
| **Any test failure / defect** (baseline — always) | `ISO29119.3.5.4` Test incident report |
|
|
12
12
|
| **Ops impact** (downtime, persistent errors, perf regression, data corruption) | + `SOC2.CC7.2` System monitoring and incident response |
|
|
13
13
|
| **Security vulnerability** (auth bypass, injection, data exposure beyond GDPR scope) | + `SOC2.CC7.2` + relevant ISO 27001 controls |
|
|
@@ -12,7 +12,7 @@ The skill is **Phase A scope** (per [DevAudit-Installer#119](https://github.com/
|
|
|
12
12
|
## What this skill owns
|
|
13
13
|
|
|
14
14
|
| Artefact | Lives at | Tier |
|
|
15
|
-
|
|
15
|
+
| --- | --- | --- |
|
|
16
16
|
| `docs/SRS.md` (the SoT, project-spanning) | Top-level project docs | 2 (project strategy) |
|
|
17
17
|
| `compliance/evidence/REQ-XXX/srs-alignment.md` (per-REQ Tier 3 evidence) | Per-REQ evidence directory | 3 (per-REQ) |
|
|
18
18
|
|
|
@@ -65,7 +65,7 @@ Input: the REQ's `compliance/plans/REQ-XXX/implementation-plan.md` plus the work
|
|
|
65
65
|
**Step 3 — Categorise each AC:**
|
|
66
66
|
|
|
67
67
|
| AC ⇒ SRS state | Action |
|
|
68
|
-
|
|
68
|
+
| --- | --- |
|
|
69
69
|
| **Exact match** — AC traces 1:1 to an existing SRS item, no behavioural delta | Record the mapping; no SRS edit needed |
|
|
70
70
|
| **Match + drift** — existing SRS item covers the AC's surface but the behaviour has shifted (e.g. new field, new edge case, new error path) | Flag the item as *potentially stale*; the plan must mark it for update in this cycle OR justify why the SRS prose still covers it |
|
|
71
71
|
| **No match** — AC introduces behaviour the SRS doesn't yet describe | Propose new `REQ-AREA-NNN` (next free ID per area — see Step 4) with a Given/When/Then stub the operator edits |
|
|
@@ -79,7 +79,7 @@ Input: the REQ's `compliance/plans/REQ-XXX/implementation-plan.md` plus the work
|
|
|
79
79
|
## SRS items proposed/touched
|
|
80
80
|
|
|
81
81
|
| AC | SRS item | Status | Notes |
|
|
82
|
-
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
83
|
| AC1 | REQ-ORDER-005 (existing) | unchanged | Trace-only |
|
|
84
84
|
| AC2 | REQ-INV-010 (new — proposed) | stub | <one-line behaviour description> |
|
|
85
85
|
| AC3 | REQ-INV-011 (new — proposed) | stub | <one-line> |
|
|
@@ -113,7 +113,7 @@ generated_at: <ISO timestamp>
|
|
|
113
113
|
## ACs traced
|
|
114
114
|
|
|
115
115
|
| AC | SRS item | Action this cycle |
|
|
116
|
-
|
|
116
|
+
| --- | --- | --- |
|
|
117
117
|
| AC1 | REQ-ORDER-005 | unchanged |
|
|
118
118
|
| AC2 | REQ-INV-010 | added (new — see Phase 1 stub) |
|
|
119
119
|
| AC3 | REQ-INV-011 | added (new) |
|
|
@@ -385,7 +385,7 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
|
|
|
385
385
|
- **`requirements-aligner` fails** (e.g. no `docs/SRS.md`): If `block_on_stage_1` is true, halt — "requirements-aligner could not find SRS.md. Operator action — create `docs/SRS.md` or disable `requirements_aligner.block_on_stage_1` in `sdlc-config.json`." If false, warn and continue with `@srs-deferred` on all ACs.
|
|
386
386
|
- **`adr-author` fails**: Warn and continue — ADR is advisory by default. Mark the plan's "Architecture decisions" section as "ADR assessment skipped — <error>".
|
|
387
387
|
- **`risk-register-keeper` fails**: If `block_on_stage_1` is true, halt. If false, warn and continue — mark the plan's "Risk register entries" section as "Risk assessment skipped — <error>".
|
|
388
|
-
9. **Update `compliance/RTM.md`** with the new entry: REQ-XXX, title, risk class, linked issue, linked test cases (placeholder), and a provenance marker `sdlc-implementer@<version>` (devaudit-installer#226). The provenance column is the last column in the RTM row — `validate-commits.sh` in CI checks for its presence when `feat`/`fix`/`refactor`/`perf` commits cite a REQ-XXX. Without the stamp, CI fails with "no sdlc-implementer provenance in RTM.md." If the RTM table doesn't have a provenance column, add one with header `Provenance`.
|
|
388
|
+
9. **Update `compliance/RTM.md`** with the new entry: REQ-XXX, title, risk class, linked issue, linked test cases (placeholder), and a provenance marker `sdlc-implementer@<version>` (devaudit-installer#226). The provenance column is the last column in the RTM row — `validate-commits.sh` in CI checks for its presence when `feat`/`fix`/`refactor`/`perf` commits cite a REQ-XXX. Without the stamp, CI fails with "no sdlc-implementer provenance in RTM.md." If the RTM table doesn't have a provenance column, add one with header `Provenance`. If any RTM cell text needs literal pipe characters (regexes, enum examples, status notes), escape them as `\|` rather than writing bare `|`, otherwise markdownlint will misparse the row as extra columns.
|
|
389
389
|
10. **Post plan summary as an issue comment.** Format: TL;DR; Risk class + signals; Acceptance criteria (with SRS-IDs); Architectural decisions (ADR-NNN reference or no-ADR rationale); Risk register entries (RISK-NNN list); Technical approach (one paragraph); Dependencies; Test scope.
|
|
390
390
|
11. **Checkpoint** — pause for human approval **iff** risk class is HIGH or CRITICAL. LOW and MEDIUM pass through to Phase 2 automatically. The checkpoint can be forced on for all classes via the `--require-plan-approval` flag (or `DEVAUDIT_REQUIRE_PLAN_APPROVAL=1` env var) for orgs that want it always-on.
|
|
391
391
|
12. **Update SDLC status sticky** before exiting Phase 1: `bash scripts/update-sdlc-status.sh "$ISSUE_NUM" "Phase 1 complete — plan written to compliance/plans/REQ-XXX/implementation-plan.md (risk class <CLASS>)" "Phase 2 — sdlc-implementer auto-continuing"` (or "Operator action — review plan + ping resume" if the HIGH/CRITICAL checkpoint paused).
|
|
@@ -511,6 +511,59 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
|
|
|
511
511
|
|
|
512
512
|
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.
|
|
513
513
|
|
|
514
|
+
5bb. **Render the Test Cycles table from the portal's cycle read model when available (devaudit-installer#394).** Do not hand-build cycle rows from uploaded artefacts if the portal exposes first-class cycle records. Query the release-journey / cycle API, save the JSON, and render the markdown table with:
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
bash scripts/render-test-cycles.sh /tmp/release-journey.json
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
First-class rows must preserve:
|
|
521
|
+
- source release
|
|
522
|
+
- SDLC stage
|
|
523
|
+
- cycle ordinal within that source release + stage
|
|
524
|
+
- cycle kind / outcome
|
|
525
|
+
- workflow or run link
|
|
526
|
+
- related evidence
|
|
527
|
+
- incident or remediation reference
|
|
528
|
+
|
|
529
|
+
If the portal does not yet expose first-class cycles, the same helper emits the legacy `testCycleId` grouping fallback and labels it as such. Keep the fallback note in the final `test-execution-summary.md`; it is part of the audit trail during rollout.
|
|
530
|
+
|
|
531
|
+
5c. **Run the Phase 3 completion guard before any PR/release-review step (devaudit-installer#341).** The tracked-release evidence pack is incomplete until the required Git artefacts exist. Before proceeding past Phase 3, verify:
|
|
532
|
+
|
|
533
|
+
- `compliance/evidence/REQ-XXX/test-scope.md`
|
|
534
|
+
- `compliance/evidence/REQ-XXX/test-plan.md`
|
|
535
|
+
- `compliance/evidence/REQ-XXX/test-execution-summary.md`
|
|
536
|
+
- `compliance/evidence/REQ-XXX/security-summary.md`
|
|
537
|
+
- `compliance/pending-releases/RELEASE-TICKET-REQ-XXX.md`
|
|
538
|
+
- `compliance/evidence/REQ-XXX/implementation-plan.md` when the REQ risk class requires it
|
|
539
|
+
- any already-mandatory AI artefacts required by the risk/usage rules
|
|
540
|
+
- if `compliance/pending-releases/BUNDLED-CHANGES-REQ-XXX.md` exists, regenerate the paired JSON manifest too and keep both aligned with the current approval scope
|
|
541
|
+
- if `compliance/pending-releases/BUNDLED-CHANGES-REQ-XXX.md` exists, the canonical artefacts must carry the bundle narrative too:
|
|
542
|
+
- release ticket includes `## Bundled Changes` or `## Absorbed Predecessor Releases`
|
|
543
|
+
- `test-execution-summary.md` includes `## Bundled Release Context`
|
|
544
|
+
- `security-summary.md` includes `## Bundled Release Context`
|
|
545
|
+
- `ai-use-note.md` includes `## Bundled Release Context` when AI use is documented
|
|
546
|
+
|
|
547
|
+
Run:
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
MISSING=0
|
|
551
|
+
for f in \
|
|
552
|
+
compliance/evidence/REQ-XXX/test-scope.md \
|
|
553
|
+
compliance/evidence/REQ-XXX/test-plan.md \
|
|
554
|
+
compliance/evidence/REQ-XXX/test-execution-summary.md \
|
|
555
|
+
compliance/evidence/REQ-XXX/security-summary.md \
|
|
556
|
+
compliance/pending-releases/RELEASE-TICKET-REQ-XXX.md
|
|
557
|
+
do
|
|
558
|
+
[ -f "$f" ] || { echo "MISSING: $f"; MISSING=1; }
|
|
559
|
+
done
|
|
560
|
+
[ "$MISSING" -eq 0 ] || exit 1
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
If any required artefact is missing, halt with an explicit error and do **not** continue to Phase 4:
|
|
564
|
+
|
|
565
|
+
> "Phase 3 incomplete — `test-execution-summary.md` is missing. This file satisfies the portal's Test Reports gate (`evidence_type=test_report`). Create it before opening the release PR."
|
|
566
|
+
|
|
514
567
|
6. **Organise artefacts** under `compliance/evidence/REQ-XXX/` with date-prefixed naming:
|
|
515
568
|
|
|
516
569
|
```
|
|
@@ -601,7 +654,7 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
|
|
|
601
654
|
--base-url <devaudit-base-url>
|
|
602
655
|
```
|
|
603
656
|
|
|
604
|
-
The watcher persists retry state in `.sdlc-pr-watch.json`, polls `gh pr view` + `gh pr checks`, re-runs likely flaky workflows automatically, and re-runs the Release Approval Gate when the portal is already approved but GitHub has not converged yet. Use `--once` when you only need a single classification pass.
|
|
657
|
+
The watcher persists retry state in `.sdlc-pr-watch.json`, polls `gh pr view` + `gh pr checks`, re-runs likely flaky workflows automatically, and re-runs the Release Approval Gate when the portal is already approved but GitHub has not converged yet. For a release PR (`$INTEGRATION_BRANCH -> $RELEASE_BRANCH`), it must not call the PR green until the full required release check set has reached terminal success: `Quality Gates`, `Release Scope Integrity`, `Compliance Validation`, `DevAudit Release Approval`, and `E2E Regression Suite`. Use `--once` when you only need a single classification pass.
|
|
605
658
|
|
|
606
659
|
6. **Hard stop only after blocker classification.** Phase 4 ends here. Do not proceed to merge; the human's next action is reviewing on the portal or clearing the categorized blocker above.
|
|
607
660
|
7. **Update SDLC status sticky** before halting: `bash scripts/update-sdlc-status.sh "$ISSUE_NUM" "Phase 4 — truthful release PR #<N> prepared against $RELEASE_BRANCH; blockers classified" "Operator action — review PR #<N> + approve UAT release on the portal; sdlc-implementer halts until you ping resume REQ-XXX"`. This is a critical handoff — the sticky must reflect that the agent has stopped + the operator is on the hook.
|
|
@@ -620,7 +673,7 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
|
|
|
620
673
|
|
|
621
674
|
**Release Approval Gate retry (devaudit-installer#211 Gap 17).** If the Release Approval Gate check fails on the PR and the portal approval was already given (API sync delay, stale cache), retry logic: re-run the Release Approval Gate workflow up to 3 times with 30-second intervals (`gh workflow run check-release-approval.yml` or trigger via `workflow_dispatch`). If it still fails after 3 retries: halt — "Release Approval Gate still failing after 3 retries. Portal may show approval but the gate can't verify it. Operator action — check the portal release status manually, verify the API key is valid, and re-run the workflow from GitHub Actions if needed."
|
|
622
675
|
|
|
623
|
-
**Auto-refresh on UAT approval (devaudit#562, devaudit-installer#283).** When the portal's UAT approval is granted, the portal automatically sends a `repository_dispatch('release-approved')` event to the consuming project's repo. This triggers `check-release-approval.yml` to re-run without manual intervention. The retry logic above is still needed for edge cases (API sync delays, network issues), but the common path is now fully automated. If the auto-refresh doesn't fire (e.g. portal GitHub trigger misconfigured), the manual retry sequence above remains the fallback.
|
|
676
|
+
**Auto-refresh on UAT approval (devaudit#562, devaudit-installer#283, #351).** When the portal's UAT approval is granted, the portal automatically sends a `repository_dispatch('release-approved')` event to the consuming project's repo. This triggers `check-release-approval.yml` to re-run without manual intervention and create a fresh passing `DevAudit Release Approval` check run on the approved PR head SHA. The retry logic above is still needed for edge cases (API sync delays, network issues), but the common path is now fully automated. If the auto-refresh doesn't fire (e.g. portal GitHub trigger misconfigured), the manual retry sequence above remains the fallback.
|
|
624
677
|
|
|
625
678
|
### Phase 5 — Finalise or change-request loop (SDLC stage 5)
|
|
626
679
|
|
|
@@ -640,6 +693,7 @@ Invoked separately by the user after UAT activity on the portal. Trigger: "resum
|
|
|
640
693
|
- `gh pr merge <M> --merge` (merge commit; `--squash` and `--rebase` are blocked by branch protection on SDLC repos and would break the audit trail).
|
|
641
694
|
- **Before watching `post-deploy-prod.yml`**, verify the workflow exists and has triggered: `gh run list --workflow post-deploy-prod.yml --limit 1 --json status,conclusion`. If no run appears within 5 minutes of the merge, halt — "post-deploy-prod.yml did not trigger after merge. Check workflow configuration, secrets, and deployment platform. Operator action — run `gh workflow run post-deploy-prod.yml` manually, then ping `resume REQ-XXX`."
|
|
642
695
|
- Watch `post-deploy-prod.yml` via `gh run watch` — block until the workflow reaches a terminal state. Wrap in a timeout (30 minutes default, configurable via `sdlc-config.json:post_deploy.timeout_minutes`). If the timeout fires: halt — "post-deploy-prod.yml has not reached a terminal state in N minutes. The deployment may be stuck. Operator action — check hosting platform logs, decide whether to wait or rollback, then ping `resume REQ-XXX`."
|
|
696
|
+
- Treat `post-deploy-prod.yml` success as necessary but not sufficient. The workflow must also confirm the hosting platform's GitHub deployment status for the merged SHA reached terminal `success`. If the host deployment is still `queued` / `in_progress`, remain blocked. If it reaches `failure`, halt — "The host deployment for <sha> failed after merge. Do not approve Production or mark Released. Operator action — inspect hosting logs / rollback / resume once the production state is understood."
|
|
643
697
|
- Verify production smoke evidence uploaded (`--environment production`) at `https://devaudit.metasession.co/projects/<slug>/releases/<version>`.
|
|
644
698
|
- **Read `production_review.terminal_status` from `sdlc-config.json`** (default: `prod_review`). Branch:
|
|
645
699
|
- If `released` (Option B): PATCH directly to `released` — `PATCH /releases/<version>` with `{"status": "released"}`.
|
|
@@ -193,7 +193,7 @@ If the portal state is `uat_rejected` (not `uat_changes_requested`), the reviewe
|
|
|
193
193
|
The release ticket (`compliance/pending-releases/RELEASE-TICKET-REQ-XXX.md`) `**Status:**` field is updated at each transition in the change-request loop, mirroring the portal's state machine for audit trail completeness:
|
|
194
194
|
|
|
195
195
|
| Transition | Release ticket status |
|
|
196
|
-
|
|
196
|
+
| --- | --- |
|
|
197
197
|
| Entering iteration N | `CHANGES REQUESTED — ITERATION N` |
|
|
198
198
|
| After evidence re-compile (Step 5) | `TESTED - PENDING SIGN-OFF (ITERATION N)` |
|
|
199
199
|
| After UAT re-approval (Phase 5 happy path) | `APPROVED — READY FOR MERGE` |
|
|
@@ -8,8 +8,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
8
8
|
|
|
9
9
|
### 1. Never skip the UAT review gate
|
|
10
10
|
|
|
11
|
-
| | |
|
|
12
|
-
|---|---|
|
|
11
|
+
| | | | --- | --- |
|
|
13
12
|
| **What** | The skill must not attempt to merge a PR while the `DevAudit Release Approval` check is red. |
|
|
14
13
|
| **Why (framework)** | ISO 27001 A.8.32 (Change management); SOC 2 CC8 (Change management); EU AI Act Art. 14 (Human oversight). The UAT gate is the load-bearing human-oversight checkpoint. |
|
|
15
14
|
| **Enforcement** | Portal-side via `check-release-approval.yml` workflow status check + branch protection. Skill-side: never call `gh pr merge` until the check is green. |
|
|
@@ -17,8 +16,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
17
16
|
|
|
18
17
|
### 2. For HIGH/CRITICAL, never act as the UAT approver
|
|
19
18
|
|
|
20
|
-
| | |
|
|
21
|
-
|---|---|
|
|
19
|
+
| | | | --- | --- |
|
|
22
20
|
| **What** | The skill must verify at Phase 4 that the configured UAT reviewer (in `compliance/plans/REQ-XXX/implementation-plan.md` §Four-eyes attestation slot) differs from the skill-trigger user. If they match, halt. |
|
|
23
21
|
| **Why (framework)** | SOC 2 CC8.1 — segregation of duties; ISO 27001 A.5.15 (Access control — duty segregation). The change-author cannot also be the change-approver for higher-risk work. |
|
|
24
22
|
| **Enforcement** | Portal-side: the release-approval API rejects self-approval for MEDIUM/HIGH/CRITICAL risk classes. Skill-side: refuses to open the PR if the configured reviewer matches the trigger user. |
|
|
@@ -26,8 +24,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
26
24
|
|
|
27
25
|
### 3. Plan checkpoint mandatory for HIGH/CRITICAL
|
|
28
26
|
|
|
29
|
-
| | |
|
|
30
|
-
|---|---|
|
|
27
|
+
| | | | --- | --- |
|
|
31
28
|
| **What** | At Phase 1 step 8, the skill pauses for human approval of the plan **iff** risk class is HIGH or CRITICAL. LOW/MEDIUM pass through automatically. Can be forced on for all classes via `--require-plan-approval` flag or `DEVAUDIT_REQUIRE_PLAN_APPROVAL=1` env var. |
|
|
32
29
|
| **Why (framework)** | EU AI Act Art. 14 (Human oversight for high-risk AI systems); SOC 2 CC3 (Risk assessment requires human judgement); ISO 29119 §6 (Test management — planning is a documented human step). For HIGH/CRITICAL work the plan IS the design — human review must precede code. |
|
|
33
30
|
| **Enforcement** | Skill-side. Phase 1 explicitly halts and waits for the human's "go" before Phase 2. |
|
|
@@ -35,8 +32,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
35
32
|
|
|
36
33
|
### 4. Change-request loop triggers full UAT re-review
|
|
37
34
|
|
|
38
|
-
| | |
|
|
39
|
-
|---|---|
|
|
35
|
+
| | | | --- | --- |
|
|
40
36
|
| **What** | When new commits land on a PR after a UAT change-request, the portal's release-approval state resets. The skill respects the reset, surfaces a "UAT re-review needed" comment, and never assumes the prior approval still covers the new changes. |
|
|
41
37
|
| **Why (framework)** | ISO 27001 A.14.2.4 (Restrictions on changes to software packages — each change goes through controls); SOC 2 CC8.1 (Each change requires approval). Treating "approval given once, all subsequent commits inherit it" would make UAT a one-shot rubber-stamp. |
|
|
42
38
|
| **Enforcement** | Portal-side: the release-approval state machine resets on new commits to the linked branch. Skill-side: re-requests review explicitly via the portal API after each change-request iteration. |
|
|
@@ -44,8 +40,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
44
40
|
|
|
45
41
|
### 5. AI involvement disclosed on every commit
|
|
46
42
|
|
|
47
|
-
| | |
|
|
48
|
-
|---|---|
|
|
43
|
+
| | | | --- | --- |
|
|
49
44
|
| **What** | Every commit the skill creates carries a `Co-Authored-By: Claude <noreply@anthropic.com>` trailer (or equivalent for the specific Claude model in use). |
|
|
50
45
|
| **Why (framework)** | ISO 27001 — transparency norms; EU AI Act Art. 13 (Transparency and provision of information to deployers); GDPR Art. 22 (data subjects' right to know about automated decisions, where applicable). When an auditor traces a commit, the AI involvement must be visible. |
|
|
51
46
|
| **Enforcement** | Skill-side. Every `git commit` call includes the trailer. CI's `compliance-validation.yml` workflow can be configured to grep for `Co-Authored-By` on PRs labelled with the AI-touched marker; this is optional but recommended. |
|
|
@@ -53,8 +48,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
53
48
|
|
|
54
49
|
### 6. All portal mutations through audit-logged APIs
|
|
55
50
|
|
|
56
|
-
| | |
|
|
57
|
-
|---|---|
|
|
51
|
+
| | | | --- | --- |
|
|
58
52
|
| **What** | The skill calls `devaudit push` and the standard portal HTTP APIs — never a database back-channel, never a service-role-key-equivalent that bypasses the audit log. |
|
|
59
53
|
| **Why (framework)** | ISO 27001 A.12.4 (Logging and monitoring); SOC 2 CC4 + CC7 (Monitoring activities + system operations). Every action that affects compliance state must produce an audit-log entry attributable to a human identity (the user whose PAT is in `DEVAUDIT_USER_TOKEN`). |
|
|
60
54
|
| **Enforcement** | Skill-side. All portal interaction goes through `devaudit push` or `curl`/`gh api` against the documented REST endpoints. |
|
|
@@ -64,8 +58,7 @@ The constraints are enforced in `SKILL.md` and in the smoke pass. Where applicab
|
|
|
64
58
|
|
|
65
59
|
### 7. Rubber-stamping at UAT
|
|
66
60
|
|
|
67
|
-
| | |
|
|
68
|
-
|---|---|
|
|
61
|
+
| | | | --- | --- |
|
|
69
62
|
| **What** | If the UAT reviewer approves without actually reading the change, the controls are formally satisfied but substantively hollow. |
|
|
70
63
|
| **Why (framework)** | SOC 2 CC4.1 (Monitoring activities — the entity should detect this via its own QA sampling). Not enforced by any control mechanism; relies on human discipline. |
|
|
71
64
|
| **Enforcement** | Not architectural. Mitigations: the SKILL.md's Principles section names the UAT reviewer as "the load-bearing human"; the portal's UAT-review UI intentionally adds friction (no one-click approve from email); org policy should random-sample approvals for QA. |
|
|
@@ -255,7 +255,7 @@ jobs:
|
|
|
255
255
|
echo "::warning::Approved SHA (${APPROVED_SHA:0:8}) differs from PR HEAD (${PR_HEAD_SHA:0:8}). Code may have changed after approval."
|
|
256
256
|
fi
|
|
257
257
|
|
|
258
|
-
- name:
|
|
258
|
+
- name: Create refreshed PR check run (workflow_dispatch / repository_dispatch re-trigger)
|
|
259
259
|
if: env.BOOTSTRAP_MODE != 'true' && (github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
|
|
260
260
|
env:
|
|
261
261
|
GH_TOKEN: ${{ github.token }}
|
|
@@ -283,31 +283,21 @@ jobs:
|
|
|
283
283
|
CHECK_NAME="DevAudit Release Approval"
|
|
284
284
|
DETAILS_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
285
285
|
COMPLETED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
286
|
-
EXISTING_ID=$(gh api \
|
|
287
|
-
"/repos/${{ github.repository }}/commits/${TARGET_SHA}/check-runs?name=DevAudit%20Release%20Approval" \
|
|
288
|
-
--jq '.check_runs[] | select(.name == "DevAudit Release Approval") | .id' \
|
|
289
|
-
| head -1 || true)
|
|
290
286
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
-f completed_at="$COMPLETED_AT" \
|
|
309
|
-
-f details_url="$DETAILS_URL" \
|
|
310
|
-
-f "output[title]=DevAudit release approval confirmed" \
|
|
311
|
-
-f "output[summary]=Release ${{ steps.release.outputs.version }} is approved in DevAudit."
|
|
312
|
-
echo "Created ${CHECK_NAME} check run on ${TARGET_SHA}."
|
|
313
|
-
fi
|
|
287
|
+
# DevAudit-Installer#351 — GitHub's Feb 2025 check-run changes
|
|
288
|
+
# forbid externally mutating an existing workflow-owned check run
|
|
289
|
+
# from a workflow_dispatch / repository_dispatch flow. The refresh
|
|
290
|
+
# path therefore creates a fresh success check run on the approved
|
|
291
|
+
# SHA instead of PATCHing the original failed PR check.
|
|
292
|
+
gh api "/repos/${{ github.repository }}/check-runs" \
|
|
293
|
+
-X POST \
|
|
294
|
+
-f name="$CHECK_NAME" \
|
|
295
|
+
-f head_sha="$TARGET_SHA" \
|
|
296
|
+
-f status=completed \
|
|
297
|
+
-f conclusion=success \
|
|
298
|
+
-f completed_at="$COMPLETED_AT" \
|
|
299
|
+
-f details_url="$DETAILS_URL" \
|
|
300
|
+
-f external_id="${{ github.run_id }}" \
|
|
301
|
+
-f "output[title]=DevAudit release approval confirmed" \
|
|
302
|
+
-f "output[summary]=Release ${{ steps.release.outputs.version }} is approved in DevAudit."
|
|
303
|
+
echo "Created refreshed ${CHECK_NAME} check run on ${TARGET_SHA}."
|