Commit Graph
1147 Commits
Author SHA1 Message Date
jschoubben dc1aee51d9 W13.5: the node agent asks mesh-recovery for a restore point before a form change and restores it at a revert
Before a move across a kept data's form change the node agent asks snapshot-kept and waits for the ended of its own act; at a revert it stops the newer build (Env.Stop), asks kept-points, asks restore-kept with the snapshot of the point of the form and fingerprint it reverts from, waits for restored, applies the reverted build, and calls the point's catch-up as the module's tool through the tool runner. The wait is in the have (ask-at, act), bounded by a bounds key of the state bounds (recovery-wait-minutes, 90), and each ending is read as the table of 560 says. The manifest consumes mesh-recovery's ended and restored and invokes its three verbs.

Builds: design 47 G §296, §297, §554, §555, §560, §630, §631, §632, §633, A-77, A-92, A-98, A-108
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 00:16:31 +01:00
jschoubben cf378f9a25 G §421, §683: the node-engine reads the entry its want names by fingerprint and keeps its entries and wants
The node's own composer reads the catalog half through meshcatalogclient's Entries cache over its own calls of
mesh-catalog's verb entry, and no longer watches or reads the indexer's modules, manifests and verdicts or the
builder's builds: a module's manifest is its entry's, each artifact's reference is made from the digest its want's
part names (artifact-store://<module>/<artifact>/blobs/<digest>, A-50). A want whose entry is asked or not found is
held, its have the phase held with a detail opening entry-asked: or entry-missing: naming the fingerprint. The
entries and wants it composes from are kept in composed-<node> (entry.<digits> and want.<module>), written before
the composition that uses them, read at start before anything is asked, a kept want standing until the wants'
live read answers, and dropped when nothing names them. The shadow keeps its reads (G §628).

The node grant gains the verb entry and the running stream's consumer calls; OverNATS hears the running stream
as the link's session does.

Builds: design 47 G §421, §683, §614, §628, A-47, A-50
2026-11-11 23:55:50 +01:00
jschoubben 2b916ac043 G A-98: the node agent gains Env.Stop, which stops a module's units and containers and removes nothing
Builds: design 47 G §297, A-98

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-11 23:51:09 +01:00
jschoubben 7c7b5e2d68 G A-92: the node-engine's manifest declares the state bounds, a lifetime per key, in its old section
Builds: design 47 G §560, §557, §627, A-77, A-92
(the seat definition: mesh-contracts 2ae0c679304b828a3973dd23ecd19861577d141d)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-11 23:48:16 +01:00
jschoubben 5173f2a31c W13.8: the node-engine fetches a kept build through the build node's kept-artifact, the node taken from the want's kept-on
A want that names a node in kept-on, for an artifact its parts name, is fetched through kept-artifact of that node's build seat and
read as an object on the bus, checked against the digest; with no kept-on it is fetched from the store, and the builder's builds
are read no more (the apply hook, the fetch and the object read from bc8fbc7, its node and fingerprint from the want).

Builds: design 47 G §271, §526, §421 (A-50)
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-11 23:39:36 +01:00
jschoubben 38e13ef030 H-13: the node-engine's seat-list and held-module findings go through mesh-sdk's held writer
The seat list's five-minute finding and the finding of a held module are raised as they happen, so they use the held
writer (seeded at Start, Held() answers what stands) over the contract of the seat mesh-conditions; the keepers keep no
set or sweep of their own, and the writer is started before the seat list reader writes or clears any. The engine's own
finding stream stays its foundation stream mesh-host-findings.

Builds: design 47 G §529, A-29, A-30, A-37, A-38, A-40
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-11 22:37:21 +01:00
jschoubben 189ed10c36 The node-engine's compositions use the catalog key's codec meshcatalogkey, as meshcatalogclient's wrappers go
Builds: design 47 G §670

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 21:18:40 +01:00
jschoubben 75f5c64646 The node-engine says no capabilities-changed: manifest-reads-changed alone says a node's capabilities, as the contracts' K6 has the seat
The join with mesh-contracts' K6 (7d730a4a) removes the event and its body; H-3's second source of the same fact goes (haveState.capsSaid, capabilitiesToSay, sayCapabilities), the test asserts none is said.

Builds: design 47 G §590

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 21:13:24 +01:00
jschoubben 5d3b446988 H-8: a want's parts are checked by the digests the composition fetches
A want with parts is applied only when every fetched archive, process and container
digest is among the parts and every part is a fetched digest; otherwise the module
keeps running what it has and its have is held with detail parts-differ naming the
digests. A want with no parts is applied as before.

Builds: design 47 G §524, §379

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 15:47:04 +01:00
jschoubben ce01ec1f68 H-13: the node-engine's findings are written and said by mesh-sdk's finding writer
A finding is written in the node's state findings and followed by finding-written or finding-cleared on the engine's own
stream mesh-host-findings; the engine states every finding it observes at its start (the seat list's finding only while the
reader waits for the list, else not) and when the keeper asks, and answers an ask by a new statement. The node's grant in
the golden file gains the stream's publish, the ask stream's consumer, and the whole of its state findings.

Builds: design 47 G §383, §384, §390, §461, §485, §503

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 14:15:16 +01:00
jschoubben 602ed830e9 H-15: the apply guard and the yields read the node-engine's module from the entry claiming its seat
The module is the one whose catalog entry claims node-engine, else the one this node heard run the build its own
fingerprint names; no name is fixed in the guard or in the compose.

Builds: design 47 G §364, §527, §428

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 14:05:43 +01:00
jschoubben a073a001c5 H-7: the node record states the capability want-parts
Builds: design 47 G §525, §94, §192

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 14:00:21 +01:00
jschoubben 45e2b946c7 H-5: the seats a node passes on are decided from what every node said it runs, by SeatsToPassOn's new input
The node follows the node-engine seat's running events (an ordered read of the last message of each subject, then a durable
consumer), keeps what each node runs by `at`, acts on none until the first read ended, and hands the composer each node's
heard build with the manifest read by the event's digest; compose resolves the passes through catalogue.SeatsToPassOn
(heard, entries) with the trunk's entry for a node that said nothing.

