Commit Graph
100 Commits
Author SHA1 Message Date
jschoubben f87c9720ed J2: the tool runner tells a subscribed bundle how its module's consumer stands, as mesh/heartbeat (stdio.OnHeartbeat), at each idle beat and once Missed (ADR 0615, ADR 0621, issue 1966)
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 14:10:25 +01:00
jschoubben d71cd5cef6 TLS-5, TLS-6: the views package is mesh-sdk's (go/views), and mesh_first_view_again is recorded through mesh-hand-acts before it is done (ADR 0615 §6, ADR 0565 §10, issue 1966)
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 12:14:14 +01:00
jschoubben 31247dff6b TLS-5, TLS-6: the tool runner holds the indexer's manifests and modules and the assigner's placement and seat-holders from their first views and views events, never their state, and the console gains mesh_first_views and mesh_first_view_again (ADR 0615, ADR 0621, issue 1966)
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 12:06:20 +01:00
jschoubben 8b1ab467a9 TLS-1, TLS-2, TLS-3: the runner declares its own secret ledgers, refuses a bundle tool named as a ledger repair, and states the capabilities of its calls in its PING (issue 1966)
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 11:40:03 +01:00
jschoubben 7fd9d893c0 Give node-tools new manifest bytes (version 2), the recovery of the moment for a stale verdict
mesh/delivery merged: source.main moved to novox/mesh-tools@84ede95c4af7
mesh/delivery-group group feat/l3-final merged: every member is merged
mesh/check checking 7fd9d893c0a5 on 84ede95c4af7 | novox/mesh-tools#60 in group feat/l3-final
The running indexer holds a refusal from 21:14 for the exact bytes of this manifest, which says tool-runner again. A new digest is read afresh; the thorough fix of stale verdicts is in the indexer in this group (issue 774).

Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
2026-11-04 00:44:17 +01:00
jschoubben 0fb4591c9d Pin mesh-sdk 85ba0a9a70d8, the group's head of feat/l3-final (issue 774)
mesh/delivery closed: a newer head of the same pull request
mesh/delivery-group group feat/l3-final checking: 3 of 5 member(s) ready
mesh/check failed (2): unit: mesh-provisioner-client/cmd/mesh-provisioner-client.TestNatsANodeComingBackFil…; and 1 more | 0fb4591c9da9 on b4819dc1fb73
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
2026-11-03 23:43:11 +01:00
jschoubben 7da4c55752 Put tool-runner back in node-tools' manifest (L3 final, issue 774)
The judge that knows the word runs now.

Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
2026-11-03 23:09:34 +01:00
jschoubben 40e0e8282b Take tool-runner out of node-tools' manifest until the judge that knows it runs
mesh/delivery merged: source.main moved to novox/mesh-tools@b4819dc1fb73
mesh/delivery-group group fix/l3-words-after-judge merged: every member is merged
mesh/check being carried to 40e0e8282b38 on b4819dc1fb73 | from 01ee2ef39488, mesh-catalog e6de42630355, mesh-delivery 4154c3040cee
The running indexer's judge refuses the word, a refused manifest holds the bus's user list, and so the indexer build
that knows the word is never granted. The node-engine on main and node-tools find the runner by its name; the grants
part keeps the runner's users as they run while no manifest says it; the word comes back once the new judge runs
(issue 774).

Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
2026-11-03 21:28:29 +01:00
jschoubben 8b8a760047 Pin mesh-sdk b7abe203a929, the group's head of feat/l3b-bus: it keeps, deprecated, the exported names the running parts still use
mesh/delivery merged: source.main moved to novox/mesh-tools@01ee2ef39488
mesh/delivery-group group feat/l3b-bus merged: every member is merged
mesh/check checking 8b8a7600479e on 01ee2ef39488 | novox/mesh-tools#58 in group feat/l3b-bus
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
2026-11-03 18:50:12 +01:00
jschoubben db3dd04be7 Pin mesh-sdk cf5812101b0b, the group's final head of feat/l3b-bus (the module graph left mesh-sdk)
mesh/delivery closed: a newer head of the same pull request
mesh/delivery-group group feat/l3b-bus checking: 2 of 4 member(s) ready
mesh/check checking db3dd04be7b6 on 8c1e04dd3709 | novox/mesh-tools#58 in group feat/l3b-bus
2026-11-03 17:15:17 +01:00
jschoubben d13890b944 Pin mesh-sdk 65b7adc8bdd9, the group's head of feat/l3b-bus 2026-11-03 17:15:17 +01:00
jschoubben b3903446f9 Remove the TypeScript runtime code that called the old catalog module's tools; a test finds no file naming one (ADR 0604 section 4, issue 774) 2026-11-03 17:15:17 +01:00
jschoubben e550c87a29 Pin mesh-sdk e7ce86ff62b5, the group's head of feat/l3b-bus (review round 2) 2026-11-03 17:15:16 +01:00
jschoubben ff7661a136 Pin mesh-sdk 825483043549, the group's head of feat/l3b-bus (review round 1) 2026-11-03 17:15:16 +01:00
jschoubben 84533edf2e Pin mesh-sdk 09ec82cb3551, the group's head of feat/l3b-bus (ADR 0601) 2026-11-03 17:15:16 +01:00
jschoubben ea516ece5a node-tools says it is the tool runner (tool-runner), so mesh-sdk and its readers never know it by its name; pinned at mesh-sdk a973bfa (issue 774, the operator 2026-11-03) 2026-11-03 17:15:16 +01:00
jschoubben 43d3fba501 Pin the group's mesh-sdk head f8bd12e in place of the local replace (issue 1966)
mesh/delivery merged: source.main moved to novox/mesh-tools@8c1e04dd3709
mesh/delivery-group group feat/bus-state merged: every member is merged
mesh/check pass 43d3fba501d3 on b8e42cf54cf6 | unit 6460 run, 262 kept, 27 skipped | integration 6639 run, 264 kept, 35 skipped | over bound: unit, in…
2026-11-03 15:35:30 +01:00
jschoubben df929b48b5 Leave the own secret ledgers out of node-tools' manifest until the vault holds it on every machine, reading a missing file as no ledger credentials; grant the test's ledger account as the grants part does (issue 1966 T6) 2026-11-03 15:29:47 +01:00
jschoubben 961ec0ef96 Append and snapshot a ledger on mesh-sdk's ledger subjects, the ones its account is granted, refusing a binding naming others (issue 1966 T6) 2026-11-03 15:17:12 +01:00
jschoubben 5a9e997349 Check a ledger operation against the types its binding carries, refusing a ledger bound with none (issue 1966 T2) 2026-11-03 15:15:58 +01:00
jschoubben fadc73f73b Key and answer a ledger index by mesh-sdk's IndexKey and IndexEntry, the one shape the owner's watcher also writes (issue 1966 T3) 2026-11-03 15:15:00 +01:00
jschoubben d206b0dde1 Prove against the real bus that the ledger keeps its promises: one writer wins, the state never goes back, a cut or full state catches up, the snapshot rebuilds, the repairs repair, a forged author is refused (issue 1966 T7) 2026-11-03 13:52:58 +01:00
jschoubben 2bb0a6461d Publish a module's ledger history and snapshots only on its own ledger connection, read from the runner's own secret ledgers and followed without a restart (issue 1966 T6) 2026-11-03 13:51:47 +01:00
jschoubben 38a634723b Stamp a ledger operation with the caller the runner proved for the call in flight it names, refusing another module's call or one not in flight; serve the ledger calls on the pipe (issue 1966 T5) 2026-11-03 13:49:15 +01:00
jschoubben 8fe7ef3b82 Serve a ledger owner its repairs rebuild, reindex, snapshot and lag as tools, its own ledgers only, marked acts or reads (issue 1966 T4) 2026-11-03 13:46:54 +01:00
jschoubben 63c1e3faa2 Read a ledger: an instance's state, its history oldest first with sequence and author, a watch of its states, a declared index (issue 1966 T3) 2026-11-03 13:42:33 +01:00
jschoubben ad22c5e9fe Apply a ledger operation: check it against its type, append it with the last sequence expected, derive the state at the revision read, write the snapshot (issue 1966 T2) 2026-11-03 13:40:45 +01:00
jschoubben d6c516ab44 Serve a bundle its own bound objects, streams and work queues on its pipe (issue 1966 T1) 2026-11-03 13:34:32 +01:00
jschoubben 24c0ec0d32 Pin mesh-sdk at f02f142, the sdk1 head whose tests no longer leak package globals, so the group's check builds against it
mesh/delivery merged: source.main moved to novox/mesh-tools@b8e42cf54cf6
mesh/delivery-group group feat/sdk1 merged: every member is merged
mesh/check checking 24c0ec0d324a on d7d908cf67ae | novox/mesh-tools#56 in group feat/sdk1
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 20:14:16 +01:00
jschoubben bd24ceafa9 Pin mesh-sdk at the sdk1 group's head 1c7356c, so the group's check builds every module against the narrowed SDK it was written for
mesh/delivery-group group feat/sdk1 checking: 7 of 7 member(s) ready
mesh/delivery closed: a newer head of the same pull request
mesh/check failed: integration: meshbuildgo/cmd/mesh-build-go.TestAComposeAskIsBuiltOnceAndAnsweredOnTheBus: NOT CHECKED: the node-engine's composer c…
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 19:29:53 +01:00
jschoubben 3f538027e9 Read a per-node state through mesh-sdk's pernode package, so the runtime and a process share one copy of its rules
Replaces the runtime's own bucket listing, advisory hearing and per-bucket bookkeeping; the bound on progress and the runtime's shapes stay here. ADR 0593 §6.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 18:31:18 +01:00
jschoubben 8114b45884 Serve a per-node state to a bundle as one state: get by the key's node, keys and watch over every node's bucket, a later bucket too
The provisioner, the assigner and the view read every node's composition (ADR 0593 §6); the runtime followed mesh-sdk's membership.StateIssued PerNode and process.NodeFamily on its own connection.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 18:27:34 +01:00
jschoubben e475d9f849 Pin mesh-sdk to the group head of issue 1126
mesh/delivery merged: source.main moved to novox/mesh-tools@d7d908cf67ae
mesh/delivery-group group feat/1126-removal merged: every member is merged
mesh/check checking e475d9f849ca on 49f9269376e3 | novox/mesh-tools#55 in group feat/1126-removal
Every member builds against mesh-sdk abf5eac, the head of feat/1126-removal, so the group is checked as one contract.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 12:27:34 +01:00
jschoubben e6f27a5f74 Pin mesh-sdk to the group head of issue 1126
Every member builds against mesh-sdk f569924, the head of feat/1126-removal, so the group is checked as one contract.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 12:20:14 +01:00
jschoubben c678511871 Pin mesh-sdk to the group head of issue 1126
Every member builds against mesh-sdk 729a86b, the head of feat/1126-removal, so the group is checked as one contract.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 11:56:55 +01:00
jschoubben 4f636b7080 Name no controller verb in hints and drop its handover and paging reads, since the controller ended (issue 1126 B19)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 11:23:14 +01:00
jschoubben 29fd452628 Pin mesh-sdk at c21d8fd, the removal group's head, so every member builds the same contract (issue 774)
mesh/delivery merged: source.main moved to novox/mesh-tools@49f9269376e3
mesh/delivery-group group feat/l3-removal merged: every member is merged
mesh/check failed: mesh-build-go: the check of novox/mesh-catalog#590: the ask mvyhumdm860c7f's step on shanks did not end within 30m0s of its start |…
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 00:53:42 +01:00
jschoubben 331fa06b54 The tool runner reads the memberships state again until it can, instead of giving a module up at its one follow
A JetStream 503 or a timeout at the follow (a bus right after its boot) left the module with no membership for good, since
Follow runs once per module and the stream fallback is gone. The read is now tried again with a growing wait (1 s doubling
to 30 s) until it watches the key or the connection closes; the failure is said once, and its reading once it succeeds.
Tests: none added; a step added to an existing unit test (TestAModuleHearsEveryStreamItsMembershipNames), which fails
without the retry.

