diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index abd25c87..63070bdf 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -4,6 +4,7 @@ status: in-progress code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, hq 00-META/checks] updated: 2026-11-05 decisions: + - "ADR 0638" - "ADR 0637" - "ADR 0636" - "ADR 0635" @@ -613,7 +614,7 @@ From its delivery, a check is this: ### A try: a delivery group's check at exact commits -*ADR 0637; ADR 0593 §7, §9, ADR 0636 §4, ADR 0548 §5, ADR 0596 §1, §2.* +*ADR 0637, ADR 0638; ADR 0593 §7, §9, ADR 0636 §4, ADR 0548 §5, ADR 0596 §1, §2.* A try says beforehand whether a check will pass. It is the check's own code run on commits nobody pushed to a pull request, and it owes the forge nothing. @@ -636,8 +637,14 @@ pull request, and it owes the forge nothing. state, on its stream `checks`. The indexer, the holder of the seat `mesh-catalog`, consumes them: on `try.started` it writes `candidates.` with one pull per member, its modules and fingerprints from the previews, validated with the seat definitions the members carry, and on `try.ended` it deletes it. It reads no - state of the checker's; at its start it recovers the tries still open through the checker's tool - `checker_tries` (ADR 0596 §1, §2; the record changing ADR 0637 §4). The indexer's tools read and drop a try's + state of the checker's (ADR 0638 §1, §2, which change ADR 0637 §4; ADR 0596 §1, §2). A narrowed try emits + neither event, because it makes no candidate. +- **At its start the indexer recovers the open tries before it handles the events.** It creates its consumer on + the stream `checks` first, then calls the checker's tool `checker_tries`, declared in its `invokes`, which + answers the open tries with their members and whether each is whole. It writes a candidate for each whole open + try that has none, deletes every candidate whose try is not open, and only then handles the events it holds. A + try that starts or ends between the call and the consumer is heard as an event, and each write is by try id, so + a try seen both ways is written once and deleted once (ADR 0638 §3). The indexer's tools read and drop a try's candidate. The candidate is the try's alone: the check, the gate and the forge bridge leave it alone, and the forge is owed no status and no Approve (ADR 0637 §4). - **A try and a check share kept verdicts.** The try computes each package's digest as the check does and keeps @@ -657,7 +664,10 @@ pull request, and it owes the forge nothing. order, refuses five malformed asks, ends as error without a candidate, keeps no verdict from an error, and fails naming the node on a refused composition; the examiner's table validates a try's manifests as the check does; the whole-module test starts a placed engine and a candidate and shows that the check of a tried head runs no - package with a kept verdict; the indexer's take-in table writes and deletes a try's candidate. The registry + package with a kept verdict; the indexer's take-in table writes a try's candidate on its start, deletes it on its end, and recovers at its + start (an open whole try gets its candidate, a candidate of a try not open goes, a narrowed try gets none, a try + started between the call and the consumer gets one), and the checker's try test shows both events for a whole + try, neither for a narrowed one, and `checker_tries` answering the open tries (ADR 0638 §4). The registry group's review finds no copy of the shared names. Live, the registry group is tried whole before its push, and the checker's try read names each member, the composition per node and every failure (ADR 0637 §9).