From 3cf02d173aa91ec1f818cbcc2d471a8eddb6405d Mon Sep 17 00:00:00 2001 From: REPPL <77722411+REPPL@users.noreply.github.com> Date: Tue, 15 Sep 2026 19:40:09 +0100 Subject: [PATCH 1/2] chore: file the session-mailbox intents, the basics-plus-adapter principle and the messaging survey Two drafts: a shared-directory mailbox between sessions across accounts and mounts (the built-in basic) and an opt-in adapter to a local broker (full power), sequenced after it. The principle states the stance the maintainer set for every capability. The research note holds the survey that ranked them under the local-only bound, and the calibration note grades the routing. Assisted-by: Claude:claude-opus-5 --- .../brief/06-delivery/03-out-of-scope.md | 2 + ...ne-or-one-local-network-leave-each-othe.md | 50 +++++++ ...a-local-message-broker-brings-push-deli.md | 49 +++++++ .../basics-built-in-adapters-bring-power.md | 45 ++++++ .../2026-08-15-decomposition-calibration.md | 31 +++++ ...9-15-agent-messaging-on-a-local-network.md | 131 ++++++++++++++++++ 6 files changed, 308 insertions(+) create mode 100644 .abcd/development/intents/drafts/itd-2609151838312703-sessions-on-one-machine-or-one-local-network-leave-each-othe.md create mode 100644 .abcd/development/intents/drafts/itd-2609151838327688-an-opt-in-adapter-to-a-local-message-broker-brings-push-deli.md create mode 100644 .abcd/development/principles/basics-built-in-adapters-bring-power.md create mode 100644 .abcd/development/research/notes/2026-09-15-agent-messaging-on-a-local-network.md diff --git a/.abcd/development/brief/06-delivery/03-out-of-scope.md b/.abcd/development/brief/06-delivery/03-out-of-scope.md index c9c65946..1a239503 100644 --- a/.abcd/development/brief/06-delivery/03-out-of-scope.md +++ b/.abcd/development/brief/06-delivery/03-out-of-scope.md @@ -108,6 +108,8 @@ gate. That is what keeps "not hand-counted" true after the day it was written. - `itd-175` — The product thinker writes down how this could be wrong, and what would show it (Phase 8; the defeater list an acceptance rests on) - `itd-176` — Whatever ships says how hard anyone looked at it (Phase 7) - `itd-201` — every question abcd's agents put to a human is asked one at a time, in plain language, in the addressee's register, with options that widen +- `itd-2609151838312703` — sessions on one machine or one local network leave each other messages in a shared mailbox abcd owns (the built-in basic; nothing leaves the local network) +- `itd-2609151838327688` — an opt-in adapter to a local message broker brings push delivery and cross-machine reach to the session mailbox (sequenced after the mailbox) - `itd-2609151541116052` — every question an interview puts to a human shows the thing being decided before it asks, at every step (refines itd-201) - `itd-2609091014076309` — Session and agent worktrees live in a machine-scoped store (`~/.abcd/worktrees///`) that abcd lists and reclaims, never beside the user's own projects (the rule is adr-2609091248200336; `builds_on` itd-118, whose worktree clause it supplies the store and the reclaim verb for) - `itd-2609091416295622` — A session sees the records its sibling worktrees hold before it mints or fixes one: a read-only ledger diff over `git worktree list --porcelain` (open there and absent here; open here and terminal there), a line on the `/abcd` board and on the record dispatch, no claim and no write (split from itd-2609091034175565 on the maintainer's ruling of 2026-09-09; the shippable piece) diff --git a/.abcd/development/intents/drafts/itd-2609151838312703-sessions-on-one-machine-or-one-local-network-leave-each-othe.md b/.abcd/development/intents/drafts/itd-2609151838312703-sessions-on-one-machine-or-one-local-network-leave-each-othe.md new file mode 100644 index 00000000..cb513f7e --- /dev/null +++ b/.abcd/development/intents/drafts/itd-2609151838312703-sessions-on-one-machine-or-one-local-network-leave-each-othe.md @@ -0,0 +1,50 @@ +--- +id: itd-2609151838312703 +slug: sessions-on-one-machine-or-one-local-network-leave-each-othe +spec_id: null +kind: null +suggested_kind: null +reclassification_history: [] +builds_on: [] +severity: minor +impact: additive +origin: researcher-authored +production_mode: dictated-and-formatted +--- + +# Sessions on one machine or one local network leave each other messages in a shared mailbox abcd owns: a session under another account or on another machine writes a signed record into a shared directory, the recipient's prompt hook injects it and acknowledges it, and every message stays a readable record; no daemon, no dependency, nothing leaves the local network + +## Press Release + +> _Seeded from a quoted-text intent capture. Expand into the full press-release narrative before planning._ + +## Why This Matters + +Sessions on one machine or one local network leave each other messages in a shared mailbox abcd owns: a session under another account or on another machine writes a signed record into a shared directory, the recipient's prompt hook injects it and acknowledges it, and every message stays a readable record; no daemon, no dependency, nothing leaves the local network + +## Mechanism + +> _Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token `None stated.` alone on its line to record the claim as considered and declined._ + +## Scope Conditions + +> _Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet — `abcd intent plan` stamps each with a persistent identity. Replace this line with those bullets, or with the exact token `None stated.` alone on its line._ + +## Acceptance Criteria + +> _Required (the itd-1 discipline): add at least one Given-When-Then bullet describing the verifiable bar for "shipped" before this draft can be planned._ + +## Prior Art + +- [2026-09-15-agent-messaging-on-a-local-network](../../research/notes/2026-09-15-agent-messaging-on-a-local-network.md) — the survey this draft rests on: a Maildir-shaped shared-directory mailbox ranked first as the built-in basic under the local-only bound. +- [basics-built-in-adapters-bring-power](../../principles/basics-built-in-adapters-bring-power.md) — the stance that makes this the basic half; the broker adapter is itd-2609151838327688. +- The prompt-router hook (`abcd hook prompt-router`, itd-20's loader) — the injection path the mailbox reuses; no second hook. +- The hand protocol of 2026-09-15: two sessions under two accounts passing dated notes through one shared markdown file; this draft removes its two failure modes (colliding appends, no acknowledgement). + +## Open Questions + +_None recorded yet._ + +## Audit Notes + +_Empty. Populated by intent-auditor when intent moves to shipped/._ diff --git a/.abcd/development/intents/drafts/itd-2609151838327688-an-opt-in-adapter-to-a-local-message-broker-brings-push-deli.md b/.abcd/development/intents/drafts/itd-2609151838327688-an-opt-in-adapter-to-a-local-message-broker-brings-push-deli.md new file mode 100644 index 00000000..52928611 --- /dev/null +++ b/.abcd/development/intents/drafts/itd-2609151838327688-an-opt-in-adapter-to-a-local-message-broker-brings-push-deli.md @@ -0,0 +1,49 @@ +--- +id: itd-2609151838327688 +slug: an-opt-in-adapter-to-a-local-message-broker-brings-push-deli +spec_id: null +kind: null +suggested_kind: null +reclassification_history: [] +builds_on: [itd-2609151838312703] +severity: minor +impact: additive +origin: researcher-authored +production_mode: dictated-and-formatted +--- + +# An opt-in adapter to a local message broker brings push delivery and cross-machine reach to the session mailbox: with the adapter enabled a session is woken the moment a message arrives, machines on the local network exchange messages without a shared mount, and every delivered message is still mirrored to the mailbox as a record; without it the mailbox works as before + +## Press Release + +> _Seeded from a quoted-text intent capture. Expand into the full press-release narrative before planning._ + +## Why This Matters + +An opt-in adapter to a local message broker brings push delivery and cross-machine reach to the session mailbox: with the adapter enabled a session is woken the moment a message arrives, machines on the local network exchange messages without a shared mount, and every delivered message is still mirrored to the mailbox as a record; without it the mailbox works as before + +## Mechanism + +> _Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token `None stated.` alone on its line to record the claim as considered and declined._ + +## Scope Conditions + +> _Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet — `abcd intent plan` stamps each with a persistent identity. Replace this line with those bullets, or with the exact token `None stated.` alone on its line._ + +## Acceptance Criteria + +> _Required (the itd-1 discipline): add at least one Given-When-Then bullet describing the verifiable bar for "shipped" before this draft can be planned._ + +## Prior Art + +- [itd-2609151838312703](itd-2609151838312703-sessions-on-one-machine-or-one-local-network-leave-each-othe.md) — the basic this adapter extends; sequenced after it, and it shares the mailbox's record contract. +- [2026-09-15-agent-messaging-on-a-local-network](../../research/notes/2026-09-15-agent-messaging-on-a-local-network.md) — ranks an embedded NATS server with JetStream as the adapter, with an MCP mailbox server as the runner-up. +- [basics-built-in-adapters-bring-power](../../principles/basics-built-in-adapters-bring-power.md) — the stance; the adapter is opt-in and never a precondition. + +## Open Questions + +_None recorded yet._ + +## Audit Notes + +_Empty. Populated by intent-auditor when intent moves to shipped/._ diff --git a/.abcd/development/principles/basics-built-in-adapters-bring-power.md b/.abcd/development/principles/basics-built-in-adapters-bring-power.md new file mode 100644 index 00000000..ec68611e --- /dev/null +++ b/.abcd/development/principles/basics-built-in-adapters-bring-power.md @@ -0,0 +1,45 @@ +# Basics built in, an external dependency brings full power + +**The rule.** Every abcd capability ships with a basic form that works with +no daemon and no dependency beyond the abcd binary and the operating system, +and offers an opt-in adapter to an external dependency for the full form. The +basic is never a stub: it does the job at the scale a single person or a small +team hits first, and it keeps working when the adapter is absent. The adapter +never becomes a precondition: a repository or a machine that declines it +loses reach or speed, not the capability. + +**Why.** abcd is for people who know what they want to build and need help +shipping it; a capability that needs a broker, a service, or a network before +it does anything is a capability most of them will never switch on, and a +capability that only works through a vendor's cloud is one they cannot trust +with their record. The basic form is also where the contract is discovered, +which is the same reason the [script-first MVP](script-first-mvp.md) puts the +first cut in a script: the on-disk shapes, the failure modes and the verbs +worth having stabilise under real use before the adapter has to preserve +them. And the adapter's cost is real: a running process, an authentication +story, a second audit trail; it should be paid by the people who need what it +buys, not by everyone. + +**Bounds.** + +- The basic form and the adapter share one record contract. What the basic + writes as a file, the adapter mirrors as a file; a capability is never + auditable in one form and opaque in the other. +- The adapter is host-agnostic in the same way the basic is: it depends on + the external tool, never on a particular agent harness or a vendor's + cloud. A local-network dependency qualifies; a hosted relay does not. +- "Basic" is measured at the user surface, not at the code: the test is + whether a person with the binary alone can do the thing, not whether the + code path is short. + +**Live instances.** The oracle backends (host-delegated by default; native, +CLI, API and MCP as opt-in adapters). The secret scanners (the native +detector is the default; gitleaks and trufflehog are opt-in dependencies the +install offers). The session mailbox (a shared-directory mailbox is the +basic; an embedded broker is the adapter). + +**Promotion.** This principle is the standing statement of the "host-delegated +by default" boundary in the conventions, widened from LLM work to every +external dependency. No enforcement hook exists; per the promotion path in +this directory's [README](README.md), it becomes a discipline-kind intent +the moment one does. diff --git a/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md b/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md index 5fcba328..f2d16300 100644 --- a/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md +++ b/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md @@ -1417,3 +1417,34 @@ Per hand-run, append: in the file the rules loader puts before every session. The table caught it because verifying "already shipped" meant reading both the code and the rule that describes it, and they disagreed. + +### 2026-09-15 — messaging between sessions on one machine and one local network (hand-run at filing) + +- **Proposal:** the best way for a local setup that lets agents communicate + across user accounts and machines on the same network; whether Hermes or + OpenClaw answer it; whether abcd can carry it, given that abcd comes with + basic functionality and an external dependency brings full power. +- **Table:** + + | Part | Type | Home | + | --- | --- | --- | + | A shared-directory mailbox between sessions, across accounts and mounts, delivered by the prompt hook | capability | intent `itd-2609151838312703` | + | An opt-in adapter to an embedded broker for push delivery and cross-machine reach | capability | intent `itd-2609151838327688`, sequenced after the mailbox | + | "abcd comes with basic functionality; an external dependency brings full power" | stance | principle `basics-built-in-adapters-bring-power` | + | The survey with its sources and rankings | reference | research note `2026-09-15-agent-messaging-on-a-local-network` | + | A message from another account is untrusted input: signed, size-capped, sanitised, injected only from a mailbox the recipient owns | trust rule | an ADR at the mailbox's planning; not filed yet | + +- **Links:** the adapter `builds_on` the mailbox; both refine the + host-delegated-by-default boundary in the conventions. No reversal. +- **Verdict:** four options offered (SPLIT into two intents plus principle + and note; one intent covering both halves; HOLD with the note and the + principle only; decide later); the maintainer chose SPLIT. The table's + routing survived as offered. +- **Notes:** two constraints arrived mid-run and reshaped the survey before + it returned: local machine and local network only, and the + basics-plus-adapter stance. The first removed the harness's own + cross-machine path (vendor-relayed) from consideration; the second turned + a ranking of transports into a pair of rungs. The named tools both turned + out to be agent runtimes with their own peer protocols, not message paths + for a foreign harness, which is the finding that made "build it into abcd" + the answer rather than "adopt one of them". diff --git a/.abcd/development/research/notes/2026-09-15-agent-messaging-on-a-local-network.md b/.abcd/development/research/notes/2026-09-15-agent-messaging-on-a-local-network.md new file mode 100644 index 00000000..180b88ca --- /dev/null +++ b/.abcd/development/research/notes/2026-09-15-agent-messaging-on-a-local-network.md @@ -0,0 +1,131 @@ +# SOTA survey — messaging between agent sessions on one machine and one local network + +Dated 2026-09-15. Compiled from one host-run research pass, challenged per +[`prefer-sota`](../../principles/prefer-sota.md) against this repository's +conventions, and shaped by two maintainer constraints stated the same day: +every option must stay on the local machine or the local network, never a +vendor relay; and abcd ships a basic that needs no dependency, with an +external dependency as the opt-in that brings full power +([`basics-built-in-adapters-bring-power`](../../principles/basics-built-in-adapters-bring-power.md)). +Evidence tiers follow the ladder the context-window survey of 2026-08-22 +uses. + +**Why this note.** Two abcd sessions under two operating-system accounts on +one machine spent 2026-09-15 passing notes through a markdown file on a +shared desktop, one dated heading per message. It worked, and it has two +failure modes: two appends can collide, and nothing acknowledges. The +maintainer asked what the state of the art is, whether two named tools +answer it, and whether abcd should carry the capability itself. The routing +that followed is in the decomposition-calibration note; this note holds the +survey. + +## What the harness offers today + +The first harness has native cross-session messaging (its documentation, +vendor tier): same-machine delivery over a per-session socket that is +restricted to one operating-system user, so two accounts on one machine +cannot reach each other; cross-machine delivery through the vendor's servers +over its remote-control connection. Discovery is by files on disk: two +sessions reach each other only when they can see the same files. Its +channels feature pushes events into a session and needs vendor +authentication. Under the local-only bound, none of this is the transport; +the documented socket is usable only as a same-user wake-up, and that use is +noted below. + +## The two named tools + +**Hermes Agent** (Nous Research, MIT; primary docs). An agent runtime whose +"gateway" is a chat-platform gateway, not a message router. It implements the +A2A protocol (agent card at a well-known path, JSON-RPC on a fixed port, +localhost-only without a token, per-peer tokens and an explicit host binding +for remote exposure), so it qualifies under the local-network bound, but the +peer on the other end must itself be an A2A server; a session of the first +harness is not one. Its own documentation steers agents on one machine to +in-process delegation or its kanban board, a single-host SQLite file under a +trusted-local-user model. Verdict: a possible future peer through an A2A +adapter, not a message path. + +**OpenClaw** (the project renamed twice in early 2026; independent +foundation, MIT; primary docs). A single local gateway process: agents run +inside it and message each other through it, agent-to-agent open by default +until an allowlist is written, cross-machine only by tunnelling to the one +hub, with a token-theft vulnerability fixed this year. Verdict: poor fit +against minimal daemons and host-agnosticism; relevant only if such an agent +later becomes a peer. + +## Ranked options + +1. **Built-in basic: a shared-directory mailbox in Maildir shape.** One + record per message; the sender writes to a `tmp/` directory and renames + into `new/`; the recipient moves `new/` to `cur/` as the acknowledgement. + Rename delivery was designed to need no locking (Maildir specification, + spec tier). Across accounts the directory is one both can write; across + machines it is a mount the operating system already provides, so abcd + runs no daemon. Each message carries the sender's identity and a + signature over the body with a key held under the sender's `~/.abcd`, the + same shape an independent file-mailbox project converged on (anecdote + tier), and the first harness's own agent teams use a file mailbox per + agent (vendor tier). Delivery into a running session is the prompt hook + abcd already owns, injecting unread mail on the next prompt; a same-user + watcher may post a wake-up line through the harness's documented socket. + Limits, from the sources: keep `tmp/`, `new/` and `cur/` on one mount + because rename must not cross devices; unique names carry the host name + and entropy; never place an SQLite index on a network mount (the SQLite + project's own corruption warning, vendor tier); on macOS a shared + directory needs an inherited ACL for the group, which the community + documents and Apple does not. It cannot wake an idle session across + accounts, deliver in under a second, fan out to subscribers, or reach a + machine without a mount. + +2. **Opt-in adapter for full power: an embedded NATS server with + JetStream, inside the abcd binary as a Go module.** Adds push delivery + and subscriptions, cross-machine reach without a mount, subject + addressing keyed on repository identity, at-least-once persistence, and + real authentication (NKeys sign a server nonce so no secret crosses the + wire; tokens; TLS; subject-level permissions). Costs one long-running + process on the network, mandatory authentication configuration because + an unconfigured server admits every connection (NATS documentation, + vendor tier), and a mirrored file record per delivered message so the + audit trail stays where the basic keeps it. Runner-up adapter: an + MCP-based mailbox server with markdown mailboxes in a git repository + (Python daemon, bearer token, poll-only from the session; under active + development, anecdote tier). + +3. **Hermes Agent as a peer**, through an official A2A Go library, once one + is a session worth messaging. Keep the record format mappable to an A2A + message so the adapter is cheap. + +4. **OpenClaw as a peer**, below Hermes for the reasons above. + +5. **A2A direct, one server per session**: deferred. The specification + assumes each agent exposes a served endpoint with TLS and OAuth-class + authentication and says nothing about local-network deployment; a + server per note-passing session is the wrong weight. + +## Not adopted + +- The harness's native messaging as the transport: user-scoped socket and + a vendor-relayed cross-machine path. +- The harness's channels: vendor-gated and not host-agnostic. +- ZeroMQ with CurveZMQ: strong authentication and encryption without a + broker, but no persistence, so no record and both sessions must be up. +- Mosquitto and Redis Streams: credible brokers that do not embed in a Go + binary, so each is a second install; a fallback if NATS is rejected. +- SQLite on the shared mount, per the corruption warning. +- A coordination protocol rather than a note-passing one: the practitioner + report that works keeps writes single-threaded and calls free-form agent + swarms a distraction (position piece, contested); the mailbox carries + findings and handovers, which is what the desktop file already carries. + +## Fit judgement + +The mailbox is the formalisation of the hand protocol the two sessions ran +today, with the two failure modes removed; it is a documented protocol +before any automation, host-agnostic because any harness that can write a +file participates, auditable because the message is the record, and +transport-agnostic for the core because `internal/core` produces a record +and a surface writes it. The broker adapter matches the basics-plus-adapter +principle exactly and carries the same record contract. Both are filed as +intents; the security posture of a message from another account (untrusted +input: signed, size-capped, sanitised before a terminal, injected only from +a mailbox the recipient owns) is an ADR for the mailbox's planning. From 21cab51389ebe7971501865054574cb5a5d6d6dc Mon Sep 17 00:00:00 2001 From: REPPL <77722411+REPPL@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:52:43 +0100 Subject: [PATCH 2/2] chore: capture docs lint walking gitignored content under a lint root A peer session reported the second instance of the class behind the exempt_paths finding: the lint read a gitignored clone cache inside a lint root and raised thousands of findings none of which were the repository's own prose. Captured as iss-2609151952353626. Refs: iss-2609151952353626, iss-2609151150180583 Assisted-by: Claude:claude-opus-5 --- ...alks-gitignored-content-under-a-lint-root-in.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .abcd/work/issues/open/iss-2609151952353626-abcd-docs-lint-walks-gitignored-content-under-a-lint-root-in.md diff --git a/.abcd/work/issues/open/iss-2609151952353626-abcd-docs-lint-walks-gitignored-content-under-a-lint-root-in.md b/.abcd/work/issues/open/iss-2609151952353626-abcd-docs-lint-walks-gitignored-content-under-a-lint-root-in.md new file mode 100644 index 00000000..37077d6b --- /dev/null +++ b/.abcd/work/issues/open/iss-2609151952353626-abcd-docs-lint-walks-gitignored-content-under-a-lint-root-in.md @@ -0,0 +1,14 @@ +--- +schema_version: 1 +id: "iss-2609151952353626" +slug: "abcd-docs-lint-walks-gitignored-content-under-a-lint-root-in" +severity: "minor" +category: "bug" +source: "agent-finding" +found_during: "peer session report 2026-09-15 (a teaching-repo session; second instance of the class behind iss-2609151150180583)" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/core/lint/lint.go" +--- + +abcd docs lint walks gitignored content under a lint root. In a repository whose lint roots include a delivery folder, a shipped fetch script writes assessment data and a cached git clone of the abcd repository under that folder, which .gitignore excludes; the lint read the whole cached clone (5,391 findings, 94 blockers, all inside the ignored folder, none in the repository's own prose). exempt_paths covers the content-authoring families only, so with the folder exempted ten links_resolve blockers still fire from inside the cache, whose record files link to paths that resolve only in the abcd checkout. A gitignored path is by definition not the repository's documentation; the lint could ask git check-ignore once per root and prune ignored directories, the way the site publisher already does, and name what it pruned. Workaround the adopter took: the fetch script keeps its clone cache outside every lint root. Observed on the v0.8.0 plugin binary. Second instance of the class behind iss-2609151150180583 (exempt_paths cannot excuse links_resolve).