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 68a2cafd..13a5763b 100644 --- a/.abcd/development/brief/06-delivery/03-out-of-scope.md +++ b/.abcd/development/brief/06-delivery/03-out-of-scope.md @@ -109,6 +109,8 @@ gate. That is what keeps "not hand-counted" true after the day it was written. - `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-2609061543533170` — one verb sets up a managed repository's release-rendered site end to end: the site composition, the wrangler configuration, the render-then-deploy workflow, the environments it needs, and the worker itself where a credential is held +- `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-2609151658486398` — a release cut publishes the security advisories its fixes close, and closes those resolved as won't-fix (the publication step the 2026-08-27 advisory-handling pilot named as its target) - `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) 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 dd5708c5..2bcd8992 100644 --- a/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md +++ b/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md @@ -1684,6 +1684,12 @@ Per hand-run, append: - **Proposal:** whenever a user is interviewed, provide the appropriate context: before asking whether acceptance criteria stand, show them; for every interaction during the interview. +### 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 | @@ -1731,3 +1737,23 @@ Per hand-run, append: advisories triaged today ended in three different states (fixed and released; fix in progress; not a vulnerability, won't-fix), which is the case split the intent's criteria have to cover. + | 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. 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).