Skip to content

Manual Test Runbook — R4: CAB Automation (via E7)

Owner: Sagar  |  Time: ~5 min (Parts A/B offline) · +10 min (Part C live)  |  Cloud: none for Parts A/B · GitHub read for Part C

Promotes R4 (apps/cab-automation/) from 🟦 Code Complete → 🟩 Shipped. Parts A/B are offline ($0). Part C lists real PRs and files CAB review issues through the E7 CLI — extending the proven E7 ticketing bridge (I5/R2/K4).


Prerequisites

  • Local tooling: node >= 20, npm
  • (Part C only) gh authenticated to a repo; E7 (apps/ticket-platform/) built; tracker creds in env (e.g. GITHUB_TOKEN for --platform github)
  • Working directory: apps/cab-automation

Steps

Part A — build, typecheck, unit tests (offline, ~3 min)

  1. bash cd apps/cab-automation npm install npm run typecheck npm test

Expected: typecheck clean; 24 tests pass across assess.test.ts (normalize both gh + flat shapes; label / risk-path / emergency / none assessment; case-insensitivity; custom policy; sample end-to-end; dedupe), render.test.ts (CAB vs. emergency header, reasons + matched paths never invented, backout + approval checklist), and ticket.test.ts (E7 argv, output parse, dry-run, emergency labelling).

Part B — offline dry-run on the sample (~2 min, $0)

  1. ```bash npm run build node dist/index.js --input examples/changes.sample.json --out-dir ./out

    Expected: `dry-run — 2 of 4 change(s) require CAB`. The 4 sample PRs:
    #301 (`impact:high` + touches `modules/`,`live/` → high), #302 (docs only →
    none), #303 (`break-glass` + `policy/` → high, emergency/retroactive), #304
    (test only → none). Inspect:
    
    ```bash
    cat out/cab-records.json   # requiring_cab=2; reasons list the matched labels/paths
    ls out/cab-*.md            # cab-301.md, cab-303.md
    

  2. (Custom policy) Confirm the policy is configurable — treat docs/ as risky:

node dist/index.js --input examples/changes.sample.json --risk-paths "docs/" --out-dir ./out

Expected: #302 now also requires CAB (touches docs/).

Part C — live list + file via E7 (~10 min)

  1. Build E7 and confirm the CLI contract:
( cd ../ticket-platform && npm install && npm run build )
node ../ticket-platform/dist/index.js --platform dry-run --title t \
  --body "x" --dedupe-key k --output /tmp/e7.txt && cat /tmp/e7.txt

Expected: /tmp/e7.txt contains ticket_id=…, ticket_url=…, ticket_updated=… — the contract R4 parses.

  1. Assess real open PRs and file CAB issues for the high-impact ones (GitHub shown):
export GITHUB_TOKEN=   # repo-scoped
node dist/index.js \
  --state open \
  --platform github --repo <org>/<test-repo> \
  --ticket-cmd "node ../ticket-platform/dist/index.js" \
  --out-dir ./out

Expected: one CAB issue per qualifying open PR, labelled cab + change-management + impact:* (+ emergency where applicable), body = the CAB review with the matched reasons. Re-run the same command and confirm each outcome is updated: true in out/cab-records.json (idempotent — no duplicates).

  1. (Gate use) Confirm --fail-on-cab true exits non-zero when an open PR needs CAB — this is how a branch-protection check blocks merge until CAB review is recorded.

Pass criteria

  • Part A — typecheck clean; 24 tests pass
  • Part B — sample dry-run flags 2/4 (default policy), 3/4 (docs/ added to risk paths)
  • Part C — a real high-impact PR files a CAB issue via E7; a second run updates it (no dup)
  • Generated cab-records.json + cab-*.md look correct (reasons match labels/paths, no fabrication)

Failure mode

Over- or under-scoping CAB — too many low-value PRs flagged, or a risky path missed. Tuned via --cab-labels / --risk-paths / --emergency-labels; the per-change dedupe key (cab=<n>) keeps re-runs updating one ticket. R4 only ever cites the matched labels/paths as the reason — it never invents a justification. Documented in the README.

Cost impact

$0 — pure orchestration; read-only gh pr list. No resources created.

Removal path

Delete apps/cab-automation/. Nothing external is provisioned.


Sign-Off

Field Value
Part A (unit tests) ☐ PASS
Part B (offline dry-run) ☐ PASS
Part C (live via E7) ☐ PASS / ☐ skipped
Tester
Date
Result ☐ PASS