Write ADR 0666's asks into design 46 and its versions into design 51
ADR 0666 §6 has the operator-channel offer a fourth ask instead of refusing it, never holding the newest back; design 46 now says which ask waits and how it is offered again. ADR 0666 §9 numbers a package when it is published and has that publication rebuild its dependents; design 51 now says how the builder numbers it, says it on the seat mesh-builds, and who asks a tagged version once the checker goes. Claude-Session: https://claude.ai/code/session_01JG73KK8HD1gufnqyFxMFdW
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-tools, mesh-sdk, mesh-catalog]
|
||||
updated: 2026-11-06
|
||||
updated: 2026-11-10
|
||||
decisions:
|
||||
- "ADR 0667"
|
||||
- "ADR 0666"
|
||||
- "ADR 0347"
|
||||
- "ADR 0345"
|
||||
- "ADR 0344"
|
||||
@@ -221,7 +223,20 @@ when the title and the note alone do not fit, and says that too.
|
||||
|
||||
### Limits, batching, history
|
||||
|
||||
- An asker holds **at most three open asks**; a fourth is refused in words.
|
||||
- An asker holds **at most three open asks**; a fourth is refused in words. *Amended 2026-11-10, ADR 0666 §6, from the
|
||||
delivery of design 47's milestone G:* **no ask is hidden, and the newest is never held back.** An asker still has at
|
||||
most three asks offered at once, but a fourth is offered, not refused: the oldest of its offered asks is held back
|
||||
instead, kept open with its answer tickets withdrawn, its message edited to say it waits behind newer asks of the
|
||||
same asker, and offered again, with new tickets, as soon as one of the three ends. An ask with the same `about` as an
|
||||
open one of the same asker replaces it (§10), so a held-back ask is never one a newer ask already stands for. `asks`
|
||||
lists each asker's held-back asks with since when, and the router's tool `ask-again` offers one now, holding back the
|
||||
oldest offered one in its place. A Decline ends an ask like any answer, and its asker may ask again at once: the
|
||||
pipeline runner's verb `ask-again` asks a declined `approval` step so (design 47, *Approval is a step*). Why the
|
||||
oldest: the newest is what the asker needs now, and the oldest has had the operator's eye longest; holding it back
|
||||
edits its message rather than removing it, so the operator still sees it waits. *How it is checked:* the router's
|
||||
whole-module test offers a fourth ask and holds back the oldest, offers the held-back one again when one ends,
|
||||
replaces an open ask by a newer one with the same `about`, and offers an ask after a Decline; live, a fourth ask and
|
||||
a declined approval each reach the operator (design 47, test 71).
|
||||
- Asks count against the router's hourly cap, as messages do; answers do not.
|
||||
- Asks to one channel within the burst window go out together under a heading ("3 questions waiting"),
|
||||
each as its own message, answerable and editable alone.
|
||||
@@ -424,7 +439,8 @@ what it does in plain words, its assurance level (`acknowledge`, `approve`, `des
|
||||
answer (`operator`); an expiry; what happens on expiry, in words; and optionally what it is about (a
|
||||
condition's key), so a newer ask about it replaces the older. It is refused at once, on its asker's
|
||||
`decided` subject, when its words break a rule, when no ready channel can carry one of its options' levels,
|
||||
or when the asker already has three open.
|
||||
or, until the delivery of design 47's milestone G, when the asker already has three open; from that delivery a fourth
|
||||
is offered and the asker's oldest held back (§6, *Limits, batching, history*; ADR 0666 §6).
|
||||
|
||||
**A warrant** carries the ask's id and asker, the option, `by` ("the operator, via telegram, user id
|
||||
verified"), the channel module, the proofs, the level met and when. No secret. An ask that ends without one
|
||||
@@ -577,7 +593,8 @@ runner's bus permissions.
|
||||
refused and said: waiting, declined (not asked again for 10 minutes), expired, already run, or the router's
|
||||
refusal.
|
||||
- **Fail closed:** a secret's shape in an argument or more than 16 KiB of arguments, no operator channel, a
|
||||
fourth open ask, an unpublished ask, an unreadable router record, node file or mark: nothing runs.
|
||||
fourth open ask (until design 47's milestone G is delivered, after which a fourth is offered and the oldest held
|
||||
back, §6), an unpublished ask, an unreadable router record, node file or mark: nothing runs.
|
||||
- **The controller** enforces the same mark on its own verbs, asking as `mesh-controller`.
|
||||
- **Marked first:** `node-login-shell.execute` on every node once the reads it carried have tools (issue 418).
|
||||
`mesh-delivery.release` waits until a warrant the controller holds passes the mark of a verb it calls (issue
|
||||
@@ -702,6 +719,7 @@ Each phase ends at its own *done when*. Owning repositories from [`repos.md`](..
|
||||
| **5 — Authorise, with TOTP** | `authorises` in the verb table; the router's checks for the code; direct calls refused, break-glass; `retire approve` takes `expect`; the hand-act fields; the TOTP seed as the router's state, enrolled at a terminal with ten recovery codes; `factor recover`, `factor status`, the local-only break-glass enrolment; no P2 tier before recovery codes exist; optional key enrolment; the self-check probe for the away channel; agents' grants lose the authorising verbs | mesh-controller; mesh-catalog (agents' grants, the desk's code prompt) | one controller test per refusal passes; at the desk, approve needs a code; a recovery drill re-enrols with a recovery code, and is announced |
|
||||
| **6 — Telegram live** | the `telegram` module (built in 5a) with replies and forced-reply codes, under its own account on the control node; the operator's two bots configured; the watcher assigned off the control node; the dead-man ping | mesh-catalog | the self-check says the away channel carries every tier; rehearsals: an approve and a destroy answered on the phone, with the hand-acts read |
|
||||
| **7 — A call that needs approval** (ADR 0286) | `needs-approval` in the manifest and the seat list, issued in the membership, withheld from a runner without `approval-mark/1` in its bus permissions (controller); the act's digest in TypeScript beside Go, with shared vectors (shared library); the check, the ask, the runner's `approvals`, the node's used file and `warranted` (tool runner); the controller's own verbs; `execute` marked (the controller's seat list) once issue 418's reads exist | mesh-controller, mesh-sdk, mesh-tools, mesh-catalog | a marked call on a node is asked on the phone, does nothing, runs once when made again after Approve, is refused the third time and asked again, and `hand-acts` shows the warrant |
|
||||
| **8 — No ask hidden** (ADR 0666 §6), delivered with design 47's milestone G | a fourth ask offered and the asker's oldest held back, offered again when one ends; `asks` lists the held-back asks; the router's tool `ask-again`; the pipeline runner's `approval` asks and their `about` | mesh-catalog (the router) | a fourth ask and a declined approval each reach the operator; `asks` shows the held-back one |
|
||||
|
||||
**Switching phase 5a on: the operator's steps, in order** (amended 2026-10-09, ADR 0259). Each line is typed with
|
||||
`nox` (`mesh-cli`) on the control-node, from the operator's own account, which is the controller's terminal
|
||||
|
||||
@@ -6,13 +6,15 @@ code:
|
||||
- mesh-catalog modules/artifact-store-tools (the store's tools), modules/distribution (its program, holding the two image seats)
|
||||
- mesh-catalog modules/gitea (package retention; the two package seats' verbs in its Go bundle)
|
||||
- mesh-catalog modules/mesh-build-go, modules/mesh-build-node, modules/mesh-build-image (publishing through the seats)
|
||||
- mesh-delivery modules/mesh-delivery-builder (versions, tag asks), the forge bridge, the indexer, the checker, the assigner
|
||||
- mesh-delivery modules/mesh-delivery-builder (versions, tag asks; from milestone G a package numbered at its publication, the seat `mesh-builds`), the forge bridge, the indexer, the checker, the assigner, modules/mesh-delivery-pipeline (`tag-wanted` from milestone G)
|
||||
- mesh-sdk (the bus helper for sending in parts)
|
||||
- mesh-catalog modules/docker (image pruning)
|
||||
- mesh-host internal/apply (every new image of a module pulled before any of its containers is replaced; a failed pull applied again on the status view's `settled` for the store's holder, and at the node-engine's start), internal/compose (each routed image reference written with its seat and that seat's holder)
|
||||
- mesh-delivery modules/mesh-grants (what a node-engine hears: the status view's `settled`)
|
||||
updated: 2026-11-04
|
||||
updated: 2026-11-10
|
||||
decisions:
|
||||
- "ADR 0667"
|
||||
- "ADR 0666"
|
||||
- "ADR 0605"
|
||||
- "ADR 0612"
|
||||
- "ADR 0614"
|
||||
@@ -160,7 +162,8 @@ the verb.
|
||||
entry turns `published` and the builder writes the done key then, so a late store is never lost.
|
||||
- **What is published when**: a package or an image from a trunk build under its version, or as a tagged version; a
|
||||
bundle or an archive from every done key by its digest alone, a candidate's included, and at the trunk's claim the
|
||||
build module calls `publish` with the version and the held digest, which stores nothing. An upstream image is copied
|
||||
build module calls `publish` with the version and the held digest, which stores nothing. From the delivery of design
|
||||
47's milestone G a package's version is given at its publication instead (*The versions*). An upstream image is copied
|
||||
by `mirror` with its pinned digest.
|
||||
- **The done key names the reference the seat answered**, in ADR 0605 §9's form from this milestone on:
|
||||
`<registry>/<module>/<artifact>@sha256:<digest>` for an image, bundle, archive or upstream copy and
|
||||
@@ -263,7 +266,26 @@ the verb.
|
||||
|
||||
### The versions
|
||||
|
||||
- **The builder numbers every trunk build** of a package, image, bundle or archive at its claim: the package series
|
||||
- **From the delivery of design 47's milestone G, a package is numbered when it is published** (ADR 0666 §9). The
|
||||
builder numbers a package's version at its publication, never only when its build is claimed: a package's trunk
|
||||
build is claimed with no number and built by its digest, and once its build is done the builder gives it the next
|
||||
count of its series, under compare-and-set, and says `numbered`, on which the build module calls `publish` with
|
||||
the version and the held digest, as below for a floor not yet known. A build of an older source revision of the
|
||||
same watched branch than one already numbered for that name is not numbered and publishes nothing, so a version never
|
||||
names older content than the one below it. When the holder says `published`, the builder says the publication as the
|
||||
event `package-published` of its seat `mesh-builds` (the name, the version, the fingerprint, the commit, the watched
|
||||
branch). On it every artifact with a "published before it builds" edge to the package is rebuilt against the new
|
||||
version, and the pipeline runner, which consumes the event, starts its pipeline (design 47, *A publish rebuilds*);
|
||||
nothing else is rebuilt, and a change to a package's tests alone publishes nothing. This removes the claim's wait
|
||||
for earlier merges' numbers below, which held a group on 2026-11-09 (research 086, Findings). Why at publication: a
|
||||
number given at the claim must wait for every earlier merge's number, and a build that never publishes keeps a
|
||||
number nothing holds. An image, bundle or archive keeps the rule below. How it is checked: in the builder's
|
||||
whole-module test a package's trunk build is numbered only once built, an older revision's build after a newer one
|
||||
publishes nothing, `package-published` is said once per publication, and only the importing artifacts rebuild
|
||||
(design 47, test 80).
|
||||
- **A build that cannot read the published packages refuses**, naming the unread state, never building against a guess
|
||||
(ADR 0666 §9; design 47, test 70).
|
||||
- **Until that delivery, the builder numbers every trunk build** of a package, image, bundle or archive at its claim: the package series
|
||||
its manifest declares (design 32; `0.1` when it declares none) and the next count for that name, under
|
||||
compare-and-set. Numbers follow the order of the forge bridge's merge events: a claim of a later merge waits until
|
||||
every earlier merge of the same name whose fingerprint the indexer still holds is numbered (a fingerprint replaced
|
||||
@@ -318,7 +340,11 @@ the verb.
|
||||
|
||||
- **Asked by an event, never by a push** (ADR 0610 §1). The checker emits `tag-wanted` (repository, branch, head,
|
||||
tag), on a family of its own, `checker.asks`, kept seven days, apart from its verdicts, so a waiter on a verdict does
|
||||
not wake on it, for each head of a delivery group member that declares a package; a person asks through `builder_tag`. The
|
||||
not wake on it, for each head of a delivery group member that declares a package; a person asks through `builder_tag`.
|
||||
From the delivery of design 47's milestone G the checker goes, and the pipeline runner says `tag-wanted` instead, on
|
||||
its own seat `mesh-pipeline-runner`, for each member that declares a package of a run on request of a group not yet
|
||||
merged (ADR 0666 §11): a group merged together is one source revision whose packages are published before its
|
||||
dependents build, so only a run on request needs a tagged version. The
|
||||
builder consumes the event on a durable consumer and keeps the ask in its own state `tag-asks`, removed when its
|
||||
branch is merged or deleted, or its pull request closed. An ask the builder has not answered within five minutes is narrated in the build log
|
||||
with what it waits on.
|
||||
@@ -326,7 +352,9 @@ the verb.
|
||||
and Go's `@latest` skips it. A package new in a group is numbered from its floor (`0.1.0-feat-x.1`).
|
||||
- **A group's check builds after `published`**: Go members by the tagged version, TypeScript members with their lock
|
||||
naming it and the registry's integrity; nothing is packed for a check, and a lone pull request's check publishes
|
||||
nothing. No `published` within the publish's bound (10 minutes) fails the check naming the package.
|
||||
nothing. No `published` within the publish's bound (10 minutes) fails the check naming the package. From the
|
||||
delivery of design 47's milestone G the same holds for a group's run on request, whose pipeline steps build after
|
||||
`published`, and a step that gets no `published` within the bound ends failed, naming the package.
|
||||
- **Removed with its branch**: on the forge bridge's `merged` event, its pull `closed`, or its branch-deleted event,
|
||||
heard on a durable consumer, the builder
|
||||
calls each seat's `remove`. It acknowledges the event only once every seat emitted `removed`; until then it retries
|
||||
|
||||
Reference in New Issue
Block a user