will treats the deployment platform as a contract dependency: this
repository specifies required semantics, ships a fake adapter for tests, and
calls the real API through src/agent/deploy-client.ts. Luci and the host
deployment implementation are separate projects; their internals are out of
scope here.
Revision submission
POST /v1/revisions with the envelope in revision.schema.json.
Accepted only when issued by Luci, gates are green, and both image digests
exist in will's registry namespace.
The platform binds compatibilityBaseline to the current production
revision at submit time and rejects or holds the candidate if that
baseline changed since CI produced its compatibility evidence (spec AC10).
Rollout state machine (platform-owned)
submitted -> candidate(pending)
process fails -> runtime restart (systemd rules), stays pending
ready, then restarts -> stability window resets, stays pending
restart budget exceeded or rollout deadline missed -> deployment rollback
continuously ready for the full stability window -> promoted to current
Startup deadline (old-service SIGTERM to candidate readiness): 60 s.
Continuous-ready stability window: 5 min.
Component restarts allowed during probation: 0 (any restart rejects).
Recreate, no overlapping replicas; volumes and secret references stable.
After promotion, failures restart and alert; no causality-based rollback.
Rollback
Startup/probation failure restores the transaction's captured rollback
target (the exact current revision when the candidate started), never the
older value of previous.
v0 bootstrap has no rollback target: failure stops the candidate and alerts.
Rollback activates a reconciliation barrier: no descendant deploys until
an accepted revision explicitly declares reconciles: <failed revision>.
Explicit late rollback (agent tool) restores the previous promoted revision
once, then the same barrier applies.
Events (cursor-based, retained forever)
GET /v1/events?after=<cursor> returns ordered events and nextCursor:
build, deploy, promote, startup-failed, probation-failed,
rollback, reconcile.
Events carry a platform event id; will mirrors them idempotently.
startup-failed, probation-failed, rollback wake the agent.
Rollback API (agent-scoped)
POST /v1/rollback restores only the immediately previous promoted revision
for will's target; the credential is scoped to exactly this operation.
Required Luci extensions
Build and boot-test the two-image pod (nested OCI build + boot test).
Issue the trusted revision record (commit, digests, gates, build identity).
Call POST /v1/revisions after gates pass.
Expose GET /api/v1/repos/{repo}/runs as JSON for the agent's CI watch.
Scheduled, non-deploying ZAI canary job (secret-gated; manual until then).
Operator emergency path
The same API through an operator CLI; no second SSH mutation path.
# Deployment platform contract (required external semantics)
will treats the deployment platform as a **contract dependency**: this
repository specifies required semantics, ships a fake adapter for tests, and
calls the real API through `src/agent/deploy-client.ts`. Luci and the host
deployment implementation are separate projects; their internals are out of
scope here.
## Revision submission
- `POST /v1/revisions` with the envelope in `revision.schema.json`.
- Accepted only when issued by Luci, gates are green, and both image digests
exist in will's registry namespace.
- The platform binds `compatibilityBaseline` to the current production
revision at submit time and **rejects or holds** the candidate if that
baseline changed since CI produced its compatibility evidence (spec AC10).
## Rollout state machine (platform-owned)
```
submitted -> candidate(pending)
process fails -> runtime restart (systemd rules), stays pending
ready, then restarts -> stability window resets, stays pending
restart budget exceeded or rollout deadline missed -> deployment rollback
continuously ready for the full stability window -> promoted to current
```
- Startup deadline (old-service SIGTERM to candidate readiness): **60 s**.
- Continuous-ready stability window: **5 min**.
- Component restarts allowed during probation: **0** (any restart rejects).
- Recreate, no overlapping replicas; volumes and secret references stable.
- After promotion, failures restart and alert; no causality-based rollback.
## Rollback
- Startup/probation failure restores the transaction's captured rollback
target (the exact current revision when the candidate started), never the
older value of `previous`.
- v0 bootstrap has no rollback target: failure stops the candidate and alerts.
- Rollback activates a **reconciliation barrier**: no descendant deploys until
an accepted revision explicitly declares `reconciles: <failed revision>`.
- Explicit late rollback (agent tool) restores the previous promoted revision
once, then the same barrier applies.
## Events (cursor-based, retained forever)
- `GET /v1/events?after=<cursor>` returns ordered events and `nextCursor`:
`build`, `deploy`, `promote`, `startup-failed`, `probation-failed`,
`rollback`, `reconcile`.
- Events carry a platform event id; will mirrors them idempotently.
- `startup-failed`, `probation-failed`, `rollback` wake the agent.
## Rollback API (agent-scoped)
- `POST /v1/rollback` restores only the immediately previous promoted revision
for will's target; the credential is scoped to exactly this operation.
## Required Luci extensions
1. Build and boot-test the two-image pod (nested OCI build + boot test).
2. Issue the trusted revision record (commit, digests, gates, build identity).
3. Call `POST /v1/revisions` after gates pass.
4. Expose `GET /api/v1/repos/{repo}/runs` as JSON for the agent's CI watch.
5. Scheduled, non-deploying ZAI canary job (secret-gated; manual until then).
## Operator emergency path
The same API through an operator CLI; no second SSH mutation path.