The node-engine refused the whole pass when two modules claimed a seat held once, or when a consumer's credential was
refused. Now the composer leaves that module out of the declaration and composes the rest: the module is returned held
(Resolved.Held, resolution.ResolveHolding), reaches the declaration as left out through the filter and the declaration
#218 already keep (Rendering.NotPlaced), and Declared.LeftOut names it. The second claimant of a seat is the one held;
its claim is not this node's holding. The rest-of-mesh view and the network use the same, so a node with a held module
stays on the network. Resolve stays strict for callers that cannot leave a module out.
Quick fix: hold only the credential refusal (resolve.go planForNow), about 20 minutes. Thorough fix, chosen: every
claim problem is attributed to its module (claimsOf) and both kinds go through the one left-out path of ADR 0163 rule 6,
in the declaration, the filter and the network, so no per-kind refusal of a pass remains in the composer. Left for the
next step: a declared-and-not-made own secret (NotMadeError) and the Foreseeing-mode refusal still refuse the pass; the
frombus candidate path holds those by stub already.
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
Rules skipped a left-out module's expose and reaches, so its listens
opened at the manifest's default source and an operator's narrowing for
the node was dropped (ADR 0046). Its exposure is now read like any
module's (exposureOf); where it cannot be read for that module, its
listens open no wider than the mesh (noWiderThanTheMesh), never at the
manifest's default.
Left for the thorough fix, composing a left-out module as what runs of
it (Carried, as a held module is): the filter also opens for a left-out
module that never ran on the node, and it opens the new manifest's
listens rather than what the old composition runs.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
A module left out of the declaration for a setting its new definition no
longer composes (ADR 0163 rule 6) keeps running what it ran, but
resolutionCompose dropped it from the modules the filter is derived from,
so the filter closed the ports it still serves. On novox, 2026-11-09
07:46-09:24 UTC, the artifact store's want at build 6e1dfaa8 (listens on
5100, no container publishes 5000) met the node layer's ports
{"5000": 5100}: GivenPorts refused it, distribution was left out, and
5100 closed while the old registry container served there; every build
failed "dial tcp 10.10.0.1:5100: i/o timeout".
The filter is now derived from the composed modules and the left-out
ones; a left-out module's settings (exposure) are still not read.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
The provider held on its machine is composed apart, so no module of the composed set serves the provision; its
manifest's served values reached the consumer's binding raw and the binding refused the consumer for a
${bound:route:name-web} it does not require (the group check of 8a80e8e86858 on novox, mesh-build-node beside a held
gitea). Each such key is now left out and said on the need, as a provider elsewhere leaves it out (ADR 0346).
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
Eight lists of seat verbs (checker, enrolment, artifact sweep, delivery, node-resolver, node-nfs-server,
node-mounts, mesh-config's input) and their schema helpers were read by nothing but one test, and drifted
from their seats (B0's verb input never reached the checker's copy). A guard row in the seats test finds
any list of the catalogue's verbs written in the node-engine's code.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
The state, events and types of the seat mesh-module-assigner say assignments; the legacy node key form is gone from the
reads; the dead seat-verb list of the retired name is deleted. The placement guard and the placed-file sense stay.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
The provision artifact-store retires, so the store is found by the holder of
container-image-registry and the listen it opens to the mesh, on the port its
node put it on; every name of the store, oci-artifact-registry's too, answers
that address. The engine states form:seat-reach with its contract.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
The group's mesh-build-go requires go-package-registry, which the forge
now provides; the stand-in listed the forge's offers by hand and missed it,
so the test failed against the group's catalogue. It now takes them from
the catalogue's gitea manifest, so a registry the forge gains needs no edit.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/check being carried to 966093d8d067 on fabfdf04f78a | from 4d47ff5ce743, mesh-catalog dd458cb155f5
The vault judged a module handed only when its assignment already carried a handing plan, and the node-engine followed
that word: a module with no plan was composed the old way, refused for a key only the provider's helper answers
(forge-account's ssh_alias), and so never got its plan. resolution.Handing is now the manifest, its build and the
machine alone; the vault's word is read only to say where the two disagree. A refusal of a file or an own secret the
provisioner's client should fill now says "handed module not handed" and why, never only the keys a binding lacks or a
secret to make.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
ADR 0593 §7: the environment's rendering left mesh-sdk for the node-engine,
so its two integration tests (the POSIX environment sourced twice, and
the service manager reading the systemd rendering) move with it.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0593 §7: the composition is the node-engine's, so its tests hold
what the indexer's judge tests and route-proxy's tests proved by
composing: a bundle's words per machine, a Go bundle's delivery, the
credential form in a handed plan, settings refusals, placeholder and
vault refusals, the session's files, a field set aside composed whole,
route-proxy's manifest composing for a machine, a route endpoint's
machine port in six cases and the plan's route entry end to end. Two
table tests, one subtest per item; route-proxy's manifest is captured
beside the catalogue.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk
carries no composition rule. The catalogue functions only the
node-engine's composition reaches (Resolve, Resolution's Compose,
Declaration, DataItems, LeftOut, Rules and the rest, the settings,
placeholder and template refusals, the rendering helpers) are copied
with their tests into internal/compose/resolution; a method of a
mesh-sdk shape becomes a function taking it first. The composition
calls its own copies, and the captured catalogue its tests read lives
here now, shared by mesh-compose's tests.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL