# Incremental Delivery Operating Model

audience: AI coding agents first.

status: DONE
task IDs: #1, #2, #3
source request: On 2026-08-13 owner supplied an industry-standard trunk-based development and temporary-feature-flag example from another project. Owner requested gap analysis, removal of assumptions irrelevant to Overdeck, addition of missing Overdeck constraints, and a new Overdeck-specific plan. On 2026-08-13 owner approved incremental execution: land the smallest safe piece immediately, then continue with independently verifiable slices; partial wiring is acceptable only when inert and non-breaking. Owner clarified that Overdeck already has guarded landing, current-main candidates, tests/review, `origin/main` publication, deployment queue/local installer, receipts/status data, and partial dark delivery. NEVER build another delivery system; strengthen and connect existing machinery. This plan defines canonical policy and incremental sequence; implementation remains coordinated with `2026-08-11-controller-owned-dark-delivery.md`.

## Outcome

Adopt one Overdeck delivery contract: short-lived isolated task worktrees feed guarded `main`; verified slices deploy immediately; incomplete user-visible behavior stays server/controller-dark; exact evidence is reused; installed behavior and owner-visible status close delivery.

Do NOT copy generic `origin/master`, generic production rollout, release-branch, or database-first assumptions into Overdeck.

## Gap analysis

### Keep from supplied example

- Split work into smallest independently verifiable slices.
- Land verified slices promptly; NEVER hold completed work in long-lived release branches.
- Keep dependent/conflicting mutations sequential. Parallelize only disjoint files and state.
- Reuse still-valid receipts; NEVER rerun identical unaffected gates.
- Keep security protections unflagged.
- Require disabled behavior to be inert, not CSS-hidden.
- Use expand–migrate–contract for destructive persistence changes.
- Require rollback and temporary-flag removal.

### Replace for Overdeck

- Replace `origin/master` with guarded `origin/main`.
- Replace direct per-task push with `.claude/scripts/ship.sh`; initialize missing controller through canonical `ship-init.sh`, never hand-type merge/push sequences.
- Replace vague “production” with exact installed Overdeck runtime: controller, collector, web app, workstation module, or remote node named by component.
- Replace generic server flag with controller-owned, fail-closed state outside Git. States: `OFF → INTERNAL → CANARY → ON → RETIRED`; emergency rollback: any live state → `OFF`.
- Replace “staff → limited users → everyone” with audience stages only where Overdeck has a real identity boundary. Single-owner/local tools MAY use `OFF → ON`; NEVER invent cohorts.
- Replace generic database rule with persistence-boundary rule. Apply expand–migrate–contract to SQLite, JSONL, manifests, settings, event/receipt schemas, API envelopes, and fleet state—not only databases.
- Replace “task complete after push” with installed owner-visible proof. Push without canonical deploy/install is incomplete.
- Replace local-heavy verification with affected deterministic gates through established remote admission for heavy work. No workstation fallback.

### Add missing Overdeck requirements

- Work only in `od-worktree` isolated worktrees; shared checkout is read-only.
- Preserve unrelated WIP. Build disposable candidate from refreshed `origin/main`; NEVER rebase stale source lane in place.
- Freeze scope, acceptance, affected paths, dependencies, change class, activation plan, rollback, and receipt identity before implementation.
- Classify every slice before coding: `always-on atomic`, `dark-capable`, `migration preparation`, or `security`. Do not add flags to docs, tests, refactors, compatible internal tooling, or complete atomic fixes.
- One flag controls one user-visible capability, not a project phase or branch. Flag definition MUST include stable ID, owner, default/failure state, audiences, fallback, observability, review deadline, rollback window, removal condition, cleanup task, and introduced task/SHA.
- Disabled path MUST perform no new route exposure, writes, jobs, external calls, background work, API-semantic change, or visible UI. Provider/config/state failure MUST preserve old behavior or stable disabled response.
- Agent/task code MUST NOT mutate runtime activation state. Existing controller owns state transitions. Activation requires exact deployed commit/tree/artifact plus bound installation, smoke, and browser receipts where UI exists.
- Feature flags do not replace compatibility design. Old and new code/data versions MUST coexist across deploy and rollback window.
- Build once; deploy exact verified artifact/tree from pristine deploy source. NEVER deploy dirty task-worktree bytes.
- Persist intent before publication, deployment, activation, migration, or retirement side effects; reconcile observed state after crash/lost response. Operations MUST be idempotent.
- Security-sensitive evidence admission requires dedicated least-privilege authority and signed identity-bound attestations. Generic controller authentication MUST NOT authorize rollout evidence.
- Local infrastructure follows install-before-land: candidate install, real installed-entrypoint proof, then guarded land and canonical deploy. Product work follows branch → gates → land → deploy → activate.
- Owner request pre-approves delivery and routine activation. NEVER pause for Git/deploy/arm permission. Stop only for irreversible destruction or unresolved product scope.
- Owner-visible Delivery UI MUST show slice, status, exact version, gates, review, deployment target, activation state, failure reason, rollback, and flag-removal debt. A database row or terminal log alone is not delivery observability.
- Cleanup MUST verify recovery bundle/restore path before deleting worktrees, refs, old schema, old code, or flags.
- Any factory phase/retry/gate/permission/commit behavior change MUST pass `python3 -m pytest modules/harness/factory/tests/ -q`.
- Any UI change MUST follow `.claude/skills/od-ui-dev/SKILL.md` and remote browser verification through `e2e-remote`.
- Address every warning and security-gate signal; passed-with-noise is not green.

## Acceptance criteria

1. Canonical agent instructions point to this operating model without duplicating it.
2. Delivery controller accepts a frozen slice contract containing scope, dependencies, change class, affected gates, activation, rollback, and receipt identity.
3. Guarded candidate assembly starts from refreshed `origin/main` and preserves source WIP.
4. Gate receipts bind candidate tree, gate graph, declared inputs, lockfile, toolchain/environment, fixtures/schema, command, result, warnings, log digest, and artifact digest. Exact matches reuse proof; changed identity invalidates it.
5. Controller serializes conflicting slices and safely permits disjoint verification; publication revalidates against latest `main`.
6. Exact verified artifact/tree reaches canonical runtime; installed version and real entrypoint are proven.
7. Dark-capable slices use fail-closed controller state and inert OFF behavior. Security and complete atomic fixes are never hidden behind flags.
8. Activation requires exact deployed identity plus required installation/runtime/browser receipts. Kill switch works without code publication.
9. Persistence changes prove expand, compatibility, migration, data verification, activation, rollback window, and later contract removal as separate receipts.
10. Every temporary flag has removal debt from creation; controller/UI surfaces overdue review or rollback windows; retirement removes code, state, and definition only after proof.
11. Crash/retry tests cover publication, deployment, evidence admission, activation, migration, rollback, and retirement without duplicate side effects or false success.
12. Owner-visible Delivery surface gives who/what/when/where/how/account, every gate/log/diff/tool run, current blocker, next automatic action, and rollback status.
13. One representative always-on slice, dark UI/API slice, persistence migration, security fix, and local-infrastructure fix pass end-to-end through installed proof.
14. Supplied generic example is not installed or copied as policy; obsolete assumptions are absent from canonical docs.

## Preserved WIP

- Existing implementation and receipts remain in `docs/plans/2026-08-11-controller-owned-dark-delivery.md`; this policy does not overwrite or restart that work.
- Existing land queue, deploy queue, factory reliability, WIP triage, signed evidence, and Delivery UI work remain authoritative in their current plans.
- Shared checkout modifications and unrelated worktrees remain untouched.

## Constraints

- One controller, one lifecycle state authority, one receipt ledger. NEVER add parallel daemon or competing database.
- Minimal slices only. Every changed line traces to one accepted slice.
- Never weaken a gate, silently suppress warning, deploy from dirty source, infer state from branch names, or make Git refs the task database.
- Never create staged audiences without a real identity boundary.
- Never flag security enforcement, data-integrity protection, tests, docs, refactors, or complete atomic fixes.
- Never contract persistence schema in same slice as first compatible expansion.
- Never require owner to choose worktree, branch, merge, push, deploy, restart, activation, or cleanup mechanics.

## Incremental landing sequence

Land each slice independently as soon as its focused gates pass. A later slice MUST NOT delay an earlier safe slice. Existing queue/controller/deployer remain authoritative; every slice modifies or connects an existing seam.