Builds: design 47 G §199, §249, §459, §536, §556

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 13:58:33 +01:00
jschoubben b41a0d59b6 H-14: a module held for its claim is the finding module-held until it is composed or no longer wanted
Builds: design 47 main file (A claim problem holds its module), test 55

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:12:55 +01:00
jschoubben f3813a279e H-6: the seat verb process-builds reads the build each process was started with; the engine keeps no callers table
Builds: design 47 G §262, §245, §440, §447

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:09:56 +01:00
jschoubben 420087ab14 H-4: running says stopped, with no fingerprint, once the have no longer holds the module
Builds: design 47 G §365, §404

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:06:10 +01:00
jschoubben 26581d87ed H-3: the node-engine says composed, running and capabilities-changed on the seat's subjects
Builds: design 47 G §260, §227, §226, §177, §309, §404

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:05:18 +01:00
jschoubben 730860b274 H-2: every service and container is started with MESH_FINGERPRINT, the fingerprint of the want it applies
Builds: design 47 G §201, §205, §239

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:03:47 +01:00
jschoubben decbce4c54 H-1: the node-engine claims its seat, says its findings on its own stream and hears running
Builds: design 47 G §364, §387, §199, §368, §411, §438

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 12:03:13 +01:00
mesh-tools 14c22b4a45 Merge pull request 'The seat-list finding is read from the node's own state, so a restart clears it (issue 1966)' (#223) from fix/1966-seat-list-finding-from-the-bus into main 2026-11-11 01:34:11 +00:00
jschoubben e64c8ad0ca The node's golden grant reads its own findings, as the grants part composes it (issue 1966)
mesh/delivery merged: source.main moved to novox/mesh-host@14c22b4a4586
mesh/check checking e64c8ad0ca62 on 14c22b4a4586
mesh-grants gives the engine the owner's read of its state findings for its own node's keys (EngineFindingsGrants); the golden
grant held only the write, so the engine could not read the finding it clears at the first full read.

