Commit Graph
2036 Commits
Author SHA1 Message Date
mesh-tools cdbdb47474 Merge pull request 'xterm: every resource a config value, today's values as defaults (issue 1656)' (#416) from fix/1656-xterm-config into main 2026-10-21 18:36:28 +00:00
mesh-tools db5e6c5b48 Merge pull request 'Name the wait in the Stop hook's suggested calls, route adopt's counter reset through fsys, and stop writing empty counter files' (#421) from fix/1749-1757-wait-list into main 2026-10-21 18:19:19 +00:00
jschoubben b9dcf19c3f Merge remote-tracking branch 'origin/main' into fix/1656-xterm-config
mesh/repo-check head b9dcf19c3f91 merged into trunk db5e6c5b48f4 beside mesh-controller#420@9d260412 — pass: its merge-check.sh passed, each part in its to…
mesh/merge-gate head b9dcf19c3f91 merged into trunk db5e6c5b48f4 — pass: group fix/1656-xterm-config composed: every machine composes with the change as it…
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 fix/1656-xterm-config failed: a member failed
2026-10-21 19:43:29 +02:00
jochen e3a714d5f0 Stop writing an empty refusal-counter file on every stop of every session (issue 1749)
mesh/merge-gate head e3a714d5f0f0 merged into trunk c3564c1accf3 — pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes …
mesh/repo-check head e3a714d5f0f0 merged into trunk c3564c1accf3 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
writeRefusalCounters wrote "{}" and, since it now routes through fsys
(this branch's earlier commit), created the waits folder on every single
stop, even for a session that never had a wait: one counter file per
session id, piling up on a node that uses the wait list at all. It now
removes the file instead of writing empty counters, a no-op when there
was never one to begin with, so a stop with nothing to record leaves
neither the file nor the folder; a refusal still writes it, and the
stop right after the wait is done (or let through) removes it again.
2026-10-21 19:41:05 +02:00
jochen 08cec8cb1c Route adopt's refusal-counter reset through fsys, and name the wait in the Stop hook's suggestions (issues 1749, 1757)
issue 1749: AdoptName reset both session ids' refusal-counter files with
os.WriteFile, bypassing fsys; on a node whose agent has its own account
(ADR 0266) the module runs as the operator's account and cannot write
into the agent's home directly, so the reset silently failed. writeRefusalCounters
now goes through fsys (MkdirAll then WriteFile), as every other write into
the agent's home does; it is also called from the Stop hook itself, which
already runs as the agent's own account, where fsys is its zero value and
behaves exactly as the plain write did before.

issue 1757: the Stop hook's suggested watched and said calls left out `by`,
which claude_code_wait requires on every op, so a session following the
suggestion word for word was refused. Both now carry "by" from the wait's
own By field (already kept per wait since issue 1629). The SessionStart
hook's suggested adopt call already carried by; added a test for it too,
alongside the Stop hook's two, each extracting the exact JSON the hook
prints and feeding it back to the tool's own dispatch to prove it is
accepted as printed.
2026-10-21 19:35:33 +02:00
mesh-tools c3564c1acc Merge pull request 'A session's wait list and the plugin's Stop hook, so a written-down wait is never left unwatched (ADR 0489, ADR 0490)' (#420) from feat/wait-list into main 2026-10-21 17:18:48 +00:00
jschoubben e4cbffbaa9 Merge remote-tracking branch 'origin/main' into fix/1656-xterm-config
mesh/merge-gate out of date: judged against trunk 7a7a4034852a, the trunk is now c3564c1accf3; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk 7a7a4034852a, the trunk is now c3564c1accf3; judged again on a recheck or when it is merged
mesh/delivery superseded: a newer head of the same pull request
2026-10-21 19:16:12 +02:00
jochen 0f159a1662 Fix review round 2 of the wait list and its hooks (issues 1629, 1743, 1744, ADR 0490)
mesh/merge-gate head 0f159a166200 merged into trunk 7a7a4034852a — pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes …
mesh/repo-check head 0f159a166200 merged into trunk 7a7a4034852a — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
The Stop hook treated a missing waits file exactly like one that could
not be read: a notice on every stop of every session with no waits —
the normal state, not an exceptional one. DecideStop now treats
os.ErrNotExist as the ordinary case of no open waits, silently; the
notice is still said for a file that exists but cannot be read or does
not parse.

ADR 0490 §1 keeps waits under a name, but the file a hook reads is kept
per session id: writing it from only the name an op just acted on meant
a second name bound to the same session id had its waits silently drop
out of enforcement the moment the first name was touched, and adopting
one name away emptied the id's file outright even when another name was
still bound to it. Every write now rewrites a session's file from the
union of every name currently bound to it (sessionWaitsUnion), adopt's
rewrite of the superseded id included.

Also: each atomic write gets its own temp file name, so two writes to
the same path can never interleave on one; adopt clears the refusal
counter of both the superseded and the adopting session, so a fresh
three-strikes count starts under the new binding; and list is read-only
again — it no longer claims an unbound name or refuses a session that
is not (yet) the one bound to it, and instead says who currently holds
the name.
2026-10-21 18:43:03 +02:00
jochen f0beea153e Key a wait list by name, not session id, so it survives a /clear (issues 1629, 1744, ADR 0490)
Claude Code gives a session a new session_id at /clear, with nothing
naming the earlier one, so keying claude_code_wait's state by session id
lost a session's waits the moment it cleared. ADR 0490 changes ADR 0489
§1: waits are now kept under the caller's name and node (by, who@node);
every op also takes session, the caller's current id, and the module
keeps a binding of the name to the session that last called for it. An
unbound name is claimed by the first call for it; a session whose own
id no longer matches the binding is refused on every op, naming the
session that holds it, until it calls the new op adopt, which always
takes the name over at once (no bound protects a recent call) and tells
the earlier session so on its own next call.

The mirrored file a hook reads stays keyed by session id (a hook only
ever has that), holding whichever name's waits are currently bound to
it; adopting rewrites both the old id's file (emptied) and the new id's
(filled) in the same call. A second mirrored file, the node-wide index,
lists every name on the node with an open wait; the SessionStart hook
now also reads it, on every start, and prints the exact adopt call for
each name, so a session with a brand new id can find and reclaim its
own waits without calling back into the module.
2026-10-21 18:32:50 +02:00
mesh-tools 7a7a403485 Merge pull request 'Files go through the store: object-store links, node-files upload/download, a document converter, and brother printing a key, a path on any machine or a web link (design 60 F3, ADR 0468)' (#417) from feat/files-through-the-store into main 2026-10-21 16:31:22 +00:00
jochen 02a8837348 Fix review round 1 of the wait list and its hooks (issues 1629, 1743, 1744)
A session id reaching the Stop and SessionStart hooks was only checked
for blank, so "../../x" or "a/b" could read or write outside the waits
directory; both hooks now hold every session id to waitSessionID before
building any path, and allow (saying why) rather than fail on a bad one.
claude_code_wait's list/watched/done/said held only add to that same
check, letting a malformed id through as an ordinary, always-empty key;
they all refuse it now.

The Stop hook's three-strikes cap could be bypassed forever if its
counter file could not be written on a refusal: it now allows instead,
saying so, so a wait can never hold a turn open indefinitely. Its advice
offered mesh_wait on a wait's event family unconditionally, ignoring
that the session's tool runner may not be granted it (ADR 0367 §2); it
now offers mesh_wait only "if this session's tool runner is granted it,
otherwise start a watcher", and drops the family entirely when a wait
has none.

Both hooks' fail-open and let-through notices were said only on stderr,
which Claude Code does not show the operator on an allowed (exit 0)
outcome; they now also print the same words as a "systemMessage" JSON
object on stdout, which Claude Code does show.
2026-10-21 18:23:42 +02:00
jochen 0fa427dad3 Add the plugin's Stop hook so a written-down wait is never left unwatched (issue 1743)
A session could end its turn while a wait it wrote down with
claude_code_wait had nothing following it. The plugin's Stop hook
(claude-code stop <waits-dir>) refuses the stop while a wait is within
its bound and unwatched, or past its bound and not said, reading the
waits file directly with no network and a 5s bound; it fails open on a
missing or malformed file or a panic, and lets a wait through after
three refusals in a row rather than holding the session forever.
Renames TestThePluginsOnlyHookIsTheGuard to cover the session-start and
Stop hooks too.
2026-10-21 18:08:13 +02:00
jochen 37628f4bce Add the plugin's SessionStart hook so a session learns its own id (issue 1744)
A session is never told its session id by any tool, only by a hook's
stdin, so it cannot name itself to claude_code_wait. The plugin's
SessionStart hook (claude-code session-start <waits-dir>) prints the id
and how to give it, plus the session's still-open waits after a /clear,
reading the waits file claude_code_wait mirrors directly rather than
calling back into this module. Carries the Stop hook's command and the
GuardFiles.WaitsDir plumbing MarketplaceWith needs for both (issue 1743
wires the Stop hook's dispatch next).
2026-10-21 18:07:36 +02:00
jschoubben 6cf51173d5 Give the Service its own fetch client and open-document waits instead of reading package variables from background goroutines, which a test or reload changed meanwhile: data races under -race (issue 1601)
mesh/repo-check head 6cf51173d586 merged into trunk b2f5ebb27dbf beside mesh-controller#424@550cf37d — pass: its merge-check.sh passed, each part in its to…
mesh/merge-gate head 6cf51173d586 merged into trunk b2f5ebb27dbf — pass: group feat/files-through-the-store composed: every machine composes with the chang…
mesh/delivery superseded: its walk was superseded and names no walk that took it over: a walk that took it over answers its merge, and it follows that wa…
mesh/delivery-group group feat/files-through-the-store stopped: superseded, not carried by a later delivery: novox/mesh-catalog@6cf51173d586, novox/mesh-contro…
2026-10-21 18:03:58 +02:00
jschoubben ad85a979e3 Read the upload fake under a lock, since the print runs in the background and the test read it meanwhile: a data race under -race (issue 1598) 2026-10-21 18:03:58 +02:00
jochen 56c68be7fa Keep a session's wait list in the claude-code module (issue 1629)
A session can end its turn while an Approve it expects is still open and
nothing then watches it. claude_code_wait (add/watched/done/said/list)
keeps each session's waits in the module's waits state, keyed by its
session id and node, and mirrors them whole and atomically to a file
under the agent's home that the plugin's coming hooks (1743, 1744) will
read without calling back into this module.
2026-10-21 17:59:10 +02:00
jschoubben aef2a1a91f Merge remote-tracking branch 'origin/main' into feat/files-through-the-store
mesh/delivery-group group feat/files-through-the-store rejected: a member's own check failed
mesh/merge-gate waits for its group's composed check
mesh/repo-check head aef2a1a91ffc merged into trunk b2f5ebb27dbf beside mesh-controller#424@550cf37d — fail: its merge-check.sh failed: --- FAIL: TestAScan…
mesh/delivery superseded: a newer head of the same pull request
2026-10-21 17:49:29 +02:00
mesh-tools b2f5ebb27d Merge pull request 'Fill a delivery made from its verdict from its pull request's announcement, and say what it waits for (issue 1726)' (#419) from fix/1726-delivery-from-verdict into main 2026-10-21 15:40:16 +00:00
mesh-tools 3259765d46 Merge pull request 'Read automx's rows in a mode its image's sqlite3 knows (issue 1630)' (#418) from fix/1630-automx-rows-sqlite into main 2026-10-21 15:08:27 +00:00
jschoubben 4b9464f3ce Supersede older heads when an announcement or edit fills a delivery made from its verdict, and say truthfully what fills it (issue 1726)
mesh/merge-gate head 4b9464f3ceeb merged into trunk 3259765d46bc — pass: builds mesh-delivery-gate → novox; no bus step; every machine composes with the ch…
mesh/repo-check head 4b9464f3ceeb merged into trunk 3259765d46bc — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@6cf51173d586 (merged as 7a7a4034 into main, walk plan-17925972200…
2026-10-21 17:06:51 +02:00
jschoubben 1f7dd702d2 Read automx's rows with a mode its image's sqlite3 knows, since it refuses -json (issue 1630)
mesh/merge-gate head 1f7dd702d283 merged into trunk 90ecba4e50a3 — pass: builds mailu, sent nowhere; no bus step; 1 wait(s) for a person; every machine com…
mesh/repo-check head 1f7dd702d283 merged into trunk 90ecba4e50a3 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
2026-10-21 16:24:58 +02:00
jschoubben dd31d991cd Fill a delivery made from its verdict from its pull request's announcement, and say what it waits for (issue 1726) 2026-10-21 16:18:43 +02:00
jschoubben a2deae03b7 Answer printer.print within 25 s as started with its ask id, and read it with printer.print {ask}, so no call is cut by the tool runner (issue 1598)
mesh/merge-gate checking again: rejected at 16:52 only because the group sibling mesh-controller#424 (227c86eb) no longer merged into main; the sibling's n…
mesh/repo-check checking again: rejected at 16:52 only because the group sibling mesh-controller#424 (227c86eb) no longer merged into main; the sibling's n…
mesh/delivery-group group feat/files-through-the-store checking: 0 of 2 member(s) ready
mesh/delivery superseded: a newer head of the same pull request
2026-10-21 15:25:17 +02:00
jschoubben 72ef20a4e7 Follow a conversion with convert {ask}, each call under 25 s, and leave the SDK's call timeout alone (issue 1600) 2026-10-21 15:23:33 +02:00
jschoubben 778356f10c Answer a conversion not done in 25 s as converting and read it with convert {ask}, so no call is cut by the tool runner (issue 1595) 2026-10-21 15:22:36 +02:00
jschoubben 7c97ce0bf8 Bound an upload and a download to 25 s, so a tool call is never cut while the transfer goes on (issue 1597) 2026-10-21 15:21:56 +02:00
jschoubben 68e1ad80ac Declare the seat document-converter in only-office's seats (issue 1595) 2026-10-21 15:19:03 +02:00
jschoubben 6e2762d943 Declare the seat object-store in minio's seats (issue 1516) 2026-10-21 15:19:03 +02:00
jschoubben dc2b0641bf Merge remote-tracking branch 'origin/main' into feat/files-through-the-store 2026-10-21 15:10:43 +02:00
jschoubben b54640e386 Post conversions to the document server's documented /converter path (issue 1596) 2026-10-21 15:10:35 +02:00
jschoubben 6358041eca Convert a Word, spreadsheet, slide, text or web document to PDF through the converter before printing it (issue 1600) 2026-10-21 15:09:47 +02:00
jschoubben 657b38ccd1 Print a web link: the device process fetches it bounded, never inside the mesh or the machine, stores it under its SHA-256 and prints that (issue 1599) 2026-10-21 15:07:34 +02:00
jschoubben e959cf339b Make printer.print take exactly one of object, path with node, or url, send a machine's file through its node-files, and check the printer's formats first (issue 1598) 2026-10-21 15:05:03 +02:00
jschoubben cb226c6fef File a scan from the store by the link the device process signs, not by parts over the bus (issue 1601) 2026-10-21 15:01:09 +02:00
jschoubben 278014fd79 Add the converter process: take convert-asks, have the document server make the PDF with a token only it holds, and put it to the target link (issue 1596) 2026-10-21 14:58:41 +02:00
jschoubben caae838a2a Claim document-converter and serve convert: queue the ask for the converter and read its answer, holding no credential (issue 1595) 2026-10-21 14:55:47 +02:00
jschoubben 6ee3507af0 Serve node-files.upload and download: a machine's file goes into a bucket and an object comes out of one, by short links, never over the bus (issue 1597) 2026-10-21 14:54:17 +02:00
jschoubben 06ca1b7fb9 Serve object-store.link: a signed link to one object, signed with the bucket's link key, for the consumer and its shares; retire the root-signed minio_presigned_url (issue 1516) 2026-10-21 14:52:14 +02:00
mesh-tools 90ecba4e50 Merge pull request 'Capture automx's live answers as fixtures and add a read-only tool for its database rows, before R4d replaces it (issue 1630)' (#415) from feat/r4d-automx into main 2026-10-21 12:47:49 +00:00
jschoubben 5b3fd1008a Make a link key per bucket, limited to get and put of its objects and kept as minio's own secret, so links are not signed by the root account (issue 1594) 2026-10-21 14:47:14 +02:00
mesh-tools 671ab9a3ba Merge pull request 'Pin gitea, keycloak, mesh-provisioner-client, postgres and route-adapter to a mesh-sdk commit on main, so a fresh go mod download resolves them once the feature branch goes (issue 1663)' (#414) from fix/1663-sdk-pins-on-main into main 2026-10-21 12:30:06 +00:00
jschoubben 0a7c58766c Pin gitea, keycloak, mesh-provisioner-client, postgres and route-adapter to a commit of mesh-sdk main, since the pinned one is on a feature branch only (issue 1663)
mesh/merge-gate head 0a7c58766c20 merged into trunk 4efac366cebb — pass: builds gitea, keycloak, mesh-provisioner-client, postgres, route-adapter → ace, g1…
mesh/repo-check head 0a7c58766c20 merged into trunk 4efac366cebb — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivering: 0 machine step(s) passed
2026-10-21 14:07:01 +02:00
jschoubben 454c5662dd Add automx_rows, a read-only tool for the rows automx answers from (issue 1630)
mesh/merge-gate head 454c5662ddcb merged into trunk 671ab9a3ba7b — pass: builds mailu, sent nowhere; no bus step; 1 wait(s) for a person; every machine com…
mesh/repo-check head 454c5662ddcb merged into trunk 671ab9a3ba7b — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivering: 0 machine step(s) passed
2026-10-21 14:02:37 +02:00
jschoubben 8fba5e831b Capture what automx answers today, before a Go program replaces it (issue 1630) 2026-10-21 13:59:58 +02:00
mesh-tools 4efac366ce Merge pull request 'Pin mesh-provisioner, mesh-vault and rofi to a mesh-sdk commit on main, so a fresh go mod download (mesh-build-go's fetch) resolves them (issue 1659)' (#413) from fix/1659-fetch-pseudo-version into main 2026-10-21 11:40:06 +00:00
mesh-tools 38ac738d84 Merge pull request 'Add netcheck_request: one HTTP request and its whole answer, so a service's live answers can be captured, refusing loopback, unspecified and link-local addresses (issue 1643)' (#412) from fix/1643-http-request into main 2026-10-21 11:27:33 +00:00
jschoubben 92c5e1d9ae Pin mesh-provisioner, mesh-vault and rofi to a commit of mesh-sdk main, since the pinned one is on no branch and no fetch can resolve it (issue 1659)
mesh/merge-gate head 92c5e1d9aea8 merged into trunk 38ac738d8463 — pass: builds mesh-provisioner, mesh-vault, rofi → g14, novox, shanks; no bus step; every…
mesh/repo-check head 92c5e1d9aea8 merged into trunk 38ac738d8463 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
2026-10-21 13:14:57 +02:00
jschoubben a01e1ea7fb Refuse a host in a short or legacy numeric form (127.1, 2130706433, 0x7f.0.0.1) in netcheck_request before any lookup, so the refusal does not depend on the resolver
mesh/merge-gate head a01e1ea7fb64 merged into trunk d74c1cb995a4 — pass: builds netcheck → ace, g14, novox, shanks; no bus step; every machine composes wit…
mesh/repo-check head a01e1ea7fb64 merged into trunk d74c1cb995a4 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
2026-10-21 13:07:08 +02:00
mesh-tools d74c1cb995 Merge pull request 'Read manifests that name shares: mesh-build-go and mesh-build-node take mesh-sdk 465beb4 (issue 1657)' (#411) from feat/files-through-the-store-builders into main 2026-10-21 11:01:03 +00:00
jschoubben 2d30dc2f1e Read manifests that name shares: mesh-build-go and mesh-build-node take mesh-sdk 465beb4 (issue 1657)
mesh/merge-gate head 2d30dc2f1ef7 merged into trunk b5dbfbb78450 — pass: builds mesh-build-go, mesh-build-node → g14, novox, shanks; no bus step; every mac…
mesh/repo-check head 2d30dc2f1ef7 merged into trunk b5dbfbb78450 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
2026-10-21 12:52:28 +02:00