1. **S0 — Canonical policy (now):** this plan plus index row. Documentation only; zero runtime effect. Land immediately.
2. **S1 — Queue continuation visibility:** preserve existing landing behavior; add one read-only status/receipt transition showing `landed → deployment queued/running/succeeded/failed → installed proof pending/passed/failed` plus next automatic action. No new queue.
3. **S2 — Landing-to-deploy continuation:** connect successful existing land receipt to existing deployment queue idempotently. Keep manual/current path as fallback; no activation.
4. **S3 — Installed proof closure:** attach exact installed component/version and real-entrypoint result to existing delivery receipt. A failed proof remains visible and retryable; never report done early.
5. **S4 — Receipt identity audit:** inventory current receipt keys and add mismatch tests for candidate tree, gate graph, declared inputs, lockfile, toolchain, fixtures/schema, warnings, and artifact digest. No reuse yet.
6. **S5 — Safe receipt reuse:** enable reuse only for exact S4 identity matches; surface reused receipt origin and age. Changed identity runs the gate.
7. **S6 — Exact candidate/artifact/deployment identity:** close remaining identity gaps in existing current-main candidate and deploy paths; never build a parallel artifact pipeline.
8. **S7 — Crash reconciliation:** persist/reconcile existing land and deploy queue transitions after process crash or lost response; prove no duplicate publication/deployment.
9. **S8 — Failure and next-action UI:** expose existing queue, receipt, deploy, and proof state through collector/read model, reusable deck-ui components, and UI; remote browser proof required.
10. **S9 — Temporary activation definition:** strengthen existing dark-delivery definition with fail-closed default, cleanup task, review date, rollback window, and removal condition. All initial definitions remain `OFF`.
11. **S10 — One inert OFF path:** connect one incomplete user-facing capability to existing controller state; prove disabled route/write/job/API/UI behavior is unchanged.
12. **S11 — Evidence-bound activation:** connect existing signed evidence and exact deployed identity to current activation state. Generic controller authentication MUST NOT authorize evidence.
13. **S12 — Kill switch and real audience stages:** prove immediate rollback to `OFF`; add audience eligibility only where Overdeck has a real identity boundary.
14. **S13 — Compatibility and persistence lifecycle:** strengthen existing persistence seams incrementally: expand, dual compatibility, migrate/verify, then later contract.
15. **S14 — Flag debt and retirement:** surface overdue flags; automatically open/track removal; remove compatibility code, state, and definition only after rollback window and recovery proof.
16. **S15 — Representative proofs:** separately land always-on, dark UI/API, migration, security, and local-infrastructure examples; retire legacy paths only after parity.

Every slice records its own affected files, tests, review, commit, deployment/installed state, rollback, and next slice before landing.

## Execution steps

1. Land S0 now through guarded `main`; deploy canonical docs if the repository deployment includes them.
2. Before each later slice, inventory only its existing seam and shrink scope to the smallest additive or inert change.
3. Implement and land S1–S16 in order where dependent. S14 collector/read-model work MAY proceed alongside S3–S8 when paths and state do not overlap.
4. Never bundle a blocked or failing later slice with a green earlier slice.
5. Keep legacy behavior authoritative until replacement slice has exact parity and rollback receipts.

## Current receipt

