CC8.1 — Change management (branch policy, plan mode, sub-agent review)
Status: Implemented Owner: Agent #38 (Senior Compliance Lead, SOC 2 + ISO 27001) Last reviewed: 2026-05-28 Next review: 2026-08-28
Trust Services Criteria reference
The entity authorises, designs, develops or acquires, configures, documents, tests, approves, and implements changes to infrastructure, data, software, and procedures to meet its objectives. The control covers the change-authorisation workflow, the test-before-implementation discipline, the segregation between author and reviewer, the deployment pipeline, and the post-implementation review.
How ZeroAuth meets this control
The change-management framework is anchored in ADR 0011 — "Branching workflow: dev + main only" (commit 51bc705). The decision: two long-lived branches and no feature branches. main is force-push-disabled, PR-required, CI-required, linear-history-required, squash-merge-from-dev-only. dev is force-push-disabled, CI-required-on-push, the integration target for the whole 50-agent team. PRs from dev to main only when a sprint or phase exit gate is met. Hotfixes go straight to dev followed by a same-day PR to main. No chore/*, feat/*, fix/*, release/*, hotfix/*, per-agent feature branches.
Commit-time gates (per 06-ways-of-working.md "Commit-time gates" — 7 enumerated automated checks) execute via the pre-commit hook and the CI mirror:
tsc --noEmit— zero errors.eslint .— zero errors.jest --findRelatedTests <staged>— green.- Secret scan — no
Co-Authored-By: Claude, no patterns from00-README.md§10. - Forbidden-payload-key scan — Express handlers do not introduce
image|template|pixel|depth|frame|raw_face|raw_finger. - ADR-trail scan — new deps in
package.jsonhave a matching ADR; changed*.zkeyhas a matching ADR. - Commit-message gate — subject ≤ 72 chars, imperative, no
feat:/fix:/WIPprefix, no emoji; body has noCo-Authored-By: Claudetrailer.
--no-verify is forbidden. CI mirrors the gate on dev and main. Sub-agent approval is the additional gate before merge.
Plan-mode is the change-authorisation step. 06-ways-of-working.md "Plan mode" lists the trigger paths: any change touching ≥ 5 files OR any of src/services/zkp.ts, src/services/identity.ts, src/services/api-keys.ts, src/services/audit.ts, src/middleware/tenant-auth.ts, src/routes/v1/zkp.ts, src/routes/v1/identity.ts, circuits/**, contracts/**, mobile/prover/**, mobile/keystore/**. Plan-mode authoring is a written design proposal before code lands. Skipping plan-mode results in a PR revert + agent reminder.
Sub-agent review is the segregation-between-author-and-reviewer mechanism. 06-ways-of-working.md "Sub-agent rules" maps touched paths to required reviewers:
| Touched path | Invokes |
|---|---|
src/middleware/tenant-auth.ts | security-reviewer |
src/services/api-keys.ts, src/services/tenants.ts | security-reviewer |
src/services/jwt.ts, src/services/key-management.ts | security-reviewer + cryptographer-reviewer |
src/routes/v1/zkp.ts, src/services/zkp.ts, src/services/proof-pairing.ts | security-reviewer + cryptographer-reviewer |
src/services/identity.ts, src/services/attestation.ts | security-reviewer + cryptographer-reviewer |
src/services/audit.ts, src/services/platform.ts (audit-write paths) | security-reviewer + cryptographer-reviewer |
circuits/** | cryptographer-reviewer |
contracts/** | cryptographer-reviewer + security-reviewer |
A PR is not mergeable until the relevant sub-agent posts an explicit APPROVE row. REQUEST_CHANGES blocks the merge. A REQUEST_CHANGES that goes unaddressed for 24 hours escalates to Role 1.
Test-before-implementation discipline is CLAUDE.md standing instruction #2: "Write the request-level test before the implementation. Especially for verification, replay defence, and tenant isolation. The test for 'wrong tenant rejected' must exist before 'right tenant accepted' can be merged." This is enforced at code-review by the sub-agents reading the diff.
The deployment pipeline is /.github/workflows/deploy.yml — triggered on push to main, deploys to the production VPS via SSH using the zeroauth-deploy user. Failure of CI on main fails the deploy fast (per CLAUDE.md standing instruction #8). Branch protection on main (enforced via ADR 0011) means a non-PR push, or a PR with failing CI, never reaches deploy.
The audit-trail for changes is the audit_events table — admin actions, key issuance, tenant config changes all write rows through appendAuditEvent (commit a475ed8). The hash chain (ADR 0013, commit 27ed93c) makes the change trail tamper-evident; the on-chain anchor (ADR 0014, commit d6c6a4e) makes it externally verifiable.
Circuit-version changes have their own dedicated discipline. ADR 0015 (commit 27ed93c) §"Landing a new version" mandates: ADR opened → trusted-setup ceremony → circuit source + artefacts committed → Groth16Verifier redeploy → EXPECTED_VKEY_SHA256 updated → cryptographer-reviewer APPROVE → external cryptographer attestation. No shortcuts. The boot-time vkey check (commit e98d158) prevents an out-of-band swap.
Dependency changes go through the dep-add skill (.claude/skills/dep-add/SKILL.md) — every new dep is an ADR. The scripts/check-dep-trail.sh script enforces it at commit time.
Evidence references
- ADR
0011-branching-workflow.md(commit51bc705) —dev+mainbranching policy. docs/plan/bfsi-v1/06-ways-of-working.md"Commit-time gates" — 7 automated checks.docs/plan/bfsi-v1/06-ways-of-working.md"Plan mode" — change-authorisation trigger list.docs/plan/bfsi-v1/06-ways-of-working.md"Sub-agent rules" — author-vs-reviewer segregation table..claude/agents/security-reviewer.md,.claude/agents/cryptographer-reviewer.md— sub-agent definitions..claude/skills/dep-add/SKILL.md— every-dep-is-an-ADR skill.scripts/check-dep-trail.sh— dep-ADR enforcement.- ADR
0015-circuit-version-pinning.md(commit27ed93c) + commite98d158— circuit-change discipline. - ADR
0016-zod-input-validation.md(commit76f8d4e) — ADR-first dep-add demonstration (ADR lands ahead of C-022 install). /.github/workflows/ci.yml,/.github/workflows/deploy.yml— CI + deploy pipelines.- Commit
a475ed8—appendAuditEventtamper-evident change trail. - Commit
d6c6a4e—AuditAnchorcontract.
Open gaps + remediation roadmap
- GitHub branch-protection technical enforcement — audit finding C-16 open-phase-1; protected-branch settings on
main, tracked as a sprint-2 ops ticket. - PR template that prompts for plan-mode + sub-agent-review status — target week 6 (2026-07-06).
- Quarterly change-management walkthrough — first cycle target week 14 (2026-08-24).
- Auto-generated SOC 2 change-evidence report — pulls from
git log+ sub-agent review history. Target week 22 (2026-10-12), pairs with the evidence-collector decision (D-Q1-11).
Test or audit query
git log --pretty='%H %s' --all -- main..dev | head -20 — review the change set in flight. gh pr list --state merged --base main --search "review:approved" returns the recent merge stream. For any sensitive-path PR (e.g. touching src/services/zkp.ts), the PR review thread carries the security-reviewer + cryptographer-reviewer APPROVE rows. Sample commit subjects (length ≤ 72, imperative, no prefix): 5e3b79d, 51bc705, 27ed93c, e98d158, a475ed8.