Repository navigation
v0.2.0 — governed kernel: contracts, missions, evidence, link
v0.2.0 — Governed kernel: contracts, missions, evidence, link
Date: 2026-09-02 · Base: main @ 05cdacb · Range: 0eca06b (freeze-slice-0, PR #9) → fb5bbfb (kanban closure for the v0.2 wave, PR #27)
v0.1 built the execution machinery: durable Work objects, lease-based
scheduling, disposable workers, webhook ingestion, result publishing. v0.2
makes that machinery governed: every surface the kernel exposes is pinned by
a frozen, hash-attested contract, and regression tests over those contracts
are law — drift changes a hash, never silently changes semantics.
What each merged slice added
Contract Freeze Slice 0 — contracts(freeze) (PR #9, 0eca06b)
Twenty frozen contracts materialized as 21 draft-07 JSON schemas under
contracts/schemas/, wrapped in contracts/manifest.json (21 entries;
work.schema/handoff inlined) with a freeze-attestation SHA-256 in
contracts/manifest.sha256
(2d2f1d27474a908a19aafb9c152be5e27c80987400f21cdfca94080b8bf14a86).
tests/contracts/ adds 21 contract tests (conformance, baseline,
adversarial, compatibility) that are now regression law: a schema change
without a re-generated manifest hash fails CI by design. Compatibility rule
frozen per proto.charter/1.0: N-1 read tolerance; breaking changes require a
major version bump.
k-mission-01 — kernel(mission) (PR #10, ab87f8d)
Mission contract + budget ledger (ADR-0008/0009). Mission Works carry a
MissionContract (budget ceiling, verification criteria, purpose bindings,
kill switch) and a BudgetLedger (reserved at lease time, consumed
continuously, clock paused while WAITING_HUMAN, stopped on hard stop; late
provider bills recorded but never push user-visible consumption past the
ceiling). The state machine gains the forward mission states
WAITING_HUMAN, SUSPENDED, BUDGET_EXHAUSTED — reachable only by mission
works, never by CI works.
k-mission-02 — kernel(mission) persistence (PR #11, 5041452)
Handoff/checkpoint persistence (ADR-0010, handoff.schema/1.0). A handoff is
the frozen 5-layer checkpoint payload (state snapshot, narrative, decision
log, priority queue, warnings) written only on kernel-recognized
suspend/wait/fail transitions. Suspend/resume is fail-closed: an invalid
handoff is never persisted, resume without a checkpoint is refused, and a
checkpoint whose re-derived hash mismatches its persisted hash
(ErrCorruptHandoff) is never silently resumed from. Schema v8: works.mission_json
column + work_handoffs table.
k-evid-01 — evidence(quittance) (PR #12, a83a8a9)
FailureAttribution + Quittance (ADR-0011/0024) in services/evidence: the
settlement-grade mission receipt layer. Kernel-negation law: a work that
failed verification can never carry a price hint
(ErrQuittanceFailedPriced) and a quittance cannot exist without an evidence
bundle (ErrQuittanceNoEvidence) — failed ⇒ no price.
k-hal-01 — hal(cpi) (PR #13, 4f05fc0)
The CPN provider boundary at cpi/1.0 (ADR-0012/0018): a single frozen
handshake/exec/snapshot contract every compute provider speaks. Plus the
conformance harness (packages/providers): interface compliance alone proves
nothing — every future provider must pass the executable ConformanceSuite
before it can be registered.
k-pulse-01 — hal(pulse) (PR #14, 4994501)
PULSE-Node CPN adapter (packages/providers/pulse_provider.go, ADR-0013/0026),
consent-gated and request-only: it announces only capabilities backed by an
active ConsentGrant, every wire call carries the grant reference and the
daemon re-validates (double enforcement), and with no grants it emits zero
outbound bytes — every call fails locally before any network dial. v1
transport is loopback HTTP on 127.0.0.1:7777 with a localhost pairing token;
mTLS is the v2 upgrade path.
k-now-01 — shell(now) (PR #15, d9c77de)
NOW-shell contract surface (ADR-0025, shell.contracts/1.0,
packages/shell): typed validation law for every shell surface plus the NOW
projection — the live mission view of what needs human attention first and
what the budget clock is doing. NOW is a read surface (T1); privileged
actions (approve/deny/kill/take/hand_back) belong to the COMMAND surface at
T3 and can never be exposed by pulse or local_only surfaces.
k-cap-01 — capability(cap) (PR #16, b1491fd)
Capability-evaluation law (packages/capability, policy.token/1.0): a
shell contract declaration executes only if the frozen contract allows it AND
the caller's policy token carries a matching scope. Grants carry token_id,
work_id, org, and can only ever narrow, never widen, delegation.
k-billing-01 — billing(settle) (PR #18, d7bc4e4)
Settlement law over quittance + budget (packages/billing, ADR-0011/0024 +
0009): settlement consumes the budget ledger against a quittance under four
laws — clock law (paused clocks never meter), clamp law (late bills never
push past the ceiling), late-bill evidence law, fail-closed (no quittance, no
settlement). Settlement never mutates the ledger.
WORKS Conversation V1 Task 1 — journaling (PR #19, e89d2e9)
Every canonical state transition is journaled to the durable per-work event
journal (schema v9 work_events, globally monotonic sequences), with a REST
journal listing for the conversation mirror; SSE consumers resume with
sequence > cursor.
k-link-01 — feat(link) (PR #20, 4f9bc69)
The WORKS-Link server surface (ADR-0026/0027, services/api/link_handler.go,
packages/link): the only routes a PULSE device may present to the kernel —
POST /link/v1/pair, POST /link/v1/mounts, GET /link/v1/missions,
POST /link/v1/revoke. /link/v1/commands exists in the frozen
link.wire/1.0 enum but is deliberately not mounted: the request-only law
(PULSE is never a controller) makes every privileged command structurally
unmountable. Auth: SAS pairing (6-char human-displayed code) mints a
short-lived HMAC device token; the service re-reads durable device state on
every call. Schema v10: link_devices + link_mounts. Enabled opt-in via
WORKS_LINK_PAIRING_SECRET (min 32 bytes); without it every link route stays
mounted and answers 503 fail-closed — never a silent default. See
runbooks/link-surface.md.
Upgrade notes (v0.1 → v0.2)
- No breaking wire changes. All new surfaces are additive and the frozen
compatibility rule is N-1 read tolerance perproto.charter/1.0; existing
API clients keep working unchanged. - Schema migration v7 → v10, automatic and idempotent on restart. The
production store (/var/lib/works/works.db) is currently at schema v7.
Restartingworks-api/works-workerwith the new binary applies, in order:
v8 (works.mission_json+work_handoffs, PRAGMA-checked column add),
v9 (work_eventsjournal), v10 (link_devices+link_mounts). All
migrations areCREATE TABLE IF NOT EXISTS/ introspection-guardedALTER TABLE— safe to run repeatedly, no data backfill. Verify after restart:
sqlite3 /var/lib/works/works.db 'select max(version) from schema_version'
→10. WORKS_LINK_PAIRING_SECRETis opt-in. Generate one (openssl rand -hex 32, ≥ 32 bytes), add it to/etc/works/works.env, and restart. If it
is absent or short, the link surface is mounted but every route answers
503 — that is the intended fail-closed posture, not an error to fix under
pressure. Setup walk-through: runbooks/link-surface.md.- Contract tests are regression law. If you change anything under
contracts/schemas/, re-runpython3 contracts/gen_freeze.py— the
manifest hash must move visibly. CI runs the 21 tests intests/contracts/.
Governance invariants (unchanged by v0.2, now contract-pinned)
- State machine authority — only the kernel moves a
Workthrough its
transitions; the transition table is frozen inwork.schema/1.0and locked
by baseline contract tests. - Evidence-on-disk for
SUCCEEDED— a succeeded work has evidence
records; a quittance cannot exist without an evidence bundle. - Lease TTL — leases expire and are re-grantable; expired leases are
reclaimable viaListExpiredLeases. - Idempotent webhooks — webhook ingestion is replay-safe.
- Frozen contract tests — the 21 tests in
tests/contracts/fail on
drift; the manifest hash is the freeze attestation. - Pool enforcement at grant — BYOC pool membership is checked when a
lease is granted, not later. - Cache exit≠0 refusal — the content cache never stores results from a
failed attempt.
ADR boundary (honest note)
ADRs 0005–0007 live in this repo (docs/adr/). ADRs 0008–0027 referenced by
the v0.2 slices live in the AVC workspace docs, not in this repository —
they are cited from the frozen schemas and package docs here, but their text
is not vendored in-repo.
Verification at release
go build ./...— cleango test ./tests/contracts/ -count=1— 21/21 PASS- Full suite
go test ./... -count=1— all packages ok (per
contracts/FREEZE_EVIDENCE.md: 30/30 packages, exit 0) - v0.2.0 wave slices (PRs #22–#27) — exact-head CI + post-merge main CI
both SUCCESS; e2e green;works-kanban validategreen; standards
registry parses.
v0.2.0 wave (the last 5 PRs in this release)
| Slice | Title | PR | Merge SHA |
|---|---|---|---|
| k-039 | v0.2.0 release notes + WORKS-Link runbook + README kernel section | #22 | 46a7a10 |
| k-035 | Revoke cascades mission suspension with handoff (ADR-0020/0026) | #23 | 8ec59b3 |
| k-036 | Wire conformance of /link/v1 vs frozen link.wire/1.0 + pairing/1.0 |
#24 | 8d0ee8d |
| k-037 | works missions CLI — NOW-ordered mission projection |
#25 | 03ba423 |
| k-038 | WebUI work-detail journal timeline (escaped, last 50 events) | #26 | e405f9e |
| kanban | k-impl-035..039 closed on the board |
#27 | fb5bbfb |
Five workers, disjoint file-ownership, all exact-head CI SUCCESS, all
post-merge main CI SUCCESS, no scope drift into other slices.