- 2026-08-13: Compared supplied example with repository instructions, shared delivery doctrine, guarded `main` landing, canonical local deployment, controller-owned dark-delivery plan, feature evidence security history, receipt identity rules, remote-heavy-gate policy, and owner-visible observability requirements.
- 2026-08-13: Main gaps found: wrong branch/controller, push-as-completion, generic production/cohort assumptions, database-only migration scope, no worktree/WIP safety, no exact artifact/evidence identity, no crash reconciliation, no install-before-land exception, no signed evidence authority, no owner-visible lifecycle, and no mandatory flag-removal enforcement.
- 2026-08-13: Policy authored only. No runtime, controller, flag, database, deployment, or activation behavior changed.
- 2026-08-13 sizing estimate: full acceptance scope was initially estimated at **35–55 files** and **4,500–7,500 changed LOC** before seam-level inventory.
- 2026-08-13 implementation inventory revised remaining work to approximately **28–45 distinct files** and **3,100–5,500 changed LOC**, excluding documentation. Existing code already provides guarded current-main landing, land intent/fencing, deploy entrypoint/dispatch ledger, delivery records, exact SHA/tree schemas, readiness evaluation, signed Ed25519 evidence verification, dedicated evidence authority, replay protection, fail-closed feature definitions/evaluation, `OFF/INTERNAL/CANARY/ON/RETIRED` lifecycle, rollback/CAS/crash tests, expiry reconciliation, cleanup metadata, and partial CI delivery query/data seams. S9 is effectively done; controller portions of S11/S12 are done; S7 and S14 require extensions, not replacements. Largest remaining areas: queue-to-deploy/installed-proof closure, canonical receipt identity/reuse, exact producer-side artifact chain, owner-visible read model/UI, one real inert OFF integration, one representative persistence lifecycle, and trusted deployment-side evidence producer.
- 2026-08-13 owner approved immediate incremental execution and explicitly allowed inert partial wiring. Sequence revised to improve existing queue first; no new delivery infrastructure.
- 2026-08-14 S3 landed as `504bc2d0d4fa371cad08032c2ef4ebc63728f3f8`; canonical deployment completed and installed controller entrypoint was active.
- 2026-08-14 S4 landed as `9537ac72fb9e70d250ff7d0ce0d3f9a8ddd75552`; exact ten-field gate identity contract and mismatch coverage passed 268 controller tests, typecheck, diff check, and independent review.
- 2026-08-14 S5 landed and deployed: immutable successful-receipt reuse requires exact indexed identity; origin and age exposed; changed, failed, malformed, non-canonical-time, and future receipts fail closed. Installed controller active.
- 2026-08-14 independent review found remote payload basename admission bypass during S5 landing. Exact trusted path now required; regression test passed; deployed copy verified rejecting untrusted path.
- 2026-08-14 S6 landed as `be9e2cafb1b012c4619582b75a73a558445b6d6d`. Evidence admission now fails closed unless candidate, signed deployment claim, independently observed deployment, tree, target, and artifact identities match exactly. Installed manifest proof matched commit `be9e2cafb1b012c4619582b75a73a558445b6d6d`, tree `f658ce2866e8bb3ea7ebee969efdcc9766194caa`, artifact `a7011dd01452f2b9dc6aaf557a8dfae760488e686010f8885391e035a90ea3f4`; controller service active. Rollback: deploy the prior landed controller revision, which atomically replaces the manifest and restarts the service.
- 2026-08-14 S7 landed and deployed as `69949d01f`; normal dispatch now emits machine-readable durable acceptance, and replay after a lost response returns the same running identity without a second remote launch. Installed entrypoint and controller service verified.
- 2026-08-14 S8 candidate `bf5133d5a` adds Delivery to `/ci` using existing `SectionCard`, `StatusChip`, and `StaleBadge`. It exposes authoritative status, operation, holder, queue depth, and failure reason. Unsourced next action, exact wait, lease owner, remote node, receipt, timing, and retire/resume state are explicitly labeled not recorded. Verification: 18 focused tests, web typecheck with zero diagnostics, diff check, independent review CLEAN.
- 2026-08-14 S10 landed as `d1c446a8f`, deployed, and remained OFF. Post-land review found readiness initially trusted receipt IDs without validating exact receipt bindings; repair landed and deployed as `7aa4aae3d`. It now requires exact primary and supplementary feature/deployment receipt binding, controller target identity, and all readiness checks. Installed controller/web/collector active; authenticated installed preview returned exact prior `404 not found`. Focused verification: 23 server tests, typecheck, diff check, independent review CLEAN. Rollback remains immediate controller state `OFF`; no audience cohorts were added because this single-owner capability has no real identity boundary.
- 2026-08-14 S13–S15 representative lifecycle proof landed as `b3296949a`; guarded landing twice died during candidate fetch, so the already verified candidate used the authorized direct-land path. Canonical deployment completed at newer `main` revision `babf6afdb`, which contains `b3296949a`; controller, web, and collector are active. The jobs migration proof verifies the complete preserved legacy row, original schema metadata, and exact additive field definitions. Existing retirement tests prove normal expiry, rollback-window enforcement, and evidence/state cleanup. Independent review CLEAN. No destructive contract or invented audience cohort was added.

## Next executable action

None. Incremental delivery acceptance is complete; future feature work uses this installed operating model and removes temporary definitions only after its recorded rollback window.