Act under a lease, keep accounts by order, one writer at composition (hq to-be 45 Phase 2) #83

Merged
mesh-admin merged 1 commits from feat/a-core-that-cannot-fail-silently-phase-2 into main 2026-10-06 10:30:29 +00:00
Contributor

Controller side of to-be 45 Phase 2 (hq ADR 0227, decided details in hq ADR 0229, hq PR on decision/0229-the-cores-order-and-the-brake). Host side: mesh-host #35 (merged).

  • Lease (internal/lease): mesh-controller_lease/holder, 15 s age, renew 5 s, CAS; epoch = revision taken at; gate closes 3 s before expiry by the clock; refused renewal = lost → exit; release on stop. serve takes it before asserting the bus. Epoch floor in the store (migration 0068 controller_epoch), bucket compacted past it if raised from nothing. Unleased (no epoch, S12 urgent) only if nobody holds it and the bus refuses the write. Shell commands act under the holder's epoch or a lease of their own.
  • Declarations carry epoch (signed envelope) only to machines whose latest account had report_sequence; would-send uses the epoch last sent; allot and link.Declare both gated.
  • Reports: contract in internal/link/order.go (matches mesh-host Order, report_sequence, older_than, refused_older). Accounts kept by (epoch, sequence, report_sequence); older refused + counted; unordered → digest rule (267).
  • Plans compare-and-set on revision, with epoch (SavePlan(*Plan), ErrPlanMoved). Conditions/calls carry epoch, not written off the lease.
  • S12, S13 (writer named by epoch), D5 live; bucket reset said.
  • Writers table compiled, enforced in PermissionsFor; controller no longer publishes mesh.control.>.
  • Contracts for every consumed kind (internal/link/contracts.go) + check; empty-on-error lint (internal/lint).
  • mesh-host pin moved to its main (3e80b7a) so D1's validator accepts epoch.

Tests: full suite go test -count=1 -p 1 ./... against postgres:17 + nats:2.11 green; -race on lease/link/conditions/broker/lint/inventory and the new cmd tests. Two controllers at once: internal/lease (contention, handover, expiry, refused renewal, floor) and cmd/mesh-controller TestTwoControllersOneActs (store + bus, the loser writes nothing).

Merge after the mesh-host genesis-lock PR (branch feat/a-core-that-cannot-fail-silently-phase-2-grants), else the genesis test fails. Live: the first build serves unleased until a push of the bus's machine delivers the user list granting the lease bucket (S12 says so).

Controller side of to-be 45 Phase 2 (hq ADR 0227, decided details in hq ADR 0229, hq PR on `decision/0229-the-cores-order-and-the-brake`). Host side: mesh-host #35 (merged). - **Lease** (`internal/lease`): `mesh-controller_lease`/`holder`, 15 s age, renew 5 s, CAS; epoch = revision taken at; gate closes 3 s before expiry by the clock; refused renewal = lost → exit; release on stop. `serve` takes it before asserting the bus. Epoch floor in the store (migration **0068** `controller_epoch`), bucket compacted past it if raised from nothing. Unleased (no epoch, S12 urgent) only if nobody holds it and the bus refuses the write. Shell commands act under the holder's epoch or a lease of their own. - **Declarations** carry `epoch` (signed envelope) only to machines whose latest account had `report_sequence`; would-send uses the epoch last sent; allot and `link.Declare` both gated. - **Reports**: contract in `internal/link/order.go` (matches mesh-host `Order`, `report_sequence`, `older_than`, `refused_older`). Accounts kept by (epoch, sequence, report_sequence); older refused + counted; unordered → digest rule (267). - **Plans** compare-and-set on `revision`, with `epoch` (`SavePlan(*Plan)`, `ErrPlanMoved`). Conditions/calls carry epoch, not written off the lease. - **S12, S13 (writer named by epoch), D5** live; bucket reset said. - **Writers table** compiled, enforced in `PermissionsFor`; controller no longer publishes `mesh.control.>`. - **Contracts** for every consumed kind (`internal/link/contracts.go`) + check; **empty-on-error lint** (`internal/lint`). - mesh-host pin moved to its main (3e80b7a) so D1's validator accepts `epoch`. Tests: full suite `go test -count=1 -p 1 ./...` against postgres:17 + nats:2.11 green; -race on lease/link/conditions/broker/lint/inventory and the new cmd tests. Two controllers at once: `internal/lease` (contention, handover, expiry, refused renewal, floor) and `cmd/mesh-controller TestTwoControllersOneActs` (store + bus, the loser writes nothing). **Merge after the mesh-host genesis-lock PR** (branch `feat/a-core-that-cannot-fail-silently-phase-2-grants`), else the genesis test fails. Live: the first build serves unleased until a push of the bus's machine delivers the user list granting the lease bucket (S12 says so).
mesh-admin added 1 commit 2026-10-06 10:29:41 +00:00
Two controllers could both act (issue 204), a reconcile's report could
overtake the apply after it and the digest decided (issue 267), and a grant
could make a second writer of a machine's report.

- The lease (internal/lease, ADR 0229): mesh-controller_lease key `holder`,
  15 s age, renewed every 5 s by compare-and-set; the epoch is the revision
  it was taken at. The gate is the clock (stops 3 s before expiry); a refused
  renewal is a loss and the process exits; a holder that stops gives it back.
  serve takes it before asserting the bus. Epochs kept in the store
  (migration 0068 controller_epoch) as a floor: a bucket raised from nothing
  is compacted past it. Unleased (no epoch, S12 urgent) only when nobody
  holds it and the bus will not let it be written. A shell command acts
  under the holder's epoch, or its own lease when none.
- Declarations carry `epoch` inside the signed envelope, only to a machine
  whose latest account carried a report_sequence (mesh-host #35); would-send
  is composed with the epoch last sent. Allot and the send both pass the gate.
- Reports: contract in internal/link/order.go (epoch, sequence,
  report_sequence, older_than, refused_older). Accounts kept by epoch, then
  sequence, then report sequence; older refused, counted; unordered reports
  keep the digest rule. Plans by compare-and-set on a revision, with epoch.
  Conditions and calls carry the epoch and are not written off the lease.
- S12 and S13 (naming the writer by epoch) watched, D5 run; reset of the
  bucket said. Writers table compiled in and enforced in PermissionsFor; the
  controller no longer publishes mesh.control.>. A contract per consumed
  kind, and the empty-on-error lint over the repository.
- mesh-host pinned to its main with the epoch in the validator (D1 validates
  the envelope as sent).

Needs mesh-host's genesis lock with the lease grant (mesh-host PR) for
TestTheInstallersFirstUserListIsWhatTheControllerWouldCompose.
mesh-admin merged commit 20c147ffdb into main 2026-10-06 10:30:29 +00:00
mesh-admin deleted branch feat/a-core-that-cannot-fail-silently-phase-2 2026-10-06 10:30:29 +00:00
Author
Contributor

Delivery novox/mesh-controller@20c147ffdb9a — held since 2026-10-06T23:05:28Z

Held for a person: merged without a passing check: only a person decides that it goes on — mesh-delivery.release with why lets it go on.

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#83 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@20c147ffdb9a` — **held** since 2026-10-06T23:05:28Z Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on. **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#83 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
This repo is archived. You cannot comment on pull requests.
No Reviewers
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#83