The catch-up of the heads the source names runs before a source-moved is read, once per branch; the gate's source bucket is no longer read.
internal/index compiles against the new contracts again (SourceByMainValue is gone); tests of earlier subtasks that
the broken compile hid are fixed (the validator's MAJOR.MINOR version in their manifests).
Builds: design 47 G §15, §115, §362
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
The refusal of a status in a manifest (IX20) relies on strict decoding: a manifest
field naming a status is an unknown field and is refused. The `*` emitter of
consumes (design 47 G §386) is held for the design writer's answer on model-usage's
`*.usage.*`.
Builds: design 47 G §89, §368, §387
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
A manifest naming a status is refused as an unknown field (strict decoding); the
two seat-table tests read the seat definitions as contracts now answer them.
Builds: design 47 G §6, §21, §23, §28, §101, §95 test
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Design 47 *A module's registration* (b229f5c4 lines 480-481): a unit test of the manifest validator
refuses a template in the manifest of every part on its list, the runner's included. The row of
TestTheIndexerJudgesEveryManifestOnce now judges mesh-delivery-pipeline beside mesh-config; it fails
with the list as it stood before 0ad243c1.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Builds ADR 0666 §4 (the runner is a foundation part: the bus module's own delivery waits on its
pipeline), changing ADR 0619 §1 and §3: judge.Foundation, the one list in code, gains
mesh-delivery-pipeline, so its manifest keeps its state in the old sections and a request of
new-form bus state by it is refused.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
A merge waiting behind a gathered group is named by indexer_pending under its own key; when the
group ends it joins the group's revision under the oldest member's key, so its own key was never
said taken. takenWaits now also says every claimed entry's key, no key twice. T8 checks the merge
behind the group ends under its own key.
Builds: design 47 "Taken in by the indexer it names" (A wait is bounded, said and recoverable); 1966/AC195-1, AC195-3
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
A merge taken in with no take-in.pending said for it (read from indexer_pending at a
watchman restart, or said pending by the own-build-unknown path) ended with no taken
event, so the watchman raised take-in-waits for a wait nothing held. takeInWholeBy now
says taken for each wait WaitsOf names for the claimed entries (a revision by its oldest
merge's key, a group by its g. key) as well as for its said waits, without saying a key
twice. Drops are unchanged.
Builds: design 47 "Taken in by the indexer it names" (A wait is bounded, said and recoverable); 1966/AC195-1, AC195-2, AC195-3, AC195-4
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Both manifests drop the read mesh-delivery-watchman.presence and invoke seat:mesh-watchdogs.presence; buildrun's ReadsCalls, its presence bucket and both watchPresence copies go. The machine is asked once when the bound key expires; a node that returns is asked again on manifest-reads-changed, and the finding clears on its answer. The indexer's finding is stamped with the wait's clock.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Both write it through buildrun.ReadsCalls over enginereads Keeper.Unanswered as the assigner does, read the watchman's presence for a machine heard, arm a bound key that expires at the five minutes (no timer) and clear the finding when the node answers or its machine is away.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
indexer_judge with a digest and the start pass's judgeStale wrote the verdict and said nothing, so a part waiting on manifest-accepted never heard it.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
A message heard on the forge is the forge bridge heard, the callee of the call:
after each one a merge unread since CallUnansweredAfter or longer writes the
finding naming the bridge's call, and a merge no longer unread clears it. While
nothing is heard on the forge (the bridge's machine away) no finding is written;
the merge is read again when the forge is heard. No timer.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Without the unjudged state the bind's pass accepted the refused manifest with a
warning and the waiting one, and said manifest-accepted for both; the row settles
Q3: the indexer says what grants follows, so the grants part is unchanged (no D8).
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
A judge pass that failed lost the set of manifests the take-in newly wrote, which
lived only in its memory: the next pass found no verdict, took each as accepted
before any verdict (ADR 0579 §1), and wrote a refusal as a warning. The take-in
now keeps each new digest in the indexer's own state unjudged before it writes
the module naming it; every judge pass judges those as fresh and ends a key once
its verdict is written or no module holds it. indexer_read_unjudged reads the
state; indexer_judge judges it again by hand.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
The indexer's call for a merged message is a kept call (CallKept). A load that met a deadline or no
responders keeps the entry as unread (Pending.Unread, indexer_pending's unread), with a line that
names the read again rather than a drop; after every message heard on FORGE, of any kind, an unread
merge is evaluated again. The bridge's own answer stays lost. indexer_take_in_pending already reads
the message again (Q8).
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
#650, its repository's head, was dropped on the advice of a line that named a drop where nothing
covered it; its changes would never have been taken in. The rule lived only in the record and the
advice; the tool now checks it, and the advice names the read again.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
Note 155: a manifest-reads-changed said before the assigner's consumer existed was never heard, and
ace's bootstrapped statement stood. Each part registers the engine-reads keeper's AtBind on its hub
and calls the verb as a kept call (CallKeptOn). The asks-at-bind half (Q7) is not in this commit.
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
mesh/check failed (6): integration: mesh-delivery-indexer/cmd/mesh-delivery-indexer.TestIndexerWritesModule…; and 5 more | 3a63813b3d75 on fb69c8dee691
An indexer that started while the bus's storage was down read no published package,
took every import for unpublished and wrote the version line over ~130 modules'
fingerprints, which a later pass kept through the build's shortcut. A failed or empty
read of the packages state, where held modules were computed from published ones,
now fails the pass and says why; a version line clears the import form it was
computed beside; indexer_fingerprints_again computes the import form again by hand,
acting first and recording the hand act after, with a bound.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
mesh/check failed (2): integration: mesh-delivery-assigner/cmd/mesh-delivery-assigner.TestAProposalIsAnswer…; and 1 more | af3b678a92f0 on 042b8d1fc160
holdLost builds a pending take-in naming neither WaitsFor nor Unknown, which TakeIn's check refused, so the hold stayed
in the journal and the watchman never saw it.
Quick fix: set Unknown on holdLost's event. Thorough fix (chosen): the check accepts a pending revision that names Lost,
the field made for it; one naming nothing is still refused. Tests: a row accepting Lost, the refusal row kept, and the
lost-hold scenario encodes its said event.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
Quick fix: none smaller than this (the bridge fix alone leaves a covered merge needing the bridge).
Thorough fix (chosen): loadNewest asks takenAlready (already used for group members) before loading the newest merge of
a repository; at or behind taken it is marked Covered, said once in the log, and never read. A merge whose ancestry
cannot be asked is read as before. Test: a row pair behind/ahead of taken with a bridge that cannot answer.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
mesh/check checking 173a7654ba61 on e39ec444bd39 | novox/mesh-delivery#184 in group fix/1966-views-durable
A consumer is made from now, so an event said between a first view and the consumer is never delivered; the hub says when the bus made it (EventHub.OnBound) and each follower asks again if behind (Follower.ConsumerMade).
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
mesh/check failed (3): mesh-build-go: the go.mod of novox/mesh-sdk at 396511b7a276, beside the change, cann…; and 2 more | 00232c71977b on 9c6bf236b6b1
Every recompute wrote every key of its modules state again with identical bytes: recomputeLocked
compared the package versions with reflect.DeepEqual across two map types (the contract's
map[string]string and sdkstep.PackageVersions), which never match. Each write was a views
event, and a reader of the views took each as a gap and asked the whole first view again.
The comparison is by maps.Equal now, and write itself skips an answer whose bytes are the
bytes held, for every caller and every state it writes; the merge's written list counts only
real writes.
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
mesh/check failed (2): mesh-delivery-checker: no published of the tagged version of go-sdk of mesh-delivery…; and 1 more | ee6fd92b4d1a on 7f412185525e
Every reader of the seat list holds the bootstrapped seats from its start
(ADR 0636 §2), so a manifest naming one is read by every node-engine
whatever its statement names. graph.MissingReads, in the Delivery domain's
SDK, is the one rule both holds judge with; mesh-sdk is not changed.
ace's engine states no seat, so the want of the node-engine's own build
0bd8cbad (needing mesh-catalog) and of restic (needing node-backup) were
held on ace: the engine that would state them could not be delivered. The
indexer's hold judges only mesh-wide reads today, so its verdicts do not
change; it takes the rule so the two stay one.
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
mesh/check failed: mesh-build-go: the change's manifests cannot be judged: the seat list is not read (the seat list is … | 2e9f23f34828 on 68581bed7e36
The review of 0f5c186b: counting each record's packages made 94 sub-package
paths, commands among them, known names, which design 32 forbids; the seven
names refused live are each their record's module (issue 1966).
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
The indexer's judge refused manifests whose `packages` name a Go package that no
manifest declares as a package artifact: such a package has no series key, and
knownPackages took series keys only, though each module the trunk published has
a per-module record in the packages state naming its Go module and packages.
knownPackages (and the checker's PackageNames) now also count each record's
module and packages[].package; an unreadable state still judges no name.
Quick vs thorough: this is the quick fix, the smallest change that lets the
trunk's own records name what the manifests name. The thorough fix is that a
build module builds Go package artifacts, so every Go package gets a series
(the registry milestone); then the records stop being a source of names. Done
now because the 15 refused manifests hold the bootstrap of the registry delivery.
mesh/check pass 71a56d4606c9 on b73315ffe05c | carried from a37ee99b41d5 | unit 495 run, 947 kept | integration 494 run, 1014 kept | composition passe…
Both were published with the JetStream acknowledgement awaited, a request and response, for ten seconds each, and
manifest-accepted once more on failure. On a bus refusing the subject (the old grants do not grant the new indexer
mesh.seat.mesh-catalog.event.manifest-accepted) no acknowledgement ever came, so each judging pass took about twenty
seconds a manifest and the indexer never reached the forge's messages nor the seat definitions: the take-in stood
still. Now both are published plainly on their subject with the dedup id in Nats-Msg-Id, as an event is (the
operator, 2026-11-07: everything is event-driven); the stream that keeps the subject drops a duplicate by its id, and a
refusal is said on the connection's error handler, as the journal already shows. An error of the publish itself (no
connection) still goes to the caller, which retries once and writes the unsaid finding.
Quick vs thorough: thorough for these two events (every publish of a seat event by the indexer is now an event);
sayTakeIn keeps its acknowledged publish, said in the issue for 47/G.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
mesh/check pass e01d265decb3 on b73315ffe05c | carried from a37ee99b41d5 | unit 495 run, 947 kept | integration 494 run, 1014 kept | over bound: integ…
The running indexer (built at the registry merge) publishes every Go module of a repository it published before in
one forge listing; seatfiles, published at 6bc232eb and removed since, is not in the tree, so the listing fails and
every take-in of mesh-delivery is 'computed and not written' (journal 19:56:29: 'the directory
modules/mesh-delivery-indexer/seatfiles is not in novox/mesh-delivery'). mesh-delivery #165 fixed that in the new
indexer, which cannot run yet. The module comes back as it stood at 6bc232eb, imported by nothing, until the new
indexer runs; the follow-up removes it. The operator's bootstrap of 2026-11-07.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
publish asked the forge for every published module of the repository in one call; when the merge removed one (seatfiles), the whole call failed and a revision's own new Go modules stayed unpublished, so the take-in waited for a version only its own take-in would publish. packagesAt now reads the modules one by one when the tree lacks a directory and leaves the missing one out, said.
#163's group-wait end, the retried start and its subtest are kept whole; its
names follow the registry's translation off mesh-sdk go/delivery (trunk,
takein, meshdeliveryclient), as the rest of pending.go already does.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
mesh/check failed: novox: not composed on novox: mesh-delivery-indexer: frombus: mesh-delivery-indexer is wanted at src… | 0520c126195b on bab05c66b3cb
mesh/check checking 9c9ed7a1d8f1 on 2d201f781ced | novox/mesh-delivery#162 in group feat/b0-checking-program
The operator's answer: mesh-build-go reading the checker's state inputs broke ADR 0596 §2. The run ask's input now names
the verb seat:mesh-delivery-checker.input; the checker's tools serve it from the state inputs (Reader.Input, checked
against its digest), and the state is the checker's own again, read by no other module.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
The checking program's seat list parsed the definition format a second time beside the
indexer's judge. The indexer's reading moves whole into its own sibling module seatfiles
(a domain path, as takein), with ResolveRaw keeping every field as written for a request's
seats; the judge and the take-in read through it, and the checker's rules only find the
definitions and say why one is left out (the lead's ruling on D3, ADR 0634 §1).
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
The checker read any touched contracts module's definitions, skipped the
check that a definition names its own directory's seat, and copied the
indexer's tree reading. sdk/seatdefs now holds the reading and the rule of
which contracts module may define a seat; the indexer's keeping, its
revision seats and the checker's head seats all use it. Two heads defining
one seat fail the judging unless one hands it over to its domain's module.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
grouppackages is the Delivery SDK's (ADR 0634) and imports sdk/buildstep and sdk/trunk, not the deleted mesh-sdk/go/delivery.
The checker's packagesFor lays the group's tagged versions (design 51) over grouppackages.Heads, so a heard tag still stands
before a member's head; the composer and the trunk's manifest validator are built with no tags. Fetches carry the versions
in buildstep.Fetch.Packages, so withPackages is gone; the group's fetch names no beside ref, so the test of the node-engine
member beside reads its commit alone.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
One shared function (sdk/grouppackages) for the check asks, the judge, the composer and a candidate's builds, so a producer cannot leave a member out.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i