Builds: design 47 H-7, ADR 0636 §1 (the finding is cleared at the first full read), ADR 0596 §2 (the owner reads its state), issue 1966

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 02:23:10 +01:00
jschoubben 6304332ad5 The seat-list finding is read from the node's own state, not kept in memory (issue 1966)
A new node-engine process cleared nothing at its first full read of the seat list, because the Waiter remembered in memory whether
it had written the finding; ace and g14 kept the condition for ever. The Waiter now asks the node's state findings whether the
finding stands, clears it at the first full read and writes it at the bound only when it does not stand.

Builds: design 47 H-7, ADR 0636 §1 (the finding is cleared at the first full read), issue 1966

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 02:20:42 +01:00
mesh-tools 783a2d2207 Merge pull request 'The node-engine says its events once through a transport fault, and an unsaid one at the next link (ADR 0668; issue 1966; group fix/1966-call-made-once)' (#222) from fix/1966-call-made-once into main 2026-11-10 07:20:32 +00:00
jschoubben d581acdeda H4: the builder machine of the toolchain tests has the tool runner's seat-settle-delay (issue 1966; mesh-catalog's issue 1748, ADR 0664 §5)
mesh/delivery merged: source.main moved to novox/mesh-host@783a2d22073f
mesh/delivery-group group fix/1966-call-made-once merged: every member is merged
mesh/check checking d581acdedae3 on 783a2d22073f | novox/mesh-host#222 in group fix/1966-call-made-once
Since mesh-catalog 6b8e7fc6 the build modules ask the capability seat-settle-delay of the machine, so on
the stand-in builder without it mesh-build-go and mesh-build-node were left out as unhostable and both
toolchain tests failed against the catalogue's main, on mesh-host's trunk as on this group's head.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 05:57:04 +01:00
jschoubben 9cd03a7430 H3: the row of sayOnce feeds the old JetStream client's own no responders, nats.ErrNoStreamResponse (issue 1966, ADR 0668 §1; review round 1, finding 2)
mesh/delivery closed: a newer head of the same pull request
mesh/delivery-group group fix/1966-call-made-once rejected: composed together: the checker's verdict at the members' heads (c54b617d200d): mesh-delivery-checker
mesh/check failed: mesh-delivery-checker: no published of the tagged version of go-meshconditions of mesh-health-and-re… | 9cd03a7430cc on f50442ac7a2d
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 04:12:04 +01:00
jschoubben 5aa6d39a98 H2: an engine event not said is kept and said at the next link's opening (issue 1966, ADR 0668 §4)
A failed say was only a line in the engine's log; now it is said again when a link opens, beside the
statement made while no link was open (proved by a step of the node key test, with H1's publish).

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 02:57:34 +01:00
jschoubben 4685610c19 H1: the node-engine publishes its seat's events again through a transport fault, under one message id (issue 1966, ADR 0668)
One publish of manifest-reads-changed with a 10 s deadline was the likely loss behind note 155; the
stream takes the id once, so publishing again is safe.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 02:57:34 +01:00
mesh-tools f50442ac7a Merge pull request 'An unread seat list holds what is new, says so, and is read again by the operator's sessions (issue 1966; group fix/1966-seat-list-unread)' (#221) from fix/1966-seat-list-unread into main 2026-11-10 00:44:44 +00:00
jschoubben 5c353cfc7b S3: the read seat-list answers the operator's sessions and the healers, as its seat says
mesh/delivery-group group fix/1966-seat-list-unread merged: every member is merged
mesh/delivery merged: source.main moved to novox/mesh-host@f50442ac7a2d
mesh/check checking 5c353cfc7bf0 on f50442ac7a2d | novox/mesh-host#221 in group fix/1966-seat-list-unread
The node-engine seat's definition names "the operator and the healers" for
both seat-list verbs, and design 47 G keeps it; the read was opened to every
proved caller on a ruling the review withdrew. node-tools stays on both: every
console call is proved as its machine's tool runner (issue 627, issue 1966).

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 01:16:05 +01:00
jschoubben a484d5f960 S5: the whole node reads its seat list after a holder that re-served
The live case of ace, in process against a real bus: the stand-in of the seat
mesh-catalog answers as nothing serves it (no responders) while the node's
reader first asks, then serves; the same reader reads the list within the
bus's retry bound, with no event of the seat and no hand act (issue 1966,
ADR 0636 §8). The test of an unread list now reads the reason that names the
bootstrapped seats.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 00:48:14 +01:00
jschoubben 4af6c274b8 S4: an unread seat list holds a module before its build is read
On ace, a node-engine left on its bootstrapped seat list could not find the
artifact store's seat, refused avahi's archive reference and with it the whole
pass, so the seat-list hold never ran and every module said "reaches no
artifact store". While the list is unread, a placed module whose seats are not
all bootstrapped is now held as it runs before anything of its build is read
(frombus.Scope.Held), its reason names the bootstrapped seats the node holds,
and a pass refused whole says the unread list first (issue 1966).

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 00:40:53 +01:00
jschoubben 7bf7e29a32 S3: the seat-list verbs answer a proved operator's session
seat-list-again answered person.<name> and the healers, but every call through
the mesh MCP server is proved as its machine's tool runner (issue 627), so no
operator's session could make a node read its seat list again. node-tools now
stands for that session; the read seat-list is open to every proved caller, as
ADR 0636 §7 limits only the read again. The verb names come from the contract.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 00:32:44 +01:00
jschoubben 81bc0cc388 S1: keep the bus's "no responders" beside ErrNotAsked on an ask
A request that reached no one is asked again by mesh-sdk's busretry only when
it can see the bus's own error; the node-engine's ask dropped it, so the seat
list's first read, which fell into its holder's re-serve, was never asked
again (issue 1966).

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-10 00:29:54 +01:00
mesh-tools 9d8647aa0f Merge pull request 'The node-engine leaves an unchanged unit running across its own replacement, and says what changed when it restarts one (issue 1966)' (#220) from fix/1966-engine-restarts-unchanged into main 2026-11-09 22:09:40 +00:00
jschoubben aa649d85a0 The restart line names no part of a value; the new rows join existing tests (issue 1966, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-host@9d8647aa0f56
mesh/check checking aa649d85a065 on 9d8647aa0f56
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-09 22:56:42 +01:00
jschoubben bcd815a6bb A tool runner is no longer restarted by a build of the engine: owned paths name the directory of every build, and a restart names its cause (issue 1966)
The tool runner's unit carries the paths modules own, for the holder of node-files. The engine's own
archive is unpacked into a place named for its build, so every engine replacement changed that word
and restarted the tool runner with nothing of it changed (novox 21:16, 22:25, 22:38 on 2026-11-09).
A resource unpacked into a place named for its build now owns the directory holding every build.
The restart line now names the unit's directive, word and key that differ, never a value.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-09 22:49:20 +01:00
mesh-tools 6e461bd24a Merge pull request 'A claim problem or a refused credential holds its module, not the whole pass (issue 1966, recovery)' (#219) from fix/1966-s1-partial-pass into main 2026-11-09 17:54:55 +00:00
jschoubben ef41fa2e27 The node-engine's live path holds a module whose claim or credential fails (issue 1966, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-host@6e461bd24aa5
mesh/check being carried to ef41fa2e2796 on 6e461bd24aa5 | from 7c483da93a03
compose.CompositionsHolding returns the modules the declaration leaves out for a claim that cannot be held or a refused
credential; frombus composeEach holds each with those words, so the node-engine keeps what it handed of the module (no
stop of a running module), the candidate answer and the check's sandbox name it refused, and the rest composes.
CredentialsNeeded asks nothing for a held module. Resolve and checkClaims move to a test helper (production uses
ResolveHolding and holdClaims); a pass refused anyway names a held module's reason among the others.

Quick fix: Declared.Held read in the composer only. Thorough, chosen: the same held words reach every reader of the
composition (selfcompose, ComposeSent, the candidate answer) through composeEach's one hold path.

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
2026-11-09 13:04:55 +01:00
jschoubben 868ee6beb0 A claim problem or a refused credential holds its module, not the whole pass (issue 1966, S1 and S5)
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
2026-11-09 12:52:54 +01:00
mesh-tools 7c483da93a Merge pull request 'The filter keeps the openings of a module left out of the declaration that still runs (issue 1966, recovery)' (#218) from fix/1966-filter-keeps-openings into main 2026-11-09 09:49:15 +00:00
jschoubben 17a4ac620c A left-out module's openings keep its per-node narrowing (issue 1966, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-host@7c483da93a03
mesh/check checking 17a4ac620c07 on 7c483da93a03
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
2026-11-09 10:43:48 +01:00
jschoubben 95f45b1a74 Keep a left-out module's openings in the filter: it still runs (issue 1966)
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
2026-11-09 10:36:55 +01:00
mesh-tools 2019122379 Merge pull request 'Gate record of mesh-host's forge-made merges (issue 1966, recovery)' (#217) from fix/1966-forge-made-merge into main 2026-11-09 08:45:52 +00:00
jschoubben e504c12940 Record this repository's forge-made merges in the delivery gate, so the indexer takes them in (issue 1966, recovery)
mesh/delivery merged: source.main moved to novox/mesh-host@20191223794a
mesh/delivery-group group fix/1966-forge-made-merge merged: every member is merged
mesh/check checking e504c129401b on 20191223794a | novox/mesh-host#217 in group fix/1966-forge-made-merge
Merges made on the forge directly since 2026-11-09 07:04 UTC have no gate merge record,
and the indexer holds them; an empty merge through the gate covers this repository's head.
Second of its kind: the group's mesh-delivery member removes the need (the forge bridge
reads a forge-made merge's pull request from the forge).

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-09 09:17:02 +01:00
mesh-tools 25d677d20c Merge pull request 'The node-engine says why it composes a wanted module at no composition, and hands again one its agent lacks (issue 1966, recovery)' (#216) from fix/1966-views-page-time into main 2026-11-09 08:13:14 +00:00
jschoubben 6bde46cb00 The wait-for-the-composer step settles a want again without a real sleep and counts only ghost's own tells (issue 1966)
mesh/delivery merged: source.main moved to novox/mesh-host@25d677d20c93
mesh/delivery-group group fix/1966-views-page-time merged: every member is merged
mesh/check checking 6bde46cb0084 on 20191223794a | novox/mesh-host#216 in group fix/1966-views-page-time
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-09 09:09:40 +01:00
jschoubben 3ea81943f5 The wait-for-the-composer test settles the want again without a real sleep (issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-09 09:05:30 +01:00
jschoubben 3dc4307aec The node's words for a want it composes nothing of are said once per reason, and proved on the live paths (issue 1966)
The said-once keys no longer hold where the indexer's picture stands; a module composed from the manifest for want of a done
build is named in Pass.Unmade; the agent's wait is told once per want and again after the composition was there; the two tests
are folded into existing ones.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-09 09:04:45 +01:00
jschoubben 5f37a43b91 The node says why it composes nothing of a want, and hands again what its agent waits for (issue 1966)
Every pass names each wanted module it made no composition of, with why (Pass.Unmade, the verb compose, one journal line per
change); a want not taken is said; the agent says once per want that it waits for the composer and why, and tells it, so a
composition the composer believed handed is handed again.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-09 08:58:33 +01:00
mesh-tools 9b55bcb127 Merge pull request 'The node-engine fetches every artifact before it replaces anything, and a failed apply no longer claims the old composition runs (issue 1966, recovery)' (#215) from fix/1966-fetch-before-replace into main 2026-11-09 00:16:25 +00:00