(issue 774, 774/S32, review g1 round 1)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 00:51:19 +01:00
jschoubben 5b2ff5e321 Test that node-tools' manifest is not refused by the lease write's check (ADR 0571 §13)
Tests: one added, the first of its kind in this repository; the repository holds 128 unit tests, within its budget of 500.
Built against the group's mesh-sdk through a go.work outside the tree; go.mod is not re-pinned here.

(issue 774, 774/S33)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 00:26:04 +01:00
jschoubben 4fbfdfad13 The tool runner reads its membership from the grants part's state alone: no stream read, no subject heard (ADR 0571 §10)
Follow no longer asks the ASSIGNMENTS stream for a copy nor subscribes mesh.assignment; a module with no membership key is
said so and served in its derived shape. The test mesh issues memberships where the grants part keeps them.
Tests: none added; the stream-fallback assertions of two existing tests are replaced by their state-only counterparts, and
the test mesh no longer makes the stream. The two integration tests of the bus were run locally against the embedded bus.

(issue 774, 774/S32)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 00:25:19 +01:00
jschoubben fb6631aee1 Pin group A's mesh-sdk head on main
mesh/delivery merged: source.main moved to novox/mesh-tools@75943ca7b0c3
mesh/delivery-group group feat/l5-l7-main merged: every member is merged
mesh/check checking fb6631aee1a2 on 75943ca7b0c3 | novox/mesh-tools#53 in group feat/l5-l7-main
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 09:57:49 +01:00
jschoubben d41bee158c node-tools waits on the self-check's checked, not the controller's (ADR 0571 clause 13, issue 1955)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 09:54:39 +01:00
jschoubben c494018074 Pin the group's mesh-sdk head after the gofmt fix
mesh/delivery merged: source.main moved to novox/mesh-tools@110e55cb4836
mesh/delivery-group group feat/judge-once merged: every member is merged
mesh/check checking c4940180746a on c2f01bf10b68 | novox/mesh-tools#52 in group feat/judge-once
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 03:27:07 +01:00
jschoubben 4cdf63443d Pin mesh-sdk to the group's head after review round 1
mesh/delivery closed: a newer head of the same pull request
mesh/delivery-group group feat/judge-once checking: 4 of 6 member(s) ready
mesh/check checking 4cdf63443d59 on c2f01bf10b68 | novox/mesh-tools#52 in group feat/judge-once
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 03:13:22 +01:00
jschoubben 1e9995faba Pin mesh-sdk to the delivery group's head
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 02:46:53 +01:00
jschoubben f6c401ecd2 Declare credential form none for the provision, which hands consumers no credential
The manifest judge refuses an offer that says no credential form (issue 1585).

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-01 02:43:23 +01:00
jschoubben be2fc2e9b6 Pin mesh-sdk at the group's head acbf80a (issue 774)
mesh/delivery merged: source.main moved to novox/mesh-tools@c2f01bf10b68
mesh/delivery-group group feat/072-moves merged: every member is merged
mesh/check failed: shanks: the check of novox/mesh-controller#487 failed: go mod download in modules/route-proxy: go: git.novox.be/novox/mesh-controll…
2026-10-31 10:25:46 +01:00
jschoubben aa05629375 Pin mesh-sdk at the group's head (issue 774) 2026-10-31 09:30:08 +01:00
jschoubben 35a7ff70fe Read the seat mesh-placement's state through the sdk's PlacementsOf, and write the test mesh's placement as the seat does, one key per module and node (issue 774, research 072 row 37) 2026-10-31 09:29:32 +01:00
jschoubben 747bfa71aa Merge pull request 'A state watch given up hands nothing more to its bundle (issue 774)' (#50) from fix/sweep-2026-10-30 into main
Reviewed-on: #50
2026-10-30 18:13:12 +00:00
jschoubben 316a5a2fc3 A watch given up or stopped hands over nothing more; arrival of current values restarts its bound (issue 774)
mesh/delivery merged: source.main moved to novox/mesh-tools@747bfa71aa32
mesh/delivery-group group fix/sweep-2026-10-30 merged: every member is merged
mesh/check checking 316a5a2fc317 on 0edcd2501dae | novox/mesh-tools#50 in group fix/sweep-2026-10-30
Quick: check the watch context before each deliver in StateWatch. Thorough (chosen, same
file kind): also LogWatch drops a message fetched as it stopped, and the bound restarts
on arrival, not only after the bundle took a value.
2026-10-30 18:22:01 +01:00
jschoubben 0edcd2501d Merge pull request 'The tool runner reads the grants part's memberships through the mesh-sdk codec (issue 774)' (#49) from fix/memberships-shape into main
Reviewed-on: #49
2026-10-30 14:42:20 +00:00
jschoubben ac645e2cae Refuse a held-back membership's old wrapper in the tool runner, pinning mesh-sdk's review-round-1 codec
mesh/delivery merged: source.main moved to novox/mesh-tools@0edcd2501dae
mesh/delivery-group group fix/memberships-shape merged: every member is merged
mesh/check checking ac645e2caedd on 3c9068f99a43 | novox/mesh-tools#49 in group fix/memberships-shape
The old grants part wrote its wrapper for a held-back membership too; the new part leaves such a key alone, and taking
it would serve what the hold kept back with the stream's copy ignored. The integration test now proves that copy is
served instead. Review round 1 of issue 774's fix.
2026-10-30 15:38:40 +01:00
jschoubben a479a90fb2 Read the grants part's memberships through mesh-sdk's codec, so the tool runner serves its node's modules
The tool runner unmarshalled the state's value straight into its membership; the grants part had written its wrapper
there, so every module decoded empty, was marked as given by the grants part, and the correct copy on the assignments
stream was passed over: novox served no tool. followGrants now reads with membership.BareGrantsMembership, which takes
the bare membership, still takes the old wrapper (what the live mesh holds until the part writes again), and refuses
a value naming no node or module, leaving the stream's copy in force.

The fixture IssueInGrants built its value by hand from this package's type and so agreed with the mistake; it now
writes through mesh-sdk's encoder, and IssueInGrantsWrapped writes the old wrapper for one integration test that
proves tools and state are served from it (it fails without this fix with the empty membership seen live).

Issue 774 (the bus login list, L3). Quick fix: unwrap here alone. Thorough, chosen: one codec in mesh-sdk the writer
and this reader share, so the two cannot drift again. Pins mesh-sdk at the head of its fix/memberships-shape.
2026-10-30 15:31:26 +01:00
jschoubben 250aa73a56 Pin mesh-sdk 2da0de7, the release's final head with main merged in, so mesh-tools builds with the group's one SDK (issue 1955)
mesh/delivery merged: source.main moved to novox/mesh-tools@3c9068f99a43
mesh/delivery-group group feat/774-l3-reland merged: every member is merged
mesh/check checking 250aa73a5631 on 95a12105cf7b | novox/mesh-tools#48 in group feat/774-l3-reland
2026-10-30 01:12:55 +01:00
jschoubben e32eef2379 Pin mesh-sdk 6e4a301, the release's final head, so mesh-tools builds with the group's one SDK (issue 1955) 2026-10-30 00:16:11 +01:00
jschoubben 070ae53128 Pin mesh-sdk 007b6fd, the release's final head, so mesh-tools builds with the group's one SDK (issue 1955) 2026-10-30 00:05:45 +01:00
jschoubben 8c0618cfc5 Prove a later assignments-stream membership changes nothing once the grants part's state has given one (issue 1955, ADR 0571 clause 7) 2026-10-29 23:44:19 +01:00
jschoubben 54680238a0 Read memberships from the grants part's state, what the mesh holds from the indexer and placement, and give bundles newest, since and watch on logs, so the tool runner asks the controller for nothing it keeps (issue 1955, ADR 0571 clauses 1, 4, 5, 7)
Pins mesh-sdk bb993dd. The assignments stream stays the membership's
fallback until the lease write; a log another module keeps is read as
<module>.<log>.
2026-10-29 23:42:43 +01:00
jschoubben 200249a84f Let the TypeScript mesh client take every role's tools from the console on its machine, so it asks the controller for none (issue 1955, ADR 0571 clause 5)
The Go console answers mesh/seats beside MCP's methods from mesh-sdk's seat
definitions and placement's seat-holders. The console test that runs bundles
expects the unread seat-holders line beside ghost.
2026-10-29 23:19:55 +01:00
jschoubben 67850457ef Read seat verbs' replaces from mesh-sdk's seat contract and seat holders from placement's seat-holders state, so the console asks the controller for neither (issue 1955, ADR 0571 clauses 4 and 5)
Pins mesh-sdk f9a496d. The controller's nodes and modules reads remain.
2026-10-29 23:13:42 +01:00
jschoubben 9d67b0995f Bind node-tools' consumers by mesh-provisioner's plans and provisions alone, dropping the read of the controller's assignments the sdk's helper no longer makes (issue 1954 L6-T1)
Pins mesh-sdk 692dbf9 (L6-P3).
2026-10-29 22:43:58 +01:00
jschoubben e9009b7f04 Answer mesh/state.info with a bucket's fill and caps, so a bundle's tools can say how full its state is (issue 1952) 2026-10-29 22:43:58 +01:00
jschoubben 9fc97e45c9 Let node-tools' provider helper read mesh-provisioner's provisions and plans by mesh-sdk's names, so the runtime follows ADR 0570's records off the controller (issue 1954 L6-T1)
Pins mesh-sdk 4a96793 (go/provisions). The assignments read stays while the
sdk's helper still reads plans there (until L6-P3). A watch's expire now
reads as a removed key.
2026-10-29 22:34:34 +01:00
jschoubben 1583fa85d9 Let a bundle write a state key with its own time to live and hear its end, so wakes need no in-process timer (issue 1952)
mesh/state.create and mesh/state.put take ttl_seconds (mesh-sdk 32f5ce3's
CreateTTL/RenewTTL contract); a bucket not declared key-ttl is refused,
naming it; a watch hands an expired key as op "expire". Pins mesh-sdk 32f5ce3.
2026-10-29 22:11:39 +01:00
jschoubben 2966c1e32c Runtime state guard: hold a provider reference's node and module to the mesh's name pattern, so no credential rides in one (issue 1126)
mesh/delivery merged: source.main moved to novox/mesh-tools@95a12105cf7b
mesh/check being carried to 2966c1e32c3d on 95a12105cf7b | from 27266f99a3c3
2026-10-28 21:49:52 +01:00
jschoubben 1a0424117a Runtime state guard: a credential-shaped name passes only holding an exact provider reference, node and module, so a placement's binding is kept and nothing else gets through (issue 1126) 2026-10-28 21:48:27 +01:00
jschoubben 23f5babe33 Runtime state guard: a name holding an object is data, not a credential, so a placement's binding of the provision secret is kept (issue 1126) 2026-10-28 21:47:06 +01:00
jschoubben a9b02bc676 node-tools: keep the stopping-runtime test under a second, and start no first bundle once stopping
mesh/delivery merged: source.main moved to novox/mesh-tools@27266f99a3c3
mesh/delivery-group group fix/shutdown-bound merged: every member is merged
mesh/check pass a9b02bc67604 on 6cc33988801f | unit 2192 run, 3794 kept, 57 skipped | integration 2208 run, 3829 kept, 57 skipped | over bound: unit, …
The test watched two seconds per row; a 10 ms restart pause and a 250 ms window
prove the same. launch.Start itself now refuses while the runtime stops, so a
reload's first start is held too (issue 1126).
2026-10-28 15:40:39 +01:00
jschoubben f016c67a72 node-tools: start no bundle again once the runtime itself is stopping (issue 1126)
The service manager stops node-tools by signalling its whole group, so every
bundle gets SIGTERM with it; the launcher took each exit for a fault and started
the bundle again, for the 15 s the runtime took to stop. On ace's reboot of
2026-10-28 those restarted bundles dialled the system bus once polkit and the bus
had stopped, the bus and polkit came back during the shutdown, nothing stopped
them a second time, and the reboot waited 29 minutes on its job timeout.

ShutDown, called first on SIGTERM, keeps any bundle from starting again, by a
restart or by a call; a running one still answers.
2026-10-28 15:30:12 +01:00
jschoubben 8cdb7c3032 The credential wait's test stays under a second, and a failed watch says the re-read, not a restart (issue 1496)
mesh/delivery merged: source.main moved to novox/mesh-tools@6cc33988801f
mesh/delivery-group group fix/1496-start-health merged: every member is merged
mesh/check checking 8cdb7c303210 on a5097dc69ab2 | novox/mesh-tools#45 in group fix/1496-start-health
Review of 3baeaec: TestAwaitCredential took 1.9 s, over the unit limit; it now
sets the watch's settle to 10 ms, writes at 20 ms and gives up at 100 ms (0.2 s).
The watch's journal line for a failure named a bundle and a restart; the
credential wait now says it is read again every 30 s instead.
2026-10-26 22:18:12 +01:00
jschoubben 3baeaece61 A module's runtime waits for its broker credential and its account at a start, bounded, instead of exiting (issue 1496)
The node-engine starts a module's runtime before the provisioner's client fills
its broker file, and the bus carries a new account only after it reloads its
users. The runtime exited on both and was restarted until they were there (ace,
2026-10-26 21:19: mesh-build-node's and mesh-build-image's runtimes exited twice).
It now waits up to five minutes from its start, said once: the file is read again
each time its directory changes (the bundles' inotify watch, a 30 s backstop),
and an authorization refusal is asked again with the backoff. Past the bound it
gives up loudly; a file with no url, a pin mismatch and a bad URL stay final.
2026-10-26 22:06:39 +01:00
jschoubben 9f25e5c9f6 mesh_search: filler words of a question (did, our, on, all) need not match, so the operator's own words find a tool; a query of filler finds nothing
mesh/delivery merged: source.main moved to novox/mesh-tools@a5097dc69ab2
mesh/check pass 9f25e5c9f6c1 on a5097dc69ab2 | carried from bb6a0e3192db | unit 116 run, 11 kept, 11 skipped | integration 118 run, 11 kept, 10 skippe…
2026-10-26 14:03:49 +01:00
jschoubben 3331719407 Ask the bus whether a bound consumer still exists, so a deleted and remade one is rebound within a rebind tick, not after nats.go's heartbeat (issue 1945)
mesh/delivery merged: source.main moved to novox/mesh-tools@bb6a0e3192db
mesh/check pass 33317194073a on bb6a0e3192db | unit 115 run, 11 kept, 11 skipped | integration 117 run, 11 kept, 10 skipped | over bound: unit (slowes…
nats.go ends a pull loop on a deleted consumer only when a pull is pending at that moment; otherwise the loop waits out its heartbeat. The rebind tick now looks each bound consumer up by name and compares its creation time.
2026-10-25 16:02:27 +01:00
jschoubben 2cd5550dc7 A stopped tool drops its membership handler and a stopped bundle starts no copy on a call, so a replaced bundle's old tools stay gone (issue 1945, review round 2)
mesh/delivery merged: source.main moved to novox/mesh-tools@5d6cee9d844e
mesh/check pass 2cd5550dc70f on 77b05089c8df | unit 0 run 126 kept | int 0 run 128 kept | clone 9.5s | composition passed on 4 machines
Its events are refused before the old bundle stops, the bundle watch follows a directory made between
its stat and its watch, and a bundle's reason is read without node's colour codes.
2026-10-25 15:44:10 +01:00
jschoubben d8ac69904d Refuse an event heard during a reload instead of panicking, and judge a bundle by its entrypoint alone (issue 1945, review)
An event a module's consumer heard after the module was dropped for a
reload read a deleted entry and panicked node-tools, taking every tool on
the machine down. The handler now refuses an event of a consumer that is no
longer the module's, and a stopped hearing hands nothing on and offers the
event again at once.

A bundle that writes beside itself (a cache, a socket) loaded itself again
after every quiet spell, because the signature took in every file in its
directory. A delivery puts every file in place anew, so the entrypoint alone
tells a new build. The watch also looks once as it begins, so a bundle that
came between its load and the watch is not missed.

Tests: 1945/AC23 and AC24 in internal/runtime/reload_test.go, and a stopped
hearing in internal/bus/hearing_stopped_test.go.
2026-10-25 15:26:02 +01:00
jschoubben b0ded57294 Serve a tools bundle as soon as it is in place, changed or gone, with no restart; say why a bundle cannot start (issue 1945)
node-tools loaded every bundle once at start, so a bundle delivered after
it started (mesh-files on shanks, 2026-10-25 12:08) went unserved until a
hand restart, and a missing file was said as "not executable". The
runtime now watches the entrypoints' directories with inotify, loads a
module again once a burst of changes settles, and discovery answers with
what is served now. A bundle that cannot start says it does not exist, is
not executable with its mode, or the exec error.

Tests: 1945/AC19-AC22 in internal/runtime/reload_test.go.
2026-10-25 15:09:49 +01:00
jschoubben 77b05089c8 Merge pull request 'Bound a state watch's hand-over by its progress, not its whole set, so the gitea module binds the checker's owed statuses again (issue 1726)' (#41) from fix/1726-group-check-status into main
Reviewed-on: #41
2026-10-24 10:35:43 +00:00
jschoubben 0211844e6a Bound a state watch's hand-over by its progress, not its whole set, so a large state's newest keys are handed over (issue 1726)
mesh/delivery delivering: 0 machine step(s) passed
mesh/check pass 0211844e6ad3 on 0e985f9bf186 | unit 0 run 117 kept | int 0 run 119 kept | clone 5.4s | composition passed on 4 machines
The gitea module's watch of mesh-delivery-checker.owed failed at every attempt
since 03:05 on novox: about 200 owed keys, each a round trip to the bundle,
outlast a 10 s bound for the whole set. The bundle dropped its handler, the
oldest keys were written again every 40 s and the newest, handed over last,
never were: group fix/1937-done-key-blobs's pass never reached mesh/check.
StateWatch now fails only when no current value is handed over within
StateTimeout.
2026-10-24 07:42:08 +02:00
jschoubben 0e985f9bf1 Merge pull request 'R4g (mesh-tools): seat.pull and seat.settle for the build modules, merge-check.sh and the root image module go (design 47)' (#40) from feat/r4g into main
Reviewed-on: #40
2026-10-23 17:51:33 +00:00
jschoubben 860043fd7f Pin mesh-sdk at feat/r4g's head a2c813a6, its test fixture fix, with go.sum tidied
mesh/delivery failed: its walk failed, carrying its own commit: a gate on a first machine (what it carried put back), a build, a machine
mesh/delivery-group group feat/r4g merged: every member is merged
mesh/check checking 860043fd7fa0 on e0fadc43d9dd | novox/mesh-tools#40 in group feat/r4g
2026-10-23 17:06:12 +02:00
jschoubben 589bfc0bc5 Record the checksums of mesh-sdk feat/r4g 9205222a for the group's modules (R4g)
mesh/delivery-group group feat/r4g rejected: a member's own check failed
mesh/delivery superseded: a newer head of the same pull request
mesh/check failed: g14: novox/mesh-catalog#464: checks/health/go.mod names mesh-sdk a9560890ee26, which is neither on mesh-sdk's trunk nor the group's…
2026-10-23 16:26:11 +02:00
jschoubben 3b5a38e4a4 Pin mesh-sdk at feat/r4g's head 9205222a, the merge of lanes A, B, S8 and F1, so every module r4g touches builds against one SDK
go.sum gains its lines from go mod tidy once mesh-sdk feat/r4g is pushed.
2026-10-23 16:22:02 +02:00
jschoubben 755f77ca45 Merge branch 'feat/r4g-asks' into feat/r4g 2026-10-23 16:20:32 +02:00
jschoubben 9153a280f8 Let a bundle pull one message from its listed worker and settle it, so a build module takes an ask only when it has a free slot, in its workers' order (issue 1887 A11, ADR 0525 §4) 2026-10-23 15:28:06 +02:00
jschoubben 8ee6db7d9a Remove the toolchain image module; node-tools is the repository's only module (issue 979, S1; ADR 0524 §5)
Only build-agent built inside that image, and it goes in R4g.
2026-10-23 15:25:33 +02:00
jschoubben 5dffb920ff Delete merge-check.sh; tests that launch bundles skip with their reason (issue 1295, S2; ADR 0529)
The checker runs node-tools' Go level and its npm test; what the script said
was NOT TESTED HERE is a skip naming the missing node or @novox/mesh-sdk.
2026-10-23 15:25:10 +02:00
jschoubben d295fd4250 Say nothing serves a call only for the bus's own no-responders, never for a tool's error that mentions 503 (issue 1529)
mesh/merge-gate head d295fd4250a7 merged into trunk 18260ce9beca — pass, with a note: builds mesh-tools, node-tools (+40 dependent(s)) → ace, g14, novox, s…
mesh/repo-check head d295fd4250a7 merged into trunk 18260ce9beca — pass: its merge-check.sh passed
mesh/delivery covered after its failure: a later walk that contains it was delivered: plan-1792534538429799487 (novox/mesh-tools at e0fadc43 into main, d…
2026-10-21 00:02:34 +02:00
jschoubben 494d0787e2 Wait for a stopped bundle's exit instead of sleeping after it
mesh/delivery delivered
mesh/merge-gate pass: builds mesh-tools, node-tools → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of …
mesh/repo-check pass: its merge-check.sh passed
Launched.Stop now returns once the bundle's exit is handled, bounded by
StopWait, and the launcher reads its restart pauses once at Start, so
the exit goroutine no longer races a test that changes them. The caller
tests drop their half-second pause (novox/hq issue 476).
2026-10-12 10:43:22 +02:00
jschoubben 541de48e04 node-tools: only a call pattern names a caller, and a fall-back for want of a responder is said (hq issue 365, review)
mesh/merge-gate pass: builds mesh-tools, node-tools → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of …
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery delivered
callerOn reads a caller only under the call kind, so a tool subscription ending
in a wildcard never yields one. A caller-named call that reached nobody is said
once per subject before it is asked on the old subject, so a runtime or grant
that drifted behind is seen rather than a quiet unproven. The caller tests wait
for their bundle's exit, which reads the launcher's restart pauses another test
sets.
2026-10-11 11:22:29 +02:00
jschoubben ab0f888d67 node-tools: a tool call names its caller, and the module is told it from the subject (hq issue 365)
mesh/merge-gate pass: builds mesh-tools, node-tools → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of …
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery-group group fix/365-a-tool-call-names-its-caller delivering: 0 of 4 delivered
mesh/delivery superseded: a newer head of the same pull request
Each tool and seat verb is also served on its caller-named subject, kind call
with the caller's bus user last, which the controller grants each user with its
own name alone; the runtime hands the module that caller in the call's _meta,
never from the body. Calls through the runtime (the console and modules'
invokes) ask the caller-named subject first and the old one only when the first
reached nobody: nothing serves it yet, or the bus refused it because the grant
is not delivered yet, which ends the call at once rather than after 30 s. The
old subjects stay served and say no caller for one release (hq issue 464).
2026-10-11 05:19:08 +02:00
jschoubben 020003ea3f Cite hq ADR 0170, not 0169: the firewall seat's record was renumbered after a collision on hq main 2026-10-02 14:52:28 +02:00
jschoubben fb0dcd0cc1 A node-scoped seat's verb is callable through the console, naming its machine (hq ADR 0169)
The listing left node-scoped seats out, so <seat>.<verb> never resolved as a
seat's and the call went to a module subject nothing served. Listed now with
their scope: the schema requires the machine, the call carries it in the
subject, and a call without one is refused in words.
2026-10-02 14:23:26 +02:00
jschoubben feb13c1de6 A registration under a stranger's name is said and skipped, not fatal
A module implementing a seat its credential does not (yet) claim registered tools under the seat's
name; the runtime treated them as the module's own, refused to serve another module's key, and the
whole runtime restarted in a loop — postgres on the control node, 2026-10-01, whose credential predated
the claims. Such a registration is now named in the log and left out; the module's own tools serve.
2026-10-01 16:47:03 +02:00
jschoubben a01b5f5b78 The membership is read by its subject
The runtime asked the assignments stream's root for the last message by subject in the body, and the
mesh grants a module's account only the subject-addressed form of the direct get — the server refused
every read (Publish Violation on $JS.API.DIRECT.GET.ASSIGNMENTS for every module on the new runtime),
so every runtime kept the derived shape. The address is now the stream then the subject, nothing in the
body, which is the one address the account has.
2026-10-01 16:16:57 +02:00
jschoubben ce8c37a7fc The listing test tells the seat's two verbs apart: one keeps its own node, the other takes none 2026-10-01 15:43:36 +02:00
jschoubben 809e2b11ec The listing test indexes the module's tool after the seat's two verbs 2026-10-01 15:42:58 +02:00
jschoubben 670b486ac0 A seat's verb keeps a node of its own; only a module's tool gives it to the subject
The console moved every call's node into the subject (ADR 0159), so mesh-controller.push {node: x}
became a call to the seat's verb on machine x, which nothing serves — the mesh's own verbs could not
be given a machine from the console at all. A role's verb takes no machine from the console; its
arguments are its own.
2026-10-01 15:42:35 +02:00
jschoubben e7b98f1fbc A runtime serves what the mesh issued it, and a seat's verbs are implemented under the seat's name (hq ADR 0160)
The one address a runtime derives for itself is mesh.assignment.<node>.<module>. It reads the
membership there with a direct get on the ASSIGNMENTS stream, serves each tool exactly where the
membership says — the plain subject in the module's queue when the mesh issued one, this machine's
beside it — and follows the subject, re-serving when a new membership arrives. A mesh that has issued
nothing yet gets the shape it always derived, and the log says so.

A seat's verbs are the role's, not the software's (ADR 0159): a module implements them with
registerModuleTools("<seat>", …), the runtime serves that on the seat's subjects when the credential
claims the seat, and never lists it among the module's own tools. A module named like its seat
registers once and is both.

The tools answer carries each tool's subjects, and the console and CLI call the subject the listing
gave them instead of composing one.
2026-10-01 15:17:14 +02:00
jschoubben c65f1993ba A tool call names the machine it is for, every answer says which machine answered, and a holder's
runtime serves its seat's verbs (novox/hq ADR 0159)

A module on several machines served one subject in one queue group, so a call reached whichever
instance answered first and nobody could ask one machine's instance. Now each instance also serves
its subject with its machine as the last token, `<module>.<tool>@<node>` addresses it, and every
answer carries the machine that gave it: the console lists `node` on every module tool, strips it
into the subject, and appends "answered by <node>" to the answer; `mesh call` prints it.

And a seat's verbs are served by whoever claims the seat: the credential names the claimed seats
and the verbs each promises, the runtime serves each verb with the module's tool of the same name
on the seat's own subject, and the bus — which admits only the holder's subscription — decides where
that serving is real. Design 33 §3 and §4, built.
2026-10-01 13:58:22 +02:00