From 83026f26a0434d18d4e35084f17987bede2cc7ec Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sat, 5 Sep 2026 12:57:25 -0400 Subject: [PATCH 01/15] =?UTF-8?q?docs(j5):=20how=20the=20J5=20docs=20are?= =?UTF-8?q?=20organized=20=E2=80=94=20five=20kinds,=20lifetimes,=20two=20i?= =?UTF-8?q?dentifier=20kinds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- docs/j5/process/docs.md | 90 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 docs/j5/process/docs.md diff --git a/docs/j5/process/docs.md b/docs/j5/process/docs.md new file mode 100644 index 000000000000..5c2881b54a23 --- /dev/null +++ b/docs/j5/process/docs.md @@ -0,0 +1,90 @@ +--- +title: "How the J5 docs are organized" +kind: process +--- + +# How the J5 docs are organized + +Every document under `docs/j5/` is one of five kinds. The kind decides where the file lives, what its frontmatter says, and — most importantly — whether anything may cite it as the truth about the product. + +| Kind | Directory | Answers the question | Expected lifetime | May be cited as current truth? | +| -------------- | ----------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------ | +| **definition** | `product/` | What is the product, today, at end state? | Evergreen — kept true as long as the product exists | Yes — the only kind that may | +| **plan** | `plans/` | What are we building next, in what order, with what scope? | Until executed; afterwards a historical "what did we do there?" artifact | Only for scope and sequence | +| **research** | `research/` | What did we learn by studying something, as of a date? | Decays — with time, and with large changes to the product or the thing studied | No — cite the definition | +| **record** | `worklog/` | What happened, and how did a decision get made? | Permanently accurate about its date; never about now | No — cite the definition | +| **runbook** | `runbooks/` | How do I operate the software? | While the software it describes runs; re-verified when the software changes | For operations only | + +`process/` (this directory) holds the rules for working in the repository and is cited for those rules only; a process rule is valid until it is changed. + +## Lifetime is the point + +The kinds differ most in how long they stay true. A **definition** is the only kind that is maintained to stay true — that is what makes it citable. A **plan** is true while it is being executed and then becomes history: nobody maintains a finished plan, so nothing may depend on one. **Research** is accurate as of its `as_of` and decays from there — with the passage of time and with large changes to the product record or to the thing studied; a reader checks the date before trusting it. A **record** is always accurate about the day it describes and never about today, which is why it cannot be a source of truth even though it is never wrong. When you are unsure which kind a document is, ask how long it is expected to stay valid. + +## Definitions + +A definition says what the product is. It is written in the present tense, as if the feature exists at its end state, and it is **rewritten, never appended**: when the product changes, the sentence that was true changes, and the History section gains one line saying when and why. Narrative of who proposed what, PR numbers, and build status never appear in the body. + +Every feature definition has the same sections, in this order: + +1. **Problem** — one paragraph linking the problem or goal in `problems.md` it serves. +2. **Definition** — what it is, and what it is not. +3. **Acceptance criteria** — a numbered list. Each criterion is one testable sentence about observable behavior. These are the only numbered items in the docs, and the only things that get referenced by number (see IDs below). +4. **Scenarios** — concrete situations written as user stories or worked examples, each naming the criteria it exercises. +5. **Scope** — what the current build includes and what waits, by criterion number, linking the plan that sequences it. Scope cuts are stated here and in the plan, nowhere else. +6. **History** — one line per amendment: date, what changed, and a link to the record. + +Core definitions (`principles.md`, `problems.md`, `glossary.md`, `use-cases.md`, `fleet-vision.md`, `cross-device.md`) keep their own shapes but follow the same rule: rewritten, never appended; cited by name. + +**Who edits definitions.** Anyone may propose a change — in a record, an issue, or a PR — but a definition is changed only through a reviewed docs PR that Product has checked against the other definitions and the principles. This is what keeps definitions from contradicting each other: a decision written down in a session is a proposal until the definition carries it. + +## Identifiers + +There are two kinds of identifier, and both carry the name of the thing they belong to, so a human can read them without a lookup table: + +- **An acceptance criterion, numbered within its feature** — written as the feature name plus the number: "Fleet page AC3", "Squadron AC1". It always links to the criterion. Numbers are never reused within a feature; a retired criterion keeps its number and is marked retired in History. +- **A milestone, numbered within its plan** — written as the plan or feature name plus the number: "Fleet observability M1", "Crews M2". It always links to the milestone in its plan. A milestone's lifetime is the plan's: once executed, the identifier is history and nothing current may depend on it. + +Nothing else is numbered: + +- **Principles and lenses are cited by name** ("never guess", "the human-contact spectrum"), never by position — positions have changed and will change again. +- **Glossary terms are cited by name**, in Title Case for named product concepts (Squadron, Crew, Captain, Role, Playbook, Memo, Exchange, Peer Agent, Subagent, Spawning Guide, Fleet page) and lowercase for descriptive words (fleet, agent, participant, inbox, ledger, dashboard). +- **Work items are GitHub issues** ("#28") and nothing else. No document assigns a letter-number to a piece of work. +- **Plans sequence work by milestone** ("Fleet observability M1"), and each milestone links the GitHub issues that carry it. + +The letter registers used before 2026-09-05 (D, E, X, R, SC, ST, SB, IB, TA, AR, SP, QS, FV, DV, M, P, J, and the A/B/DQ/SQ ticket series) are retired. Records that use them are left as written; each definition that absorbed a register says so in its History line ("former E1–E7 and SC1–SC4 → AC1–AC11") so an old reference can still be followed. + +## Plans + +A plan sequences work. It names milestones ("Fleet observability M1", "Crews M2"), links the GitHub issues that carry each one, states scope cuts by feature and criterion, and carries `status: active | done` in its frontmatter. A plan never restates acceptance criteria and never defines anything; when a plan and a definition disagree, the definition wins and the plan is wrong. + +## Research + +A research document reports what was learned from studying code, a product, or a practice. Its frontmatter carries `as_of:` (a commit or a date) and every claim is a claim about that moment. Research is never cited as the truth about our product; if a finding changed the product, the definition changed and its History links the research. + +## Records + +A record says what happened: a design session, a review, a retrospective, a priority input, a friction list. Filenames are date-first — `2026-09-04-fleet-visibility-session.md` — so the directory sorts as a timeline. A record is never edited after the fact except to add a pointer to the definition that now holds its outcome. A record never defines anything current: if it contains a decision, the decision's home is the definition it links, and the record is the story of how it got there. + +## Runbooks + +A runbook tells an operator how to run the software. It may cite definitions for behavior and process docs for repository rules. + +## Frontmatter + +```yaml +--- +title: "…" +kind: definition | plan | research | record | runbook | process +as_of: 2026-09-05 # research only: the commit or date the study describes +status: active | done # plans only +--- +``` + +## One test per kind + +- Is this true of the product at end state? → definition. +- Does this sequence or scope work? → plan. +- Is this what we learned from studying something else, as of a date? → research. +- Did this happen on a date? → record. +- Does this tell an operator what to do? → runbook. From 9ca13de57c3643bd117800945261541361a39527 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sat, 5 Sep 2026 13:08:23 -0400 Subject: [PATCH 02/15] docs(j5): glossary rewritten as index + owned distinctions; casing rule made unambiguous Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/glossary.md | 135 +++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 49 deletions(-) diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 3aeb3d524184..fe0253eb2bce 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -1,63 +1,100 @@ --- -title: "Product glossary" -kind: spec +title: "Glossary" +kind: definition --- -# Product glossary +# Glossary -The J5 product vocabulary of record. One entry per term, with a pointer to the defining document — the pointer is authoritative when detail matters. Terms inherited unchanged from T3 Code (project, thread, turn, environment, checkpoint, provider…) live in the upstream glossary at `docs/internals/glossary.md`; this file covers what J5 adds or redefines. **Writing convention:** named product concepts are written Title Case — Squadron, Crew, Captain, Manifest, Role, Playbook, Memo, Exchange — so readers know it's our concept, not the generic word; descriptive terms (fleet, agent, participant, inbox, ledger, dashboard) stay lowercase, and code identifiers are unaffected. Update this file as terms settle — a stale glossary is worse than none. +The J5 vocabulary, in one place, so that a name used anywhere in these docs resolves to exactly one meaning. -## The agent organizational family +**Two kinds of entry.** Most terms name something a product definition owns; for those the entry is an index — the term, a one-line gloss that only identifies the thing, and the definition that owns it. The gloss never states a rule or a property; if a sentence here could be argued with, it belongs in the owning definition instead. A few terms are distinctions everyone must share but that no feature builds — Subagent versus Peer Agent is the model — and for those the glossary is the owner and the entry is the full definition. -We use a civil-nautical theme to make onboarding users to these concepts easier. +**Casing.** A named product concept is written in Title Case — Squadron, Crew, Captain, Role, Manifest, Playbook, Memo, Exchange, Peer Agent, Subagent, Spawning Guide, Registrar — so a reader knows it is our concept and not the ordinary word. Everything else is lowercase, including fleet, agent, participant, inbox, ledger and dashboard. A surface's proper name is Title Case (Fleet page). Code identifiers keep their own spelling. -| Term | Meaning | -| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Fleet** | The totality — all of a user's agents across every connected server (the merged client view, X2). Never a sub-grouping. | -| **Squadron** | User-created grouping of agents, artifacts, PRs, and their ledger around a large or long-running initiative. A grouping, never a boundary; single home, immutable membership; lives entirely on one server (X1). Formerly code-named "epic" (renamed 2026-08-17). Defined in `features/squadron.md`. | -| **Crew** | A group of agents spawned as a unit from a Crew definition: fixed membership, entirely within one Squadron, archived only as a unit. The hands running one piece of work. Defined in `features/crews.md`. (R12–R17) | -| **Role** | A reusable, user-authored definition of a kind of agent: identity/prompt content, model + reasoning allowlist, skill allowlist, posture. Spawnable solo or composed into Crew definitions. Defined in `features/roles.md`. (R28) | -| **Manifest** | Implementation vocabulary, not a separate concept: the artifact form of a Crew definition — composes Roles into a Crew with their wiring. The user's content — git-versioned, portable, shareable by construction. (R12, R28) | -| **Captain** | Derived role archetype, not a platform entity: any agent with Crews placed under it. Runs Crews, serves as tie-breaker; never a communication router. Captaincy follows placement. Defined in `features/crews.md`. (R18–R22) | +**Upstream's words.** T3 Code's own vocabulary — thread, turn, project, worktree, provider, session, checkpoint, projection, receipt — is defined in [upstream's glossary](../../internals/glossary.md) and is not restated here. Upstream words that upstream does not define (settled, snoozed, pinned, archived, steer, queue) are used in J5 docs with upstream's meaning; where J5 defines behavior around one of them, the entry below points at the definition that does. J5 does not write its own definition of an upstream word unless a measured confusion requires one. -## Spawning (settled 2026-08-24; worklog: `../worklog/spawn-terminology-session-2026-08-24.md`) +## Organization -| Term | Meaning | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Subagent** | Adopts upstream's own word. A worker an agent runs inside its own provider session (Claude Task workers, Codex collab children, Cursor task subagents): an **un-addressable child** — same provider only, dies with the parent's session, can never be moved out of the parent's tree, almost always created for a one-off task. What the user _sees_ varies by harness (summary block to a mirrored read-only view); what never varies is that the user cannot talk to it. Not a participant; never in the ledger (D1). **The platform cannot control Subagent creation and does not try** — it only observes what harnesses surface. _(Implementation-vocabulary caveat: upstream code also labels `delegate_task` children "subagents" (`origin: "app_owned"`) — that usage is not ours.)_ | -| **Peer Agent** | J5's term (no upstream collision). An agent spawned by another agent as a **full citizen**: the user cannot tell it from any other agent without checking provenance — full conversation visibility, direct interaction, independently managed lifecycle, any provider. All platform spawning law governs Peer Agents and only Peer Agents: R21 placement, Squadron inheritance, the creation-time Registrar, ledger participanthood. | -| **Spawn** | The verb for creating either kind, always qualified — "spawn a Subagent," "spawn a Peer Agent." Unqualified "spawn" in J5 documents means a Peer Agent spawn. | -| **Spawning Guide** | The user-authored guide consulted at the moment of spawning: selection guidance (provider/model/reasoning per kind of work, which Role to pick) and brief conventions. Platform ships the mechanism and the factual catalog; the judgment layer is the user's ([spawning-guide.md](features/spawning-guide.md), SP1–SP2, 2026-08-30). | +| Term | Gloss | Owner | +| ------------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| fleet | All of a user's agents across every connected server — the totality, never a sub-grouping | [cross-device.md](cross-device.md) | +| **Squadron** | The user-created grouping of agents and their work that everything else is organized under | [features/squadron.md](features/squadron.md) | +| **Squadron home** | The one Squadron an agent belongs to, recorded when it is created | [features/squadron.md](features/squadron.md) | +| **Registrar** | The creation-time step that records an agent's Squadron home | [features/squadron.md](features/squadron.md) | +| **Crew** | A group of agents that work one task as a unit | [features/crews.md](features/crews.md) | +| **Captain** | Any agent with Crews placed under it | [features/crews.md](features/crews.md) | +| **Role** | A reusable, user-authored definition of a kind of agent | [features/roles.md](features/roles.md) | +| **Manifest** | The artifact form of a Crew definition — implementation vocabulary, not a separate concept | [features/crews.md](features/crews.md) | +| **Playbook** | User-authored step content that a Role or Crew follows | [features/playbooks.md](features/playbooks.md) | +| placement | Where an agent sits in the display tree | [a2a/substrate.md](a2a/substrate.md) _(moves to the A2A definition when it is rewritten)_ | +| provenance | The recorded fact of how an agent came to exist — spawned by whom, forked from what, or unrecorded | [a2a/substrate.md](a2a/substrate.md) _(moves to the A2A definition when it is rewritten)_ | +| **Shared Squadron** | Several people sharing one Squadron on one server | [features/shared-squadrons.md](features/shared-squadrons.md) | -## Communication (A2A) +## Agents -| Term | Meaning | -| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Participant** | Anything with its own thread: main agents, agent-created child agents, and humans. Provider-native subagents are not participants. (D1) | -| **Agent** | An LLM participant. | -| **Node** | A participant as rendered in the communication graph. | -| **Exchange** | The reply obligation: a reply-expected send mints an `exchangeId`; idempotent open per sender→receiver pair; one reply closes everything on it; the sender judges completeness at closure (R3). States: open / stalled / answered / dropped. Never called a "thread" — an exchange travels _through_ T3 threads. (D9) | -| **Communication ledger** | The per-squadron append-only event log — source of truth for all A2A state; rows never edited, corrections are new rows; survives restarts. (A2A M1) | -| **Projection** | A derived, materialized, disposable view over the ledger (graph, inbox, stall report, playback). Wipe-and-rebuildable, never authoritative. | -| **Silence notice** | A platform-authored fact bundle appended when an agent says nothing — turn ended, no closing reply, open outbound exchanges listed structurally. Labels (awaiting-human, blocked-on-peer…) are projection policy, not ledger fact. (D6, R4) | -| **Envelope** | The platform's per-channel prompt wrapper teaching protocol semantics at the moment of action; carries measured time facts (R25). Versioned config the user owns. | -| **Exchange vs delegation** | A Peer Agent spawn carries its initial task plus whether and what reply is expected in the spawn brief; it is never followed by a reply-expected ask. Exchanges remain the reply-obligation primitive for later work owed by an existing participant. Upstream's `delegate_task` realizes an excluded middle less capably (sidebar-hidden lineage, subagent labeling, spawn requires an active parent run); **direction (2026-08-24): exclude `delegate_task` from the J5 product surface**. Provider-native Subagent work never appears in the ledger. (D1; ST5; SP4) | +These entries are the distinctions the whole team must share; the glossary owns them. + +| Term | Definition | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| agent | An LLM-driven participant running in a provider session. The ordinary word, lowercase. | +| participant | Anything that can send and receive over the communication ledger: agents registered in a Squadron, and people. Provider-native Subagents are not participants. | +| **Peer Agent** | An agent spawned by another agent as a full citizen: it has its own top-level thread, the user can read and talk to it like any other agent, it has an independent lifecycle, and it may run on any provider. The user cannot tell it from a human-created agent without checking its provenance. All platform law about spawning, membership, placement and messaging applies to Peer Agents and only to Peer Agents. | +| **Subagent** | Upstream's word, adopted: a worker an agent runs inside its own provider session (Claude Task workers, Codex collab children, Cursor task subagents). The user cannot talk to it, it cannot be moved out of its parent's tree, and it ends with its parent's session. What the user _sees_ of it varies by provider; what never varies is that it is not addressable. The platform cannot control Subagent creation and does not try; it only observes what the provider surfaces. | +| spawn | The verb for creating either kind, always qualified — "spawn a Subagent," "spawn a Peer Agent." Unqualified "spawn" in J5 docs means a Peer Agent. | +| Foreground, Background | The two ends of the human-contact spectrum: a Foreground agent talks with the person through chat often; a Background agent reaches the person only through the inbox or its Captain. Agents can sit in between. Owner: [principles.md](principles.md), the human-contact spectrum lens. | +| **Spawning Guide** | The user-authored guide consulted when spawning: which provider, model and reasoning for which work, and how to write a brief. Owner: [features/spawning-guide.md](features/spawning-guide.md). | + +## Communication + +| Term | Gloss | Owner | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| message | One durable send from a participant to a participant | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | +| ask | A message that opens an Exchange — the receiver owes a reply | [a2a/agent-tools.md](a2a/agent-tools.md) | +| reply | The message that closes an Exchange | [a2a/agent-tools.md](a2a/agent-tools.md) | +| plain message | A message that opens no Exchange; agents may send one to agents, never to a person | [a2a/agent-tools.md](a2a/agent-tools.md), [features/inbox.md](features/inbox.md) | +| **Exchange** | The reply obligation an ask creates between one sender and one receiver. Never called a "thread" | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | +| intent | The one-line summary an ask carries, shown wherever the Exchange is listed | [a2a/agent-tools.md](a2a/agent-tools.md) | +| urgency | How soon a person's answer is needed, set only on asks to a person | [features/inbox.md](features/inbox.md) | +| obligation | What an open Exchange is to its receiver: a reply owed | [features/inbox.md](features/inbox.md) | +| envelope | The platform's wrapper around a delivered message that tells the receiving agent who sent it and what it owes | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | +| communication ledger, ledger | The per-Squadron append-only record of every message, delivery, Exchange and notice — the source of truth for all A2A state | [a2a/substrate.md](a2a/substrate.md) _(A2A definition when rewritten)_ | +| delivery receipt | The recorded fact that a message reached its receiver's thread | [a2a/substrate.md](a2a/substrate.md) | +| delivery alarm | The recorded fact that a delivery failed | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| silence notice | A platform-authored fact appended when an agent's turn ends without a reply it owed | [a2a/substrate.md](a2a/substrate.md) _(A2A definition when rewritten)_ | +| queue, steer | The two ways a message reaches an agent mid-turn: queued behind the active turn, or steered into it. Agent deliveries queue; only a person steers, explicitly | [a2a/substrate.md](a2a/substrate.md) | +| human node | A person as a participant in the communication graph, keyed by person id | [features/inbox.md](features/inbox.md) | ## Humans and attention -| Term | Meaning | -| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **Person id** | The durable local identity (`human:`) minted at first run, used in every ledger row; external auth binds to it later. Nothing may assume exactly one human (R29's multi-human invariant). (R9) | -| **Inbox** | The obligation queue: open exchanges addressed to a person, urgency-ranked. Every item blocks a sender. Pure — no inferred mail, no auto-promoted stalls, no memos. (M4, R5, R26) | -| **Observability dashboard** | Where the human investigates "why isn't X done": stalls, blocked-on-peer chains, liveness. (R5) | -| **Backlog pane** | The pull-based view of all agents' memos. Third sibling to the inbox and observability views — shared UI allowed, shared data model never. (R26) | -| **Memo** | A small self-addressed message an agent stores via platform tool: non-blocking, always user-visible, per-agent, agent-cleared, optionally deferred via `resurface_after` — the one platform-initiated re-injection. The v1 agent data primitive. Defined in `features/memos.md`. (R31–R35) | - -## Structure and work - -| Term | Meaning | -| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Org placement** | The display-tree position of an agent; equals spawner at spawn ("you command what you brief", R21 amending D10); human-only re-parent is the sole divergence. Cascade operations follow placement. | -| **Playbook** | User-authored step content a Role or Crew executes; the platform holds the step pointer (advanced by tool call) and delivers each next step fresh, per participant. Engine = platform, steps = content. Defined in `features/playbooks.md`. (R27; backlog candidate) | -| **Shared Squadron** | The multi-user capability: several people on one server sharing Squadrons (shift handoff, two humans before one agent). Distinct from cross-device (X1–X5) and federation (X4). Defined in `features/shared-squadrons.md`. (R29; backlog candidate) | -| **Epic** | Historical name for squadron in pre-2026-08-17 documents; read as squadron. Inspired by Traycer's own epic concept in the design workspace. | +| Term | Gloss | Owner | +| -------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| person id | The durable local identity of one person; nothing may assume there is exactly one person | [features/shared-squadrons.md](features/shared-squadrons.md) | +| inbox | The person's queue of open asks addressed to them | [features/inbox.md](features/inbox.md) | +| **Fleet page** | The page that shows every agent in a Squadron with its measured status | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| Squadron scope | The sidebar's selection of one Squadron, or all | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| **Memo** | A small self-addressed note an agent keeps through the platform, visible to the person | [features/memos.md](features/memos.md) | +| backlog pane | The person's view of all agents' Memos | [features/memos.md](features/memos.md) | +| "Expects reply", "Replied" | The two words reader-facing cards use for an open and a closed Exchange, on every surface | [features/thread-a2a-rendering.md](features/thread-a2a-rendering.md) | +| observability dashboard | Retired name: what it described is the Fleet page | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | + +## Lifecycle + +| Term | Gloss | Owner | +| ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| archive | Retiring an agent for good; its record stays readable, its open Exchanges end loudly | [features/archive-flow.md](features/archive-flow.md) | +| retired | The state of an archived participant | [features/archive-flow.md](features/archive-flow.md) | +| orphan | A working agent whose placement parent has been archived | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| settled | Upstream's thread-triage state ("I'm done looking at this") and nothing else. J5 docs no longer use "settled" to mean a decision was made | upstream mechanics; see [worklog](../worklog/upstream-settled-vs-archived-research-2026-08-29.md) for the confusion this line resolves | + +## Retired names + +| Name | Now | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| epic | Squadron. Pre-2026-08-17 records use "epic"; read it as Squadron | +| team | Not a concept. Crew is the group that works as a unit; there is no other grouping | +| thread (as the reply obligation) | Exchange. "Thread" means only upstream's conversation | +| delegate_task | Not on the J5 agent surface; a Peer Agent spawn carries its task in the brief, and an Exchange carries any later obligation | + +## Terms still waiting for an owner + +These are glossed above with a provisional owner. The doc-by-doc pass gives them a home: placement, provenance, message/ask/reply/plain message, envelope, ledger, silence notice and queue/steer move into the rewritten A2A definition; Fleet page, Squadron scope, orphan and delivery alarm into the Fleet page definition when the current contract lands. From 25f280196bc1b7028e713d327f7ee60547a65ffe Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sat, 5 Sep 2026 13:41:35 -0400 Subject: [PATCH 03/15] =?UTF-8?q?docs(j5):=20cite=20principles=20by=20name?= =?UTF-8?q?=20=E2=80=94=20headings=20un-numbered,=20every=20numeric=20cita?= =?UTF-8?q?tion=20rewritten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/decision-log.md | 6 +-- docs/j5/product/design-review-2026-08-21.md | 56 ++++++++++----------- docs/j5/product/features/memos.md | 2 +- docs/j5/product/principles.md | 22 ++++---- docs/j5/product/problems.md | 42 ++++++++-------- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/j5/product/decision-log.md b/docs/j5/product/decision-log.md index d4ee2cb62670..b5ad0afba589 100644 --- a/docs/j5/product/decision-log.md +++ b/docs/j5/product/decision-log.md @@ -30,9 +30,9 @@ Running record of product-level decisions from Jackson. One row per decision; st | 2026-08-21 | Product principles | **Three named principles adopted** (`principles.md`): (1) communication flows peer-to-peer, decisions flow through the hierarchy — captains are never routers; (2) the human-contact spectrum (chat-contact specifically) — manifests declare posture, chattiness gets measured (item 4), platform never enforces position; (3) prompting problems are not platform problems — elevation of the 2026-08-16 platform/non-platform boundary. | Settled — check all designs against these | | 2026-08-22 | Foundations | **Problems & goals doc adopted** (`problems.md`) with foundations register R24–R35 (`design-review-2026-08-21.md`): time-stamped envelopes for time-blind agents; the inbox≠backlog distinction and the **memo primitive** (per-agent self-messages, all user-visible, no per-turn injection, `resurface_after` paging, dashboard/badge/archive-warning/chat-drawer surfacing); playbook engine direction (step pointer + fresh-step injection = platform, steps = content; linear first, DAG same family); manifests = platform schema in git-versioned files (user's content — portability/shareability must not be un-solved); agent cron/DB primitives parked with named trigger. | Settled | | 2026-08-22 | Shared squadrons | **Ratified as a distinct third capability** — several people on one server (L2-support shift handoff, two humans before one agent), not cross-device (X1–X5), not federation (X4). Settled now: the multi-human invariant (nothing may assume exactly one human; surfaces are person-scoped), delivery targets are one-user-or-all-users (no human group management), duty-addressing recorded as a door. Deep architecture session before any build; backlog candidate, likely post-item-4. | Settled — invariant in force immediately | -| 2026-08-22 | Product principles | **Principles 4–5 added** (`principles.md`): (4) status is read, never asked — if the user must ask an agent for a fact, the platform is missing a surface; (5) tools that make agents better, never systems that make them perfect — elevated from the perfect-Reviewer non-goal and "AI fails like humans fail." | Settled — check all designs against these | -| 2026-08-22 | Product principles | **Principle 6 added** (`principles.md`): the platform delivers facts, never judgment — it fixes the mechanical half of agent unawareness (deliver the measured fact) but never converts facts into conclusions ("crew done" vs "crew waiting" is undecidable); where discernment is required, the move is a nudge to a mind carrying the facts. Problems restructured into themes the same day (`problems.md`): fleet observability; human attention; agent weaknesses (async-blindness / context-as-memory / large unsupervised groups); cleanup at scale; Traycer/T3 inheritances. Roles moved from problems to goals. | Settled | +| 2026-08-22 | Product principles | **Two principles added** (`principles.md`): _status is read, never asked_ — if the user must ask an agent for a fact, the platform is missing a surface; and _build tools that make agents better, never systems that make them perfect_ — elevated from the perfect-Reviewer non-goal and "AI fails like humans fail." | Settled — check all designs against these | +| 2026-08-22 | Product principles | **Principle added** (`principles.md`): _the platform delivers facts, never judgment_ — it fixes the mechanical half of agent unawareness (deliver the measured fact) but never converts facts into conclusions ("crew done" vs "crew waiting" is undecidable); where discernment is required, the move is a nudge to a mind carrying the facts. Problems restructured into themes the same day (`problems.md`): fleet observability; human attention; agent weaknesses (async-blindness / context-as-memory / large unsupervised groups); cleanup at scale; Traycer/T3 inheritances. Roles moved from problems to goals. | Settled | | 2026-08-23 | Docs | **Docs reorganized and the evergreen/worklog convention adopted.** Single-doc folders flattened to `topic.md`; feature definitions of record live under `product/features/` (Squadron, Crews, Roles, Playbooks, Memos, Shared Squadrons, PR pane); build-time records (tickets, reviews, retros, fork-setup evidence) live under `worklog/` — historical by nature, read product docs for current truth. Use-cases doc written (`use-cases.md` — agentic software development; production monitoring with L2 support as an elevated chapter). Principles restructured into the beliefs/lenses/principles machine (`principles.md`). | Settled — conventions govern all future docs | -| 2026-08-23 | Product principles | **Principle 7 added** (`principles.md`): simple tools at the frontier — we are pushing the bounds of how AI agents work, so build the smallest thing that solves the _observed_ problem; machinery earns its place through observed need, never anticipated completeness. Elevated from the R10 guardrail; the working test: "what did we actually observe needing?" Same session: Manifest demoted to implementation vocabulary (the artifact form of a Crew definition; Roles carry per-agent fields incl. posture); Title Case convention adopted for named concepts (glossary); Playbook advancement enriched — agent declares step completion, platform fans out per-Role instructions to all participants; Memos extracted to their own feature doc (`features/memos.md`). | Settled — Jackson editing the principle text | +| 2026-08-23 | Product principles | **Principle added** (`principles.md`): _simple tools at the frontier_ — we are pushing the bounds of how AI agents work, so build the smallest thing that solves the _observed_ problem; machinery earns its place through observed need, never anticipated completeness. Elevated from the R10 guardrail; the working test: "what did we actually observe needing?" Same session: Manifest demoted to implementation vocabulary (the artifact form of a Crew definition; Roles carry per-agent fields incl. posture); Title Case convention adopted for named concepts (glossary); Playbook advancement enriched — agent declares step completion, platform fans out per-Role instructions to all participants; Memos extracted to their own feature doc (`features/memos.md`). | Settled — Jackson editing the principle text | | 2026-08-29 | Substrate | **Upstream substrate ruling settled** (`a2a/substrate.md`): the Subagent/Peer Agent species line sorts all upstream orchestration code — consume topology-free plumbing (adapters, event core, thread commands, `sendToThread` delivery, checkpoints), consume lineage as record only (forks/Subagents; never Peer Agent semantics), rebuild the org opinion J5-side (root-thread spawn + Registrar + placement, Exchanges for result binding, placement cascade, hierarchy display), build what neither side has (Exchange re-surfacing, orphan observability). ST5's `delegate_task` exclusion gets its mechanism: a J5-owned subset toolkit (`J5OrchestratorSurface`) replaces the upstream orchestrator registration — `delegate_task`/`task_status`/`task_cancel`/`t3_thread_send`/`t3_thread_interrupt` off the agent surface (raw thread-send is transport without the law; A2A = transport + envelope + ledger + Exchange + silence). Ownership rule: upstream owns existence/lifecycle state, J5 overlays org facts, participanthood by explicit registration only (Codex shadow-thread guard). Evidence that retired the alternatives: the lineage cascade never killed children (projection bookkeeping only), and the A6 proof's "delivery failed to wake the child" was an instructed silence — asks steered into the live turn in both retained databases. Session: `worklog/substrate-session-2026-08-29.md`. Open: `create_threads`/`t3_thread_start` on the agent surface (drop recommended). | Settled — substrate.md governs | | 2026-08-31 | Peer Agent steering | **The spawn brief carries the initial task plus whether and what reply is expected.** There is no spawn-then-ask sequence: `send_message(expect_reply=true)` opens an Exchange only for later work owed by an existing participant. SP4's one brief-coaching sentence remains exactly once in the `spawn_agent` description. | Settled — amends the result-binding wording in the 2026-08-29 substrate row; `a2a/agent-tools.md` and `features/spawning-guide.md` govern | diff --git a/docs/j5/product/design-review-2026-08-21.md b/docs/j5/product/design-review-2026-08-21.md index 70b4b44932c0..28630110115c 100644 --- a/docs/j5/product/design-review-2026-08-21.md +++ b/docs/j5/product/design-review-2026-08-21.md @@ -9,46 +9,46 @@ A full-design grilling session (Jackson + Product, 2026-08-21): every open branc ## The register -| ID | Area | Ruling | -| --- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| R1 | Exchanges / lifecycle | **Archiving a participant terminates its obligations loudly.** Archive appends a platform-authored terminal notice per open inbound exchange (`receiver-retired`, mapped to Dropped, carries do-not-retry), delivered to each waiter through the normal pipeline. Sender-side open outbound exchanges get the same retirement disposition. No exchange ever waits forever on a node that can no longer answer. | -| R2 | Squadron / lifecycle | **Squadron archive is user-only, loud, and evented.** It force-closes the squadron's open exchanges via the R1 mechanism (notices reach cross-squadron waiters); human-inbox rows from the squadron leave with a visible record, never silently. | -| R3 | Exchanges / closure | **The sender judges completeness, prompted at closure.** When a reply lands, the reply-delivery envelope (third rendering of the one formatter) states: this reply closed the exchange entirely; if anything you asked remains unanswered, open a new exchange — nothing else is tracked. Completeness is a judgment call and therefore never code's (Principle 3). | -| R4 | Silence / notices | **Notices record facts; projections assign labels.** `silence.notice` carries the full measured bundle — turn ended, no closing reply, every open outbound exchange listed structurally (generalizing D6's structural peer id). Which single state labels an edge (awaiting-human vs blocked-on-peer vs turn-ended) is projection/display policy: disposable, tunable without ledger migration. States are evaluated at the recipient's turn-end over durable ledger facts regardless of which turn created them. | -| R5 | Dashboard / inbox | **Two features, not one.** The inbox is pure: letters agents deliberately sent to the human — no inferred mail, no auto-promoted stalls. The observability dashboard is where the human investigates "why isn't X done": it highlights e.g. an IC blocked-on-peer for 2 hours with the peer idle, prompting a nudge to whichever agent coordinates X. They may share a UI, never a data model. | -| R6 | Ledger / triggers | **Machine triggers are recorded roots, not participants.** Schedule/check fires append a ledger event (`trigger.fired`-kind: source id + run id) so machine-initiated chains have a recorded origin in playback. Triggers mint no exchanges and emit no silence; participant = has a thread, unchanged. External-systems-as-nodes stays an open door. | -| R7 | Cost | **Cost rolls up squadron → agent, nothing between.** Cost is measured per agent; the squadron is the only aggregation (membership immutable, so accounting is stable). No org-subtree or sub-squadron cost accounting — the re-parent attribution problem is thereby deleted, not solved. | -| R8 | Identity (item 3 seed) | **Identity = git-versioned definition files; no memory in the bundle (v1).** Closes the 2026-08-14 open counter in favor of the original no-new-memory-store call: portability comes from git (per X-register direction); provider memory is accepted as non-portable local seasoning; what an agent must never forget belongs in its definition. The Role/manifest system (item 3) carries this fully. | -| R9 | Human identity | **Durable local person id from day one.** The ledger needs a _stable_ id, not an _authenticated_ one: mint `human:` at first run, use it in every row and envelope. External auth (e.g. Clerk) binds to it later at the peer registry — X4's designated cross-person seam. App login stays deferred. | -| R10 | Exchanges / linkage | **Optional `regarding: exchange_id` on open.** A follow-on exchange (R3 reopen) links to the exchange it survives; envelope tells reopeners to carry it. One nullable column now vs a migration later. Guardrail noted with it: simple tools over completeness-striving — we are pushing the bounds of how AI works; this field passed only because it is one field. | -| R11 | Ledger / retention | **Archived ledgers are readable forever.** Archive removes a squadron from active views only; its ledger stays immutable and readable indefinitely; playback works forever; X5 client-pulled backups include archived ledgers. No deletion story in v1. | -| R12 | Crews / concept | **Two concepts: the manifest (definition) and the crew (instance).** The platform ships the machinery — author, spawn, render; every playbook (e.g. Jackson's PR Group) is one user-authored manifest, never the product's opinion. Manifests are git-versioned files (same mechanism as R8 identity). | -| R13 | Naming | **Fleet / Squadron / Crew, definition = Manifest — the nautical-civil family.** A fleet is all vessels; a squadron is a detachment grouped under a shared purpose; a crew is the hands running one vessel, each with a named station; a manifest lists a crew's roles. Simple enough to teach at onboarding. Crew is the least military word in the family (film/pit/flight/road crew) and is role-native. "Team" is retired as a reserved term. | -| R14 | Crews / lifecycle | **Crews archive as a unit; members are never individually archived or replaced.** Rationale: agent death is usually recoverable (message them again), and an irrecoverably poisoned member has likely contaminated its crewmates. Recovery = respawn the crew from the manifest. Continuity is cheap because work lives in durable artifacts outside the agents (worktree, branch, PR): the successor crew picks up where the old one left off. Solo agents (no crew) stay individually archivable. | -| R15 | Crews / workspace | **Archive never destroys work.** Archiving a crew (or any agent) never deletes worktrees, branches, or checkpoints by default; workspace cleanup is a separate explicit act. (Broader management of durable items outside the platform: deferred to those systems' build-time.) | -| R16 | Crews / spawn | **Agents can spawn crews** (within their own squadron, from user-provided manifests) — a deliberate, recorded asymmetry with user-only squadron creation (E4). The middle-management thesis requires it. | -| R17 | Crews / boundaries | **A crew lives entirely inside one squadron; a crew renders as one org node** with members beneath it, so cascade operations (D10) treat it as a unit. Membership is fixed at spawn (composes with R14) — an agent is in exactly one crew by construction; counterpart references resolve once at spawn to agent ids (no seat indirection needed). | -| R18 | Captain / concept | **Captain is a derived status, not a platform entity or a fourth tier.** The hierarchy is arbitrary-depth (managers of managers), so the management layer is made of agents in the placement tree, not container objects. A captain is any agent with crews placed under it — measured, never asserted. UI: captain chip + crews rendered as collapsible groups under their captain. ("Flotilla" reserved if a true container need ever materializes; none is expected.) | -| R19 | Captain / rights | **A captain may archive crews placed directly under it** — the only agent-invocable archive. Symmetric with R16 (retire what you command); safe because it triggers the same loud platform machinery (R1/R2). Not grandchild crews (route through the child captain or the human), not individual members (R14), not solo child agents (no identified need). | -| R20 | Crews / constraint | **Crew members cannot spawn crews — enforced in the tool surface**, not by convention: the spawn-crew tool refuses callers holding a crew seat, with an error naming the next command ("escalate to your captain"). Crews are leaf teams; wanting more hands is an escalation. | -| R21 | Hierarchy (amends D10) | **Placement parameter deleted; "you command what you brief."** Spawn-time placement (sibling/other-parent/new-root) is removed: placement = spawner, always. The scenario that motivated it — spawning-and-briefing a crew for someone else — is ratified as an anti-pattern (proxy management; Principle 1): the decider sends decision + brief to the future captain, who spawns its own crew. Provenance stays separately and immutably recorded; human-only re-parent survives as the sole divergence mechanism; captaincy follows placement. | -| R22 | Communication invariant | **Any participant may message any participant; captains are never routers.** No permission check may ever enforce communication routing or spectrum position (Principles 1–2). The graph, not the hierarchy, is how you see through a middle manager. | -| R23 | Principles | **Three principles adopted as named product docs** (`principles.md`): peer communication / hierarchical decisions; the human-contact spectrum (with riders: manifests declare posture; chattiness is measured — item 4; density lens directional); prompting-vs-platform elevated from the 2026-08-16 boundary ruling. | +| ID | Area | Ruling | +| --- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| R1 | Exchanges / lifecycle | **Archiving a participant terminates its obligations loudly.** Archive appends a platform-authored terminal notice per open inbound exchange (`receiver-retired`, mapped to Dropped, carries do-not-retry), delivered to each waiter through the normal pipeline. Sender-side open outbound exchanges get the same retirement disposition. No exchange ever waits forever on a node that can no longer answer. | +| R2 | Squadron / lifecycle | **Squadron archive is user-only, loud, and evented.** It force-closes the squadron's open exchanges via the R1 mechanism (notices reach cross-squadron waiters); human-inbox rows from the squadron leave with a visible record, never silently. | +| R3 | Exchanges / closure | **The sender judges completeness, prompted at closure.** When a reply lands, the reply-delivery envelope (third rendering of the one formatter) states: this reply closed the exchange entirely; if anything you asked remains unanswered, open a new exchange — nothing else is tracked. Completeness is a judgment call and therefore never code's (prompting problems are not platform problems). | +| R4 | Silence / notices | **Notices record facts; projections assign labels.** `silence.notice` carries the full measured bundle — turn ended, no closing reply, every open outbound exchange listed structurally (generalizing D6's structural peer id). Which single state labels an edge (awaiting-human vs blocked-on-peer vs turn-ended) is projection/display policy: disposable, tunable without ledger migration. States are evaluated at the recipient's turn-end over durable ledger facts regardless of which turn created them. | +| R5 | Dashboard / inbox | **Two features, not one.** The inbox is pure: letters agents deliberately sent to the human — no inferred mail, no auto-promoted stalls. The observability dashboard is where the human investigates "why isn't X done": it highlights e.g. an IC blocked-on-peer for 2 hours with the peer idle, prompting a nudge to whichever agent coordinates X. They may share a UI, never a data model. | +| R6 | Ledger / triggers | **Machine triggers are recorded roots, not participants.** Schedule/check fires append a ledger event (`trigger.fired`-kind: source id + run id) so machine-initiated chains have a recorded origin in playback. Triggers mint no exchanges and emit no silence; participant = has a thread, unchanged. External-systems-as-nodes stays an open door. | +| R7 | Cost | **Cost rolls up squadron → agent, nothing between.** Cost is measured per agent; the squadron is the only aggregation (membership immutable, so accounting is stable). No org-subtree or sub-squadron cost accounting — the re-parent attribution problem is thereby deleted, not solved. | +| R8 | Identity (item 3 seed) | **Identity = git-versioned definition files; no memory in the bundle (v1).** Closes the 2026-08-14 open counter in favor of the original no-new-memory-store call: portability comes from git (per X-register direction); provider memory is accepted as non-portable local seasoning; what an agent must never forget belongs in its definition. The Role/manifest system (item 3) carries this fully. | +| R9 | Human identity | **Durable local person id from day one.** The ledger needs a _stable_ id, not an _authenticated_ one: mint `human:` at first run, use it in every row and envelope. External auth (e.g. Clerk) binds to it later at the peer registry — X4's designated cross-person seam. App login stays deferred. | +| R10 | Exchanges / linkage | **Optional `regarding: exchange_id` on open.** A follow-on exchange (R3 reopen) links to the exchange it survives; envelope tells reopeners to carry it. One nullable column now vs a migration later. Guardrail noted with it: simple tools over completeness-striving — we are pushing the bounds of how AI works; this field passed only because it is one field. | +| R11 | Ledger / retention | **Archived ledgers are readable forever.** Archive removes a squadron from active views only; its ledger stays immutable and readable indefinitely; playback works forever; X5 client-pulled backups include archived ledgers. No deletion story in v1. | +| R12 | Crews / concept | **Two concepts: the manifest (definition) and the crew (instance).** The platform ships the machinery — author, spawn, render; every playbook (e.g. Jackson's PR Group) is one user-authored manifest, never the product's opinion. Manifests are git-versioned files (same mechanism as R8 identity). | +| R13 | Naming | **Fleet / Squadron / Crew, definition = Manifest — the nautical-civil family.** A fleet is all vessels; a squadron is a detachment grouped under a shared purpose; a crew is the hands running one vessel, each with a named station; a manifest lists a crew's roles. Simple enough to teach at onboarding. Crew is the least military word in the family (film/pit/flight/road crew) and is role-native. "Team" is retired as a reserved term. | +| R14 | Crews / lifecycle | **Crews archive as a unit; members are never individually archived or replaced.** Rationale: agent death is usually recoverable (message them again), and an irrecoverably poisoned member has likely contaminated its crewmates. Recovery = respawn the crew from the manifest. Continuity is cheap because work lives in durable artifacts outside the agents (worktree, branch, PR): the successor crew picks up where the old one left off. Solo agents (no crew) stay individually archivable. | +| R15 | Crews / workspace | **Archive never destroys work.** Archiving a crew (or any agent) never deletes worktrees, branches, or checkpoints by default; workspace cleanup is a separate explicit act. (Broader management of durable items outside the platform: deferred to those systems' build-time.) | +| R16 | Crews / spawn | **Agents can spawn crews** (within their own squadron, from user-provided manifests) — a deliberate, recorded asymmetry with user-only squadron creation (E4). The middle-management thesis requires it. | +| R17 | Crews / boundaries | **A crew lives entirely inside one squadron; a crew renders as one org node** with members beneath it, so cascade operations (D10) treat it as a unit. Membership is fixed at spawn (composes with R14) — an agent is in exactly one crew by construction; counterpart references resolve once at spawn to agent ids (no seat indirection needed). | +| R18 | Captain / concept | **Captain is a derived status, not a platform entity or a fourth tier.** The hierarchy is arbitrary-depth (managers of managers), so the management layer is made of agents in the placement tree, not container objects. A captain is any agent with crews placed under it — measured, never asserted. UI: captain chip + crews rendered as collapsible groups under their captain. ("Flotilla" reserved if a true container need ever materializes; none is expected.) | +| R19 | Captain / rights | **A captain may archive crews placed directly under it** — the only agent-invocable archive. Symmetric with R16 (retire what you command); safe because it triggers the same loud platform machinery (R1/R2). Not grandchild crews (route through the child captain or the human), not individual members (R14), not solo child agents (no identified need). | +| R20 | Crews / constraint | **Crew members cannot spawn crews — enforced in the tool surface**, not by convention: the spawn-crew tool refuses callers holding a crew seat, with an error naming the next command ("escalate to your captain"). Crews are leaf teams; wanting more hands is an escalation. | +| R21 | Hierarchy (amends D10) | **Placement parameter deleted; "you command what you brief."** Spawn-time placement (sibling/other-parent/new-root) is removed: placement = spawner, always. The scenario that motivated it — spawning-and-briefing a crew for someone else — is ratified as an anti-pattern (proxy management; the hierarchy carries decisions, never messages): the decider sends decision + brief to the future captain, who spawns its own crew. Provenance stays separately and immutably recorded; human-only re-parent survives as the sole divergence mechanism; captaincy follows placement. | +| R22 | Communication invariant | **Any participant may message any participant; captains are never routers.** No permission check may ever enforce communication routing or spectrum position (the hierarchy carries decisions, never messages; the human-contact spectrum). The graph, not the hierarchy, is how you see through a middle manager. | +| R23 | Principles | **Three principles adopted as named product docs** (`principles.md`): peer communication / hierarchical decisions; the human-contact spectrum (with riders: manifests declare posture; chattiness is measured — item 4; density lens directional); prompting-vs-platform elevated from the 2026-08-16 boundary ruling. | ## Foundations round (2026-08-22) — R24–R35 -The session continued with a step back to foundations: Jackson's problem statement and goals, now captured in `problems.md` (the doc these rulings assume). Principles 4–5 were adopted in this round (`principles.md`). +The session continued with a step back to foundations: Jackson's problem statement and goals, now captured in `problems.md` (the doc these rulings assume). Two principles were adopted in this round — _status is read, never asked_ and _build tools that make agents better_ — (`principles.md`). | ID | Area | Ruling | | --- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| R24 | Principle | **Status is read, never asked** — adopted as Principle 4. If the user must ask an agent for a fact, the platform is missing a surface. | +| R24 | Principle | **Status is read, never asked** — adopted as a principle. If the user must ask an agent for a fact, the platform is missing a surface. | | R25 | Envelopes / time | **The platform stamps measured time facts into everything it delivers** — open-durations, delivery timestamps, elapsed-since-request — because agents are time-blind. Versioned envelope config, M2-adjacent. Expected to convert into proactive behavior ("it's been 8 hours, let me check"; "it _is_ tomorrow, let me raise it") — behavior to study and tune, not assume. | | R26 | Attention model | **Inbox ≠ backlog.** The inbox is an obligation queue: every item blocks a sender, demands a reply, scales with working agents. A backlog is non-blocking and may grow freely. Deferred items must never route through the inbox (an inbox with 100 items hurts the attention problem); a separate primitive is required — the memo (R31–R35). Amends R5's surface list: inbox / observability views / backlog pane — shared UI allowed, shared data model never. | | R27 | Playbooks | **The playbook engine is platform; the steps are content** (brief-container precedent). Rulings: (a) the agent advances the step pointer by tool call — "on step 3" is a measured fact of the call with visible asserted-by provenance, never output-parsing; (b) linear sequences first, the initiative-level milestone/DAG view is the same primitive one level up — one family, linear ships first; (c) skills-per-step parked, unproven. New backlog candidate "playbooks & progress" — feeds item 4's panes, is not item 4. This is how PR Group and monitoring playbooks become expressible without being codified. | | R28 | Manifests | **Platform schema, file storage.** Machine-read fields (model, reasoning effort, skill allow-list, posture, playbook ref) wrap the prose role text; the platform enforces mechanics because it reads them. Riders: it is the _user's_ content — portability and shareability are requirements; git currently solves both; the implementation must not un-solve them. Skill gating is platform-only work. | | R29 | Shared squadrons | **A distinct third capability** — not cross-device (X1–X5), not federation (X4 joins two servers; this is several people on one server, the L2-support vision: shift handoff without context transfer, two humans in front of one agent). Settled now: the **multi-human invariant** — nothing built from here on may assume exactly one human; every human-facing surface is person-scoped (R9 person ids). Delivery targets are **one user or all users** — no human group management on a single server. Duty-addressing ("the on-call") recorded as an open door, undesigned. Deep architecture session required before any build. | | R30 | Agent primitives | **Agent-provisionable cron/DB parked with a named trigger**: revisit when cross-machine sync or repeated agent-setup pain makes hand-rolled stores hurt. The monitoring fleet's scraper and incident DB stay outside the platform. (Platform-owned durable schedules remain settled-build, unchanged.) | -| R31 | Memos | **No per-turn injection** — that would trade forgotten notes for context rot; the back-burner is a feature. The platform's leverage (Principle 5): the tool's existence makes usage likely; the UI makes lapses visible — dashboard backlog view, badge on agents whose backlog needs working, a warning when archiving an agent with open memos, a chat drawer for picking the next topic. | +| R31 | Memos | **No per-turn injection** — that would trade forgotten notes for context rot; the back-burner is a feature. The platform's leverage (_build tools that make agents better_): the tool's existence makes usage likely; the UI makes lapses visible — dashboard backlog view, badge on agents whose backlog needs working, a warning when archiving an agent with open memos, a chat drawer for picking the next topic. | | R32 | Memos / deferral | **`resurface_after` is the one platform-initiated re-injection** — "page me after this time." Before the time the memo truly rests; after it, it returns stamped with R25 time facts. This field is what distinguishes a deferral from a backlog item. | | R33 | Memos / visibility | **All memos are visible to the user — no private memos.** The backlog pane is pull-based (no clutter concern; the user arrives with attention to spare) and steering requires seeing everything the agent intends. Promotion to a real exchange is a deliberate agent act, never automatic. | | R34 | Memos / scope | **Shaped, not generic — memos are the v1 agent data primitive.** Clear access patterns (append, list-open, resolve, defer) earn the store its place; a generic agent DB waits for R30's trigger. | diff --git a/docs/j5/product/features/memos.md b/docs/j5/product/features/memos.md index 1ed7174b43d2..3b896f79395d 100644 --- a/docs/j5/product/features/memos.md +++ b/docs/j5/product/features/memos.md @@ -17,7 +17,7 @@ A **Memo** is a small self-addressed message an agent stores via a platform tool ## Behavior -- **No per-turn injection.** Re-injecting the list every turn would trade one failure (forgotten notes) for another (context rot) — the back-burner is a feature. The platform's leverage is Principle 5-shaped: the tool's existence makes usage likely; the UI makes lapses visible. +- **No per-turn injection.** Re-injecting the list every turn would trade one failure (forgotten notes) for another (context rot) — the back-burner is a feature. The platform's leverage is shaped like _build tools that make agents better, never systems that make them perfect_: the tool's existence makes usage likely; the UI makes lapses visible. - **All Memos are visible to the user — no private Memos.** The user only enters this view with attention to spare, and steering an agent requires seeing everything it intends to do. - **`resurface_after`** — the one platform-initiated re-injection: "page me after this time." Before the time, the Memo truly rests; after it, it returns stamped with measured time facts (R25). This field is what distinguishes a _deferral_ from a backlog item. - **Promotion is deliberate.** When a deferred thing becomes a _now_ thing, the agent opens a real Exchange. Never automatic. diff --git a/docs/j5/product/principles.md b/docs/j5/product/principles.md index d4f2d45fbaa6..4c8cde7efc1b 100644 --- a/docs/j5/product/principles.md +++ b/docs/j5/product/principles.md @@ -19,7 +19,7 @@ The falsifiable claims the product stands on. Lenses are tools that we use to refine our designs. They provide stress tests and different ways to think about the feature. -## 1. The human-contact spectrum +## The human-contact spectrum In a fleet, all agents sit somewhere on the spectrum. This spectrum is measured by how frequently an agent communicates with the user directly through the chat interface. @@ -33,7 +33,7 @@ Background agents are almost never seen by the user, so they need a way to send This lens classifies which surface serves whom, sets communication norms, and predicts where an agent's value lives: Background agents' value is in their definitions and durable artifacts (making them cheap to respawn); Foreground agents accumulate irreplaceable conversational context. -## 2. Mechanical vs. judgment +## Mechanical vs. judgment Split any "agents don't notice / don't do X" problem into two halves: the mechanical half (a measurable fact nobody delivered — the platform can fix this) and the judgment half (a call that can't be reliably decided by code — route it to a mind, agent or human, carrying the facts). @@ -49,7 +49,7 @@ Each part lends itself to different solution. We can solve a mechanical problem A feature can have parts that are mechanical and parts that are judgment. What counts as mechanics and judgment can change over time as the product and AI capabilities evolve. -## 3. Use cases +## Use cases J5 Code has multiple use cases, defined in [use-cases.md](use-cases.md). These are concrete use cases that the product is aiming to serve. Run your features through them to see how they serve those use cases. @@ -61,7 +61,7 @@ The principles in this document are what guide us when designing, architecting, Each principle states its rule, what it stands on (beliefs and lenses above), its jurisdiction — the kind of question it decides — and the cases it has already decided. R-numbers point into the [design-review register](./design-review-2026-08-21.md). A principle you cannot cite to kill or reshape a proposal is not pulling its weight. -## 1. The hierarchy carries decisions, never messages +## The hierarchy carries decisions, never messages **Rule:** any agent may message any agent directly; the org tree exists for tie-breaks, priorities, and resource calls — never as a communication path. @@ -71,7 +71,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** any-to-any messaging is a platform invariant and Captains are never routers (R22); "you command what you brief" — placement = spawner, and spawning-and-briefing a Crew for someone else is proxy management (R21); lateral-coordination norms are Role content, never permission checks. -## 2. Prompting problems are not platform problems +## Prompting problems are not platform problems **Rule:** behavior is fixed by Role definitions, prompting, and right-sized work; platform machinery only ever fixes mechanics. @@ -81,7 +81,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** reply completeness is judged by the sender, taught by envelope text, never checked by code (R3); communication-routing norms and human-contact posture live in Role definitions (R23); group cohesion, verbosity, and register are content, not tooling. -## 3. Build tools that make agents better, never systems that make them perfect +## Build tools that make agents better, never systems that make them perfect **Rule:** raise the odds of good behavior, surface the misses, cheapen the recovery — never attempt to guarantee what an agent will do. @@ -91,7 +91,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** Memos are a tool plus visibility (badges, archive warnings, the backlog pane), not forced context injection (R31); Exchange semantics are envelope-taught, not schema-coerced; recovery is cheap by design — respawn a Crew from its definition (R14), reopen an Exchange with `regarding` (R10), nudge from a pane. -## 4. The platform delivers facts, never judgment +## The platform delivers facts, never judgment **Rule:** measurements ship as features in J5 Code; verdicts route to an agent or human, carrying the facts. @@ -101,7 +101,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** silence notices inform and never auto-close Exchanges; notices carry fact bundles while labels are projection policy (R4); Playbook advancement is agent-declared, never platform-judged (R27); "Crew done" vs "Crew waiting" is structurally the Captain's or human's call, not a gap to engineer away. -## 5. Status is read, never asked +## Status is read, never asked **Rule:** if the user must ask an agent for a fact, the platform is missing a surface. @@ -111,7 +111,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** the observability dashboard and PR pane exist so "how's it going" is a read; cost rolls up per Squadron on a surface (R7); chattiness is a measured metric, not a vibe (R23). -## 6. Never guess — a plausible fake is worse than a visible gap +## Never guess — a plausible fake is worse than a visible gap **Rule:** unknowns render as unknowns, degraded data wears a staleness clock, and nothing may ever look green because data was missing. @@ -121,7 +121,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** `mergeable: UNKNOWN` renders as "?", never as mergeable; a broken poller goes quiet with a staleness clock, never loud-wrong; PR↔agent association is conservative — ambiguity shows unassociated rather than guessed (PR pane v1). -## 7. State changes are loud; nothing vanishes silently +## State changes are loud; nothing vanishes silently **Rule:** every lifecycle transition and failure leaves a visible, evented trace, delivered to whoever it affects. @@ -131,7 +131,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Cases:** archiving a participant or Squadron terminates its obligations with notices to every waiter (R1, R2); an undelivered message is a visible alarm, never a silent loss (A2A M2); membership changes are lifecycle events; archiving an agent with open Memos warns first (R31). -## 8. Simple tools at the frontier +## Simple tools at the frontier **Rule:** build the smallest thing that solves the observed problem; machinery earns its place through observed need, don't anticipate something we haven't seen. diff --git a/docs/j5/product/problems.md b/docs/j5/product/problems.md index d3e8308d76c3..eb33bf42c803 100644 --- a/docs/j5/product/problems.md +++ b/docs/j5/product/problems.md @@ -92,7 +92,7 @@ For example, a user can define a "reviewer" Role that they use to review the cod Complex work needs groups of agents with defined Roles — a Builder, a Reviewer, and a Sitter working one PR is the canonical case. A Crew is that group as a first-class thing: spawned as a unit from a user-authored, git-versioned Crew definition — the Roles it contains and how they work together — living entirely inside one Squadron, with membership fixed at spawn. Counterpart references ("escalate CI failures to your Builder") resolve at spawn, so every member knows how to work with the others without the human wiring them together. -Crews are meant to work the task they're assigned with a high degree of independence from the user, working until they hit a defined stopping point or they complete their task. They can always reach out to other agents in the Squadron for help. But, their communication to the user is rarely through direct chat — they reach the human through the inbox and their Captain (`communication-graph.md`, Principle 2's far-end norms) and record deferred items as Memos (`features/memos.md`). +Crews are meant to work the task they're assigned with a high degree of independence from the user, working until they hit a defined stopping point or they complete their task. They can always reach out to other agents in the Squadron for help. But, their communication to the user is rarely through direct chat — they reach the human through the inbox and their Captain (`communication-graph.md`, the human-contact spectrum lens's far-end norms) and record deferred items as Memos (`features/memos.md`). Crews are deliberately disposable: when their task is done, the user or spawner archives them. They archive only as a unit, members are never individually replaced, and recovery from a poisoned Crew is respawning a fresh one from its definition — cheap because the real work lives in durable artifacts (worktree, branch, PR) that survive the agents. Agents can spawn Crews themselves (Captains running Crews without the human in the loop is the point), Captains can archive the Crews they command, and Crew members can't spawn Crews of their own — wanting more hands is an escalation. @@ -106,7 +106,7 @@ Agents executing a long Playbook can forget later steps — they read it once at 2. On advance, the platform delivers the next step's instructions to every participant in the Playbook — each Role receiving its own instructions for that step, fresh in context. A single-agent Playbook is just the one-participant case. 3. Maybe swap skills per step (parked — unproven) -The user can define detailed Playbooks, targeted at either a single Role or a Crew. Either can be spawned and prompted to follow a given Playbook. As they work, the platform tracks their progress and keeps every participant supplied with its current instructions. Advancement is always agent-declared, never platform-judged (Principle 6). +The user can define detailed Playbooks, targeted at either a single Role or a Crew. Either can be spawned and prompted to follow a given Playbook. As they work, the platform tracks their progress and keeps every participant supplied with its current instructions. Advancement is always agent-declared, never platform-judged (the platform delivers facts, never judgment). ### Shared Squadrons @@ -120,22 +120,22 @@ The monitoring fleet's scraper and incident database (see the working fleet in ` One row per problem theme / goal; the pointer is where the answer is designed or tracked. -| Problem / goal | Answered by | Status | -| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| Fleet observability — agent/Crew state | Silence taxonomy + ledger projections (A2A M3/M5); Playbook step pointer (R27); dashboard surfaces (R5); Principle 4 | A2A v1 plan; item 4; Playbooks candidate | -| Fleet observability — PR management | PR pane v1; playback for review-decision audit (M5) | Pane approved, issue #6 | -| Fleet observability — cost | R7 Squadron→agent rollups | Item 4 | -| Human attention — lost/telephoned asks | Inbox + urgency (A2A M4); spectrum posture (Principle 2) | A2A v1 plan | -| Human attention — drowned conversations | Spectrum posture + delegation to Crews (Principle 2) | Principle adopted; manifest posture is item 3 | -| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | -| Async-event blindness | Silence notices to waiters (M3); `trigger.fired` (R6); time-stamped envelopes (R25) | A2A v1 plan | -| Context as bad memory | Principle 4 surfaces; R25; Memos; Playbook step injection (R27) | Principles adopted; candidates queued | -| Large, unsupervised groups | Exchanges + sender-judged closure (R3); silence machinery; memo visibility for drift steering (R33); observability dashboard | A2A v1 plan; item 4 | -| More work needs more cleanup | Archive never destroys work (R15); Crews archive as units (R14); Captain archive rights (R19); workspace cleanup tooling deferred | Register settled; tooling later | -| Traycer/T3 inheritances | Durable ledger vs RAM loss (M1); R15 vs over-eager cleanup; A2A + Squadrons vs parent-child-only flat list | A2A v1 plan | -| Roles in platform tooling | R28 platform-schema-in-git frame | Item 3 session | -| Crews | R12–R20 | Register settled; manifest schema is item 3 | -| Playbooks | R27 engine/content split | Backlog candidate | -| Shared Squadrons | R29 — multi-human invariant in force now; one-user-or-all-users delivery; architecture session before build | Backlog candidate | -| Agent cron/DB | Parked with named trigger (R30/R34) | Parked | -| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | +| Problem / goal | Answered by | Status | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- | +| Fleet observability — agent/Crew state | Silence taxonomy + ledger projections (A2A M3/M5); Playbook step pointer (R27); dashboard surfaces (R5); status is read, never asked | A2A v1 plan; item 4; Playbooks candidate | +| Fleet observability — PR management | PR pane v1; playback for review-decision audit (M5) | Pane approved, issue #6 | +| Fleet observability — cost | R7 Squadron→agent rollups | Item 4 | +| Human attention — lost/telephoned asks | Inbox + urgency (A2A M4); spectrum posture (the human-contact spectrum lens) | A2A v1 plan | +| Human attention — drowned conversations | Spectrum posture + delegation to Crews (the human-contact spectrum lens) | Principle adopted; manifest posture is item 3 | +| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | +| Async-event blindness | Silence notices to waiters (M3); `trigger.fired` (R6); time-stamped envelopes (R25) | A2A v1 plan | +| Context as bad memory | Status-is-read surfaces; R25; Memos; Playbook step injection (R27) | Principles adopted; candidates queued | +| Large, unsupervised groups | Exchanges + sender-judged closure (R3); silence machinery; memo visibility for drift steering (R33); observability dashboard | A2A v1 plan; item 4 | +| More work needs more cleanup | Archive never destroys work (R15); Crews archive as units (R14); Captain archive rights (R19); workspace cleanup tooling deferred | Register settled; tooling later | +| Traycer/T3 inheritances | Durable ledger vs RAM loss (M1); R15 vs over-eager cleanup; A2A + Squadrons vs parent-child-only flat list | A2A v1 plan | +| Roles in platform tooling | R28 platform-schema-in-git frame | Item 3 session | +| Crews | R12–R20 | Register settled; manifest schema is item 3 | +| Playbooks | R27 engine/content split | Backlog candidate | +| Shared Squadrons | R29 — multi-human invariant in force now; one-user-or-all-users delivery; architecture session before build | Backlog candidate | +| Agent cron/DB | Parked with named trigger (R30/R34) | Parked | +| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | From 5f72611372de59e8b93ae48005d6f87967371a78 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sat, 5 Sep 2026 14:16:45 -0400 Subject: [PATCH 04/15] docs(j5): Squadron rewritten as a definition; naming session moved to a record; glossary review fixes; shared example fleet Co-Authored-By: Claude Fable 5.1 --- docs/j5/process/docs.md | 2 + docs/j5/product/features/squadron.md | 78 ++++++++++--------- docs/j5/product/glossary.md | 8 +- docs/j5/worklog/2026-08-17-squadron-naming.md | 23 ++++++ 4 files changed, 71 insertions(+), 40 deletions(-) create mode 100644 docs/j5/worklog/2026-08-17-squadron-naming.md diff --git a/docs/j5/process/docs.md b/docs/j5/process/docs.md index 5c2881b54a23..c6f3c013cc7f 100644 --- a/docs/j5/process/docs.md +++ b/docs/j5/process/docs.md @@ -34,6 +34,8 @@ Every feature definition has the same sections, in this order: 5. **Scope** — what the current build includes and what waits, by criterion number, linking the plan that sequences it. Scope cuts are stated here and in the plan, nowhere else. 6. **History** — one line per amendment: date, what changed, and a link to the record. +Scenarios use one shared example fleet so a reader recognizes it from doc to doc, and never a real project: Squadrons **Billing Migration**, **Website Redesign**, and **L2 Support Rotation** (a non-development Squadron); repositories **the app repository** and **the infrastructure repository**; the person is simply **the user**. + Core definitions (`principles.md`, `problems.md`, `glossary.md`, `use-cases.md`, `fleet-vision.md`, `cross-device.md`) keep their own shapes but follow the same rule: rewritten, never appended; cited by name. **Who edits definitions.** Anyone may propose a change — in a record, an issue, or a PR — but a definition is changed only through a reviewed docs PR that Product has checked against the other definitions and the principles. This is what keeps definitions from contradicting each other: a decision written down in a session is a proposal until the definition carries it. diff --git a/docs/j5/product/features/squadron.md b/docs/j5/product/features/squadron.md index da1382eee93b..25a7270102f0 100644 --- a/docs/j5/product/features/squadron.md +++ b/docs/j5/product/features/squadron.md @@ -1,54 +1,60 @@ --- -title: "The Squadron — J5's grouping concept, defined" -kind: spec +title: "Squadron" +kind: definition --- -# The Squadron (formerly code-named "epic") +# Squadron -Settled with Jackson 2026-08-17, closing the gap the Director surfaced: the term "epic" had been adopted from Traycer research without a J5 product definition, and A2's `join_epic` implemented exclusive membership from that vacuum. This document is the definition of record. **E6 settled same day: the concept is named the _Squadron_** — squadrons make up the fleet. Everywhere earlier documents say "epic" (D3, D8, the A2A plan, the ledger design), read "squadron"; the code rename is scheduled with the Director. +## Problem + +Managing a large fleet of agents doing large, long-running work needs a unit to organize around — where things belong, what the user picks between, what a ledger is scoped to — without building walls that stop agents from reaching each other ([problems](../problems.md): fleet observability; T3's single flat list of agents keyed to folders). Upstream's unit is the folder: open a folder, get a project, base agents on it, one to one. Work is not shaped like that: many efforts touch one repository, and one effort touches several. ## Definition -A **grouping, not a boundary** — the way sets of agents, artifacts, PRs, human-targeted messages, and their communication ledger are organized around **a large amount of work or a long-running initiative**. It is a filter over shared infrastructure, not an isolation wall: messaging crosses it (D8 double-entry), human nodes are global (person-scoped `human:`, never singleton — R9/R29), the fleet dashboard aggregates across it, and the filesystem is readable regardless. +A **Squadron** is the user-created grouping of agents, their work — artifacts and pull requests — and their communication ledger, organized around a large amount of work or a long-running initiative. Squadrons make up the fleet; the name is fleet-native and names the group of agents (the naming session and the candidates it rejected are in the [record](../../worklog/2026-08-17-squadron-naming.md)). + +A Squadron is **a grouping, never a boundary**. It organizes; it never isolates. It carries no visibility or permission semantics: any agent can message any participant in any Squadron, people are global rather than per-Squadron, the Fleet page reads across Squadrons, and the filesystem is readable regardless of Squadron. + +Every agent has exactly one **Squadron home**, recorded by the **Registrar** when the agent is created and never changed afterward. A user-created agent gets the Squadron the user chose; a Peer Agent inherits its spawner's. There is no joining, leaving, or moving between Squadrons; the placement tree of a Squadron lives entirely inside it. + +Only a person creates a Squadron. Agents never do, and the platform never creates one automatically — an unnamed default container is the junk drawer that defeats the concept. Creating one is deliberately small: a name and one folder are required; a description and further folders can be added later. First run begins by creating the first Squadron, because agents need a home. -| Question | Ruling | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| E1 Boundary or label? | **Grouping/label.** Organizes; never isolates. No visibility or permission semantics. | -| E2 Membership | **Single home, no movement.** Multiple homes and movement defeat the purpose of grouping and add complexity with no identified need — cross-epic messaging and filesystem reads already cover the use cases. Membership is assigned at creation and immutable. | -| E3 Contents | **Full container over time**: agents, artifacts, PRs, human-targeted messages (plus the ledger, org tree, and eventually terminals/folder bindings). The A1 minimal entity is a seed, not the end state. | -| E4 Lifecycle & authority | **User-only creation.** An epic represents a large amount of work or a particular long-running initiative — agents never create them. (End-of-life semantics: archive expected; details when the container grows.) | -| E5 Org tree (D10 placement) | **Lives inside a single epic.** Placement moves never cross epic borders. | -| E7 Unit of user choice (added 2026-08-31) | **The Squadron is what users pick between.** Every surface where a user chooses a working context offers Squadrons; "project" disappears as a user-facing noun and remains implementation substrate (DV1: reference, never identity). Folders appear as attributes _inside_ the flow (SC1 palette; Browse-elsewhere per DV3) — never a peer choice beside Squadrons. First converted surfaces: the new-thread flow and the command palette (both ruled, from the #20 acceptance pass); remaining project-picking surfaces are converted per an inventory sweep riding the build ticket. Pickers key off Squadrons (Registrar truth), never derive from projects — two Squadrons over one folder must render as two distinct choices (DV1's acceptance criterion, restated for the UI). Agents never see pickers (R21 inheritance). Generalizes SB3's sidebar scoping and SQ1's composer to the whole surface. | +A Squadron **targets folders** rather than living in one: the Squadron is created first and targets one or more folders on one environment, while the same folder may be targeted by many Squadrons. Targeting is a **palette, never a wall** — when an agent is created in a Squadron, the Squadron's folders are offered first, and everything else on the machine stays reachable. -## Consequences for the build (the A2 fix) +The Squadron is **the unit of user choice**. Every surface where a person chooses a working context offers Squadrons; upstream's "project" is implementation substrate that a Squadron references, never a noun the user picks. Agent creation takes its Squadron from where the person already is — the sidebar's Squadron scope — and shows it in the composer, changeable until send and immutable after. Agents never see any of this: a spawned Peer Agent inherits its spawner's Squadron. -- **`join_epic` as an agent-facing tool should not exist.** Membership is fixed at creation: a user-created agent gets the epic the user chose; an agent-spawned agent inherits its spawner's epic (E2 + E4 + E5 compose to: agents always spawn within their own epic). There is no join, no leave, no move. _Amended 2026-09-12 (#129):_ `join_squadron` is the one narrow exception — a native thread that was created with **no** home (the mobile creation gap, #128) may establish its _original_ home in an explicitly selected Squadron that references its project. It is still not a join-elsewhere, leave, move, or revival: any thread with an existing home is refused, and the registration is as loud and evented as creation-time registration. -- The ledger's participant events are **lifecycle events only**: `joined` at agent creation/registration, `participant.archived` and `participant.unarchived` change visibility without changing identity or home; `participant.deleted` removes live membership. `left` records legacy permanent retirement. Agents cannot directly append these facts. -- Exclusive-join's worst property — _silently_ leaving other epics — is moot under no-movement, but the principle it violated stands recorded: membership changes, were they ever to exist, must be loud and evented. -- D3/D8 unchanged: per-epic ledger as storage/replication unit; cross-epic exchanges via double-entry. +End of life is archive; its details arrive with the container's growth. -> **Dogfood v0 note:** the v0 build ships an overridden subset of the creation UX below (exactly-one folder per Squadron, project-reference implementation). Overrides live in one place only: [`../dogfood-v0.md`](../dogfood-v0.md). This document remains the end-state truth. +## Acceptance criteria -## Creation UX — Squadrons and the agents under them (settled 2026-08-24) +1. A Squadron never restricts visibility or messaging: an agent in one Squadron can message any participant in any Squadron, and a message that crosses Squadrons is recorded in both Squadrons' ledgers. +2. Every agent has exactly one Squadron home, recorded at creation and never changed: a user-created agent gets the Squadron the user chose, a Peer Agent gets its spawner's, and no tool or interface joins, leaves, or moves an agent between Squadrons. +3. Only a person can create a Squadron; none is ever created automatically; first run cannot proceed to creating an agent until a Squadron exists. +4. Creating a Squadron requires a name and at least one folder; a description and further folders can be added at creation or later. +5. A Squadron targets one or more folders on one environment, and the same folder can be targeted by several Squadrons that remain distinct in every list and picker. +6. When creating an agent in a Squadron, the Squadron's folders are offered first and labeled, and everything else on the machine remains reachable below them. +7. Every surface where the user picks a working context offers Squadrons, and "project" never appears as a user-facing choice. +8. The composer shows the Squadron the agent will be created in, in its heading and as a chip, taking its default from the sidebar's Squadron scope; it can be changed until send and not after. +9. Agents never see a Squadron picker; a spawned Peer Agent inherits its spawner's Squadron. +10. The placement tree lives entirely within one Squadron. +11. Membership is recorded in the ledger as lifecycle events only — joined at creation, left at archive — and neither is agent-invocable. -From the creation-UX session ([worklog record](../../worklog/squadron-creation-session-2026-08-24.md)); mockups reviewed and approved by Jackson. The governing inversion: T3's shape is folder-as-container (open a folder, get a project, base agents on it — a 1:1 shape). J5's shape is **work-as-container**: the Squadron is created first and _targets_ folders, many-to-many — many Squadrons can target one repo; one Squadron can target many folders (on one environment — cross-machine targeting is item-5, out of scope). +## Scenarios -- **SC1 — Targeting = a resource palette, never a wall.** A Squadron's folder list is the default palette when creating agents in it: the worktree row offers the Squadron's folders first, labeled, with everything else on the machine reachable below a separator ("Browse elsewhere…"). One mechanical consequence only; no permission semantics (E1), no pre-provisioning — worktrees stay per-agent. The list is editable after creation; targets legitimately grow. -- **SC2 — Squadron creation is a deliberately small act** (user-only, E4): name required; description and folders optional, addable later; folders picked via the existing open/clone affordances. **First run gates on creating the first Squadron** — no auto-created "Default" (an unnamed auto-container becomes the junk drawer that defeats the concept); the gate states plainly that agents need a home, and name-only is enough. -- **SC3 — Agent creation takes Squadron context from navigation, not interrogation.** _(Amended 2026-08-29, SB3: the sidebar is **Squadron-scoped via a scope dropdown** — replacing upstream's project-scope dropdown — not Squadron-grouped; the grouped-sidebar clause was a product/UI decision, not doctrine, and the sidebar organizes by attention instead — see [`sidebar-and-roster.md`](sidebar-and-roster.md).)_ The composer inherits the current Squadron from the scope selection, shown twice: the heading ("What should we build in _⟨Squadron⟩_?" — the position the folder name used to hold) and an explicit **Squadron chip** in the sub-bar beside the worktree row — visible, changeable until send, immutable after (exactly what the creation-time Registrar receives). Agent-spawned agents never see any of this: they inherit the spawner's Squadron (R21). -- **SC4 — Phase-3 minimal line**: create Squadron (name + folder add via existing pickers), edit its folder list, the Squadron scope dropdown (per SC3 as amended), the composer chip with context inheritance, palette-first worktree row. Polished-later: clone-from-URL niceties, Squadron archive UX, colors/avatars, migration of pre-Squadron T3 projects, dashboard consequences of targeting. Out of scope: cross-machine targeting; anything boundary-shaped. +- **Two efforts, one repository.** The user creates "Billing Migration" and "Website Redesign", both targeting the app repository. Creating an agent in either offers the app repository first; the two Squadrons stay separate everywhere they are listed. (AC5, AC6) +- **First run.** A new install opens on "Create your first Squadron"; the user names it "Billing Migration" and picks the app repository; only then can an agent be created. (AC3, AC4) +- **An agent spawns a helper.** A Peer Agent spawned by an agent in "Billing Migration" has Squadron home "Billing Migration", with no picker shown to the spawner. (AC2, AC9) +- **A message crosses Squadrons.** An agent in "Billing Migration" asks an agent in "Support Rotation" a question; both Squadrons' ledgers carry the Exchange, and nothing about either Squadron blocked it. (AC1) +- **Picking where to work.** Starting a new task from the command palette offers Squadrons; the user picks one and the composer shows it, changeable until send. (AC7, AC8) -## E6 — the name: **Squadron** (SETTLED 2026-08-17) +## Scope -"Epic" mapped too closely to software development for an app that must stay open to non-dev work. **Squadron** won on: it names the _who_ (Jackson's chosen axis — the group of agents), it is fleet-native — a fleet is composed of squadrons, so the name reinforces the product's totality word instead of stealing it — and its collision map is completely empty (no code entity, no prg concept, no reserved primitive). Runners-up and vetoes, for the record: _program_ (operator-validated but "computer program" for this audience), _mission_ (leans bounded), _team_ (reserved for the item-3 roster primitive), _group_ (PR Group collision), _project_ (T3 code-entity collision — the `thread` problem again), _fleet_ (steals the totality word). Candidates as originally assessed: +The current build ([dogfood v0](../dogfood-v0.md)) narrows this definition in three places: a Squadron has exactly one folder (AC5 narrowed, stored ready to become a list); "Browse elsewhere" may be absent (AC6 narrowed); and the surfaces converted to Squadron choice are the new-thread flow and the command palette first, with the remaining pickers converted by inventory (AC7 in progress). Later: multi-folder targeting, Squadron archive, colors and avatars, migration of pre-Squadron projects. Never: cross-machine targeting; anything boundary-shaped; a Squadron with no folder. -| Name | For | Against | -| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Program** (recommended) | Jackson's own fleet operators converged on it spontaneously — "the OTel-removal program," "program lead," "program law" appear throughout the interviews; covers both bounded initiatives and standing departments; ordinary non-dev usage (research program, training program) | "Computer program" ambiguity inside a coding tool | -| **Mission** (runner-up) | Native to the fleet metaphor (fleets fly missions); implies purpose and completion; Mission Control resonance for the dashboard | Leans bounded — a standing "monitoring mission" reads slightly odd | -| Initiative | Jackson's own defining word; non-dev | Wordy; no energy; terrible abbreviation | -| Fleet | Leans into the product identity | **Steals the word for the totality** — "the fleet" naturally means all your agents; making it one grouping creates fleets-of-fleets confusion and breaks "fleet dashboard" | -| Group | Maximally neutral | Collides with PR Group (the canonical workflow unit) and the coming team/roster primitive; carries no meaning | -| Project | Familiar | Collides with T3's existing project concept; still dev-flavored | +## History -Rename cost is at its lifetime minimum right now (fresh state, one migration, few contracts); it grows with every A2A milestone that lands. +- 2026-08-17 — defined and named; former E1–E6 ([record](../../worklog/2026-08-17-squadron-naming.md); decision log). +- 2026-08-24 — creation and agent-creation experience; former SC1–SC4 ([record](../../worklog/squadron-creation-session-2026-08-24.md)). +- 2026-08-29 — sidebar scope replaces Squadron grouping in the sidebar; former SB3 ([record](../../worklog/sidebar-roster-session-2026-08-29.md)). +- 2026-08-31 — the Squadron is the unit of user choice; former E7 ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). +- 2026-09-05 — rewritten into the definition shape. Two changes of substance: a Squadron targets one or more folders, so a folder is required at creation (the name-only Squadron is no longer planned — it would complicate upstream integration) and the folder-required v0 override becomes end-state truth; messages to people are no longer listed as Squadron contents (they belong to the inbox, which is person-scoped, not Squadron-scoped). Former identifiers: E1 → AC1; E2 → AC2; E3 → Definition; E4 → AC3; E5 → AC10; E6 → Definition; E7 → AC7; SC1 → AC5, AC6; SC2 → AC3, AC4; SC3 → AC8, AC9; SC4 → Scope; the A2 `join_epic` consequences → AC2, AC11. diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index fe0253eb2bce..4d2cd0657d45 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -7,11 +7,11 @@ kind: definition The J5 vocabulary, in one place, so that a name used anywhere in these docs resolves to exactly one meaning. -**Two kinds of entry.** Most terms name something a product definition owns; for those the entry is an index — the term, a one-line gloss that only identifies the thing, and the definition that owns it. The gloss never states a rule or a property; if a sentence here could be argued with, it belongs in the owning definition instead. A few terms are distinctions everyone must share but that no feature builds — Subagent versus Peer Agent is the model — and for those the glossary is the owner and the entry is the full definition. +**Two kinds of entry.** Most terms name something a product definition owns; for those the entry is an index — the term, a one-line gloss that only identifies the thing, and the definition that owns it. The gloss never states a rule or a property; if a sentence here could be argued with, it belongs in the owning definition instead. A few terms are distinctions everyone must share but that no feature builds and for those the glossary is the owner and the entry is the full definition. -**Casing.** A named product concept is written in Title Case — Squadron, Crew, Captain, Role, Manifest, Playbook, Memo, Exchange, Peer Agent, Subagent, Spawning Guide, Registrar — so a reader knows it is our concept and not the ordinary word. Everything else is lowercase, including fleet, agent, participant, inbox, ledger and dashboard. A surface's proper name is Title Case (Fleet page). Code identifiers keep their own spelling. +**Casing.** A named product concept is written in Title Case — Squadron, Crew, Captain, Role, etc. — so a reader knows it is our concept and not the ordinary word. Everything else is lowercase, including fleet, agent, participant, inbox, ledger and dashboard. A surface's proper name is Title Case (Fleet page). Code identifiers keep their own spelling. -**Upstream's words.** T3 Code's own vocabulary — thread, turn, project, worktree, provider, session, checkpoint, projection, receipt — is defined in [upstream's glossary](../../internals/glossary.md) and is not restated here. Upstream words that upstream does not define (settled, snoozed, pinned, archived, steer, queue) are used in J5 docs with upstream's meaning; where J5 defines behavior around one of them, the entry below points at the definition that does. J5 does not write its own definition of an upstream word unless a measured confusion requires one. +**Upstream's words.** T3 Code's own vocabulary is defined in [upstream's glossary](../../internals/glossary.md) and is not restated here. Upstream words that upstream does not define are used in J5 docs with upstream's meaning; where J5 defines behavior around one of them, the entry below points at the definition that does. J5 does not write its own definition of an upstream word unless a measured confusion requires one. ## Organization @@ -20,7 +20,7 @@ The J5 vocabulary, in one place, so that a name used anywhere in these docs reso | fleet | All of a user's agents across every connected server — the totality, never a sub-grouping | [cross-device.md](cross-device.md) | | **Squadron** | The user-created grouping of agents and their work that everything else is organized under | [features/squadron.md](features/squadron.md) | | **Squadron home** | The one Squadron an agent belongs to, recorded when it is created | [features/squadron.md](features/squadron.md) | -| **Registrar** | The creation-time step that records an agent's Squadron home | [features/squadron.md](features/squadron.md) | +| **Registrar** | The part of the platform that records an agent's Squadron home when the agent is created | [features/squadron.md](features/squadron.md) | | **Crew** | A group of agents that work one task as a unit | [features/crews.md](features/crews.md) | | **Captain** | Any agent with Crews placed under it | [features/crews.md](features/crews.md) | | **Role** | A reusable, user-authored definition of a kind of agent | [features/roles.md](features/roles.md) | diff --git a/docs/j5/worklog/2026-08-17-squadron-naming.md b/docs/j5/worklog/2026-08-17-squadron-naming.md new file mode 100644 index 000000000000..3cf7cd5292b1 --- /dev/null +++ b/docs/j5/worklog/2026-08-17-squadron-naming.md @@ -0,0 +1,23 @@ +--- +title: "Naming the grouping concept: Squadron" +kind: record +--- + +# Naming the grouping concept — 2026-08-17 + +Jackson + Product lead. The grouping concept had been carried as "epic" from the Traycer research without a product definition of its own; this session defined it (the definition now lives in [`../product/features/squadron.md`](../product/features/squadron.md)) and chose its name. "Epic" mapped too closely to software development for an app that must stay open to non-development work. + +**Squadron** won on three grounds: it names the _who_ — the group of agents, Jackson's chosen axis; it is fleet-native — a fleet is composed of squadrons, so the name reinforces the product's totality word instead of stealing it; and at the time its collision map was empty (no code entity, no prior-art concept, no reserved primitive). + +Candidates as assessed in the session: + +| Name | For | Against | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Program** (recommended) | Jackson's own fleet operators converged on it spontaneously — "the OTel-removal program," "program lead," "program law" appear throughout the interviews; covers both bounded initiatives and standing departments; ordinary non-dev usage (research program, training program) | "Computer program" ambiguity inside a coding tool | +| **Mission** (runner-up) | Native to the fleet metaphor (fleets fly missions); implies purpose and completion; Mission Control resonance for the dashboard | Leans bounded — a standing "monitoring mission" reads slightly odd | +| Initiative | Jackson's own defining word; non-dev | Wordy; no energy; terrible abbreviation | +| Fleet | Leans into the product identity | **Steals the word for the totality** — "the fleet" naturally means all your agents; making it one grouping creates fleets-of-fleets confusion and breaks "fleet dashboard" | +| Group | Maximally neutral | Collides with PR Group (the canonical workflow unit) and the then-planned team/roster primitive; carries no meaning | +| Project | Familiar | Collides with T3's existing project concept; still dev-flavored | + +Vetoes recorded the same day: _program_ (operator-validated, but "computer program" for this audience), _mission_ (leans bounded), _team_ (then reserved for a roster primitive that later shipped as Crew, so the word was retired), _group_ (PR Group collision), _project_ (T3 code-entity collision), _fleet_ (steals the totality word). The code rename from epic to squadron landed in PR #8 on 2026-08-19. From 01899e1870447978a50c4e408eb3e2931427dd65 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Mon, 7 Sep 2026 13:51:51 -0400 Subject: [PATCH 05/15] docs(j5): A2A definition, substrate and agent-tools as definitions; communication-graph draft to a record; A2A plan to plans/ Co-Authored-By: Claude Fable 5.1 --- docs/j5/{product/a2a/plan.md => plans/a2a.md} | 30 +- docs/j5/process/docs.md | 11 +- docs/j5/product/a2a/agent-tools.md | 475 ++++++------------ docs/j5/product/a2a/index.md | 167 ++++-- docs/j5/product/a2a/substrate.md | 207 +++----- docs/j5/product/communication-graph.md | 126 ----- docs/j5/product/decision-log.md | 4 +- docs/j5/product/features/squadron.md | 5 + docs/j5/product/glossary.md | 50 +- docs/j5/product/problems.md | 2 +- .../2026-08-14-communication-graph-draft.md | 6 + .../a1-ledger-epic-entity/index.md | 2 +- .../a2-send-deliver-reply/index.md | 2 +- .../upstream-dedup-ground-truth.md | 2 +- .../a2a-tickets/a3-silence-detector/index.md | 2 +- docs/j5/worklog/a2a-tickets/a4-human-node.md | 2 +- .../worklog/a2a-tickets/a5-graph-read-api.md | 2 +- .../a6-placement-provenance/index.md | 2 +- .../worklog/a2a-tickets/a7-upstream-rebase.md | 2 +- 19 files changed, 430 insertions(+), 669 deletions(-) rename docs/j5/{product/a2a/plan.md => plans/a2a.md} (74%) delete mode 100644 docs/j5/product/communication-graph.md create mode 100644 docs/j5/worklog/2026-08-14-communication-graph-draft.md diff --git a/docs/j5/product/a2a/plan.md b/docs/j5/plans/a2a.md similarity index 74% rename from docs/j5/product/a2a/plan.md rename to docs/j5/plans/a2a.md index ba462dd37676..29cdafbea3a2 100644 --- a/docs/j5/product/a2a/plan.md +++ b/docs/j5/plans/a2a.md @@ -1,11 +1,12 @@ --- -title: "A2A v1 — builder-facing plan" -kind: spec +title: "A2A v1 — builder plan" +kind: plan +status: active --- # A2A v1 plan -Drafted 2026-08-16 from the settled decision register (`./index.md` — D1–D10, all closed). This document tells a builder _what to build and why it has this shape_; the register holds the decisions and rationale; the grounding section there explains the four-layer model. Read both before starting. Product definition: `../communication-graph.md`. +A plan: it sequences the A2A build and is history once executed. The definition it builds is [`../product/a2a/index.md`](../product/a2a/index.md); where this plan and the definition disagree, the definition wins. Milestones are named "A2A M1" through "A2A M5". Drafted 2026-08-16; M1–M4 shipped by 2026-09-01; M5 (graph read API) is open as issue #31. ## Base (updated 2026-09-06) @@ -17,7 +18,7 @@ Drafted 2026-08-16 from the settled decision register (`./index.md` — D1–D10 ## What v1 is NOT (scope fences) -No graph UI or attention panes (item 4). No roles/teams objects (item 3 — placement ≠ team membership). No cross-machine delivery (deferred; nothing may _assume_ single-host, but nothing implements multi-host). No deferred silence states (`waiting-on-external-gate`, `silent-tool-degradation`, PTY-quiet). No message kind tags (cut). No agent-initiated re-parenting (human-only, UI). No squadron _container_ features beyond the minimal entity below — terminals, artifacts, folders, worktree binding all stay out (future backlog items). +No graph UI or attention panes (item 4). No Roles or Crews (item 3 — placement is not Crew membership). No cross-machine delivery (deferred; nothing may _assume_ single-host, but nothing implements multi-host). No deferred silence states (`waiting-on-external-gate`, `silent-tool-degradation`, PTY-quiet). No message kind tags (cut). No agent-initiated re-parenting (human-only, UI). No squadron _container_ features beyond the minimal entity below — terminals, artifacts, folders, worktree binding all stay out (future backlog items). ## Architecture @@ -84,11 +85,28 @@ The inbox is necessarily a **cross-ledger projection**: global person-scoped hum ### Graph projection + read API (M5) -Edge = exchange (never message), state open/stalled(reason,trust)/answered/dropped, plus delegation edges from v2 delegations (D1). Read API: per-squadron cursor subscription — strictly ascending, exactly-once, gap-free relative to the cursor, with the documented caveat that _snapshot end is a batching fact, not caught-up-to-now_ — plus a full-state reconciliation query (events + snapshot, never events alone). Cross-squadron edges render in each squadron as external stubs joined by `correlation_id`. Rebuilding any projection from the ledger must be byte-equivalent — this is a test, not an aspiration. +Edge = exchange (never message), state open/stalled(reason,trust)/answered/dropped. (Delegation edges were dropped when `delegate_task` left the product surface, 2026-08-24.) Read API: per-squadron cursor subscription — strictly ascending, exactly-once, gap-free relative to the cursor, with the documented caveat that _snapshot end is a batching fact, not caught-up-to-now_ — plus a full-state reconciliation query (events + snapshot, never events alone). Cross-squadron edges render in each squadron as external stubs joined by `correlation_id`. Rebuilding any projection from the ledger must be byte-equivalent — this is a test, not an aspiration. ### Agent tool surface -Minimal, one send verb (Traycer's shape): `send_message(to, message, expect_reply?, exchange_id?, intent?, urgency?)` — reply = send carrying `exchange_id`. Plus `list_participants` with per-row capability booleans (tell callers what they may do, never let them discover by failing). Errors must name the actual state and the next command (toolsmith rule). Placement (D10): agent/thread creation tools gain a `placement` parameter (default = spawner; sibling/other-parent/root allowed); provenance recorded separately and immutably; cascade operations follow placement. +The verbs and their contracts are defined in [`../product/a2a/agent-tools.md`](../product/a2a/agent-tools.md). Errors must name the actual state and the next command (toolsmith rule). Placement equals the spawner and is never a spawn-time parameter (the parameter this plan originally specified was removed on 2026-08-21); provenance is recorded separately and immutably. + +## Build status against the definition (2026-09-05) + +The definition's acceptance criteria ([`../product/a2a/index.md`](../product/a2a/index.md)) and where the build stands: + +| Criteria | Status | +| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AC1–AC3 (ledger) | Built (A2A M1, M2) | +| AC4 (projection rebuild) | Built for the inbox and thread projections; the communication-graph projection is A2A M5 (issue #31) | +| AC5, AC6, AC9, AC10, AC11 (Exchanges) | Built | +| AC7, AC8 (several open asks to a person) | **Not built** — the shipped behavior refuses a second ask to a person while one is open; reversed by ruling on 2026-09-05, issue #111 | +| AC12–AC15 (delivery) | Built, including the Codex Astra exception (#108) | +| AC16–AC19 (the person) | Built | +| AC20, AC21 (silence) | Built with a known gap: notices are stored with a label chosen when written rather than as the pure fact bundle the definition describes, so a notice with several open asks records only its first match — the fact-bundle rework is issue #30; no surface shows the stored label as current status meanwhile | +| AC22, AC23 (envelopes) | Built except measured time facts in every channel (A2A M2 envelope true-up, issue #29) | + +Never: message kind tags; an Exchange called a thread; delivery that infers repair; a person as a per-Squadron participant. ## Milestones (each independently verifiable; formal ticket breakdown is a separate pass) diff --git a/docs/j5/process/docs.md b/docs/j5/process/docs.md index c6f3c013cc7f..7dfb55b4bc31 100644 --- a/docs/j5/process/docs.md +++ b/docs/j5/process/docs.md @@ -25,14 +25,17 @@ The kinds differ most in how long they stay true. A **definition** is the only k A definition says what the product is. It is written in the present tense, as if the feature exists at its end state, and it is **rewritten, never appended**: when the product changes, the sentence that was true changes, and the History section gains one line saying when and why. Narrative of who proposed what, PR numbers, and build status never appear in the body. +A definition is the longest-lived kind, so it **never depends on a shorter-lived one**: it cites other definitions and the glossary, and its History lines link records; it never references a plan, and it never references research as a source. If a definition needs something a plan or a research document says, that thing is defined in the definition. + +The Definition section stays at the level of concepts: what the thing is and how it is part of the solution to a problem or goal. Behavior in detail — what refuses what, what is recorded when, what a surface shows — belongs in the acceptance criteria, where it can be checked. + Every feature definition has the same sections, in this order: 1. **Problem** — one paragraph linking the problem or goal in `problems.md` it serves. 2. **Definition** — what it is, and what it is not. -3. **Acceptance criteria** — a numbered list. Each criterion is one testable sentence about observable behavior. These are the only numbered items in the docs, and the only things that get referenced by number (see IDs below). +3. **Acceptance criteria** — one numbered list, grouped under short sub-headings that follow the order of the Definition (for example _Sending_, _Delivery_, _Silence_); the numbering runs through the groups without restarting, so a criterion's number stays unique within the feature. Each criterion is one testable sentence about observable behavior. These are the only numbered items in the docs, and the only things that get referenced by number (see IDs below). 4. **Scenarios** — concrete situations written as user stories or worked examples, each naming the criteria it exercises. -5. **Scope** — what the current build includes and what waits, by criterion number, linking the plan that sequences it. Scope cuts are stated here and in the plan, nowhere else. -6. **History** — one line per amendment: date, what changed, and a link to the record. +5. **History** — one line per amendment: date, what changed, and a link to the record. Scenarios use one shared example fleet so a reader recognizes it from doc to doc, and never a real project: Squadrons **Billing Migration**, **Website Redesign**, and **L2 Support Rotation** (a non-development Squadron); repositories **the app repository** and **the infrastructure repository**; the person is simply **the user**. @@ -58,7 +61,7 @@ The letter registers used before 2026-09-05 (D, E, X, R, SC, ST, SB, IB, TA, AR, ## Plans -A plan sequences work. It names milestones ("Fleet observability M1", "Crews M2"), links the GitHub issues that carry each one, states scope cuts by feature and criterion, and carries `status: active | done` in its frontmatter. A plan never restates acceptance criteria and never defines anything; when a plan and a definition disagree, the definition wins and the plan is wrong. +A plan sequences work. It names milestones ("Fleet observability M1", "Crews M2"), links the GitHub issues that carry each one, and carries `status: active | done` in its frontmatter. **Build status lives only in plans**: which criteria of a definition the current build meets, narrows, or defers is stated in the plan, by feature and criterion number — never in the definition, which describes the end state. A plan never restates acceptance criteria and never defines anything; when a plan and a definition disagree, the definition wins and the plan is wrong. ## Research diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index c9e9a1083bf3..18a670b82915 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -1,339 +1,150 @@ --- -title: "The agent tool surface — MCP verb contracts" -kind: spec +title: "The agent tool surface — verb contracts" +kind: definition --- -# Agent tool contracts (adopted 2026-08-29) - -The definition of record for every verb on the J5 agent-facing MCP surface. [`substrate.md`](substrate.md) -rules _what_ is on the surface; this doc rules _what each verb is_ — and builders implement these -contracts rather than inventing them. **The description string is part of the contract**: it is the -agent-facing UX of the tool and is decided here, not at implementation time (Jackson, 2026-08-29). -Descriptions are written for the agent that reads them mid-turn: trigger first, distinct uses named, -positive instruction over negation. - -## Conventions (apply to every J5 verb) - -- **Naming**: snake_case verbs, snake_case parameters. (`spawn_agent`'s frozen A6 build used - `clientRequestId` from the delegate passthrough; the rebuilt contract below corrects it.) -- **Idempotency**: every mutating verb accepts optional `client_request_id` — upstream's own - pattern. Supplied, the server derives a stable command id from (provider session, request key), - so retrying the same logical call replays the original result instead of double-acting. Omitted, - the server mints a random key and each call is a fresh command — supply and reuse the id whenever - you might retry. (The frozen A6 verbs required it; they relax to optional in the rebuild, - 2026-08-29.) -- **Errors** (the toolsmith rule, `plan.md`): failures return `{ code, message }` where the message - names the _actual state_ and the _next command_ — callers must never have to discover state by - failing twice. -- **Events**: every mutation commits ledger/placement events in the same transaction as its state - change; the return happens after the sender-side commit, and delivery/side-effects continue - asynchronously. -- **Duplication rule**: each mutating verb's description keeps its one-clause idempotency sentence - even though this section covers it — the description is the only text an agent reliably reads at - call time. Nothing else is duplicated. +# The agent tool surface ---- +## Problem -## `send_message` — built (`j5/main`); description update is a small code ticket - -**Description (contract, amended 2026-09-02 — see the human-addressed-sends revision below; the -shipped string updates with that ticket):** "Send one durable message. To another agent, three -uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a -one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the -exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask -or a reply: a plain send to a person is refused — if nobody needs to act, say it in your own thread -instead. Set urgency only when asking the human. Use this tool only for participants already -returned by list_participants; when creating a Peer Agent, put any reply expectation in -spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; -delivery continues asynchronously — carry on with your work, and the reply arrives later as an -incoming message. A caller without a registered home is refused. Reuse client_request_id to retry -the same send safely." - -| Input | Type | Required | Meaning | -| ------------------- | ----------------- | -------------------------------- | ---------------------------------------------------------------------------- | -| `to` | ParticipantId | yes | Directory-listed recipient; a human requires `expect_reply` or `exchange_id` | -| `message` | string, non-empty | yes | Body; envelope adds sender identity/Squadron | -| `client_request_id` | string | no (yes for retries) | Idempotency key | -| `expect_reply` | boolean | no | Opens/joins an Exchange; requires `intent` | -| `exchange_id` | ExchangeId | no | Marks this send as the reply that closes that Exchange | -| `intent` | string | with `expect_reply` | One-line summary carried in projections | -| `urgency` | Urgency | opening an Exchange to the human | Inbox priority | - -Result: `SendMessageResult` (message id, exchange state). Errors (each naming the actual state and -the next command): sender membership (`A2ASenderNotJoinedError` family); recipient not addressable -(with the `list_participants` next-command); `expect_reply` without `intent` (an ask must carry its -one-line intent); an `exchange_id` that is unknown, already closed, or not an exchange the caller -participates in (naming the exchange's actual state); opening an exchange to the human without -`urgency`; a plain send to a human — neither `expect_reply` nor `exchange_id` — refused, naming the -two legal moves and the own-thread alternative. Events: message + exchange ledger events; delivery -receipts follow asynchronously. - -**Contract revision (ruled 2026-09-02, human-addressed sends — Jackson, in session with Product; -supersedes issue #44's A/B/C disposition and PR #57's "invisible in v0" wording):** **an -agent-to-human send must be an ask or a reply; a plain message to a person is refused -fail-closed.** Permanent law, not a v0 override. Why: (1) the inbox is asks-only (R5, IB1) — if -the receiving side shows only asks, the sending side must accept only asks, or the contract lies in -one direction; (2) a plain message to a person carries no information the sender's own thread does -not already carry — the sender's words are already there, and the human reads that thread when -engaged — so the verb's only distinctive property is that it feels like notifying while doing -nothing (the ghost-traffic class found in Jackson's 2026-09-01 session and reproduced by two -migrated agents); (3) agents on the chatty end of the spectrum would otherwise flood the person. -What an agent does instead: if nobody needs to act, it says so in its own thread, or tells the -agent holding the work context (its spawner or Captain) — not as routing (R22 stands: Captains are -never routers; agent-to-agent plain sends stay fully open) but because that thread is where the -human is already reading, and its owner judges what rises to an ask. If the person must see it, -seeing it IS the obligation: an ask with intent and urgency, which the person closes by replying. -The error names the two legal moves (ask with expect_reply + intent + urgency; reply with -exchange_id) and the own-thread alternative. Accepted cost, stated at ruling: chatty agents will -convert check-ins into low-urgency asks — the right failure mode, because it is visible and -countable per sender in the inbox and fixed in the brief or Role, where the prior-art fleet fixed -it too. **Corollary (confirmed 2026-09-02, from PR #57's implementation):** a second ask from an agent -to a person while that pair already has an open exchange is also refused (typed -`A2AHumanFollowupNotAllowedError`, before the ledger write) — under D a coalesced follow-up to a -person is a plain delivery, and it was exactly #45's invisible-follow-up finding. The error names -the way forward: wait for the reply, or `clear_own_ask` and re-ask with the combined content. -Agent↔agent coalescing is untouched. Recommended and separate, not ruled: renaming urgency `fyi` → `whenever` (an ask urgency -named "no reply needed" mislabels an obligation; the levels answer "when do you need my answer"). -Product record: [`../features/inbox.md`](../features/inbox.md) (sender-side mirror) and the -[worklog record](../../worklog/human-addressed-sends-ruling-2026-09-02.md). - -**Contract revision (ruled 2026-08-31, self-messaging):** `to` equal to the caller's own -participant id is rejected fail-closed — self-send is never legitimate (a self-Exchange is -degenerate: the caller would owe itself a reply and the silence detector would type its own -silence against it; the real self-shaped needs have dedicated verbs). Per the toolsmith rule, the -error names the caller's own participant id and the next commands: `list_participants` to find the -intended recipient and `schedule_task` for future-self triggers. Origin: -live test — an agent asked to message "the other agent" messaged itself. - -**Product sequencing note (2026-08-31):** Memo is post-v0. When Memos ship, the error and tool -description gain Memo as the notes-to-self alternative; until then, shipped copy does not name it. - -## `list_participants` — built (`j5/main`); contract revision: `display_name` - -**Description (contract):** "Your address book: the participants around you — agents and the human — -with the display name to recognize them by, the participant_id to address them with, and what each -accepts (messages, exchanges, urgency). When you're told to message someone by name or role, resolve -them here first. Your own row is marked self=true; it cannot receive messages or open exchanges from -you — use schedule_task if you need a future trigger for yourself. Native threads that never -received a Squadron home do not appear here and cannot be messaged. Archived agents are hidden by -default; set include_archived=true to see them with archived=true. They cannot receive messages or -open Exchanges. Refresh the roster after spawning, archiving, unarchiving, or deleting an agent." - -**Contract revision (found 2026-08-29):** rows carry no display name today -(`AgentParticipant = {kind, id, threadId}`), which defeats the address-book purpose — "message the -product agent" must resolve a human-recognizable name to a `participant_id`. Every row gains -**`display_name`** (the agent's thread title now; the Role name when Roles land). Small code -ticket. - -**Contract revision (ruled 2026-08-31, self-messaging):** the caller's own row is marked -**`self`** — the address book must answer "which one am I" before it can answer "who else is -there" (adopts the prior art's `[self]` marker; same live-test origin as `send_message`'s -self-send rejection). The description gains a clause telling the caller its own row is marked. - -**Canonical description amendment (ratified 2026-08-31, decision #72):** the exact contract above -supersedes all partial drafts. It names the self row, native threads without a home, and roster -refreshes without naming an unshipped lifecycle verb. -(each description carries its own native-home caveat: send_message states the caller-side -precondition — a sender without a registered home is refused; list_participants states the -listing-side consequence — native threads without a home do not appear and cannot be messaged) - -**Contract revision (ruled 2026-09-02, human-addressed sends):** human rows report -`can_receive_message: false`, `can_open_exchange: true`, `accepts_urgency: true` — the existing -capability flags already express the rule that a person receives only asks; the shipped -`true/true` row is therefore lying today and changes with the `send_message` refusal ticket. - -No inputs. Result rows: `display_name`, `squadron_id`, `participant_id`, participant kind (thread -id for agents), `can_receive_message`, `can_open_exchange`, `accepts_urgency`, plus `provenance` -(`spawned-by` / `forked-from` / `unknown` / `not-applicable` for humans / `unrecorded`) and -`placement_parent_id` — org truth carried for callers and UI; deliberately not part of the -description's pitch. Read-only; no events. - -## `spawn_agent` — rebuilt contract (root-thread Peer Agent spawn; supersedes the frozen A6 build) - -**Description (contract):** "Spawn a Peer Agent: a full-citizen teammate with its own top-level -thread, starting on your brief as its first turn. It joins your Squadron, is placed under you, and -records you as its immutable spawner; it is addressable the moment this returns. In your brief, -tell the new agent what it should do first and whether it should reply to you. Choose provider, -model, and reasoning for the work in the brief — see orchestrator_capabilities for what's -available. Reuse client_request_id to retry the same spawn safely." - -| Input | Type | Required | Meaning | -| ------------------- | ------------------------------------ | -------- | ------------------------------------------------- | -| `brief` | string, non-empty | yes | The first-turn prompt the new agent starts with | -| `title` | string | no | Thread title; derived from the brief when omitted | -| `provider` | id from `orchestrator_capabilities` | yes | Chosen per task — no inherit default (Jackson, | -| | | | 2026-08-29: inheriting is wrong more than right) | -| `model` | id from `orchestrator_capabilities` | yes | Chosen per task | -| `reasoning` | option from capabilities descriptors | yes | Chosen per task | -| `client_request_id` | string, non-empty | no | Supply and reuse to make retries safe | - -Result: `participant_id`, `thread_id`, `squadron_id`, `placement` (parent = caller, provenance -`spawned-by`, source `j5_spawn`). Semantics: creates an ordinary **root-lineage** thread via the -upstream creation seam (never `delegate_task`), registers the immutable Squadron home (fail-closed: -refuses before creation if the caller's home no longer names an existing Squadron), records -placement + provenance atomically, then starts the first turn with the brief. Errors: -caller-membership state (missing/ambiguous, with the `list_participants` next-command), home -integrity, creation failure — each naming state and next command. Events: `participant.joined`, -home registration, `participant.placement_created`. - -**Contract revision (ruled 2026-08-31, self-messaging):** the spawned agent's first-turn context -states its own `participant_id` and Squadron as platform-provided facts — the same class as the -envelope's sender identity, composed by the platform because they are measured, not judgment. A -fresh spawn is never id-blind about itself (live-test origin: an id-blind agent messaged itself). -The spawner's brief remains untouched — this rides beside it, never inside it. - -**Contract clarification (ruled 2026-08-31, SP4):** the brief carries the initial task and whether -and what reply is expected. The spawner does not follow `spawn_agent` with a reply-expected -`send_message`; that Exchange form is for later work owed by an existing participant. - -> **Spawning guide (settled 2026-08-30) — [`features/spawning-guide.md`](../features/spawning-guide.md).** -> SP4 closed this contract's held slot: the description's single sentence of brief steering above -> is the entire tool-side coaching — the report-back contract travels in the brief per the guide's -> conventions, and receipt-ACKs get no written law anywhere. SP3: provider/model/reasoning stay -> required and explicit even on Role-ful spawns — a Role's allowlist constrains the choice and an -> out-of-list pick is an error naming the excluding Role, never a silent default. Provider/model -> selection guidance and brief-writing conventions live in the guide, not here. - -## `stop_agent` — single-target (amends the frozen A6 cascade contract) - -**Description (contract):** "Stop one Peer Agent: interrupts its running turn now. The agent -remains, stays readable, and can be messaged again later — stopping halts work, it retires -nothing. Requires your current squadron_id. Reuse client_request_id to retry safely." - -| Input | Type | Required | -| ------------------- | ----------------- | -------------------------------------- | -| `client_request_id` | string, non-empty | no (supply and reuse for safe retries) | -| `squadron_id` | SquadronId | yes (must be the caller's Squadron) | -| `participant_id` | ParticipantId | yes (the one agent to stop) | - -Result: exactly one of `interrupt_requested` (a running turn is being interrupted) or -`already_idle` (no running turn; no side effect). Anything else is an error, not an outcome — -errors name the caller's actual Squadron and the corrected retry. - -**Amendment (Jackson, 2026-08-29):** the A6 build cascaded over the placement subtree; that blast -radius makes the tool less useful, so `stop_agent` and `archive_agent` are single-target. The -unit-cascade concept already has its home in the crew rulings (2026-08-21: crews spawn and archive -as units) — `stop_crew`/`archive_crew` arrive with Crews, and the A6 `PlacementCascadeService` -survives as their engine (a cascade of one is its degenerate case). - -## `archive_agent` — single-target, refuse-when-consequential with confirmation token - -**Description (contract):** "Archive one Peer Agent reversibly. Unarchive restores the same identity, but does not reopen Exchanges or replay cancelled messages. A clean archive — no open exchanges, -no running turn — completes immediately. Otherwise the call refuses and lists exactly what -archiving ends — the asks that will close, the turn that will stop — along with a -confirmation_token; call again with that token to proceed. The archived agent leaves the active -roster; its ledger and conversation stay readable forever. Requires your current squadron_id. -Reuse client_request_id to retry safely." - -| Input | Type | Required | -| -------------------- | ----------------- | -------------------------------------- | -| `client_request_id` | string, non-empty | no (supply and reuse for safe retries) | -| `squadron_id` | SquadronId | yes (must be the caller's Squadron) | -| `participant_id` | ParticipantId | yes (the one agent to archive) | -| `confirmation_token` | string | only when confirming a refusal | - -Semantics — the agent-facing form of the archive-flow rulings (AR1–AR4): the **quiet clean path** -archives immediately when nothing would be cut short; the **loud path** is a refusal whose error -lists the concrete consequences (open exchanges that will close as dropped, the running turn that -will be interrupted) — the toolsmith rule doing the human dialog's job — plus a -`confirmation_token`. The token is issued with the fact list and is bound to it: it proves the -caller saw the consequences, so the confirmation cannot be short-circuited by a preemptive flag on -the first call (Jackson, 2026-08-29). If the target's state changed since the refusal, the stale -token is rejected and a fresh refusal lists the current facts. Result: exactly one of `archived` -or `already_archived` (no side effect); a consequential target yields the refusal above — an error -carrying the fact list and `confirmation_token` — never a partial outcome. Errors: -not-caller's-Squadron, unknown participant, consequential-without-token (the refusal), stale token -— each naming state and next command. Events: archive + the obligation-closure events for each -ended exchange (loud in the ledger, not just the dialog). - -**2026-08-31 implementation alignment (Decisions #86 and #88):** the shipped J5 composition is -single-target and never consumes the placement cascade. An interrupt acknowledgement and an -observed terminal run state are separate facts; the tool does not claim a turn stopped merely -because interruption was requested. Cross-store partial failure is forward-only: committed thread -archive and ledger archive/terminal-notice facts are re-read on retry, and `already_archived` -requires the archive timestamp (or legacy departure timestamp) plus completion of every terminal lifecycle notice. When -an already-retired participant is absent from the active directory, the authorized Squadron's -ledger is used only as a consume-only replay fallback and must contain exactly one matching -`participant.joined` agent identity. Malformed or unknown-version confirmation tokens fail closed -without disclosing target facts; a token for one target cannot authorize another. - -## `clear_own_ask` — ruled, unbuilt (inbox IB1b; substrate.md "needed-but-unbuilt") - -**Description (contract):** "Withdraw an ask you sent: closes your open exchange without a reply -message. Use when the answer already arrived outside the exchange — for example, the human -answered you directly in your thread — so the obligation exits their inbox honestly. Only the -exchange's sender may clear it; the closure is recorded as sender-cleared, distinct from an -answered exchange. Reuse client_request_id to retry safely." - -| Input | Type | Required | -| ------------------- | ----------------- | ----------------------------------------------- | -| `exchange_id` | ExchangeId | yes (an exchange the caller opened, still open) | -| `client_request_id` | string, non-empty | yes | - -Result: the closed exchange state (id, closure kind `sender-cleared`, closed-at). Errors (each -naming state + next command): caller is not the exchange's sender; exchange already closed -(idempotent replay returns the original result instead when `client_request_id` matches); unknown -exchange id. Events: an exchange-closure ledger event distinguishable from reply-closure -(`sender-cleared`), so inbox status, exchange projections, and the eventual A5 graph render the -withdrawal honestly. +An agent learns what it can do from its tools, and it reads a tool's description in the middle of its work, once, under pressure. If the description is written by whoever happens to implement the tool, the agent-facing product is decided by accident. This definition states each verb on the J5 agent surface — what it does, what it takes, what it returns, how it fails — and the description string is part of the contract, because the description _is_ the agent's experience of the product. [The substrate definition](substrate.md) decides which verbs exist; this one decides what each verb is. ---- +## Definition + +### Conventions for every verb + +- **Naming**: snake_case verbs and parameters. +- **Idempotency**: every mutating verb accepts an optional `client_request_id`. When supplied, retrying the same logical call replays the original result instead of acting twice; when omitted, each call is a fresh command. Every mutating verb's description carries its own one-clause reminder to reuse the id, because the description is the only text an agent reliably reads at call time. +- **Errors — the toolsmith rule**: a failure returns a code and a message, and the message names the _actual state_ and the _next command_, so a caller never has to discover state by failing twice. +- **Events**: every mutation commits its ledger and placement events in the same transaction as its state change; the call returns after that commit, and delivery and other side effects continue asynchronously. +- **Descriptions** are written for the agent reading them mid-turn: trigger first, distinct uses named, positive instruction over negation, and no more than the agent needs to act. + +### `send_message` + +**Description:** "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask or a reply: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. You may have several asks open with the same person; to follow up on one that is still open, name it in regarding and your message joins it. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. Reuse client_request_id to retry the same send safely." + +| Input | Type | Required | Meaning | +| ------------------- | ----------------- | ------------------------------------ | ------------------------------------------------------------------------------- | +| `to` | ParticipantId | yes | A recipient listed by `list_participants`; a person requires an ask or a reply | +| `message` | string, non-empty | yes | The body; the envelope adds sender identity and Squadron | +| `expect_reply` | boolean | no | Opens an Exchange (or, between agents, joins the open one); requires `intent` | +| `intent` | string | with `expect_reply` | One-line summary shown wherever the Exchange is listed | +| `urgency` | Urgency | when opening an Exchange to a person | How soon the answer is needed | +| `regarding` | ExchangeId | no | Follow up on an open Exchange you opened with this person; the message joins it | +| `exchange_id` | ExchangeId | no | Marks this send as the reply that closes that Exchange | +| `client_request_id` | string | no | Reuse to retry safely | + +**Result:** the message id and the Exchange's state. + +**Rules.** A message to the caller itself is refused. A plain send to a person is refused. Between agents, a further ask to a peer that already holds an open Exchange from the caller joins it as a follow-up. To a person, a further ask opens a new Exchange and a new inbox item unless it names an open one in `regarding`, in which case it joins that Exchange and is shown beneath the original ask. An ask to a person without an urgency is refused. + +**Errors**, each naming the actual state and the next command: the caller has no Squadron home; the recipient is not addressable (pointing at `list_participants`); the recipient is the caller (naming the caller's own id, and `schedule_task` for a future trigger to oneself); an ask without an intent; a plain send to a person (naming the two legal moves and the own-thread alternative); an ask to a person without urgency; an `exchange_id` or `regarding` that is unknown, already closed, or not the caller's (naming the Exchange's actual state). + +**Events:** message and Exchange events in the ledger; delivery receipts follow asynchronously. + +### `list_participants` + +**Description:** "Your address book: the participants around you — agents and the human — with the display name to recognize them by, the participant_id to address them with, and what each accepts (messages, exchanges, urgency). When you're told to message someone by name or role, resolve them here first. Your own row is marked self=true; it cannot receive messages or open exchanges from you — use schedule_task if you need a future trigger for yourself. Native threads that never received a Squadron home do not appear here and cannot be messaged. The roster changes — after you spawn an agent, or when a participant retires, call this again instead of reusing a stale listing." + +No inputs. Read-only; no events. + +**Result rows:** `display_name` (the agent's thread title, or the Role name once Roles exist), `squadron_id`, `participant_id`, the participant kind, `self`, `can_receive_message`, `can_open_exchange`, `accepts_urgency`, plus `provenance` (spawned by whom, forked from what, unrecorded, or not applicable for a person) and `placement_parent_id`. A person's row reports that it cannot receive a plain message and can be asked. Provenance and placement are carried for callers and the UI; they are not part of the description's pitch. + +### `spawn_agent` + +**Description:** "Spawn a Peer Agent: a full-citizen teammate with its own top-level thread, starting on your brief as its first turn. It joins your Squadron, is placed under you, and records you as its immutable spawner; it is addressable the moment this returns. In your brief, tell the new agent what it should do first and whether it should reply to you. Choose provider, model, and reasoning for the work in the brief — see orchestrator_capabilities for what's available. Reuse client_request_id to retry the same spawn safely." + +| Input | Type | Required | Meaning | +| ------------------- | ---------------------------------------- | -------- | ------------------------------------------------------------------- | +| `brief` | string, non-empty | yes | The first-turn prompt; carries the task and whether a reply is owed | +| `title` | string | no | The thread title; derived from the brief when omitted | +| `provider` | id from `orchestrator_capabilities` | yes | Chosen per task — there is no inherited default | +| `model` | id from `orchestrator_capabilities` | yes | Chosen per task | +| `reasoning` | option from the capabilities descriptors | yes | Chosen per task | +| `client_request_id` | string | no | Reuse to retry safely | + +**Result:** `participant_id`, `thread_id`, `squadron_id`, and the placement (parent is the caller; provenance is spawned-by the caller). + +**Rules.** The new agent is an ordinary root-lineage thread created through upstream's creation seam, never through delegation. Its Squadron home is the caller's, registered before creation and fail-closed if the caller's home no longer names an existing Squadron. Placement and provenance are recorded atomically with creation; then the first turn starts with the brief. The new agent's first turn also states its own participant id and Squadron as platform-provided facts, beside the brief and never inside it. Provider, model and reasoning are required and explicit even when a Role is given: a Role's allowlist constrains the choice and an out-of-list pick is an error naming the Role, never a silent default. The brief carries the task and the reply expectation; the spawner does not follow a spawn with a reply-expected `send_message` — that form is for later work owed by an existing participant. Selection guidance and brief-writing conventions live in the [Spawning Guide](../features/spawning-guide.md). + +**Errors**, each naming state and next command: the caller's membership is missing or ambiguous; the caller's home no longer exists; creation failed. + +**Events:** participant joined, home registered, placement created. + +### `stop_agent` + +**Description:** "Stop one Peer Agent: interrupts its running turn now. The agent remains, stays readable, and can be messaged again later — stopping halts work, it retires nothing. Requires your current squadron_id. Reuse client_request_id to retry safely." + +| Input | Type | Required | +| ------------------- | ------------- | --------------------------- | +| `squadron_id` | SquadronId | yes — the caller's Squadron | +| `participant_id` | ParticipantId | yes — the one agent to stop | +| `client_request_id` | string | no | + +**Result:** exactly one of `interrupt_requested` (a running turn is being interrupted) or `already_idle` (no running turn; no side effect). An interrupt acknowledgement and an observed terminal run state are separate facts; the tool never claims a turn stopped merely because interruption was requested. Anything else is an error naming the caller's actual Squadron and the corrected retry. + +**Rule.** Stop and archive are single-target. The unit cascade belongs to Crews, which stop and archive as units through their own verbs when they exist. + +### `archive_agent` + +**Description:** "Retire one Peer Agent for good. A clean archive — no open exchanges, no running turn — completes immediately. Otherwise the call refuses and lists exactly what archiving ends — the asks that will close, the turn that will stop — along with a confirmation_token; call again with that token to proceed. The archived agent leaves the active roster; its ledger and conversation stay readable forever. Requires your current squadron_id. Reuse client_request_id to retry safely." + +| Input | Type | Required | +| -------------------- | ------------- | ------------------------------ | +| `squadron_id` | SquadronId | yes — the caller's Squadron | +| `participant_id` | ParticipantId | yes — the one agent to archive | +| `confirmation_token` | string | only when confirming a refusal | +| `client_request_id` | string | no | + +**Result:** exactly one of `archived` or `already_archived` (no side effect). A consequential target yields a refusal — an error carrying the list of consequences and a `confirmation_token` — never a partial outcome. + +**Rules.** The quiet path archives immediately when nothing would be cut short. The loud path is a refusal listing the concrete consequences — the open Exchanges that will close as dropped, the running turn that will be interrupted — plus a token bound to that list: it proves the caller saw the consequences, so a preemptive flag on the first call cannot short-circuit the confirmation. If the target's state changed since the refusal, the stale token is rejected and a fresh refusal lists the current facts. A malformed or unknown token fails closed without disclosing the target's facts, and a token for one target never authorizes another. A partial failure across stores is forward-only: committed archive and ledger facts are re-read on retry, and `already_archived` requires both the participant's departure and completion of every terminal notice. The caller cannot archive itself. + +**Errors**, each naming state and next command: not the caller's Squadron; unknown participant; consequential without a token (the refusal); stale or invalid token; self-target. + +**Events:** the archive, and an obligation-closure event for each Exchange it ended — loud in the ledger, not only in the dialog. + +### `clear_own_ask` + +**Description:** "Withdraw an ask you sent: closes your open exchange without a reply message. Use when the answer already arrived outside the exchange — for example, the human answered you directly in your thread — so the obligation exits their inbox honestly. Only the exchange's sender may clear it; the closure is recorded as sender-cleared, distinct from an answered exchange. Reuse client_request_id to retry safely." + +| Input | Type | Required | +| ------------------- | ---------- | ----------------------------------------------- | +| `exchange_id` | ExchangeId | yes — an Exchange the caller opened, still open | +| `client_request_id` | string | no | + +**Result:** the closed Exchange's state — id, closure kind `sender-cleared`, closed-at. + +**Errors**, each naming state and next command: the caller is not the Exchange's sender; the Exchange is already closed; unknown Exchange. + +**Events:** an Exchange-closure event distinguishable from a reply's closure, so the inbox, the Exchange projections and the communication graph render the withdrawal honestly. + +### Kept upstream tools + +- `orchestrator_capabilities` — providers and models (ids, labels, option descriptors) for spawn targeting, plus runtime and interaction-mode facts. It no longer advertises app-owned subagents, child tasks, or delegation; J5 verbs are advertised by their own descriptions. +- `schedule_task`, `list_scheduled_tasks`, `update_scheduled_task`, `delete_scheduled_task` — consumed as-is. +- `t3_thread_list`, `t3_thread_read`, `t3_thread_wait` — consumed as-is; if an upstream description mentions delegation, J5 re-declares that tool with corrected prose. + +## Acceptance criteria + +1. Every J5 verb's shipped description string is byte-identical to the description in this definition. +2. A plain `send_message` to a person is refused with an error naming the two legal moves; an ask to a person without urgency is refused. +3. A further ask to a person opens a new Exchange and inbox item; an ask that names an open Exchange in `regarding` joins it and is shown beneath the original ask. +4. Between agents, a further ask to a peer holding an open Exchange from the caller joins it as a follow-up. +5. A `send_message` to the caller itself is refused with an error naming the caller's own id. +6. `list_participants` marks the caller's row `self`, reports a person's row as unable to receive a plain message and able to be asked, and omits threads without a Squadron home. +7. `spawn_agent` refuses a call that omits provider, model, or reasoning, and refuses a choice outside the Role's allowlist with an error naming the Role. +8. A spawned agent's first turn contains its own participant id and Squadron. +9. `stop_agent` and `archive_agent` act on exactly one agent; neither cascades. +10. `archive_agent` on a target with open Exchanges or a running turn refuses with the list of consequences and a token; the same call with that token archives; a stale token is refused with fresh facts. +11. `clear_own_ask` closes only an Exchange the caller opened and records the closure as sender-cleared. +12. Every error from every verb names the actual state and the next command. + +## History -## `list_squadrons` — built (`j5/main`, 2026-09-12, #129); read-only Squadron directory - -**Description (contract):** "The Squadron directory for this environment: every Squadron's -squadron_id, name, and the project ids it references, plus your own thread's project id so you can -see which Squadron can home you. Use it to obtain the exact squadron_id before join_squadron. -Read-only." - -No inputs. Result: `caller_project_id` (null only when the caller thread cannot be read) and -`squadrons[]` rows of `squadron_id`, `name`, `project_ids`. The server states facts and never -picks: the caller compares `project_ids` against `caller_project_id` itself. Exists because -`list_participants` refuses unregistered callers and so cannot bootstrap `join_squadron`. No events. - -## `join_squadron` — built (`j5/main`, 2026-09-12, #129); original-home repair for native threads - -**Description (contract):** "Join a Squadron when your thread has no Squadron home yet. Pass the -exact squadron_id, taken from list_squadrons; that Squadron must reference your thread's project. -Your thread, conversation, worktree, and running work stay exactly as they are. Calling it again for -the Squadron you already belong to returns your existing registration. Reuse client_request_id to -retry safely. Warning: you cannot switch Squadrons once you're assigned, be sure you're joining the -right one." - -| Input | Type | Required | Meaning | -| ------------------- | ----------------- | -------- | ------------------------------------------------------ | -| `squadron_id` | SquadronId | yes | Explicit existing Squadron; never inferred from folder | -| `client_request_id` | string, non-empty | no | Supply and reuse to make retries safe | - -Result: `squadron_id`, `participant_id`, `thread_id`, `placement` (`placement_parent_id` null = -root; `provenance` `unknown` / `native_or_unobserved` for a previously native thread). Semantics: -acts on the authenticated calling thread only. Refuses before any write when the thread is archived -or deleted, when it already has a home in a different Squadron (`A2AHomeConflictError`), when its -identity was retired (`SquadronJoinRetiredError`), or when the Squadron does not reference exactly -the thread's project (`SquadronJoinProjectReferenceError`). A thread already homed in the requested -Squadron gets its existing registration back, gaining a root placement only if it had none. Fresh -joins compose the Registrar's original-home registration with the placement write in one -transaction under the ledger append permit, so replays with the same `client_request_id` and -concurrent retries with different ids both commit exactly one `participant.joined`. The thread, -provider session, worktree, and any running turn are untouched: no new thread, no injected task, no -interrupt. Events: `participant.joined`, `participant.placement_created`. - -This amends the Squadron ruling "there is no join, no leave, no move" for exactly one case — a -native thread that never received a home — and preserves the rest of it. - -## Kept upstream tools (via `J5OrchestratorSurface`) - -- **`orchestrator_capabilities`** — handler overridden. Response contract: providers and models - (ids, labels, option descriptors) for spawn targeting, plus runtime/interaction mode facts. It - stops advertising `appOwnedSubagents`, `canRunChildTask`, and delegation features entirely; J5 - verbs are advertised by their own descriptions, not by the capabilities payload. -- **`schedule_task`, `list_scheduled_tasks`, `update_scheduled_task`, `delete_scheduled_task`** — - consumed as-is, upstream descriptions unchanged. -- **`t3_thread_list`, `t3_thread_read`, `t3_thread_wait`** — consumed as-is (observation is - unregulated). If upstream descriptions reference `delegate_task`, the J5 surface re-declares the - affected tool with corrected prose. -- **`create_threads` / `t3_thread_start`** — **SETTLED-OMITTED (Director disposition, 2026-08-31, - under ST5's delegated realization; shipped fail-closed in the J5OrchestratorSurface).** Absent by - construction from the agent surface. Admission requires a contract amendment HERE first (corrected - descriptions included — the shipped upstream strings steer callers toward `delegate_task`), never a - registration change alone. Supersedes substrate.md's open row. +- 2026-08-29 — contracts adopted: descriptions as part of the contract, the toolsmith rule, single-target stop and archive, the confirmation-token archive ([record](../../worklog/substrate-session-2026-08-29.md)). +- 2026-08-30 — the spawn brief carries the task and the reply expectation; one sentence of brief steering in `spawn_agent` ([record](../../worklog/spawning-guide-session-2026-08-30.md)). +- 2026-08-31 — self-send refused; the `self` row; identity facts in the spawn's first turn; `display_name` on every row; `create_threads` and `t3_thread_start` omitted ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). +- 2026-09-07 — rewritten from a stack of dated contract revisions into current-state contracts; every verb's build state true as of this date (all six verbs shipped; `regarding` and the person follow-up rule are issue #111). diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index b02c25907772..2aa94cbebae8 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -1,42 +1,153 @@ --- -title: "A2A design session — grounding and decision register" -kind: spec +title: "Agent-to-agent communication" +kind: definition --- -> **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `../features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. +# Agent-to-agent communication -# A2A design session (backlog item 2) +## Problem -Working artifact for the tech-plan session started 2026-08-16. This is the single home for the open decisions (it supersedes the open-questions list in `../communication-graph.md`); the builder-facing plan artifact gets written once the register below is settled. Companion context: `../communication-graph.md` (the product definition), `../../research/t3code/orchestration-v2.md` (the base), `../../research/traycer/agent-to-agent.md` (the steal list), `../../research/jackson-prior-art/fleet-interviews-synthesis.md` (P1–P13 and the classification lens). +Single agents can get more done than ever before, but there are still limits. Context spent on building pushes important conversation with the user out of the window. Independent reviewers bring a fresh perspective. Frontier models waste usage on simple tasks that could be completed by cheaper ones. There is great value in letting agents talk to one another and coordinate work. -## Grounding: the four-layer model +However, this must be done at the platform level. LLMs are not reliable and have their limits: -Established with Jackson 2026-08-16 (ELI5 versions in the session transcript; condensed here for builders): +- Many A2A communication systems rely on polling or outside event triggers. The platform knows what is happening and can ensure timely delivery. +- Agents fall over all the time, the platform can notify the calling agent or user when that happens. +- When a user spawns many agents, they won't always pay attention to them all. Having a way for the agent to get in touch with the user beyond a "done" or "question" notification is needed. -1. **Transport** — delivery of a message into a running agent's conversation. We use T3 v2's thread layer for this (`t3_thread_send` injects into _any_ project thread; queue/steer modes; five providers). We do **not** build on v2's `delegate_task`/task layer — that is strictly parent→child (results flow to parent only, no sender identity, no reply obligation) and peer A2A lives _beside_ it, not on it. v2's topology-neutral parts we use: addressable threads + injection, the event-sourced core (command → events → projections in one transaction), and run-lifecycle events (turn started/ended). -2. **Ledger** — the per-epic append-only communication event log. Source of truth. Rows: exchange opened (with intent summary), message sent, delivery recorded, reply (closes the exchange), silence notice, participant joined/left. Never edited; corrections are new rows; survives restarts (Traycer's RAM-only open-request state is the anti-pattern). -3. **Exchanges (obligations)** — our name (D9) for Traycer's `(expectReply, responseId)` semantics, stolen whole: a reply-expected send mints an `exchangeId`; idempotent open per sender→receiver pair; follow-ups join the exchange; ONE reply carrying the id closes everything on it; taught as prompt text at the moment of action (toolsmith-validated pattern). The open exchange IS the durable fact "X owes Y an answer." Named "exchange," never "thread": a T3 thread is a whole conversation; an exchange is a reply obligation that _travels through_ T3 threads as delivery — one exchange can span several T3 threads and vice versa. -4. **Projections** — derived, materialized, disposable views over the ledger (measured-tables property: wipe and rebuild freely; never authoritative). The communication graph (nodes = participants incl. the human; **edges = exchanges, not messages**, each open/stalled/answered/dropped), the human inbox, the stall report, playback. +Agent-to-agent communication is J5's answer: a way for agents and people to talk to each other that is **durable** (nothing is lost when a process ends), **measured** (the platform records what actually happened rather than trusting what an agent says happened), and **legible** (a person can see who is waiting on whom, for what, and since when). -**Silence is measured; replies are asserted.** Typed silence notices are authored by the _platform_ about an agent when it says nothing — they are not a response schema the agent fills in (a dead agent can't fill in a schema). Detection is code over three code-level facts: delivery event + turn-end lifecycle event (hook/run-owned, never output-parsing) + absence of a reply tool-call. A `turn-ended` notice does not auto-close the exchange — it informs the waiter. +## Definition -## Decision register +Agent-to-agent communication has four layers. Each one exists to make a specific failure impossible to hide. -Settled by prior decisions (decision log / synthesis): human as first-class node (pending only D-list closure), durable log over RAM, transport-level delivery acking (P4), the two-channels envelope for human→agent inbox messages, protocol-semantics-as-prompt-text, message kind tags cut, measured-vs-asserted provenance (P2). +### Transport -| ID | Decision | Resolution | Status | -| --- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| D1 | Do v2 hierarchical delegations appear in the same ledger? | Yes for _delegations to child agents_ (agent-created real threads — fully interactable, full A2A participants); **no for provider-native subagents** (`ExecutionNode` workers with no thread of their own — not addressable, visible only via v2's `SubagentProjection` "rough log"). A2A participant = anything with its own thread: main agents, child agents, the human. Build-time verify item: exact upstream UI affordances for interacting with a delegated child mid-task | SETTLED 2026-08-16 | -| D2 | Ordinary human↔agent chat turns as graph edges? | **No** — "that's not A2A" | SETTLED 2026-08-16 | -| D3 | Ledger scope | **Per-epic** — performant and scoped by default. Jackson's cross-epic question spawned D8 | SETTLED 2026-08-16 (see D8) | -| D4 | Required intent summary on exchange-open | **Yes**, tool schema + prompt text — with the expectation of iterating the wording as agent behavior is observed (envelope/summary text is versioned config, already settled) | SETTLED 2026-08-16 | -| D5 | Message lifecycle | **Log-first** — the ledger row is the primary act; injection is a delivery attempt recorded against it. "More resilient to failure." Cost accepted: peer messaging goes through our decider/projection layer rather than thin-wrapping `t3_thread_send` | SETTLED 2026-08-16 | -| D6 | v1 silence-state set | **Ship five:** `turn-ended-no-reply` (with processed vs never-processed sub-split), `errored`, `stopped/cancelled` (carries do-not-retry), `awaiting-human` (knows / doesn't-know), `blocked-on-peer`. **Defer:** `waiting-on-external-gate`, `silent-tool-degradation` (P8), PTY-style `quiet` watchdog (may never be needed — simplification over Traycer) | SETTLED 2026-08-16 | -| D7 | v1 scope boundary | **Confirmed:** send/reply/exchanges + envelopes + durable ledger + silence notices + human inbox data model + graph read API; graph UI and panes are item 4's; lifecycle tools are v2's. Too big for one ticket — staged along five milestone seams: (1) ledger, (2) send/deliver/reply loop, (3) silence notices, (4) human node, (5) graph projection + read API. Formal ticket breakdown is its own pass after the plan artifact | SETTLED 2026-08-16 | -| D8 | **Cross-epic exchanges** | **Allow, recorded double-entry**: one row in the sender's epic ledger, one in the receiver's, shared correlation id; each ledger complete for its own participants; cross-epic edges render in both graphs as external stubs; dashboard joins. Accepted risk (Jackson): may need adjustment for cross-device work — deliberately NOT architected now while T3/Traycer's cross-machine moves are pending | SETTLED 2026-08-16 | -| D9 | **Naming** | **Exchange** (`exchangeId` for Traycer's `responseId`). "Thread" rejected — collides with T3's AppThread; an exchange is a reply obligation that travels _through_ T3 threads, not a conversation | SETTLED 2026-08-16 | -| D10 | **Hierarchy = three relationships, and org placement is free** (new, from Jackson's spawn-topology question) | Decouple: (1) _provenance_ — spawned-by, immutable, auto-recorded; (2) _delegation bindings_ — who owes whom a result: already exchanges in the ledger (v2's `delegate_task` result-binding stays, orthogonal to placement); (3) _org placement_ — a mutable display-tree pointer, default = spawner, settable at spawn to sibling / other parent / new root. No children-only restriction: with A2A, communication doesn't follow the tree, and result-flow binds to the delegator, not a tree position. (Traycer's forced `parentId`=spawner made Jackson's own org chart lie: coordinator-spawned groups displayed under the coordinator instead of their lead.) No T3 clash — creation tools gain a placement param; delegation machinery untouched. Costs: cascade stop/archive follows _placement_; re-parent is cycle-checked (v2's graph already is); v1 guardrail: re-parenting existing agents is human-only, agents choose placement only at spawn. Note: placement ≠ team membership (teams are P1 objects, item 3's territory) | SETTLED 2026-08-16 | +J5 carries a message by using upstream's thread injection: the message becomes text in the receiver's conversation. Formatted with the right metadata so the agents and users can understand it. -## Register status: fully settled 2026-08-16 +### The ledger -All ten decisions closed. Silent-inference review done with Jackson: cross-epic double-entry accepted with the remote-dev collision risk explicitly carried; one-shot delivery resiliency confirmed identical to exchanges (log-first is a pipeline property — "was it delivered" and "was it answered" are independent guarantees); fork Phase-2 status confirmed by the Director (base `j5/main` @ `e7597dac8`, additive build cleared, one certain rebase at upstream #2829 merge). **The builder-facing plan is at `plan.md`** — written along the five D7 milestone seams; sent to the Director for review before staffing. +Every Squadron has a **communication ledger**: an append-only record of everything that happens in communication — every message sent, every delivery outcome, every Exchange opened and closed, every silence notice, every participant joining or leaving. + +The ledger is the source of truth. Nothing in it is ever edited or deleted, and every message in it is delivered. The ledger survives restarts, so a question asked before the server went down is still open when it comes back. + +### The Exchange + +An **Exchange** is one open question between two participants. It begins when one participant asks the other something, it stays open for as long as the other has not answered, and it ends with the answer. The platform tracks Exchanges so that _waiting_ is visible and attributable: at any moment the platform can say who owes whom an answer, about what, and for how long. This is the fact the inbox, the Fleet page and the silence notices are all built on. + +An Exchange is never called a thread. A thread is a whole conversation; an Exchange is a single question that travels through conversations. + +### Projections + +A **projection** is a view the platform builds from the ledger — the inbox, the facts on the Fleet page, the communication graph, the playback of any earlier moment. Nothing is ever entered into a view directly. If a view is wrong, it is thrown away and rebuilt from the ledger, and it comes back the same. This is what lets the ledger be the only thing that needs to be trusted. + +## How an Exchange works + +There are three kinds of message. + +- A **plain message** carries information and creates no obligation. Agents send these to each other freely. +- An **ask** opens an Exchange: the receiver now owes a reply. An ask carries a one-line **intent** that says what is being asked, so the question is legible wherever it is listed without opening the conversation. An ask to a person also carries an **urgency**, which says how soon the answer is needed. +- A **reply** names the Exchange it answers and closes it. + +**Between agents**, one Exchange is open per pair of participants at a time. If the same agent asks the same peer again while the first question is still open, the second ask joins the open Exchange as a follow-up rather than opening a second one, so a chatty pair does not manufacture a pile of separate obligations. One reply closes the Exchange and everything that joined it. + +**To a person**, an agent may hold several open asks at once, because distinct questions deserve distinct inbox items. A follow-up to a question the person has not yet answered is explicit: the agent names the Exchange it is following up on, and the follow-up joins that Exchange and is shown beneath the original ask, so the person always sees the whole question. + +**Closing** is mechanical. An Exchange closes when the reply arrives, when the sender withdraws its own ask, or when the receiver is retired. Whether the reply was _complete_ is not the platform's judgment: a sender who is not satisfied opens a new Exchange about the earlier one, and the platform never decides that on its behalf. + +## Participants + +A participant is anything that can send and receive over the ledger: an agent with a Squadron home, or a person. People are global — one person id, known across every Squadron on the server — and nothing anywhere may assume there is exactly one of them. Provider-native Subagents are never participants. + +Every participant can message every other participant. No Squadron, no placement in a tree and no Role restricts who may talk to whom; the hierarchy carries decisions, never messages, and a Captain commands its Crews by briefing them, never by routing their messages. An agent cannot message itself. The platform states identity facts wherever it speaks: the envelope names the sender, the address book marks the caller's own row, and a spawned agent's first turn tells it who it is. + +## Delivery + +Delivery is **log-first**: the ledger row is the act, and delivery is an attempt recorded against it. A successful attempt is a **delivery receipt**; a failed one is retried; a failure past the retry limit is a **delivery alarm** — a visible fact attributed to the sender, never a silent loss, and never assumed repaired because time passed or a later message got through. "Was it delivered" and "was it answered" are independent facts. + +A message to an agent whose turn is running **queues** behind that turn and starts when it ends. **Steering** — injecting into the running turn — is a controller's act, and in J5 the only controller of an agent's turn is the person: they steer explicitly, and the control they use tells them what a steer does on that provider. There is one exception, ruled for one provider: a peer's update to an already-running Codex Astra turn is delivered into the turn, with guidance to keep the unfinished objective, because receiving information does not transfer control of the task. Platform notices always queue. + +## The person as a participant + +A person takes part in the same protocol as an agent, with two differences that follow from being a person. + +Delivery is the **inbox**, not a conversation. An ask to a person lands in their inbox, gathered across every Squadron on the server. The person's answer, exactly as written, is the reply that closes the Exchange and reaches the asker — no relay, no summary. A person receives only asks and replies; a plain message to a person is refused, because a plain message carries nothing the sender's own thread does not already show, and if the person must see something then seeing it _is_ the obligation. + +Silence is **never measured about a person**. A person has no turn that ends. How long their open asks have waited is a fact the inbox and the Fleet page show; nothing nags. When a person sends a message through the graph rather than the chat, its envelope says plainly that the person is not watching the agent's conversation and will see only what comes back on the Exchange. + +## Silence + +**Silence is measured; replies are asserted.** When an agent's turn ends without a reply it owed, the platform — never the agent — records a **silence notice**: the measured facts of what happened, not a conclusion about why. The facts are the turn that ended and how, whether the delivery was ever processed, every open outbound Exchange the agent holds, and any error or stop. + +The platform names five kinds of silence: the turn ended without the owed reply; the turn errored; the agent was stopped, which tells the waiter not to retry; the agent is itself waiting on a person, and whether that person has seen the ask; and the agent is blocked on a peer, naming the peer. A notice informs the waiter. It never closes the Exchange, and it never claims to know whether the agent forgot or is waiting on something first — that is the waiter's judgment to make with the facts in hand. + +## Envelopes + +Every delivered message is wrapped in an **envelope**: the platform's wrapper that tells the receiving agent who sent this and from which Squadron, what it now owes and how to discharge it, and the measured time. Envelope wording is versioned configuration rendered from one place, so the channels never drift, and it is written in plain words for an agent reading it in the middle of its work. People reading the app see the letter, not the envelope. + +## Vocabulary this definition owns + +message, ask, reply, plain message, Exchange, intent, urgency, obligation, envelope, communication ledger, projection, delivery receipt, delivery alarm, silence notice, queue and steer. The [glossary](../glossary.md) points here for each of them. Provenance and placement are Squadron concepts and live in the [Squadron definition](../features/squadron.md). + +## Acceptance criteria + +### The ledger + +1. Every message an agent or person sends through the platform is recorded in the sender's Squadron ledger before the sender's call returns. +2. Nothing in a ledger is ever edited or deleted, and every recorded message is delivered; a server restart loses nothing. +3. A message crossing Squadrons appears in both Squadrons' ledgers with a shared correlation id, and a crash between the two writes leaves the sender's row visible rather than losing the message. +4. Every projection can be rebuilt from the ledger to an identical result, and a mutated projection row fails the equivalence check. + +### Exchanges + +5. An ask opens an Exchange between its sender and receiver, carries a one-line intent, and carries an urgency when the receiver is a person. +6. While an Exchange is open between two agents, a further ask from the same sender to the same receiver joins it as a follow-up rather than opening a second Exchange. +7. An agent may hold several open Exchanges with the same person at once, each shown as its own inbox item. +8. A follow-up to an open ask to a person names the Exchange it follows up on, joins it, and is shown beneath the original ask in the inbox. +9. One reply naming the Exchange closes it, together with every follow-up that joined it; the sender may withdraw its own ask; the receiver's retirement closes it with a notice to the sender; nothing else closes it. +10. A message from an agent to itself is refused with an error naming the caller's own id. +11. No Squadron, placement, or Role restricts which participants may message each other. + +### Delivery + +12. Every delivery attempt is recorded; a delivery that fails past the retry limit is shown as an alarm attributed to the sender and is never marked repaired by time passing or by a different message succeeding. +13. A message to an agent whose turn is running is queued and delivered when the turn ends; no agent-originated delivery steers a running turn, except a peer update into a running Codex Astra turn, which is delivered into the turn with guidance to keep the unfinished objective. +14. Only a person can steer a running turn; the control they use names what a steer does on that provider, and when nothing is steerable it names the run's state and offers Interrupt instead. +15. Platform notices are always queued, never steered. + +### The person + +16. An agent-to-person send that is neither an ask nor a reply is refused with an error naming the two legal moves. +17. An ask to a person appears in that person's inbox regardless of which Squadron it came from. +18. A person's answer to an ask is delivered to the asker exactly as written, as the reply that closes the Exchange. +19. No silence notice is ever written about a person. + +### Silence + +20. When an agent's turn ends without a reply it owed, the platform records a silence notice holding the measured facts and delivers it to the waiter. +21. A silence notice never closes an Exchange. + +### Envelopes + +22. Every delivered message carries an envelope naming the sender, the sender's Squadron, what is owed, and the measured time. +23. A person's message sent through the graph carries an envelope saying the person is not watching the agent's conversation and will see only what returns on the Exchange. + +## Scenarios + +- **An ask and its answer.** An agent in Billing Migration asks its Captain "which schema version do we target?" with intent "schema target". The Captain's turn ends without replying; the platform records a silence notice and delivers it to the asker, whose next turn sees that the Captain's turn ended without replying. The Captain's next turn replies; the Exchange closes; the asker sees the answer. (AC5, AC9, AC20, AC21) +- **Two questions for the user.** The same agent asks the user "merge now or after the audit?" with urgency _soon_, and separately "may I delete the old branch?". Both appear as inbox items. The agent then learns something relevant to the first question and follows up on it by name; the follow-up appears under that item. The user answers each; each Exchange closes with the exact text delivered to the agent. (AC5, AC7, AC8, AC18) +- **A busy receiver.** An agent in Website Redesign sends a plain message to a peer whose turn is running a long shell command. The message queues; the peer's turn finishes normally; the message starts its next turn. The user, watching the peer, chooses to steer instead — the control says "Steer now" on this provider — and their text is injected into the running turn. (AC13, AC14) +- **A failed delivery.** An agent asks a peer that has been archived. The delivery fails, the alarm is attributed to the asker and shown on its Fleet page row; the asker withdraws its ask; the alarm remains a fact but no longer counts as a problem. (AC9, AC12) +- **Across Squadrons.** An agent in Billing Migration asks an agent in Support Rotation for an incident's status; both Squadrons' ledgers carry the Exchange under one correlation id; the Fleet page of either Squadron shows it as an open ask. (AC3) + +## History + +- 2026-08-14 — the communication graph drafted; former open questions 1–4 ([record](../../worklog/2026-08-14-communication-graph-draft.md)). +- 2026-08-16 — design settled; former D1–D10, this file's earlier form. +- 2026-08-21 — design review: former R3 (closure is mechanical, completeness is the sender's judgment), R4 (notices are measured facts; labels are read-time policy), R10 (a follow-up may name an earlier Exchange), R22 (Captains are never routers), R25 (time facts in envelopes) ([record](../design-review-2026-08-21.md)). +- 2026-08-24 — Subagent and Peer Agent distinguished; `delegate_task` excluded, so former D1's delegation edges no longer exist ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). +- 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)). +- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)). +- 2026-09-05 — rewritten into the definition shape; 2026-09-07 — provenance and placement moved to the Squadron definition (they are organization, not communication). One change of substance: an agent may hold several open asks to a person, with explicit follow-ups shown in the inbox — reversing the one-ask-per-person rule of 2026-09-02 (issue #111). Former identifiers: D1 → Participants (delegation half retired); D2 → Participants; D3, D8 → The ledger, AC3; D4 → AC5; D5 → Delivery, AC1; D6 → Silence, AC20; D7 → the A2A plan; D9 → The Exchange; D10 → the Squadron definition (placement and provenance), with its obligation half being the Exchange; R3 → How an Exchange works, AC9; R4 → Silence; R21 → the Squadron definition; R22 → Participants; R25 → Envelopes, AC22; QS1–QS4 → Delivery, AC13–AC15. diff --git a/docs/j5/product/a2a/substrate.md b/docs/j5/product/a2a/substrate.md index cc19df8a3fa7..f0a5600b098a 100644 --- a/docs/j5/product/a2a/substrate.md +++ b/docs/j5/product/a2a/substrate.md @@ -1,141 +1,74 @@ --- title: "Upstream substrate — what J5 consumes, rebuilds, and builds" -kind: spec +kind: definition --- -# Upstream substrate ruling (settled 2026-08-29) - -This doc governs the fork's relationship to upstream T3's orchestration code: which upstream -mechanisms J5 builds on, which it replaces, and what the agent-facing tool surface exposes. It lives -under `a2a/` because the A2A program forced every decision in it, but its scope is the whole fork. -Session record with the full evidence trail: [substrate session -2026-08-29](../../worklog/substrate-session-2026-08-29.md). Vocabulary of record: -[glossary](../glossary.md) "Spawning" section (ST1–ST5). - -## The organizing line - -The Subagent/Peer Agent species line (ST1–ST5, 2026-08-24) is what sorts upstream code. **Subagents -belong to providers**: the platform cannot control their creation and does not try (ST4); upstream -renders them properly; J5 only observes. **Peer Agents belong to J5**: all platform law — R21 -placement, Squadron inheritance, the creation-time Registrar, ledger participanthood — governs Peer -Agents and only Peer Agents. Every upstream mechanism is judged by one question: _does it carry an -opinion about agent organization?_ Topology-free plumbing is consumed; org-shaped opinion is -replaced by J5's systems. - -`delegate_task` was the only occupant of the middle — an app-owned child wearing Subagent -presentation (sidebar-hidden lineage, `origin: "app_owned"` subagent labeling, creation gated on an -active parent run) with Peer-shaped capabilities (durable independent runs that survive the -spawner). ST5 excludes it from the J5 product surface; this doc records the mechanical disposition. -With it gone the two-species world is clean: every creation is either a provider's business or the -platform's law. - -## The four buckets - -| Disposition | Upstream mechanism | Ruling | -| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Consume as-is** | Provider adapters and turn machinery; the event-sourced core (commands → events → projections, receipts, outbox); thread creation with settings inheritance; per-thread interrupt and archive commands; `sendToThread` steer/queue delivery; checkpoints; run-lifecycle events as an observation feed | Topology-free plumbing. J5 calls these through their public command seams and never mutates upstream projections directly. | -| **Consume as record, never behavior** | Thread lineage (`lineage.parentThreadId`, `relationshipToParent`) | Load-bearing for forks and for rendering provider-native Subagents; also a read-only provenance derivation source for creations that bypass J5 surfaces. Never a lifecycle, display, or org-semantics source for Peer Agents — who spawn with **root lineage** and need nothing from it. | -| **Rebuild (J5 owns the org opinion)** | Spawn (`delegate_task`) → J5 spawn verb: root-thread creation + Registrar + placement; its brief carries the initial task plus whether and what reply is expected. Exchanges with `expect_reply` remain the reply-obligation primitive for later work owed by an existing participant, never a second spawn step. Lifecycle cascade → placement-walking `stop_agent`/`archive_agent` dispatching upstream per-thread ops. Org display (Lineage panel) → hierarchy UI reading placement + provenance; the Lineage panel remains as the structure/debug view for Subagents and forks. | These carry upstream's structure-is-spawn-tree opinion, which is the opinion J5 exists to replace. | -| **Build (nothing exists on either side)** | Open-exchange re-surfacing (a receiver that defers a delivered ask has no "later" — the successor to the retired "auto-wake" question; memo/inbox territory, R24–R35). Orphan/runaway observability (nothing reaps children under any substrate — observe via silence machinery, never auto-kill). Squadron creation UX (SC1–SC4). | Named build items; each needs its own design pass. | - -Transport finding backing the rebuild column (measured 2026-08-29, retained proof databases): the -A2A delivery path is **proven** for the busy-receiver case and code-verified for the idle case -(delivery starts a run when no run is active/waiting; queued runs are promoted when a blocking run -terminalizes). Revised 2026-09-03 (issue #73): the busy case originally steered the ask into the -receiver's active turn; that aborted the receiver's unstarted sibling tool calls, so delivery now -**queues** behind the active turn and starts when it ends. Steer is an explicit human action on -the queued row or the composer's Mod+Enter chord, never a delivery mode; the control says what a -steer does on that provider (active steering on Claude, Codex, and OpenCode; interrupt-and-restart -on Cursor, ACP, and Grok), and when nothing is steerable it names the run's phase and offers -Interrupt instead of falling through (ruling record QS3/QS4). The one v1 proof "failure" was an -instructed silence misread as a delivery bug. `delegate_task`'s completion wake therefore fills no -gap Exchanges leave open. - -## Transport vs A2A — the layering law - -`t3_thread_send` (and the server seam beneath it, `sendToThread`) is **transport**: it injects text -into a thread and nothing more. A2A is transport **plus the law**: the envelope carrying sender -identity and Squadron, the ledger event that makes the message part of the communication graph, the -Exchange and its reply obligation, delivery receipts, and silence classification. `send_message` is -`t3_thread_send` wearing the law. A raw thread-send between agents is untracked peer communication — -it can cause the exact silent stall the communication graph exists to make visible. Therefore: J5 -consumes the seam server-side, and the raw tool never appears on the agent surface. - -## The ownership rule - -**Upstream owns existence and lifecycle state. J5 tables overlay only org facts** (Squadron home, -placement, provenance, exchange obligations). J5 writes flow through upstream's public command -seams, never into its projections. J5 read paths either join upstream state or tolerate staleness -explicitly. - -**Participanthood is granted only by explicit J5 registration surfaces** — the spawn verb, the -user composer (SC3's immutable Squadron chip → Registrar), or a controlled seed. It is never -inferred from thread existence or addressability. The guard case that forces this: Codex-native -Subagents get real shadow AppThreads holding **live** resumable provider thread refs -(`CodexAdapterV2.ts` `registerSubagentThread`, `activeProviderThreadId` set, `creationSource: -"provider"`). They are thread-having and send-capable, and they are Subagents — any future -absorption/backfill sweep must exclude `creationSource: "provider"` and subagent-lineage threads. - -## The agent tool surface — `J5OrchestratorSurface` - -Mechanism: the fork replaces the upstream orchestrator toolkit registration with a J5-owned subset -toolkit (a J5 file re-using upstream's exported `Tool` constants; thin handlers delegating to the -same `OrchestratorMcpService`; one-line swap in the MCP server layer merge). Upstream's toolkit, -handlers, service, and tests stay compiled and untouched — non-exposure, not deletion. - -| Disposition | Tools | Reason | -| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Keep | `orchestrator_capabilities` (handler overridden: stops advertising `appOwnedSubagents`/delegation), `schedule_task`, `list_scheduled_tasks`, `update_scheduled_task`, `delete_scheduled_task`, `t3_thread_list`, `t3_thread_read`, `t3_thread_wait` | Observation and self-scheduling carry no org opinion | -| Drop | `delegate_task`, `task_status`, `task_cancel` | The excluded middle species (ST5), gone whole | -| Drop | `t3_thread_send`, `t3_thread_interrupt` | Untracked twins of `send_message` / `stop_agent` — they bypass ledger, Exchange, silence, and Squadron-membership law | -| **Open** | `create_threads`, `t3_thread_start` | Recommendation on record: drop — raw creation from the agent surface is an unregistered-thread bypass of the spawn verb. Undecided; if kept, their descriptions (which steer callers toward `delegate_task`) must be re-written. | - -Companion edits outside the toolkit: `T3OrchestrationInstructions.ts` prompt text steers agents -toward `delegate_task` and away from thread creation — it gets a small in-place tracked edit. Both -touches (the layer swap, the prose edit) go into `FORK.md`'s upstream-touch inventory when the code -lands. - -**The property that makes this the right mechanism**: the subset is fail-closed on upstream -evolution. A rebase that brings new upstream tools does not extend the agent surface until someone -deliberately admits them — new agent powers get reviewed against J5 law by default. Rebase conflict -surface: the `tools.ts` exports and one merge line. - -Consequence worth recording: with agent-side raw creation dropped and human creation flowing -through SC3's composer chip, the "native creations bypass the wrapper" bound from A6 shrinks to -approximately nothing — the `unknown`-provenance cohort loses both of its sources on this fork. - -### The J5 verb surface — including needed-but-unbuilt - -The J5 toolkit carries the verbs that wear the law: `send_message`, `list_participants`, -`spawn_agent`, `stop_agent`, `archive_agent`, plus the home-repair pair `list_squadrons` and -`join_squadron` (added 2026-09-12, #129: the only verbs an unregistered native thread can use, and -`join_squadron` establishes an original home only — never a move). One verb is **ruled but unbuilt** and is recorded here -so it gets an A-series home rather than living only in a feature doc: - -- **`clear_own_ask`** (working name) — a sender closes its **own** open Exchange without a reply - message. Required by the inbox design's flow 2 (IB1b, - [`features/inbox.md`](../features/inbox.md) "Platform dependency" block): an agent's ask lands in - the human inbox, the human resolves it in direct chat instead of the inbox answer API, and the - agent then withdraws its ask so the inbox item legitimately exits. Semantics: sender-judged - closure (R3) applied to the sender's own withdrawal; refuses non-sender callers; emits a ledger - event so the closure is visible in projections (inbox status, Exchange state, the eventual A5 - graph). Until it ships, in-thread-resolved asks linger open in the human's queue — the known gap - the inbox doc tracks. - -## Legacy cohort - -Children spawned through the A6 wrapper's `delegate_task` path before this ruling are **Peer Agents -wearing subagent lineage**: registered participants with durable independent runs, placed and -provenance-recorded, whose upstream lineage row says `subagent`. They keep working; the species -guard reads registration, not lineage, so they are unaffected. No migration is required; the cohort -is bounded and dogfood-scale. - -## Open doors (deliberately, not forgotten) - -- `create_threads` / `t3_thread_start` on the agent surface (table above). -- Open-exchange re-surfacing for idle receivers (build item; memo/inbox design). -- Orphan/runaway observability policy (build item; silence-machinery surfacing). -- Forks/checkpoints session: how the lineage record's non-org consumers coexist with Peer Agent - org semantics (flagged 2026-08-29, not yet scheduled). -- May Crew members spawn solo Peer Agents — stays open per `features/crews.md` (Deferred); nothing - in this ruling leans either way. +# Upstream substrate + +## Problem + +J5 is a tracking fork of T3 Code. Upstream ships a great deal of machinery that J5 needs — provider adapters, an event-sourced core, thread creation, checkpoints — and some machinery that carries an opinion about how agents are organized, which is the opinion J5 exists to replace. Without a stated line between the two, every feature would re-decide which upstream mechanism to build on, and the agent-facing tool surface would grow by accident with each upstream rebase. This definition draws the line once. + +## Definition + +### The organizing line + +The Subagent and Peer Agent distinction (see the [glossary](../glossary.md)) sorts upstream code. **Subagents belong to providers**: the platform cannot control their creation and does not try; upstream renders them; J5 only observes. **Peer Agents belong to J5**: everything the platform says about spawning, membership, placement and messaging applies to Peer Agents and only to them. + +Every upstream mechanism is judged by one question: _does it carry an opinion about agent organization?_ Topology-free plumbing is consumed as-is. Organization-shaped opinion is replaced by J5's own systems. + +### The four dispositions + +| Disposition | Upstream mechanism | Why | +| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Consume as-is** | Provider adapters and turn machinery; the event-sourced core (commands, events, projections, receipts, the outbox); thread creation with settings inheritance; per-thread interrupt and archive; thread-send delivery with its queue and steer modes; checkpoints; run-lifecycle events as an observation feed | Topology-free plumbing. J5 calls these through their public command seams and never writes into upstream projections directly. | +| **Consume as record, never behavior** | Thread lineage (the parent thread and the relationship to it) | Needed for forks and for rendering provider-native Subagents, and a read-only source for deriving provenance when a creation bypassed J5. Never a source of lifecycle, display or organization for Peer Agents, which are created with root lineage and need nothing from it. | +| **Rebuild — J5 owns the organization** | Spawning (upstream's delegation) becomes J5's spawn verb: root-thread creation, the Registrar, placement, and a brief that carries the task and whether a reply is expected. Lifecycle (upstream's cascade) becomes J5's single-target stop and archive verbs. Organization display (upstream's lineage panel) becomes a hierarchy read from placement and provenance; the lineage panel remains for Subagents and forks. | These carry upstream's structure-is-the-spawn-tree opinion. | +| **Build — nothing exists on either side** | Re-surfacing an open Exchange to a receiver that deferred it (inbox and Memo territory); orphan and runaway observability (observe through silence machinery, never auto-kill); Squadron creation. | Named build items, each with its own definition. | + +### Transport versus communication + +Upstream's thread-send, and the server seam beneath it, is **transport**: it injects text into a thread and nothing more. Agent-to-agent communication is transport **plus the record**: the envelope naming the sender and Squadron, the ledger row that makes the message part of the communication graph, the Exchange and what it owes, the delivery receipt, and silence measurement. J5's `send_message` is upstream's thread-send wearing that record. A raw thread-send between agents is untracked peer communication — it can cause the exact silent stall the ledger exists to make visible — so J5 consumes the seam server-side and the raw tool never appears on the agent surface. + +Delivery to a busy agent queues behind the active turn; steering is the person's act, with one ruled exception for a peer's update into a running Codex Astra turn ([A2A definition](index.md), Delivery). + +### The ownership rule + +**Upstream owns existence and lifecycle state; J5 tables overlay only organization facts** — Squadron home, placement, provenance, Exchange obligations. J5 writes flow through upstream's public command seams, never into its projections; J5 reads either join upstream state or say explicitly that they may be stale. + +**Participanthood is granted only by J5's registration surfaces** — the spawn verb, the composer's Squadron chip, or a controlled seed — and never inferred from a thread's existence or addressability. The case that forces this: Codex-native Subagents get real shadow threads holding live, resumable provider references; they are thread-having and send-capable, and they are still Subagents. Any sweep that absorbs threads into the roster excludes provider-created and Subagent-lineage threads. + +### The agent tool surface + +J5 replaces upstream's orchestrator toolkit registration with its own subset: a J5-owned toolkit reusing upstream's tool constants, thin handlers delegating to the same service, and a one-line swap in the MCP server layer. Upstream's toolkit stays compiled and untouched — non-exposure, not deletion. The subset is **fail-closed on upstream evolution**: a rebase that brings new upstream tools does not extend the agent surface until someone admits them deliberately, so new agent powers get reviewed against J5's definitions by default. + +| Disposition | Tools | Why | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Keep | `orchestrator_capabilities` (its handler no longer advertises delegation or app-owned subagents), the scheduling verbs (`schedule_task`, `list_scheduled_tasks`, `update_scheduled_task`, `delete_scheduled_task`), and the observation verbs (`t3_thread_list`, `t3_thread_read`, `t3_thread_wait`) | Observation and self-scheduling carry no organization opinion. | +| Omit | `delegate_task`, `task_status`, `task_cancel` | The excluded middle species: a Peer Agent in Subagent dress. | +| Omit | `t3_thread_send`, `t3_thread_interrupt` | Untracked twins of `send_message` and `stop_agent` — they bypass the ledger, the Exchange, silence measurement, and Squadron membership. | +| Omit | `create_threads`, `t3_thread_start` | Raw creation from the agent surface would bypass the spawn verb and the Registrar. Admitting either requires a contract in [agent-tools](agent-tools.md) first, never a registration change alone. | + +Upstream's orchestration prompt text steered agents toward delegation and away from thread creation; J5 carries a small tracked edit to it, recorded in the fork inventory. + +The J5 verbs themselves — `send_message`, `list_participants`, `spawn_agent`, `stop_agent`, `archive_agent`, `clear_own_ask` — are defined in [agent-tools](agent-tools.md). + +### The legacy cohort + +Agents spawned through upstream's delegation path before the spawn verb existed are Peer Agents wearing Subagent lineage: registered, durable, placed and provenance-recorded, with a lineage row that says "subagent". They keep working; the species guard reads registration, not lineage. + +## Acceptance criteria + +1. No J5 code writes into an upstream projection; every J5 mutation goes through an upstream public command seam or a J5-owned table. +2. The agent surface exposes exactly the J5 verbs and the kept upstream tools listed above; every other upstream tool is absent by construction, and a new upstream tool arriving in a rebase is absent until admitted through a contract change. +3. An agent-to-agent message sent through the platform always has a ledger row, an envelope, and a delivery outcome; no raw thread-send is reachable from the agent surface. +4. A thread becomes a participant only through the spawn verb, the composer's Squadron chip, or a controlled seed; a provider-created thread or a Subagent-lineage thread never becomes one by any sweep. +5. A Peer Agent created through the spawn verb has root lineage; nothing about it is derived from upstream's lineage record. + +## History + +- 2026-08-24 — Subagent and Peer Agent distinguished; delegation excluded from the product surface ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). +- 2026-08-29 — the substrate line drawn: the four dispositions, the ownership rule, the fail-closed tool subset ([record](../../worklog/substrate-session-2026-08-29.md)). +- 2026-08-31 — `create_threads` and `t3_thread_start` omitted; `clear_own_ask` built. +- 2026-09-03 — delivery queues behind an active turn; steering is the person's act ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)); 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)). +- 2026-09-07 — rewritten into the definition shape; stale rows (the open `create_threads` row, "needed-but-unbuilt" `clear_own_ask`, the pending prompt-text edit, Squadron creation as "nothing exists") corrected to the current state. diff --git a/docs/j5/product/communication-graph.md b/docs/j5/product/communication-graph.md deleted file mode 100644 index 81651b3c242b..000000000000 --- a/docs/j5/product/communication-graph.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: "The Communication Graph — definition" -kind: spec ---- - -> **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. - -# The Communication Graph - -Draft for Jackson (2026-08-14). Purpose: define what the communication graph _is_ so we can close the "human as first-class node" question against something concrete. Grounded in the research: Traycer's `epic.communicationGraph.subscribe` (exactly-once, gap-free, playback) and typed-silence system; T3 v2's relationship graph and `delegate_task`. - -## The one question it answers - -**"Who is waiting on whom, for what, and since when?"** - -For a fleet of long-running agents, the expensive failure mode is not a busy agent — it's a _silent stall_: an agent waiting on a reply that will never come, a delegation whose child died, a question to the human nobody surfaced. The communication graph is the primitive that makes stalls visible, attributable, and old-age-sortable. - -## What it is NOT - -- **Not the spawn tree.** Who-created-whom (`parentId` lineage, T3 v2's root/parent/child/fork/merge-back edges) is _structure_. The communication graph is _conversation_: who is talking to whom right now and who owes whom an answer. The two overlay in UI but are different data. (T3 has only structure; Traycer has only conversation; we render both, distinctly.) -- **Not the transcript store.** Edges carry thread state and intent summaries, not message bodies. Bodies stay in transcripts; the graph links to them. -- **Not a live scrape.** It's a durable log with projections — it survives restarts and supports playback. (Traycer's open threads are RAM-only and die with the host; we explicitly do better.) - -## The primitive: a durable communication event log - -An append-only, per-epic event log. Subscribers consume it cursor-based with Traycer's contract discipline: strictly ascending, exactly-once, gap-free per cursor — and "snapshot ended" is a batching fact, never a "you're caught up" promise. - -Draft event vocabulary: - -| Event | Meaning | -| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `thread.opened` | A reply-expected send minted a `responseId`. Carries sender, receiver, and a one-line **intent summary** (see open question 4). | -| `message.sent` | A message within a thread, or a one-shot (fire-and-forget) delivery. | -| `thread.closed` | The reply arrived. One reply closes the whole thread (idempotent `responseId` semantics, stolen from Traycer). | -| `silence.notice` | Typed silence with the seven-reason taxonomy and trust levels (`turn-ended` authoritative, `quiet` advisory, `awaiting-input`, `receiver-cancelled`, …). | -| `delegation.*` | Open question 1: do v2 `delegate_task` events fold into this same log? | -| `participant.joined/left` | Spawn/archive of a graph participant, so playback renders nodes appearing and retiring. | - -## Nodes - -- **Agent** — any fleet agent, GUI or TUI, any provider. -- **Human** — Jackson (and later, other people). First-class and addressable by id like any peer. Details below. -- _(Door kept open, not built now: external systems as nodes — e.g. a PR as a node its sitter agent watches. Relevant to the dashboard's PR pane later; noting so the node model doesn't hard-code "node = LLM".)_ - -## The edge is a thread, not a message - -The rendered unit is the **thread** (`responseId`), with a state machine: - -```mermaid -stateDiagram-v2 - [*] --> Open : thread.opened - Open --> Open : message.sent (follow-ups join the thread) - Open --> Stalled : silence.notice (reason + trust attached) - Stalled --> Open : receiver resumes / replies expected again - Open --> Answered : thread.closed - Stalled --> Answered : thread.closed - Open --> Dropped : receiver-cancelled (sender told NOT to retry) - Stalled --> Dropped : receiver-cancelled - Answered --> [*] - Dropped --> [*] -``` - -Messages are events _within_ an edge. This keeps the graph legible at fleet scale — twenty agents exchanging two hundred messages is still only the handful of edges that matter, each colored by state and aged by "open since". - -## The human node - -Same protocol, different delivery. What's identical to an agent peer: - -- Agents address the human by id; `expectReply` mints a thread; the human's reply carries the `responseId` and closes it. -- Human threads are edges in the same graph, events in the same log, visible in the same playback. - -What's necessarily different: - -- **Delivery is an inbox, not prompt injection.** A `thread.opened` targeting the human lands in the human inbox — which is precisely the core feed of the dashboard's attention queue. This is where Jackson's PR-dashboard "send question/task to the human" mechanism folds in: those sends become ordinary `thread.opened` events targeting the human node, and the separate mechanism disappears. -- **Silence semantics invert.** Agents emit silence notices because hooks tell us their turn ended; humans have no Stop hook. Proposal: threads targeting the human never emit `silence.notice` to the sender — the sender already knows it's waiting on a person (this is exactly the state Traycer's `awaiting-input` exists to name). Instead, _the human's own unanswered-thread count and max-age_ become first-class dashboard metrics. Nudging the human is a UX policy question (notification settings), not a protocol event. -- **The human can also be a sender.** Jackson opening a reply-expected thread with an agent ("report when the migration is done") uses the same primitive — and his waiting-on-agents view is the same stall report every agent gets. - -```mermaid -flowchart LR - J(("Jackson
(human node)")) - D["Director"] - R["Reviewer"] - I1["Implementer A"] - I2["Implementer B"] - D -- "open 2m — needs scope call" --> J - I1 -- "answered" --> D - D -- "stalled 41m — awaiting-input" --> I2 - R -- "open 6m" --> I1 - J -. "open 1h — 'report when done'" .-> R -``` - -## Two channels, one agent — when the human sends through the graph - -(Added 2026-08-14 after Jackson's read.) A human message can now reach an agent two ways, and they mean different things: - -| | Chat interface | Inbox thread (via graph) | -| ------------------------------ | -------------------------------------------------- | ------------------------------------------------ | -| Human is watching | Yes — synchronous, sees everything the agent emits | **No** — sees only what comes back on the thread | -| Where the reply must go | Chat text is the reply | The reply tool, carrying the `responseId` | -| Agent's mental model (trained) | Deeply — this is what models are trained for | **Novel — not in the training distribution** | - -**The failure mode to design against:** models are trained to put the answer in the chat. An agent that receives an inbox message, does the work, and writes a beautiful final summary _to its own unwatched chat_ has — from the human's perspective — gone silent. The work happened; the communication didn't. - -Three layers of defense: - -1. **The envelope says the quiet part out loud.** Traycer proved protocol-semantics-as-prompt-text works (`[traycer:agent-message]`, "the responseId names a thread…"). Extend it for human-sent inbox messages, roughly: _"This message arrived via your inbox from the human. The human is NOT watching this chat and will see NOTHING you write here. The only thing they will see is what you send back on this thread with responseId=… ."_ Envelope wording should be versioned, tunable config — this is novel territory for the models and we will iterate on the text. -2. **Typed silence is the safety net — and for human→agent threads it works fully.** The agent side _has_ Stop hooks, so if its turn ends without closing the human's thread, the log gets an authoritative `turn-ended` silence notice and the dashboard shows "did the work, never replied" with a one-click nudge (which can literally re-inject "you have an unanswered thread from the human"). Note the asymmetry: threads _to_ the human emit no silence notices (humans have no hooks); threads _from_ the human get the full taxonomy. -3. **Role/identity definitions encode the norm.** "When a thread from the human is open, closing it is part of finishing the task" belongs in the soul/role layer, not just the envelope. - -**Register is part of the protocol.** Comparing how agents talk to each other over these channels vs how they talk to the human is genuinely informative — agent↔agent messages trend dense and exhaustive (correct: the peer wants completeness), while human-facing replies should be decision-first and one screen. Since the envelope already declares who the counterparty is, it can also set the register expectation, and identity definitions can carry house style for human-facing replies. Open research task: mine live A2A transcripts (including this epic's own Director↔Product exchanges) for agent↔agent vs agent↔human register differences before we write the envelope/role text. - -## Projections (what gets rendered from the log) - -1. **Live graph tile** — nodes plus thread-edges colored by state, aged by open-duration. The at-a-glance "where is the fleet stuck". -2. **Playback timeline** — scrub through the log to reconstruct "how did we get into this state" (Traycer's best new idea; steal the shape). -3. **Human inbox / attention queue** — projection: open threads where receiver = human, merged with `awaiting-input` escalations from agent↔agent threads. This is the dashboard's primary pane, per the attention-queue-first decision. -4. **Stall report** — open threads sorted by age, weighted by the trust level of the last silence notice (`turn-ended` = really stalled; `quiet` = maybe still working). - -## Open questions to close with Jackson - -Superseded (2026-08-16): decision tracking for these four questions (now D1–D4) plus the newer design decisions (D5–D7) moved to a2a/index.md — the A2A design session's decision register. The list below is kept for the original rationale only. - -1. **Do hierarchical delegations live in the same log?** T3 v2 gives us `delegate_task` (parent→child, durable result) for free. My recommendation: **yes, one unified log** — a delegation _is_ a wait, and a graph that omits it lies about who's blocked on whom. Peer threads and delegations become two edge kinds in one graph. -2. **Do ordinary human↔agent chat turns become edges?** Recommendation: **no** — only explicit thread events. Every chat turn as an edge floods the graph into noise. An agent blocked on an in-chat question still surfaces via the `awaiting-input` notice path. -3. **Scope: per-epic or fleet-global?** Recommendation: **per-epic log, fleet-level aggregation in the dashboard.** Keeps the log's delivery contract simple and matches Traycer's proven shape, while the dashboard reads across epics. (Also keeps the door open for cross-machine later: logs replicate per-epic.) -4. **Intent summaries on `thread.opened`?** Recommendation: **yes** — require senders to include a one-line "what I need" so the graph and inbox are legible without opening transcripts. Enforced the way Traycer enforces protocol semantics: as prompt text in the send tool. The inbox is only as good as its subject lines. diff --git a/docs/j5/product/decision-log.md b/docs/j5/product/decision-log.md index b5ad0afba589..537584c0f2ca 100644 --- a/docs/j5/product/decision-log.md +++ b/docs/j5/product/decision-log.md @@ -11,7 +11,7 @@ Running record of product-level decisions from Jackson. One row per decision; st | Date | Area | Decision | Status | | ---------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 2026-08-14 | A2A / Dashboard | **The human is a first-class node in the communication graph.** Jackson's personal PR dashboard already has a "send a question/task to the human" mechanism, proving the need — but it lives outside any graph. Fold it in. Human UX will differ from agent UX (inbox, not prompt injection). | Directional — closes once the communication-graph definition (`communication-graph.md`) is agreed | +| 2026-08-14 | A2A / Dashboard | **The human is a first-class node in the communication graph.** Jackson's personal PR dashboard already has a "send a question/task to the human" mechanism, proving the need — but it lives outside any graph. Fold it in. Human UX will differ from agent UX (inbox, not prompt injection). | Directional — closes once the communication-graph definition (`../worklog/2026-08-14-communication-graph-draft.md`) is agreed | | 2026-08-14 | Agent roles / identity | **No new memory store.** Providers already ship memory systems and skills are ubiquitous; a third store is unwise. Identity is a document users iterate on early, then let solidify — a versioned definition file. | Directional | | 2026-08-14 | Agent roles / identity | **Counter (Jackson's own):** provider memory + skills are provider-local and live outside our app, which hurts identity portability. Likely shape: identity = SOUL.md/AGENTS.md-style file **plus** a portable bundle (own skills, maybe own memory) that travels with it. | Open — needs a dedicated working session | | 2026-08-14 | Dashboard | **Attention-queue first, but only slightly** — the status wall is an important component, not an afterthought. | Settled as priority ordering | @@ -24,7 +24,7 @@ Running record of product-level decisions from Jackson. One row per decision; st | 2026-08-17 | Product principles | **Primitives, not methodology.** J5 Code builds the primitives that make workflows like the PR Groups successful — the exchanges/escalations ledger, the role system, PR visibility + "work this PR" nudges — but must NOT codify Jackson's PR Group methodology into the product. The playbook is one workflow expressible on the primitives, never the product's opinion. Every design asks "what generic capability does this need," never "how do I productize prg." | Settled — governs all dashboard/roles design | | 2026-08-19 | Cross-device (item 5) | **X1–X5 settled** (`cross-device.md`): authority never replicates — messages cross, read-models merge in the client. X1 squadron-on-one-server is a permanent non-goal to violate; X2 item-4 panes multi-environment from day one (incl. notifications); X3 dashboard merge ships with item 4, peer exchanges wait for a real trigger; X4 the peer registry is the cross-person seam (door open, deliberately undesigned); X5 client-pulled backups as the history-durability direction. | Settled | | 2026-08-17 | Epic concept | **The grouping concept defined (E1–E5,** `features/squadron.md`**):** a grouping, never a boundary; single home, no movement (membership fixed at creation; agents spawn within their own epic); full container over time; user-only creation; org tree lives inside one epic. Consequence: agent-facing `join_epic` should not exist — the A2 exclusive-join semantic is ratified-out. | Settled — E6 **settled 2026-08-17: named the "Squadron"** (fleet-native, names the group of agents, empty collision map); code rename scheduled with the Director | -| 2026-08-16 | A2A | **A2A design fully settled — D1–D10** (`a2a/index.md`): unified ledger with delegation edges but not provider-subagents; per-epic ledgers with cross-epic double-entry; log-first delivery; five v1 silence states; "exchange" naming; hierarchy decoupled into provenance / delegation bindings / free org placement (re-parent human-only in v1). Builder plan at `a2a/plan.md` against `j5/main` @ `e7597dac8`; Director reviewing before staffing. | Settled | +| 2026-08-16 | A2A | **A2A design fully settled — D1–D10** (`a2a/index.md`): unified ledger with delegation edges but not provider-subagents; per-epic ledgers with cross-epic double-entry; log-first delivery; five v1 silence states; "exchange" naming; hierarchy decoupled into provenance / delegation bindings / free org placement (re-parent human-only in v1). Builder plan at `../plans/a2a.md` against `j5/main` @ `e7597dac8`; Director reviewing before staffing. | Settled | | 2026-08-21 | Full-design review | **R1–R23 settled** (`design-review-2026-08-21.md`): lifecycle closure for participants and squadrons (archive terminates obligations loudly; ledgers readable forever); sender-judged exchange closure + `regarding` linkage; silence notices as fact bundles with labels in projections; inbox/observability split; `trigger.fired` roots; cost = squadron→agent only; identity = git-versioned files, no memory bundle; durable local person id. **Crew/Manifest/Captain defined**: nautical-civil naming family (team retired); crews spawn and archive as units, members never replaced; agents spawn crews, captains archive their direct crews, crew members cannot spawn crews; captain = derived status, never an entity or a router. | Settled | | 2026-08-21 | Hierarchy (amends D10) | **"You command what you brief."** The spawn-time placement parameter (sibling/other-parent/new-root) is deleted — placement = spawner, always; spawning-and-briefing a crew for someone else is ratified as an anti-pattern (proxy management). Human-only re-parent survives as the sole divergence mechanism; captaincy follows placement. Provenance unchanged: separate, immutable. | Settled — amends D10's placement leg | | 2026-08-21 | Product principles | **Three named principles adopted** (`principles.md`): (1) communication flows peer-to-peer, decisions flow through the hierarchy — captains are never routers; (2) the human-contact spectrum (chat-contact specifically) — manifests declare posture, chattiness gets measured (item 4), platform never enforces position; (3) prompting problems are not platform problems — elevation of the 2026-08-16 platform/non-platform boundary. | Settled — check all designs against these | diff --git a/docs/j5/product/features/squadron.md b/docs/j5/product/features/squadron.md index 25a7270102f0..f68131730af7 100644 --- a/docs/j5/product/features/squadron.md +++ b/docs/j5/product/features/squadron.md @@ -23,6 +23,8 @@ A Squadron **targets folders** rather than living in one: the Squadron is create The Squadron is **the unit of user choice**. Every surface where a person chooses a working context offers Squadrons; upstream's "project" is implementation substrate that a Squadron references, never a noun the user picks. Agent creation takes its Squadron from where the person already is — the sidebar's Squadron scope — and shows it in the composer, changeable until send and immutable after. Agents never see any of this: a spawned Peer Agent inherits its spawner's Squadron. +Within a Squadron, agents are organized in a **placement tree**. An agent's **placement** is where it sits in that tree: under its spawner, unless a person moves it. Whoever briefs an agent commands it, so the tree shows who is running what. An agent's **provenance** is the recorded fact of how it came to exist — created by a person, spawned by a named agent, forked from another, or unrecorded — written once and never changed. Neither placement nor provenance restricts who may message whom; the tree carries decisions, never messages. + End of life is archive; its details arrive with the container's growth. ## Acceptance criteria @@ -38,6 +40,8 @@ End of life is archive; its details arrive with the container's growth. 9. Agents never see a Squadron picker; a spawned Peer Agent inherits its spawner's Squadron. 10. The placement tree lives entirely within one Squadron. 11. Membership is recorded in the ledger as lifecycle events only — joined at creation, left at archive — and neither is agent-invocable. +12. An agent's placement equals its spawner at creation and changes only by a person's action; an agent is never placed outside its Squadron. +13. An agent's provenance is recorded at creation and never changes. ## Scenarios @@ -57,4 +61,5 @@ The current build ([dogfood v0](../dogfood-v0.md)) narrows this definition in th - 2026-08-24 — creation and agent-creation experience; former SC1–SC4 ([record](../../worklog/squadron-creation-session-2026-08-24.md)). - 2026-08-29 — sidebar scope replaces Squadron grouping in the sidebar; former SB3 ([record](../../worklog/sidebar-roster-session-2026-08-29.md)). - 2026-08-31 — the Squadron is the unit of user choice; former E7 ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). +- 2026-09-07 — placement and provenance moved here from the A2A definition (former D10 and R21): they are organization, not communication. - 2026-09-05 — rewritten into the definition shape. Two changes of substance: a Squadron targets one or more folders, so a folder is required at creation (the name-only Squadron is no longer planned — it would complicate upstream integration) and the folder-required v0 override becomes end-state truth; messages to people are no longer listed as Squadron contents (they belong to the inbox, which is person-scoped, not Squadron-scoped). Former identifiers: E1 → AC1; E2 → AC2; E3 → Definition; E4 → AC3; E5 → AC10; E6 → Definition; E7 → AC7; SC1 → AC5, AC6; SC2 → AC3, AC4; SC3 → AC8, AC9; SC4 → Scope; the A2 `join_epic` consequences → AC2, AC11. diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 4d2cd0657d45..92a1ff841fdc 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -15,20 +15,20 @@ The J5 vocabulary, in one place, so that a name used anywhere in these docs reso ## Organization -| Term | Gloss | Owner | -| ------------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| fleet | All of a user's agents across every connected server — the totality, never a sub-grouping | [cross-device.md](cross-device.md) | -| **Squadron** | The user-created grouping of agents and their work that everything else is organized under | [features/squadron.md](features/squadron.md) | -| **Squadron home** | The one Squadron an agent belongs to, recorded when it is created | [features/squadron.md](features/squadron.md) | -| **Registrar** | The part of the platform that records an agent's Squadron home when the agent is created | [features/squadron.md](features/squadron.md) | -| **Crew** | A group of agents that work one task as a unit | [features/crews.md](features/crews.md) | -| **Captain** | Any agent with Crews placed under it | [features/crews.md](features/crews.md) | -| **Role** | A reusable, user-authored definition of a kind of agent | [features/roles.md](features/roles.md) | -| **Manifest** | The artifact form of a Crew definition — implementation vocabulary, not a separate concept | [features/crews.md](features/crews.md) | -| **Playbook** | User-authored step content that a Role or Crew follows | [features/playbooks.md](features/playbooks.md) | -| placement | Where an agent sits in the display tree | [a2a/substrate.md](a2a/substrate.md) _(moves to the A2A definition when it is rewritten)_ | -| provenance | The recorded fact of how an agent came to exist — spawned by whom, forked from what, or unrecorded | [a2a/substrate.md](a2a/substrate.md) _(moves to the A2A definition when it is rewritten)_ | -| **Shared Squadron** | Several people sharing one Squadron on one server | [features/shared-squadrons.md](features/shared-squadrons.md) | +| Term | Gloss | Owner | +| ------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| fleet | All of a user's agents across every connected server — the totality, never a sub-grouping | [cross-device.md](cross-device.md) | +| **Squadron** | The user-created grouping of agents and their work that everything else is organized under | [features/squadron.md](features/squadron.md) | +| **Squadron home** | The one Squadron an agent belongs to, recorded when it is created | [features/squadron.md](features/squadron.md) | +| **Registrar** | The part of the platform that records an agent's Squadron home when the agent is created | [features/squadron.md](features/squadron.md) | +| **Crew** | A group of agents that work one task as a unit | [features/crews.md](features/crews.md) | +| **Captain** | Any agent with Crews placed under it | [features/crews.md](features/crews.md) | +| **Role** | A reusable, user-authored definition of a kind of agent | [features/roles.md](features/roles.md) | +| **Manifest** | The artifact form of a Crew definition — implementation vocabulary, not a separate concept | [features/crews.md](features/crews.md) | +| **Playbook** | User-authored step content that a Role or Crew follows | [features/playbooks.md](features/playbooks.md) | +| placement | Where an agent sits in the display tree | [features/squadron.md](features/squadron.md) | +| provenance | The recorded fact of how an agent came to exist — spawned by whom, forked from what, or unrecorded | [features/squadron.md](features/squadron.md) | +| **Shared Squadron** | Several people sharing one Squadron on one server | [features/shared-squadrons.md](features/shared-squadrons.md) | ## Agents @@ -48,20 +48,20 @@ These entries are the distinctions the whole team must share; the glossary owns | Term | Gloss | Owner | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -| message | One durable send from a participant to a participant | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | -| ask | A message that opens an Exchange — the receiver owes a reply | [a2a/agent-tools.md](a2a/agent-tools.md) | -| reply | The message that closes an Exchange | [a2a/agent-tools.md](a2a/agent-tools.md) | +| message | One durable send from a participant to a participant | [a2a/index.md](a2a/index.md) | +| ask | A message that opens an Exchange — the receiver owes a reply | [a2a/index.md](a2a/index.md) | +| reply | The message that closes an Exchange | [a2a/index.md](a2a/index.md) | | plain message | A message that opens no Exchange; agents may send one to agents, never to a person | [a2a/agent-tools.md](a2a/agent-tools.md), [features/inbox.md](features/inbox.md) | -| **Exchange** | The reply obligation an ask creates between one sender and one receiver. Never called a "thread" | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | -| intent | The one-line summary an ask carries, shown wherever the Exchange is listed | [a2a/agent-tools.md](a2a/agent-tools.md) | +| **Exchange** | The reply obligation an ask creates between one sender and one receiver. Never called a "thread" | [a2a/index.md](a2a/index.md) | +| intent | The one-line summary an ask carries, shown wherever the Exchange is listed | [a2a/index.md](a2a/index.md) | | urgency | How soon a person's answer is needed, set only on asks to a person | [features/inbox.md](features/inbox.md) | | obligation | What an open Exchange is to its receiver: a reply owed | [features/inbox.md](features/inbox.md) | -| envelope | The platform's wrapper around a delivered message that tells the receiving agent who sent it and what it owes | [a2a/agent-tools.md](a2a/agent-tools.md) _(A2A definition when rewritten)_ | -| communication ledger, ledger | The per-Squadron append-only record of every message, delivery, Exchange and notice — the source of truth for all A2A state | [a2a/substrate.md](a2a/substrate.md) _(A2A definition when rewritten)_ | -| delivery receipt | The recorded fact that a message reached its receiver's thread | [a2a/substrate.md](a2a/substrate.md) | +| envelope | The platform's wrapper around a delivered message that tells the receiving agent who sent it and what it owes | [a2a/index.md](a2a/index.md) | +| communication ledger, ledger | The per-Squadron append-only record of every message, delivery, Exchange and notice — the source of truth for all A2A state | [a2a/index.md](a2a/index.md) | +| delivery receipt | The recorded fact that a message reached its receiver's thread | [a2a/index.md](a2a/index.md) | | delivery alarm | The recorded fact that a delivery failed | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | -| silence notice | A platform-authored fact appended when an agent's turn ends without a reply it owed | [a2a/substrate.md](a2a/substrate.md) _(A2A definition when rewritten)_ | -| queue, steer | The two ways a message reaches an agent mid-turn: queued behind the active turn, or steered into it. Agent deliveries queue; only a person steers, explicitly | [a2a/substrate.md](a2a/substrate.md) | +| silence notice | A platform-authored fact appended when an agent's turn ends without a reply it owed | [a2a/index.md](a2a/index.md) | +| queue, steer | The two ways a message reaches an agent mid-turn: queued behind the active turn, or steered into it. Agent deliveries queue; only a person steers, explicitly | [a2a/index.md](a2a/index.md) | | human node | A person as a participant in the communication graph, keyed by person id | [features/inbox.md](features/inbox.md) | ## Humans and attention @@ -97,4 +97,4 @@ These entries are the distinctions the whole team must share; the glossary owns ## Terms still waiting for an owner -These are glossed above with a provisional owner. The doc-by-doc pass gives them a home: placement, provenance, message/ask/reply/plain message, envelope, ledger, silence notice and queue/steer move into the rewritten A2A definition; Fleet page, Squadron scope, orphan and delivery alarm into the Fleet page definition when the current contract lands. +Fleet page, Squadron scope, orphan and delivery alarm are glossed above with a provisional owner; they move into the Fleet page definition when its contract lands. diff --git a/docs/j5/product/problems.md b/docs/j5/product/problems.md index eb33bf42c803..7e6239fa475e 100644 --- a/docs/j5/product/problems.md +++ b/docs/j5/product/problems.md @@ -92,7 +92,7 @@ For example, a user can define a "reviewer" Role that they use to review the cod Complex work needs groups of agents with defined Roles — a Builder, a Reviewer, and a Sitter working one PR is the canonical case. A Crew is that group as a first-class thing: spawned as a unit from a user-authored, git-versioned Crew definition — the Roles it contains and how they work together — living entirely inside one Squadron, with membership fixed at spawn. Counterpart references ("escalate CI failures to your Builder") resolve at spawn, so every member knows how to work with the others without the human wiring them together. -Crews are meant to work the task they're assigned with a high degree of independence from the user, working until they hit a defined stopping point or they complete their task. They can always reach out to other agents in the Squadron for help. But, their communication to the user is rarely through direct chat — they reach the human through the inbox and their Captain (`communication-graph.md`, the human-contact spectrum lens's far-end norms) and record deferred items as Memos (`features/memos.md`). +Crews are meant to work the task they're assigned with a high degree of independence from the user, working until they hit a defined stopping point or they complete their task. They can always reach out to other agents in the Squadron for help. But, their communication to the user is rarely through direct chat — they reach the human through the inbox and their Captain (`../worklog/2026-08-14-communication-graph-draft.md`, the human-contact spectrum lens's far-end norms) and record deferred items as Memos (`features/memos.md`). Crews are deliberately disposable: when their task is done, the user or spawner archives them. They archive only as a unit, members are never individually replaced, and recovery from a poisoned Crew is respawning a fresh one from its definition — cheap because the real work lives in durable artifacts (worktree, branch, PR) that survive the agents. Agents can spawn Crews themselves (Captains running Crews without the human in the loop is the point), Captains can archive the Crews they command, and Crew members can't spawn Crews of their own — wanting more hands is an escalation. diff --git a/docs/j5/worklog/2026-08-14-communication-graph-draft.md b/docs/j5/worklog/2026-08-14-communication-graph-draft.md new file mode 100644 index 000000000000..6d93597986b0 --- /dev/null +++ b/docs/j5/worklog/2026-08-14-communication-graph-draft.md @@ -0,0 +1,6 @@ +--- +title: "The Communication Graph — draft definition (2026-08-14)" +kind: record +--- + +> **Record.** This is the 2026-08-14 draft that became the A2A design. The current definition is [`../product/a2a/index.md`](../product/a2a/index.md); its vocabulary ("thread" for an obligation, `responseId`, the seven-reason silence taxonomy, a merged escalations inbox, `delegate_task` in the log) was superseded there. Kept unedited as the story of how the design started. diff --git a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md index 4f8f5c6dfd2e..37be1637710b 100644 --- a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md +++ b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md @@ -10,7 +10,7 @@ status: 2 # A1 — Epic entity + communication ledger -**Governing artifacts (read first):** `../../../product/a2a/plan.md` (the plan — esp. §Epic entity, §Ledger, §Base), `../../../product/a2a/index.md` (decision register D1–D10), `FORK.md` in the repo. Base: `j5/main` @ `e7597dac8`, clone at `/Users/jackson/repos/jacksondr5/j5code`. +**Governing artifacts (read first):** `../../../plans/a2a.md` (the plan — esp. §Epic entity, §Ledger, §Base), `../../../product/a2a/index.md` (decision register D1–D10), `FORK.md` in the repo. Base: `j5/main` @ `e7597dac8`, clone at `/Users/jackson/repos/jacksondr5/j5code`. ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md index 0b8354c35bea..b29f165bef1d 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md @@ -8,7 +8,7 @@ status: 1 PR #7 MERGED 2026-08-19 as 6e577f15 (Builder-executed under Jackson's one-off delegation; exact-head squash guard, containment clean). Ships: pipeline, exchanges, exactly-once delivery, cross-squadron double-entry, envelopes (Jackson's wording), send_message/list_participants toolkit — membership provisioning intentionally absent per the E1–E5 boundary below. Remaining for status 2: the A2-owned registrar service in the coordinated follow-up slice + live re-proof. Next in sequence: squadron mechanical-rename PR, then registrar. -**Governing artifacts:** `../../../product/a2a/plan.md` (§Exchanges, §Message pipeline, §Envelopes, §Agent tool surface), `../../../product/a2a/index.md` (esp. D4, D5, D8, D9). Base: `j5/main` @ `e7597dac8`. +**Governing artifacts:** `../../../plans/a2a.md` (§Exchanges, §Message pipeline, §Envelopes, §Agent tool surface), `../../../product/a2a/index.md` (esp. D4, D5, D8, D9). Base: `j5/main` @ `e7597dac8`. ## Squadron rename PR-group note diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md index 604a7c602239..e01ff86808e6 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md @@ -12,7 +12,7 @@ are invisible to a first-pass test. ## Correction to the plan text -`../../../product/a2a/plan.md` §Message pipeline and the A2 ticket both say the worker "derives v2's `clientRequestId` +`../../../plans/a2a.md` §Message pipeline and the A2 ticket both say the worker "derives v2's `clientRequestId` deterministically from the ledger message id." **`clientRequestId` does not exist on the internal path.** It is an MCP-surface concept only. diff --git a/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md b/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md index d0f6bfe37e72..1d180aa9eb19 100644 --- a/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md +++ b/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md @@ -6,7 +6,7 @@ status: 0 # A3 — Silence detector -**Governing artifacts:** `../../../product/a2a/plan.md` (§Silence detection), `../../../product/a2a/index.md` (D6; grounding §"Silence is measured; replies are asserted"). Base: `j5/main` @ `e7597dac8`. +**Governing artifacts:** `../../../plans/a2a.md` (§Silence detection), `../../../product/a2a/index.md` (D6; grounding §"Silence is measured; replies are asserted"). Base: `j5/main` @ `e7597dac8`. ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a4-human-node.md b/docs/j5/worklog/a2a-tickets/a4-human-node.md index b0322882ad39..062b88684991 100644 --- a/docs/j5/worklog/a2a-tickets/a4-human-node.md +++ b/docs/j5/worklog/a2a-tickets/a4-human-node.md @@ -12,7 +12,7 @@ status: 0 > 2. **Inbox purity (R5):** the inbox contains ONLY open Exchanges deliberately addressed to a person — nothing else. No merging of stall escalations / awaiting-input observability into the attention queue (that surface is item 4's; the older communication-graph idea of merging is superseded). > 3. Base SHA is whatever `j5/main` resolves to at staffing. "Cross-ledger" reads as "cross-Squadron, per person." -**Governing artifacts:** `../../product/a2a/plan.md` (§Human node; grounding: human as first-class node; D2), design-review register R5/R9/R29 (`../../product/design-review-2026-08-21.md`). +**Governing artifacts:** `../../plans/a2a.md` (§Human node; grounding: human as first-class node; D2), design-review register R5/R9/R29 (`../../product/design-review-2026-08-21.md`). ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md index 97dc43cd267d..060dd62e161c 100644 --- a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md +++ b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md @@ -13,7 +13,7 @@ status: 0 > 3. **`regarding` linkage (R10):** where an Exchange carries the nullable `regarding` field (ships with A8), expose it as edge metadata for survives-from chains. Optional — degrade gracefully, no dependency on A8. > 4. Base SHA is whatever `j5/main` resolves to at staffing. Staffing is opportunistic per the Dogfood v0 plan (`../dogfood-v0.md`). -**Governing artifacts:** `../../product/a2a/plan.md` (§Graph projection + read API), `../../product/a2a/plan.md` (D1, D8; grounding §Projections). Base: historical, see amendment. +**Governing artifacts:** `../../plans/a2a.md` (§Graph projection + read API), `../../plans/a2a.md` (D1, D8; grounding §Projections). Base: historical, see amendment. ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md index 0a85a776d9da..4cce7b28ca87 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md @@ -6,7 +6,7 @@ status: 0 # A6 — Spawn placement + provenance -**Governing artifacts:** `../../../product/a2a/index.md` D10 (the three-relationship decoupling — read its full cell), `../../../product/a2a/plan.md` (§Agent tool surface, last paragraph). Base: `j5/main` @ `e7597dac8`. +**Governing artifacts:** `../../../product/a2a/index.md` D10 (the three-relationship decoupling — read its full cell), `../../../plans/a2a.md` (§Agent tool surface, last paragraph). Base: `j5/main` @ `e7597dac8`. ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md b/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md index ca6553f59703..a4059baaa04d 100644 --- a/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md +++ b/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md @@ -6,7 +6,7 @@ status: 0 # A7 — Planned upstream base advance -**Governing artifacts:** `FORK.md` in the repo (pin log + integration runbook), `../../product/a2a/plan.md` §Base. **Trigger: upstream PR pingdotgg/t3code#2829 merges to main** — this ticket is scheduled work waiting on that event, not a surprise to absorb mid-build. +**Governing artifacts:** `FORK.md` in the repo (pin log + integration runbook), `../../plans/a2a.md` §Base. **Trigger: upstream PR pingdotgg/t3code#2829 merges to main** — this ticket is scheduled work waiting on that event, not a surprise to absorb mid-build. ## Goal From 77331d4a87d45ab1e0f402e3a4600ff5738e598f Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Tue, 8 Sep 2026 20:19:54 -0400 Subject: [PATCH 06/15] =?UTF-8?q?docs(j5):=20steering=20after=20the=20upst?= =?UTF-8?q?ream=20integration=20=E2=80=94=20two=20independent=20policies,?= =?UTF-8?q?=20truthful-steer=20guard,=20stop=20wins=20over=20restart=20con?= =?UTF-8?q?tinuation;=20Astra=20delivery=20guidance=20removed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- docs/j5/plans/a2a.md | 2 +- docs/j5/product/a2a/agent-tools.md | 5 +++-- docs/j5/product/a2a/index.md | 14 +++++++++----- docs/j5/product/principles.md | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/j5/plans/a2a.md b/docs/j5/plans/a2a.md index 29cdafbea3a2..a326526899b6 100644 --- a/docs/j5/plans/a2a.md +++ b/docs/j5/plans/a2a.md @@ -55,7 +55,7 @@ Our reply-obligation object (D9 — never called "thread"; a T3 thread is a conv The ledger row is the primary act; delivery is an attempt recorded against it: 1. Send command validates participants, appends `message.sent` (+ `exchange.opened` if applicable) in one transaction. The tool returns once the row is durable. -2. The delivery worker drains undelivered rows: agent recipients get injection via v2's thread-send with explicit **`queue_after_active`** dispatch (revised 2026-09-03, issue #73: M2 shipped `steer_active` for a busy recipient, which aborted the recipient's unstarted sibling tool calls; delivery now queues behind the active turn and starts when it ends, and steer is an explicit human action on the queued row or the composer chord, labelled with what it does on that provider and refusing truthfully, with Interrupt offered, when nothing is steerable — ruling record QS3/QS4); the human gets an inbox row. A queued envelope is seen when the active turn ends, before silence classification of the next turn. **Exactly-once injection comes from upstream's own dedup, not from our receipt**: the worker derives v2's `clientRequestId` deterministically from the ledger message id, so a post-crash re-drain replays as the same command and v2 dedupes it. Our `message.delivered` receipt records the outcome but cannot be the guarantee — it does not survive the crash window between successful injection and recording. Success appends `message.delivered`; failure appends `message.delivery_failed` and retries with backoff. Per-message queueing is plausible future work (for example, an FYI urgency), but is deliberately not part of M2. +2. The delivery worker drains undelivered rows: agent recipients get injection via v2's thread-send with explicit **`queue_after_active`** dispatch (revised 2026-09-03, issue #73: M2 shipped `steer_active` for a busy recipient, which aborted the recipient's unstarted sibling tool calls; delivery now queues behind the active turn and starts when it ends; steering is the person's act and the person-side default follows upstream since the 2026-09-05 integration; J5 keeps the truthful-steer guard — the control says what a steer does on that provider and refuses, with Interrupt and Queue instead offered, when nothing is steerable); the human gets an inbox row. A queued envelope is seen when the active turn ends, before silence classification of the next turn. **Exactly-once injection comes from upstream's own dedup, not from our receipt**: the worker derives v2's `clientRequestId` deterministically from the ledger message id, so a post-crash re-drain replays as the same command and v2 dedupes it. Our `message.delivered` receipt records the outcome but cannot be the guarantee — it does not survive the crash window between successful injection and recording. Success appends `message.delivered`; failure appends `message.delivery_failed` and retries with backoff. Per-message queueing is plausible future work (for example, an FYI urgency), but is deliberately not part of M2. 3. Rows failing past the retry threshold surface as an alarm state in projections — an undelivered message is a **visible gap, never a silent loss**. This applies equally to one-shots (no exchange, but same delivery guarantees) — "was it delivered" and "was it answered" are independent guarantees. 4. Startup reconciliation: on host restart, the worker re-drains anything sent-but-not-delivered. No RAM-only state anywhere. diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index 18a670b82915..6ae4694beb32 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -83,7 +83,7 @@ No inputs. Read-only; no events. **Result:** exactly one of `interrupt_requested` (a running turn is being interrupted) or `already_idle` (no running turn; no side effect). An interrupt acknowledgement and an observed terminal run state are separate facts; the tool never claims a turn stopped merely because interruption was requested. Anything else is an error naming the caller's actual Squadron and the corrected retry. -**Rule.** Stop and archive are single-target. The unit cascade belongs to Crews, which stop and archive as units through their own verbs when they exist. +**Rules.** Stop and archive are single-target; the unit cascade belongs to Crews, which stop and archive as units through their own verbs when they exist. A stop is final across restarts: a committed stop wins even if the provider has not yet acknowledged it, so a stopped run is never resumed by upstream's restart continuation. ### `archive_agent` @@ -135,7 +135,7 @@ No inputs. Read-only; no events. 6. `list_participants` marks the caller's row `self`, reports a person's row as unable to receive a plain message and able to be asked, and omits threads without a Squadron home. 7. `spawn_agent` refuses a call that omits provider, model, or reasoning, and refuses a choice outside the Role's allowlist with an error naming the Role. 8. A spawned agent's first turn contains its own participant id and Squadron. -9. `stop_agent` and `archive_agent` act on exactly one agent; neither cascades. +9. `stop_agent` and `archive_agent` act on exactly one agent; neither cascades; a stopped run is never resumed after a server restart, even when restart continuation is enabled. 10. `archive_agent` on a target with open Exchanges or a running turn refuses with the list of consequences and a token; the same call with that token archives; a stale token is refused with fresh facts. 11. `clear_own_ask` closes only an Exchange the caller opened and records the closure as sender-cleared. 12. Every error from every verb names the actual state and the next command. @@ -147,4 +147,5 @@ No inputs. Read-only; no events. - 2026-08-31 — self-send refused; the `self` row; identity facts in the spawn's first turn; `display_name` on every row; `create_threads` and `t3_thread_start` omitted ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). - 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). +- 2026-09-05 — a committed stop wins over restart continuation (upstream integration, PR #112). - 2026-09-07 — rewritten from a stack of dated contract revisions into current-state contracts; every verb's build state true as of this date (all six verbs shipped; `regarding` and the person follow-up rule are issue #111). diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index 2aa94cbebae8..2509eea47313 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -65,7 +65,11 @@ Every participant can message every other participant. No Squadron, no placement Delivery is **log-first**: the ledger row is the act, and delivery is an attempt recorded against it. A successful attempt is a **delivery receipt**; a failed one is retried; a failure past the retry limit is a **delivery alarm** — a visible fact attributed to the sender, never a silent loss, and never assumed repaired because time passed or a later message got through. "Was it delivered" and "was it answered" are independent facts. -A message to an agent whose turn is running **queues** behind that turn and starts when it ends. **Steering** — injecting into the running turn — is a controller's act, and in J5 the only controller of an agent's turn is the person: they steer explicitly, and the control they use tells them what a steer does on that provider. There is one exception, ruled for one provider: a peer's update to an already-running Codex Astra turn is delivered into the turn, with guidance to keep the unfinished objective, because receiving information does not transfer control of the task. Platform notices always queue. +Two policies govern what happens when a message reaches an agent whose turn is running, and they are independent of each other. + +The **agent-side policy** is J5's: a message from an agent **queues** behind the running turn and starts when it ends. **Steering** — injecting into the running turn — is a controller's act, and in J5 the only controller of an agent's turn is the person, so no agent's message steers. There is one exception, ruled for one provider: a peer's message to an already-running Codex Astra turn is delivered into the turn as an ordinary envelope, because Astra is built to take messages during work. What the agent does with it is the agent's judgment, exactly as with any other message; the platform adds no guidance about whose instructions win. Platform notices always queue. + +The **person-side policy** is upstream's: whether the person's own send steers or queues, and the shortcuts for choosing, follow upstream on every client (documented in upstream's `docs/user/composer.md`). What J5 adds is truthfulness: the steer control always says what a steer does on this provider, and when nothing can be steered the platform refuses the steer, keeps the draft, names the run's state, and offers the two things the person can do — interrupt the run, or queue the message instead. ## The person as a participant @@ -111,8 +115,8 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel ### Delivery 12. Every delivery attempt is recorded; a delivery that fails past the retry limit is shown as an alarm attributed to the sender and is never marked repaired by time passing or by a different message succeeding. -13. A message to an agent whose turn is running is queued and delivered when the turn ends; no agent-originated delivery steers a running turn, except a peer update into a running Codex Astra turn, which is delivered into the turn with guidance to keep the unfinished objective. -14. Only a person can steer a running turn; the control they use names what a steer does on that provider, and when nothing is steerable it names the run's state and offers Interrupt instead. +13. A message to an agent whose turn is running is queued and delivered when the turn ends; no agent-originated delivery steers a running turn, except a peer message into a running Codex Astra turn, which is delivered into the turn as an ordinary envelope with nothing added. +14. Only a person can steer a running turn. The steer control — in the composer and on a queued row — names what a steer does on that provider ("Steer now", or "Interrupt and restart with this message" where the provider cannot steer); when nothing is steerable, an explicit steer is refused with the draft kept and the run's state named ("Not generating yet — starting", "Finishing up — checkpointing", and the like), the queued row's Steer is disabled, and Interrupt and Queue instead are offered. Whether the person's own send steers or queues by default follows upstream. 15. Platform notices are always queued, never steered. ### The person @@ -148,6 +152,6 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel - 2026-08-24 — Subagent and Peer Agent distinguished; `delegate_task` excluded, so former D1's delegation edges no longer exist ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). - 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). -- 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)). -- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)). +- 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)). 2026-09-05 — the person-side default returns to upstream's (steer on send, an explicit queue shortcut) with the upstream integration (PR #112); the agent-side queue policy, the Astra exception and the truthful-steer guard stand, and the two policies are recorded as independent. +- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)); 2026-09-08 — the delivery guidance that path appended ("continue the unfinished task… change course only when the user's instructions require it") is removed: an agent told by a peer that it should change course should not wait for a user who may never come; the model's behavior is observed instead (issue filed). - 2026-09-05 — rewritten into the definition shape; 2026-09-07 — provenance and placement moved to the Squadron definition (they are organization, not communication). One change of substance: an agent may hold several open asks to a person, with explicit follow-ups shown in the inbox — reversing the one-ask-per-person rule of 2026-09-02 (issue #111). Former identifiers: D1 → Participants (delegation half retired); D2 → Participants; D3, D8 → The ledger, AC3; D4 → AC5; D5 → Delivery, AC1; D6 → Silence, AC20; D7 → the A2A plan; D9 → The Exchange; D10 → the Squadron definition (placement and provenance), with its obligation half being the Exchange; R3 → How an Exchange works, AC9; R4 → Silence; R21 → the Squadron definition; R22 → Participants; R25 → Envelopes, AC22; QS1–QS4 → Delivery, AC13–AC15. diff --git a/docs/j5/product/principles.md b/docs/j5/product/principles.md index 4c8cde7efc1b..ae98f5d1e47d 100644 --- a/docs/j5/product/principles.md +++ b/docs/j5/product/principles.md @@ -143,4 +143,4 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it ## Scoped principles -Principles with narrower jurisdiction live with their stories, not here. Currently two: **authority never replicates — messages cross, read-models merge**, which governs all distributed-state design and lives in [the cross-device position paper](./cross-device.md); and **steering is a controller's act, and in J5 the only controller of a turn is the human** — agent deliveries queue by default, with the September 4 Astra exception for peer updates into an already-running Codex turn; receiving information does not transfer control of the task. The human steers explicitly and is told what a steer does on that provider — which governs mid-turn message dispatch and lives in [the queue-vs-steer ruling record](../worklog/queue-vs-steer-ruling-2026-09-03.md). +Principles with narrower jurisdiction live with their stories, not here. Currently two: **authority never replicates — messages cross, read-models merge**, which governs all distributed-state design and lives in [the cross-device position paper](./cross-device.md); and **steering is a controller's act, and in J5 the only controller of a turn is the human** — agent deliveries queue by default, with the September 4 Astra exception for peer messages into an already-running Codex turn, delivered as ordinary envelopes. The person's own send follows upstream's default; J5 adds that the person is always told what a steer does on that provider and is refused truthfully when nothing can be steered — which governs mid-turn message dispatch and lives in [the queue-vs-steer ruling record](../worklog/queue-vs-steer-ruling-2026-09-03.md). From 50b03284e80bdac786216f9329692034ec9b5eab Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Tue, 8 Sep 2026 23:18:13 -0400 Subject: [PATCH 07/15] docs(j5): inbox, thread rendering and archive flow as definitions; Replied everywhere; a person receives asks only and never opens one Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/a2a/agent-tools.md | 11 +- docs/j5/product/a2a/index.md | 8 +- docs/j5/product/features/archive-flow.md | 115 +++++------ docs/j5/product/features/inbox.md | 158 ++++++-------- .../product/features/thread-a2a-rendering.md | 194 ++++++++---------- docs/j5/product/glossary.md | 2 +- 6 files changed, 215 insertions(+), 273 deletions(-) diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index 6ae4694beb32..d30d9f1e7df2 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -21,11 +21,11 @@ An agent learns what it can do from its tools, and it reads a tool's description ### `send_message` -**Description:** "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask or a reply: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. You may have several asks open with the same person; to follow up on one that is still open, name it in regarding and your message joins it. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. Reuse client_request_id to retry the same send safely." +**Description:** "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. You may have several asks open with the same person; to follow up on one that is still open, name it in regarding and your message joins it. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. Reuse client_request_id to retry the same send safely." | Input | Type | Required | Meaning | | ------------------- | ----------------- | ------------------------------------ | ------------------------------------------------------------------------------- | -| `to` | ParticipantId | yes | A recipient listed by `list_participants`; a person requires an ask or a reply | +| `to` | ParticipantId | yes | A recipient listed by `list_participants`; a person accepts only an ask | | `message` | string, non-empty | yes | The body; the envelope adds sender identity and Squadron | | `expect_reply` | boolean | no | Opens an Exchange (or, between agents, joins the open one); requires `intent` | | `intent` | string | with `expect_reply` | One-line summary shown wherever the Exchange is listed | @@ -36,9 +36,9 @@ An agent learns what it can do from its tools, and it reads a tool's description **Result:** the message id and the Exchange's state. -**Rules.** A message to the caller itself is refused. A plain send to a person is refused. Between agents, a further ask to a peer that already holds an open Exchange from the caller joins it as a follow-up. To a person, a further ask opens a new Exchange and a new inbox item unless it names an open one in `regarding`, in which case it joins that Exchange and is shown beneath the original ask. An ask to a person without an urgency is refused. +**Rules.** A message to the caller itself is refused. A send to a person that is not an ask is refused; a person never opens an Exchange, so there is nothing for an agent to reply to. Between agents, a further ask to a peer that already holds an open Exchange from the caller joins it as a follow-up. To a person, a further ask opens a new Exchange and a new inbox item unless it names an open one in `regarding`, in which case it joins that Exchange and is shown beneath the original ask. An ask to a person without an urgency is refused. -**Errors**, each naming the actual state and the next command: the caller has no Squadron home; the recipient is not addressable (pointing at `list_participants`); the recipient is the caller (naming the caller's own id, and `schedule_task` for a future trigger to oneself); an ask without an intent; a plain send to a person (naming the two legal moves and the own-thread alternative); an ask to a person without urgency; an `exchange_id` or `regarding` that is unknown, already closed, or not the caller's (naming the Exchange's actual state). +**Errors**, each naming the actual state and the next command: the caller has no Squadron home; the recipient is not addressable (pointing at `list_participants`); the recipient is the caller (naming the caller's own id, and `schedule_task` for a future trigger to oneself); an ask without an intent; a send to a person that is not an ask (naming the legal move and the own-thread alternative); an ask to a person without urgency; an `exchange_id` or `regarding` that is unknown, already closed, or not the caller's (naming the Exchange's actual state). **Events:** message and Exchange events in the ledger; delivery receipts follow asynchronously. @@ -128,7 +128,7 @@ No inputs. Read-only; no events. ## Acceptance criteria 1. Every J5 verb's shipped description string is byte-identical to the description in this definition. -2. A plain `send_message` to a person is refused with an error naming the two legal moves; an ask to a person without urgency is refused. +2. A `send_message` to a person that is not an ask is refused with an error naming the legal move; an ask to a person without urgency is refused. 3. A further ask to a person opens a new Exchange and inbox item; an ask that names an open Exchange in `regarding` joins it and is shown beneath the original ask. 4. Between agents, a further ask to a peer holding an open Exchange from the caller joins it as a follow-up. 5. A `send_message` to the caller itself is refused with an error naming the caller's own id. @@ -146,6 +146,7 @@ No inputs. Read-only; no events. - 2026-08-30 — the spawn brief carries the task and the reply expectation; one sentence of brief steering in `spawn_agent` ([record](../../worklog/spawning-guide-session-2026-08-30.md)). - 2026-08-31 — self-send refused; the `self` row; identity facts in the spawn's first turn; `display_name` on every row; `create_threads` and `t3_thread_start` omitted ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-09-08 — a person receives asks only; the reply form toward a person is retired with the person-originated ask. - 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). - 2026-09-05 — a committed stop wins over restart continuation (upstream integration, PR #112). - 2026-09-07 — rewritten from a stack of dated contract revisions into current-state contracts; every verb's build state true as of this date (all six verbs shipped; `regarding` and the person follow-up rule are issue #111). diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index 2509eea47313..7f3c951fb56d 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -51,7 +51,7 @@ There are three kinds of message. **Between agents**, one Exchange is open per pair of participants at a time. If the same agent asks the same peer again while the first question is still open, the second ask joins the open Exchange as a follow-up rather than opening a second one, so a chatty pair does not manufacture a pile of separate obligations. One reply closes the Exchange and everything that joined it. -**To a person**, an agent may hold several open asks at once, because distinct questions deserve distinct inbox items. A follow-up to a question the person has not yet answered is explicit: the agent names the Exchange it is following up on, and the follow-up joins that Exchange and is shown beneath the original ask, so the person always sees the whole question. +**To a person**, an agent may hold several open asks at once, because distinct questions deserve distinct inbox items. A follow-up to a question the person has not yet answered is explicit: the agent references the open Exchange by its id — the id it received when it asked, and which every envelope on that Exchange carries — and the follow-up joins that Exchange and is shown beneath the original ask, so the person always sees the whole question. **Closing** is mechanical. An Exchange closes when the reply arrives, when the sender withdraws its own ask, or when the receiver is retired. Whether the reply was _complete_ is not the platform's judgment: a sender who is not satisfied opens a new Exchange about the earlier one, and the platform never decides that on its behalf. @@ -77,7 +77,7 @@ A person takes part in the same protocol as an agent, with two differences that Delivery is the **inbox**, not a conversation. An ask to a person lands in their inbox, gathered across every Squadron on the server. The person's answer, exactly as written, is the reply that closes the Exchange and reaches the asker — no relay, no summary. A person receives only asks and replies; a plain message to a person is refused, because a plain message carries nothing the sender's own thread does not already show, and if the person must see something then seeing it _is_ the obligation. -Silence is **never measured about a person**. A person has no turn that ends. How long their open asks have waited is a fact the inbox and the Fleet page show; nothing nags. When a person sends a message through the graph rather than the chat, its envelope says plainly that the person is not watching the agent's conversation and will see only what comes back on the Exchange. +Silence is **never measured about a person**. A person has no turn that ends. How long their open asks have waited is a fact the inbox and the Fleet page show; nothing nags. ## Silence @@ -107,7 +107,7 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel 5. An ask opens an Exchange between its sender and receiver, carries a one-line intent, and carries an urgency when the receiver is a person. 6. While an Exchange is open between two agents, a further ask from the same sender to the same receiver joins it as a follow-up rather than opening a second Exchange. 7. An agent may hold several open Exchanges with the same person at once, each shown as its own inbox item. -8. A follow-up to an open ask to a person names the Exchange it follows up on, joins it, and is shown beneath the original ask in the inbox. +8. A follow-up to an open ask to a person references that Exchange by its id, joins it, and is shown beneath the original ask in the inbox. 9. One reply naming the Exchange closes it, together with every follow-up that joined it; the sender may withdraw its own ask; the receiver's retirement closes it with a notice to the sender; nothing else closes it. 10. A message from an agent to itself is refused with an error naming the caller's own id. 11. No Squadron, placement, or Role restricts which participants may message each other. @@ -121,7 +121,7 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel ### The person -16. An agent-to-person send that is neither an ask nor a reply is refused with an error naming the two legal moves. +16. An agent-to-person send that is not an ask is refused with an error naming the legal move; a person cannot open an ask through the platform. 17. An ask to a person appears in that person's inbox regardless of which Squadron it came from. 18. A person's answer to an ask is delivered to the asker exactly as written, as the reply that closes the Exchange. 19. No silence notice is ever written about a person. diff --git a/docs/j5/product/features/archive-flow.md b/docs/j5/product/features/archive-flow.md index 55a87e33da2b..2c614451712f 100644 --- a/docs/j5/product/features/archive-flow.md +++ b/docs/j5/product/features/archive-flow.md @@ -1,63 +1,62 @@ --- -title: "Archive flow — the warning moment, designed" -kind: spec +title: "Archive flow" +kind: definition --- # Archive flow -Feature definition of record, settled 2026-08-29 with Jackson -([session rulings AR1–AR4](../../worklog/archive-flow-session-2026-08-29.md)). -This is the UI of the law already in force: archive terminates -obligations loudly (R1), Crews archive as units (R14), **archive never -destroys work** (R15), archive-with-open-Exchanges warns with count + -list + explicit confirmation (J1–J3), and a dropped ask leaves the -human's inbox immediately because this warning is the loud moment (IB6). -Approved mockup in the design workspace (`product/archive-flow/`). - -## The flow - -1. **Entry**: the existing thread action menu (v0); roster actions reuse - the dialog later. -2. **Pre-archive read**: open asks in both directions + the placement - subtree. Unknowns render as "couldn't check" — never as an empty, - reassuring list ([never-guess](../principles.md)). -3. **The dialog — only when facts warrant it.** A clean agent archives - without ceremony. Otherwise: the subtree line (cascade names), each - waiting ask with sender/urgency/intent/age, the outbound asks that - drop, a quiet R15 reassurance (worktrees, branches, PRs survive — - cleanup is a separate act), and one destructive-styled confirm. One - confirm; no type-to-confirm. _(Amended 2026-09-01 from Jackson's - live review of PR #36 — AR5, **row anatomy**: each open-ask row is - two lines mirroring the inbox item — header line = **urgency badge - first** (blocking/soon/fyi, inbox colors), direction glyph + - "To/From ⟨display name⟩" (agents → thread title; humans → person - name + "(inbox)"; **unknown → "Unnamed participant"**, raw ids never - in the row), time-since via the inbox's own - `open {formatElapsedDurationLabel(openedAt)}` helper so the surfaces - cannot diverge; second line = the intent verbatim, **clamped at ~3 - lines with ellipsis**. Section header carries count + consequence - ("N open asks will be terminated — waiters are notified"). Title is - "Archive ⟨agent name⟩?" with the host's fixed Confirm — the question - lives in the title so Confirm is unambiguous; "Archive anyway" as a - button label is a nice-to-have riding any future host generalization, - never a seam opened for it alone. Mockup of record: - design workspace `product/archive-flow/dialog-rows/`, Variant B.)_ -4. **Aftermath**: agent waiters get R1 terminal notices rendered as - muted platform notices (TA3); human inbox items leave immediately - (IB6); rows leave the active sidebar/roster sets. Nothing is deleted. - -## Dependencies - -Ships ahead of A9 (the dialog warns truthfully today; waiter notices are -A9's build). Subtree facts from A6 placement; needs a small client-facing -pre-archive read. Squadron archive is out of scope (no archive op exists -on the entity — SC4-later). Open Memos join as a third dialog section -when Memos ship (R31). - -## What this feature is not - -Not a delete (R15 — nothing in the workspace is touched), not a -seat-level operation (members are never individually archived — R14), -and not a place for platform judgment: every line in the dialog is a -measured fact; whether to proceed is entirely the human's or Captain's -call. +## Problem + +Archiving an agent is where obligations get stranded: the agent that was owed a reply never learns its counterpart is gone, the person's inbox keeps an ask nobody will ever withdraw, and children placed under the archived agent are left without anyone noticing. More agents mean more cleanup, and cleanup that happens silently is how a fleet loses track of itself ([problems](../problems.md): more work needs more cleanup; large unsupervised groups). Archiving is also a judgment moment — whether to proceed is the person's or Captain's call — and the platform's only honest contribution is to put the facts in front of whoever is deciding. + +## Definition + +Archiving retires an agent for good. It **never destroys work**: worktrees, branches and pull requests survive, and cleaning them up is a separate act. It is **loud**: every open Exchange the agent holds ends with a notice to the waiter, and every fact that archiving will change is shown before it happens. + +Before the dialog appears, the platform reads the facts: the agent's open asks in both directions, and the agents placed beneath it. A fact it could not read is shown as "couldn't check" — never as an empty, reassuring list. + +**The dialog appears only when the facts warrant it.** An agent with nothing open and nothing beneath it archives without ceremony. Otherwise the dialog is titled "Archive ⟨agent name⟩?" and shows: the agents beneath it that this affects; each open ask that will be terminated, as a two-line row mirroring an inbox item — urgency badge first, then "To" or "From" and the counterpart's name, then the time open, then the intent verbatim; the section's count and consequence ("N open asks will be terminated — waiters are notified"); a quiet reassurance that the workspace survives; and one destructive-styled confirm. One confirm, no type-to-confirm. Every line is a measured fact; the dialog offers no opinion on whether to proceed. + +Afterwards, waiters receive a platform notice that the Exchange ended, the person's inbox items from this agent leave immediately (the dialog was the loud moment), the agent leaves the active sidebar and the Fleet page, and its ledger and conversation stay readable forever. When Memos exist, the agent's open Memos appear as a third section of the dialog. + +The flow is reached from the agent's thread and from its Fleet page row. Crews archive only as a unit, through their own flow; a Squadron is not archived through this flow. + +This is **not** a delete, **not** a way to archive a single Crew member, and **not** a place for platform judgment. + +## Acceptance criteria + +### Facts + +1. Before the dialog, the platform reads the agent's open asks in both directions and its placement subtree; a read that fails is shown as "couldn't check", never as an empty list. + +### The dialog + +2. An agent with no open Exchanges and no agents beneath it archives immediately, with no dialog. +3. Otherwise the dialog names the agent in its title, lists the agents beneath it, lists every open ask with its urgency, direction, counterpart, time open, and verbatim intent, states the count of asks that will be terminated, and reassures that the workspace survives. +4. An ask row names its counterpart by display name — an agent's thread title, a person's name with "(inbox)" — and never shows a raw id; an unnamed counterpart reads "Unnamed participant". +5. The dialog has one confirm and no type-to-confirm. + +### Aftermath + +6. Every waiter on an ended Exchange receives a platform notice rendered as a muted notice line in its thread. +7. The person's inbox items from the archived agent leave immediately, with no terminal row. +8. The archived agent leaves the active sidebar and the Fleet page; its ledger and conversation remain readable. +9. No worktree, branch, or pull request is deleted by archiving. + +### Boundaries + +10. A Crew member cannot be archived individually through this flow. +11. The flow is available from the agent's thread and from its Fleet page row. + +## Scenarios + +- **A clean archive.** An agent in Website Redesign has finished, holds no open asks, and has nothing beneath it; "Archive" retires it with no dialog. (AC2) +- **A loud archive.** An agent in Billing Migration has an open ask from the Captain (_soon_, "schema target", open 3h) and an ask out to the user, and a helper placed beneath it. The dialog lists the helper, both asks with their rows, "2 open asks will be terminated — waiters are notified", the workspace reassurance, and Confirm. On confirm, the Captain's thread shows a muted notice that the Exchange ended, the user's inbox item is gone, and the agent's branch and pull request are untouched. (AC3, AC4, AC6, AC7, AC9) +- **A fact the platform couldn't read.** The placement read fails; the dialog says "couldn't check" for the subtree line and still lists the asks it did read. (AC1) + +## History + +- 2026-08-21 — archive is loud and never destroys work; Crews archive as units; archiving with open Exchanges warns with count, list and confirmation ([record](../design-review-2026-08-21.md); former R1, R14, R15 and the Roles/Crews session's J1–J3). +- 2026-08-29 — the flow designed; former AR1–AR4 ([record](../../worklog/archive-flow-session-2026-08-29.md)). +- 2026-09-01 — ask-row anatomy mirrors the inbox item; former AR5 (Jackson's live review of the archive build). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: AR1 → AC11; AR2 → AC1; AR3 → AC2–AC5; AR4 → AC6–AC9; AR5 → AC3–AC4; J1–J3 → AC3, AC5. Build sequencing that lived here (the dialog shipping ahead of waiter notices) is history. diff --git a/docs/j5/product/features/inbox.md b/docs/j5/product/features/inbox.md index 7edddf3345e5..b1d4b27f95e0 100644 --- a/docs/j5/product/features/inbox.md +++ b/docs/j5/product/features/inbox.md @@ -1,96 +1,72 @@ --- -title: "Inbox — the human obligation queue, designed" -kind: spec +title: "Inbox" +kind: definition --- # Inbox -Feature definition of record for the inbox's human surface, settled -2026-08-29 with Jackson -([session rulings IB1–IB7](../../worklog/inbox-session-2026-08-29.md)). -It realizes the surface R5/R26 defined: the pure obligation queue — -letters agents deliberately sent to the human, every item blocking a -sender — and the dogfood definition's heart: asks land here, and the -verbatim answer closes the exchange. Approved mockup in the design -workspace (`product/inbox/mockups/`); decision aid, not pixel spec. -Backend contract: A4's inbox projection + idempotent `answer` API. - -## Only asks reach a person (ruled 2026-09-02) - -The inbox's purity has a sender-side mirror: **an agent cannot send a -person a plain message at all** — every agent-to-human send is an ask -(intent + urgency, closed by the person's reply) or a reply to the -person's own ask. A plain send to a human is refused by the tool, -fail-closed, and the address book reports the human row as -`can_receive_message: false, can_open_exchange: true`. Why: a plain message -to a person carries nothing the sender's own thread does not already show, -and chatty agents would otherwise flood the person with traffic that owes -nothing. If nobody needs to act, the agent says so in its own thread or -tells whoever holds the work context (spawner or Captain — the thread the -human is already reading; not routing, R22 stands). If the person must see -it, seeing it is the obligation: it is an ask. Corollary: **one open ask per -agent→person pair** — a second ask while one is open is refused (a coalesced -follow-up to a person would be an invisible plain delivery, #45's finding); -the agent waits for the reply or clears its ask and re-asks with the combined -content, so the item you see is always the whole ask. Permanent law, not a v0 -override; contract of record in [`../a2a/agent-tools.md`](../a2a/agent-tools.md). - -## Where it lives - -A **bell icon with a numbered open-count badge in the rail header's trailing 32px -control-grid slot, DOM-ordered after the rail logo and aligned with the search/create -controls**, opening a **main-view Inbox page** (IB2; amended 2026-08-31 per Jackson's -PR #23 review). The page starts full-width; -iterate smaller as the product matures. The inbox is **person-scoped** -(R9/R29 — never assume one human) and **not Squadron-scoped**: obligations -are global to the person; each item wears its Squadron; the rail's scope -dropdown governs the thread list only (IB7). Since 2026-09-12 the page and bell merge every -connected environment's inbox; see [cross-device](../cross-device.md#landed-cross-environment-reads-for-squadrons-and-the-inbox-2026-09-12-125-issue-105). - -## The item - -Sender, Squadron, **intent as the subject line**, message body, urgency, -and time-since-opened as a measured R25 fact ("open 4h"). **Urgency is -the loudest element** — blocking / soon / fyi. The list orders by urgency, -then age (IB3–IB4). Collapsed items show header + intent; expanding -reveals the body and reply box. - -## Answering — two first-class flows (IB1) - -1. **Quick reply in place.** The user answers from the item; the platform - clears the ask and the reply-delivery envelope tells the agent the - platform did so (the reply closed the exchange entirely — R3). -2. **Go to the agent.** Asks are often compressed; "Open thread →" jumps - to the asker's thread, where the user reads context and replies as - normal chat. Closure then comes from the sender's side: **the agent - clears its own ask via tool** once the conversation resolved it — - sender-judges-completeness applied to withdrawal. - -> **Platform dependency:** flow 2's clear-own-ask tool (+ ledger event) -> has no build ticket yet; until it ships, in-thread-resolved asks linger -> open. Tracked with the Director. - -## Lifecycle - -Answered items recede into a collapsed **Answered shelf** (IB5). Dropped -asks — the sender was archived — **leave the inbox immediately** (IB6): -the archive-time warning (R1/J1–J3) is the loud moment, and a confirmed -archive means the user wants it gone. No terminal rows. - -## What the inbox is not - -Not a backlog (non-blocking items are Memos — R26), not an alerts feed in -v0 (the platform-alerts lane — errored agents, delivery alarms — is -post-v0 per SB7; the Fleet page carries fallen-over agents meanwhile), -not Squadron-scoped, and never a place for inferred mail or auto-promoted -stalls (R5). - -## Deferred (with reasons) - -- **Platform-alerts lane** (SB7's second lane) — post-v0; separate data - model, possibly shared surface. -- **Asker's-current-state on items** — marginal for v0 and the silence - detector records first-match facts only until A10; revisit if - dogfooding wants it. -- **Smaller/embedded inbox forms** (popover, split pane) — after the - full page proves the flows. +## Problem + +When many agents are working, what is needed from the user gets lost. An agent sits idle waiting on a decision the user does not know is needed; a question bubbles up through other agents like a game of telephone and arrives garbled or not at all; a person coming back to the fleet has no way to see what is waiting on them ([problems](../problems.md): human attention is scarce and gets lost). + +The inbox is the one place a person looks to find everything that is waiting on them, and the one place where answering actually closes the loop — the person's words reach the agent that asked, unchanged. + +## Definition + +The **inbox** is a person's queue of open asks addressed to them. It is **person-scoped, not Squadron-scoped**: a person has one inbox for the whole server, every item wears the Squadron it came from, and no Squadron selection elsewhere in the app hides an item. + +The inbox is **pure**. It holds only asks that agents deliberately sent to the person — nothing inferred, no automatically promoted stalls, no plain messages, no platform alerts. Every item blocks a sender, so the count on the bell means exactly "things waiting on me." The purity has a sender-side mirror: an agent can send a person only an ask; a plain message to a person is refused, because if the person must see something then seeing it is the obligation. The person, in turn, never opens an ask through the platform — their channel to any agent is that agent's thread — and their only act on the ledger is the answer that closes an Exchange. + +An agent may have several asks open with the same person at once, each its own item. A follow-up to a question the person has not yet answered — sent by the agent with the open Exchange's id — joins that item and is shown beneath the original ask, so the person always reads the whole question. + +An item shows who is asking and from which Squadron, the ask's **intent** as its subject line, the body, its **urgency** — the loudest element — and how long it has been open. The list orders by urgency, then age. + +A person answers in one of two ways. **Reply in place**: the answer, exactly as written, is the reply that closes the Exchange and reaches the agent, with an envelope that tells the agent the platform closed it. **Go to the agent**: the person opens the asker's thread, reads the context, and replies in ordinary chat; the agent then withdraws its own ask once the conversation resolved it, and the item leaves the inbox honestly. + +A replied item recedes to a collapsed **Replied** shelf. An ask whose sender is archived leaves the inbox immediately — the archive dialog was the loud moment, and a confirmed archive means the person wants it gone. + +The inbox is reached from a bell in the rail that carries the count of open items and opens a full page. + +The inbox is **not** a backlog (a non-blocking note an agent wants to keep is a Memo), **not** an alerts feed (an agent that fell over is a measured fact for the Fleet page, not an obligation), and **not** Squadron-scoped. + +## Acceptance criteria + +### Contents + +1. The inbox lists every open ask addressed to the person from every Squadron on the server, and nothing else: no plain messages, no inferred items, no promoted stalls, no platform alerts. +2. A plain message from an agent to a person is refused at the tool; the person's row in the address book says it cannot receive one. +3. Several open asks from the same agent to the same person appear as separate items; a follow-up that references an open ask by its Exchange id appears beneath that ask's original text in the same item. +4. The bell's count equals the number of open items. + +### The item + +5. Each item shows the sender, the sender's Squadron, the intent as its subject line, the body, the urgency, and the time since it was opened; urgency is the most prominent element. +6. Items are ordered by urgency first, then by age, oldest first within an urgency. +7. A collapsed item shows the sender line and the intent; expanding it shows the body and the reply box. + +### Answering + +8. Replying in place delivers the person's text to the asker exactly as written, closes the Exchange, and tells the agent the platform closed it. +9. "Open thread" navigates to the asker's thread; an ask resolved there stays open until the agent withdraws it, and then leaves the inbox. +10. A replied item moves to the collapsed Replied shelf and is no longer counted. +11. An ask whose sender is archived leaves the inbox immediately, with no terminal row. + +### Placement + +12. The inbox is not filtered by the sidebar's Squadron scope; each item names its Squadron. +13. The bell with its count is present in the rail on every page and opens the inbox page. + +## Scenarios + +- **Two questions, one agent.** An agent in Billing Migration asks the user "merge now or after the audit?" (urgency _soon_) and, separately, "may I delete the old branch?" Two items appear, the _soon_ one first. The agent later follows up on the first by name; the follow-up text appears beneath it. The user answers each in place; each agent-side Exchange closes with the exact text; both items move to the Replied shelf. (AC3, AC5, AC6, AC8, AC10) +- **Answering in the thread.** The user opens an asker's thread from its item, discusses the question there, and the agent, satisfied, withdraws its ask; the item leaves the inbox. (AC9) +- **Across Squadrons.** With the sidebar scoped to Website Redesign, an ask from an agent in Support Rotation still appears, wearing "Support Rotation". (AC1, AC12) +- **An archived asker.** An agent with an open ask to the user is archived after the dialog's warning; its item is gone from the inbox the moment the archive completes. (AC11) + +## History + +- 2026-08-29 — designed; former IB1–IB7 ([record](../../worklog/inbox-session-2026-08-29.md)). +- 2026-08-31 — the bell moves to the rail header (Jackson's review of the inbox build). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-09-05 — several open asks per agent and person, with follow-ups shown beneath the original (issue #111); the shelf is named "Replied", the one word for a closed Exchange on every surface (glossary). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: IB1 → Answering, AC8–AC9; IB2 → AC13; IB3–IB4 → AC5–AC6; IB5 → AC10; IB6 → AC11; IB7 → AC12. The "clear-own-ask has no build ticket" note is gone: the verb shipped. The deferred items that lived here (a platform-alerts lane, the asker's current state on items, smaller inbox forms) are backlog candidates, not part of this definition. diff --git a/docs/j5/product/features/thread-a2a-rendering.md b/docs/j5/product/features/thread-a2a-rendering.md index ed74214ab7d8..cbf58a0fe641 100644 --- a/docs/j5/product/features/thread-a2a-rendering.md +++ b/docs/j5/product/features/thread-a2a-rendering.md @@ -1,117 +1,83 @@ --- -title: "A2A in the thread view — rendering the fleet's traffic for the human reader" -kind: spec +title: "Agent-to-agent messages in the thread view" +kind: definition --- -# A2A in the thread view - -Feature definition of record, settled 2026-08-29 with Jackson -([session rulings TA1–TA5](../../worklog/thread-a2a-session-2026-08-29.md)); -TA1 amended 2026-08-31, ratified by Jackson directly while live-testing -B3's build (PR #16) — no session, amendments folded in below. **Further -amended same day by the prominence session -([TA6–TA10](../../worklog/thread-a2a-prominence-session-2026-08-31.md))**: -card surfaces, clamp, sent-message cards, and exchange-pair linking — see -"Card anatomy and states" below. -The problem: in phase-3 dogfood the human lives inside agents' threads, -and today every A2A delivery renders as a wall of envelope text — raw -participant ids, per-message protocol boilerplate, silence notices -indistinguishable from letters. The envelope is written _for the agent_; -the human should read the letter, not the postal regulations — with what -the agent actually saw one click away. Approved mockup in the design -workspace (`product/thread-a2a/`). - -## The four treatments - -1. **Incoming peer message** (TA1, as amended 2026-08-31): a distinct - block — sender display name (**clickable — navigates to the sender's - thread**; ruled into the B1/B6 scope), the exchange badge beside the - name (**"Expects reply"** — viewer-neutral copy — / _closed your - exchange_ / plain), time, message body. No second sub-line: the - squadron id row is removed. **Parsed blocks carry no raw-envelope - expander** — live use showed it duplicative, reading as debug UI. The - renderer remains a parser over versioned envelope text, and raw text - remains its **mandatory fallback** for unrecognized versions - ([never-guess](../principles.md)) — that negative control is - untouched; what changed is only that successfully parsed blocks no - longer re-expose the envelope. _(As originally settled 2026-08-29: - sender + Squadron sub-line, "expects your reply" copy, and a - "show raw envelope" expander on every block — all three amended in - Jackson's live test of the first real build.)_ -2. **Human inbox reply** (TA2): rendered as the person — **"You · via - Inbox"** for the local operator. No display names exist yet; the label - derives from the person id (multi-human invariant, R29), so named - humans render properly when names arrive. -3. **Silence notice** (TA3, expander clause amended 2026-08-31 with - TA1): one muted line — "⚠ Platform notice · ⟨counterpart⟩'s turn - ended without replying · ⟨age⟩". Parsed notices carry no expander — - the expander removal applies to parsed blocks everywhere; unparseable - notice text falls back to raw rendering, as everywhere. -4. **Outbound send** (TA4, superseded 2026-08-31 by TA8): a full **sent - card** rendered in the sender's thread — same geometry as received - cards, border-only (no fill), lucide Send icon + "To ⟨receiver⟩", with - the state badge (Awaiting reply / Reply received). Live state ships - when feasible; "Reply received" is likely derivable without A5 by - pairing the closing reply locally by exchange id. - -> **Dogfood v0 note:** TA2's "You" label is overridden in v0 — the merged -> auth principal carries no person binding, so v0 renders neutral -> `Via Inbox · ` (DV4). Overrides live in one place only: -> [`../dogfood-v0.md`](../dogfood-v0.md). This document remains the -> end-state truth; the "You" upgrade returns with the auth-subject→person -> binding session. - -Everything else — conversation, tool calls, work logs — keeps upstream -rendering untouched (TA5). - -## Card anatomy and states (TA6–TA10, 2026-08-31) - -Settled in the prominence session; approved all-states mockup in the -design workspace (`product/thread-a2a/final-treatment/`). - -- **Surface** (TA6): upstream-subtle — received cards carry the app's - faint block fill, sent cards are border-only. **Badges are the only - colorful elements**: amber = still wants something, quiet green = - resolved, neutral chip = plain reply. -- **States**: Sent-open → **Awaiting reply**; Sent-closed → **Reply - received**; Received-open → **Expects reply**; Received-closed → - **Replied**. All copy viewer-neutral. **Chip copy follows the measured - `exchangeRole` and only that** (clarified 2026-08-31, B7 Reviewer - finding #130): role=reply → neutral "Reply" chip; role=none, absent, - or unrecognized → **no chip** (a plain message demands nothing; - never-guess forbids asserting an undeclared role); role=followup → - neutral "Follow-up" if the case is reachable. -- **Clamp** (TA7): every card body clamps at 2 lines with the upstream - chevron pattern ("› N more lines"); UI limit, never content limit. -- **Alignment & direction** (TA8): all A2A cards left-aligned (only the - human's messages sit right); lucide **Send** + "To ⟨name⟩" vs lucide - **Inbox** + "From ⟨name⟩". -- **Time** (TA9): timestamps are time-since-sent from the delivery - record. -- **Linking** (TA10): exchange-pair links only — no titles, no - summaries, no UUIDs. Every reply card (either direction) carries a - clickable verbatim one-line quote strip of the ask it closes; resolved - badges link to their paired message (same-thread - scroll-and-highlight); cross-thread reach is the clickable sender - name, exact-message deep-linking the stretch. **Caveat: if linking - turns technically difficult, the PR Group raises it to Jackson — - never overcomplicate the system for linking.** - -## Scope - -v0, except live exchange chips (A5-gated). All discrimination uses -metadata already on delivered messages (`createdBy`, -`creationSource: "mcp"`, ledger message id in the thread message id) — -no text parsing for classification, and no server changes required for -the static treatments. - -## What this feature is not - -Not a change to what agents receive (envelope content is A8/Director -territory), not a summary layer (bodies render verbatim; the platform -composes nothing), and not an inbox: exchange chips inform, they never -demand — obligations live in [the inbox](inbox.md). - -## Copy amendment (Jackson, 2026-09-01, #23 final pass) - -Reply-delivery cards use the standard card vocabulary — the "Expects reply" / "Replied" family with the quiet-green resolved state — never exchange-closure rhetoric ("closed your exchange" is mechanics vocabulary, not reader copy). The split is deliberate: the agent-facing envelope TEXT keeps its mechanical instruction (the platform closed this exchange; no further reply is required) because agents need mechanics; human-facing UI says "Replied" because readers need plain words. Implementation rides the spawn-brief/sent-card lane (issue #41), which owns card-state vocabulary. +# Agent-to-agent messages in the thread view + +## Problem + +The person lives inside agents' threads. Every message an agent receives from another agent, every silence notice, every reply that arrives through the inbox, is delivered as an envelope written _for the agent_ — participant ids, protocol instructions, the mechanics of what is owed. Read raw, a thread becomes a wall of postal regulations in which the actual letters are hard to find, and a notice is indistinguishable from a message ([problems](../problems.md): fleet observability, human attention). + +The person should read the letter, not the envelope: who said what to whom, what is still waiting, and what has been answered — in plain words, at a glance, with the conversation's own rendering left alone. + +## Definition + +Agent-to-agent traffic in a thread is rendered as **cards** — a distinct treatment from the conversation, which keeps upstream's rendering untouched. Four kinds of item get a card. + +A **received message** from another agent shows the sender's name (a link to the sender's thread), a badge for what the message asks of the reader, the time, and the body. There is no envelope on the card: the renderer reads the versioned envelope text and shows the letter. If it meets an envelope version it does not understand, it shows the raw text rather than guessing — a visible fallback, never a plausible fake. + +A **reply that arrived through the inbox** is rendered as the person who sent it: "You · via Inbox" when the reader is that person, otherwise the person's name. The label comes from the person id, so it is right for any number of people. + +A **silence notice** is one muted platform line — "⚠ Platform notice · ⟨counterpart⟩'s turn ended without replying · ⟨age⟩" — visibly not a letter from anyone. + +A **sent message** is a card in the sender's own thread, the same shape as a received card, showing the receiver and whether the message still waits for a reply. + +Cards are quiet. Received cards carry the app's faint block fill, sent cards are border-only, and **badges are the only colorful elements**: amber for something still waiting, quiet green for something resolved. All A2A cards sit on the left; only the person's own messages sit on the right. Long bodies clamp to a couple of lines with the app's usual "more lines" affordance — a display limit, never a content limit. Times are time-since-sent, from the delivery record. + +Every badge uses **one vocabulary, in plain words**, on every surface that shows an Exchange: a message that wants something says **Expects reply** (received) or **Awaiting reply** (sent); a closed Exchange says **Replied**; a plain message shows no badge at all, because it demands nothing and the platform never asserts a role it did not measure. The mechanics — "the platform closed this exchange" — stay in the agent-facing envelope, where an agent needs them; a reader never sees them. + +Cards **link across an Exchange**: a reply card carries a clickable verbatim quote of the ask it answers, and a resolved badge links to its paired message in the same thread. Reaching another thread is the sender's name. There are no generated titles, summaries, or ids — bodies render verbatim, and the platform composes nothing. + +This is **not** a change to what agents receive, **not** a summary layer, and **not** an inbox: a badge informs, it never demands; obligations live in the [inbox](inbox.md). + +## Acceptance criteria + +### Received messages + +1. A message from another agent renders as a card with the sender's name, a badge reflecting only the measured Exchange role, the time since it was sent, and the body; the sender's name navigates to the sender's thread. +2. A card never shows the envelope; a message whose envelope version the renderer does not recognize renders as its raw text. +3. A plain message shows no badge; a received ask shows "Expects reply"; a received message that closed an Exchange shows "Replied"; a follow-up shows "Follow-up". + +### The person's replies + +4. A reply that arrived through the inbox renders as the person: "You · via Inbox" for the reader who sent it, the person's name for anyone else. + +### Notices + +5. A silence notice renders as one muted platform line naming the counterpart and the age, visibly distinct from any message card. + +### Sent messages + +6. A message the agent sent renders as a border-only card in its own thread, showing the receiver and "Awaiting reply" while its Exchange is open or "Replied" once it closed; a plain send shows no badge. + +### Surface and copy + +7. Badges are the only colored elements on a card: amber while something waits, quiet green when resolved. +8. All A2A cards are left-aligned; only the person's own messages are right-aligned. +9. Card bodies clamp to a fixed number of lines with an expand affordance; nothing is truncated in the record. +10. No surface shows exchange-closure mechanics as reader copy; "Expects reply", "Awaiting reply", "Replied" and "Follow-up" are the only Exchange words a reader sees. + +### Linking + +11. A reply card, in either direction, carries a clickable verbatim quote of the ask it answers, and following it scrolls to and highlights that ask in the same thread. +12. A resolved badge links to its paired message in the same thread. + +### Conversation + +13. Everything that is not A2A traffic — conversation, tool calls, work logs — renders exactly as upstream renders it. + +## Scenarios + +- **An ask arrives.** An agent in Billing Migration receives "which schema version do we target?" from its Captain: a card with the Captain's name, an amber "Expects reply" badge, "2m", and the question. The agent replies; its thread now shows a sent card to the Captain that says "Replied" and quotes the question. (AC1, AC3, AC6, AC11) +- **The user answers from the inbox.** The user replies in the inbox; the agent's thread shows the reply as "You · via Inbox" when the user reads it, and the ask card's badge turns quiet green. (AC4, AC7, AC12) +- **A peer went quiet.** The Captain's turn ended without replying; the agent's thread shows one muted line, "Platform notice · Captain's turn ended without replying · 40m", and nothing that looks like a message. (AC5) +- **A plain update.** A peer sends a status update with no ask; the card has no badge at all. (AC3) + +## History + +- 2026-08-29 — the four treatments designed; former TA1–TA5 ([record](../../worklog/thread-a2a-session-2026-08-29.md)). +- 2026-08-31 — three amendments from Jackson's live test of the first build: no envelope expander on parsed cards (the raw fallback stays), no Squadron sub-line, badge copy "Expects reply", clickable sender name. Same day, the prominence session settled card anatomy, states, clamp, alignment, time and linking; former TA6–TA10 ([record](../../worklog/thread-a2a-prominence-session-2026-08-31.md)). +- 2026-09-01 — reader copy uses the "Expects reply" / "Replied" family, never closure mechanics (Jackson's final review of the inbox build). +- 2026-09-05 — "Replied" becomes the one word for a closed Exchange on every surface, replacing "Reply received" on sent cards and "Answered" on the inbox shelf (glossary). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: TA1 → AC1–AC3; TA2 → AC4; TA3 → AC5; TA4, TA8 → AC6, AC8; TA5 → AC13; TA6 → AC7; TA7 → AC9; TA9 → Definition (time); TA10 → AC11–AC12. The v0 rendering of the person's inbox reply as `Via Inbox · ⟨person⟩` (the "You" claim needs a person binding the auth principal does not yet have) is build status and lives in the dogfood plan. diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 92a1ff841fdc..8421348b2e93 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -50,7 +50,7 @@ These entries are the distinctions the whole team must share; the glossary owns | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | message | One durable send from a participant to a participant | [a2a/index.md](a2a/index.md) | | ask | A message that opens an Exchange — the receiver owes a reply | [a2a/index.md](a2a/index.md) | -| reply | The message that closes an Exchange | [a2a/index.md](a2a/index.md) | +| reply | The message that closes an Exchange; from a person, the inbox answer is the only reply and the only message they send | [a2a/index.md](a2a/index.md) | | plain message | A message that opens no Exchange; agents may send one to agents, never to a person | [a2a/agent-tools.md](a2a/agent-tools.md), [features/inbox.md](features/inbox.md) | | **Exchange** | The reply obligation an ask creates between one sender and one receiver. Never called a "thread" | [a2a/index.md](a2a/index.md) | | intent | The one-line summary an ask carries, shown wherever the Exchange is listed | [a2a/index.md](a2a/index.md) | From c2510a2eb1a683ec236d0d3e4ccd654a13408070 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Tue, 8 Sep 2026 23:19:00 -0400 Subject: [PATCH 08/15] =?UTF-8?q?docs(j5):=20A2A=20definition=20=E2=80=94?= =?UTF-8?q?=20a=20person=20receives=20asks=20only=20and=20never=20opens=20?= =?UTF-8?q?one=20(repairs=20edits=20missed=20against=20the=20staged=20text?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/a2a/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index 7f3c951fb56d..0cdc9948808b 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -75,7 +75,7 @@ The **person-side policy** is upstream's: whether the person's own send steers o A person takes part in the same protocol as an agent, with two differences that follow from being a person. -Delivery is the **inbox**, not a conversation. An ask to a person lands in their inbox, gathered across every Squadron on the server. The person's answer, exactly as written, is the reply that closes the Exchange and reaches the asker — no relay, no summary. A person receives only asks and replies; a plain message to a person is refused, because a plain message carries nothing the sender's own thread does not already show, and if the person must see something then seeing it _is_ the obligation. +Delivery is the **inbox**, not a conversation. An ask to a person lands in their inbox, gathered across every Squadron on the server. The person's answer, exactly as written, is the reply that closes the Exchange and reaches the asker — no relay, no summary. A person receives only asks; a plain message to a person is refused, because a plain message carries nothing the sender's own thread does not already show, and if the person must see something then seeing it _is_ the obligation. The person never opens an ask through the platform: their channel to an agent is that agent's thread, which they can open at any time, and their only act on the ledger is the answer that closes an Exchange. Silence is **never measured about a person**. A person has no turn that ends. How long their open asks have waited is a fact the inbox and the Fleet page show; nothing nags. @@ -134,7 +134,7 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel ### Envelopes 22. Every delivered message carries an envelope naming the sender, the sender's Squadron, what is owed, and the measured time. -23. A person's message sent through the graph carries an envelope saying the person is not watching the agent's conversation and will see only what returns on the Exchange. +23. The answer a person gives in the inbox reaches the agent wrapped in an envelope that says the Exchange is closed and no further reply is owed. ## Scenarios @@ -153,5 +153,5 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel - 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). - 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)). 2026-09-05 — the person-side default returns to upstream's (steer on send, an explicit queue shortcut) with the upstream integration (PR #112); the agent-side queue policy, the Astra exception and the truthful-steer guard stand, and the two policies are recorded as independent. -- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)); 2026-09-08 — the delivery guidance that path appended ("continue the unfinished task… change course only when the user's instructions require it") is removed: an agent told by a peer that it should change course should not wait for a user who may never come; the model's behavior is observed instead (issue filed). +- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)); 2026-09-08 — a person never opens an ask through the platform; their only ledger act is the closing answer (the 2026-08-14 design's person-as-sender is dropped; the unused person-origin envelope channel goes with it, issue #119). Same day, the delivery guidance that path appended ("continue the unfinished task… change course only when the user's instructions require it") is removed: an agent told by a peer that it should change course should not wait for a user who may never come; the model's behavior is observed instead (issue filed). - 2026-09-05 — rewritten into the definition shape; 2026-09-07 — provenance and placement moved to the Squadron definition (they are organization, not communication). One change of substance: an agent may hold several open asks to a person, with explicit follow-ups shown in the inbox — reversing the one-ask-per-person rule of 2026-09-02 (issue #111). Former identifiers: D1 → Participants (delegation half retired); D2 → Participants; D3, D8 → The ledger, AC3; D4 → AC5; D5 → Delivery, AC1; D6 → Silence, AC20; D7 → the A2A plan; D9 → The Exchange; D10 → the Squadron definition (placement and provenance), with its obligation half being the Exchange; R3 → How an Exchange works, AC9; R4 → Silence; R21 → the Squadron definition; R22 → Participants; R25 → Envelopes, AC22; QS1–QS4 → Delivery, AC13–AC15. From 37d599fdbd99d168d7c9aa9e43825cd929660606 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Wed, 9 Sep 2026 13:35:14 -0400 Subject: [PATCH 09/15] =?UTF-8?q?docs(j5):=20Roles,=20Crews,=20Memos,=20Pl?= =?UTF-8?q?aybooks,=20Spawning=20Guide,=20Shared=20Squadrons=20as=20defini?= =?UTF-8?q?tions=20=E2=80=94=20the=20design-review=20register=20dissolved?= =?UTF-8?q?=20into=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/features/crews.md | 90 +++++++++++++------- docs/j5/product/features/memos.md | 62 +++++++++----- docs/j5/product/features/playbooks.md | 42 +++++---- docs/j5/product/features/roles.md | 87 ++++++++++++------- docs/j5/product/features/shared-squadrons.md | 49 ++++++----- docs/j5/product/features/spawning-guide.md | 88 ++++++------------- 6 files changed, 237 insertions(+), 181 deletions(-) diff --git a/docs/j5/product/features/crews.md b/docs/j5/product/features/crews.md index ecbb5fd55cc3..70a4d1b65530 100644 --- a/docs/j5/product/features/crews.md +++ b/docs/j5/product/features/crews.md @@ -1,53 +1,81 @@ --- -title: "Crews — groups of agents spawned and retired as a unit" -kind: spec +title: "Crews" +kind: definition --- # Crews -Feature definition of record. The problems and goals it serves ([problems doc](../problems.md)): complex work needs groups of agents with defined Roles working with high independence from the user — and Foreground agents need somewhere to delegate context-heavy work so they can stay responsive touchpoints. Rulings baked in: R12–R20 and R21–R22 in [the register](../design-review-2026-08-21.md), plus the item-3 product session ([worklog record](../../worklog/roles-crews-session-2026-08-23.md)). +## Problem -## The Crew +Complex work needs a group of agents with defined jobs working together with a high degree of independence from the person — a builder, a reviewer, and a sitter on one pull request is the canonical case. Wiring such a group by hand every time is slow and error-prone, groups that die leave stranded obligations, and a Foreground agent that keeps the person's attention needs somewhere to hand context-heavy work so it can stay responsive ([problems](../problems.md): large unsupervised groups, human attention, more work needs more cleanup). -A **Crew** is a group of agents spawned as a unit from a user-authored, git-versioned **Crew definition** — the [Roles](roles.md) it contains and how they work together. (The definition's artifact form is called a _Manifest_ in implementation vocabulary; at the product level, defining a Crew _is_ the definition.) The canonical example is the PR Group: a Builder, a Reviewer, and a Sitter working one PR end to end. +## Definition -- **Membership is fixed at spawn.** Counterpart references ("escalate CI failures to your Builder") resolve at spawn, so every member knows how to work with the others without the human wiring them together. -- **A Crew lives entirely inside one Squadron** and renders as one node in the org tree, with its members beneath it — cascade operations treat it as a unit. -- Crews work their task with high independence, until a defined stopping point or completion. They can always reach any other agent in the Squadron directly — but their communication with the user is rarely direct chat: they are Background agents, reaching the human through the inbox or their Captain, and recording deferred items as [Memos](memos.md). +A **Crew** is a group of agents spawned as a unit from a user-authored **Crew definition**: which Roles it contains and how they work together. The definition is the user's content — a file, portable and shareable, git optional, like a Role. (Its artifact form is called a Manifest in implementation vocabulary; at the product level, defining a Crew is the definition.) -**Definition integrity is checked where it's structured**: a Crew that references a Role that doesn't exist (missing file, renamed) is a visible defect in the library before anyone spawns it. Prose counterpart mentions are never parsed or validated — that's a judgment task, and guessing at it is worse than not checking ([never-guess](../principles.md) applies to validators too). +**Membership is fixed at spawn.** Counterpart references in the definition ("escalate CI failures to your Builder") resolve once, at spawn, so every member knows how to work with the others without the person wiring them together. A Crew lives entirely inside one Squadron and renders as one node in the placement tree with its members beneath it; anything that acts on the unit acts on all of them. -## Command: Captains +Crews work their task with high independence until a defined stopping point or completion. They can always reach any other agent in the Squadron directly. Their communication with the person is rarely direct chat: they lean Background, reaching the person through the inbox or through their Captain, and recording deferred items as Memos. -Any agent with Crews placed under it is a **Captain** — a derived, measured status, not a platform entity or a tier. The management layer is made of agents in the placement tree, which nests to any depth; there is no container object above the Crew. +**Definition integrity is checked where it is structured.** A Crew definition that references a Role that does not exist is a visible defect in the library before anyone spawns it. Prose counterpart mentions are never parsed or validated — that is a judgment task, and guessing at it is worse than not checking. -- **"You command what you brief"** (R21): whoever spawns and briefs a Crew commands it — spawning a Crew _for someone else_ is proxy management; instead, send the decision and brief to the future Captain, who spawns its own Crew. Placement = spawner, always; human-only re-parent is the sole exception. -- **Agents spawn Crews** (R16) — Captains running Crews without the human in the loop is the point. Crew _members_ cannot spawn Crews (R20, enforced in the tool surface): wanting more hands is an escalation to your Captain. -- **A Captain may archive the Crews directly under it** (R19) — the only agent-invocable archive; it triggers the same loud platform machinery as any archive. -- **Captains are never routers** (R22): any participant may message any participant; [the hierarchy carries decisions, never messages](../principles.md). -- UI: a Captain chip; its Crews render as collapsible groups. +### Captains -## Lifecycle: deliberately disposable +Any agent with Crews placed under it is a **Captain** — a derived, measured status, not a platform entity or a tier. The management layer is made of agents in the placement tree, which nests to any depth; there is no container above the Crew. -Crews archive **only as a unit** — members are never individually archived or replaced (R14). Rationale: agent death is usually recoverable (message them again), and an irrecoverably poisoned member has likely contaminated its Crewmates. Recovery is **respawn from the definition**: cheap, because a Background Crew's value lives in its definition and its durable artifacts (worktree, branch, PR), which survive the agents — the successor Crew picks up where the old one left off. Two platform rules make this safe: +- **The spawning agent is the Captain.** Whoever spawns and briefs a Crew commands it. Spawning a Crew _for_ someone else is proxy managemen. We do not do that. Instead, send the decision and the brief to the future Captain, who spawns its own Crew. +- **Agents spawn Crews.** Captains running Crews without the person in the loop is the point. Crew _members_ cannot spawn Crews — wanting more hands is an escalation to the Captain — and the tool refuses a member with an error naming that next step. +- **A Captain may archive the Crews directly under it** — the only agent-invoked archive, and it triggers the same loud machinery as any archive. Not grandchild Crews, not individual members, not solo agents. +- **Captains are never routers.** Any participant may message any participant; the hierarchy carries decisions, never messages. +- A Captain shows a Captain chip; its Crews render as collapsible groups. -- **Archive never destroys work** (R15): no worktrees, branches, or checkpoints deleted by default; workspace cleanup is a separate explicit act. -- **Archive is loud** (R1/R2): open Exchanges terminate with notices to every waiter, who can reopen against the successor with `regarding`. +### Lifecycle -## Archive and respawn are judgment moments — the platform composes nothing +Crews are deliberately disposable. They **archive only as a unit** — members are never individually archived or replaced — because an agent's death is usually recoverable by messaging it again, and an irrecoverably poisoned member has likely contaminated its crewmates. Recovery is **respawn from the definition**, which is cheap because a Background Crew's value lives in its definition and its durable artifacts — worktree, branch, pull request — which survive the agents. Two platform rules make this safe: archive never destroys work, and archive is loud, with every open Exchange ending in a notice to its waiter. -Settled in the item-3 session, from the poisoned-Crew scenario: +**Archive and respawn are judgment moments, and the platform never makes that decision itself.** Archiving a Crew with open Exchanges warns with the count and the list and requires confirmation; the expectation, carried in guidance rather than enforced, is that a Captain checks with the person and they plan together. The successor Crew gets a fresh brief written by whoever respawns it — where things stand, the state of the durable artifacts, what to do next. There is no auto-forwarded original brief, no generated summary, no transferred conversation, no inherited obligations, no auto-reopened asks; the archived Crew's brief, ledger and artifacts stay readable for the respawner to consult. -- **Archiving a Crew with open Exchanges warns loudly**: the archive action surfaces the count and the list (who is waiting, on what) and requires explicit confirmation. The expectation — carried in guidance at the moment of action, not enforced — is that a Captain in this situation **checks with the human**: they make a plan together (what happens to the open decision, who tells the waiters, what the successor needs) and implement it. -- **The successor Crew gets a fresh brief, written by the respawner**: where things stand, the state of the durable artifacts, what to do next. The platform does **not** compose it — no auto-forwarded original brief, no generated state summary, no transferred conversation history, no inherited obligations, no auto-reopened asks. Every one of those is a judgment call, and this is an extreme judgment task. -- What the platform does provide is **the record to consult while writing**: the archived Crew's brief, ledger, and artifacts remain readable forever (R11), and the surviving worktree/branch/PR are visible facts. +The platform ships the machinery — define, spawn, render, warn, archive. The Playbook a Crew follows and the Roles it contains are always the user's content: the PR Group is one Crew definition someone wrote, never the product's opinion. -## Platform and content +## Acceptance criteria -The platform ships the machinery — define, spawn, render, warn, archive. The Playbook a Crew executes and the Roles it contains are always the user's content: the PR Group is one Crew definition someone wrote, never the product's opinion. +### The definition -## Deferred (with reasons) +1. A Crew definition is a file the user can read, copy and share, naming the Roles it contains and their wiring; git is optional. +2. A Crew definition that references a Role that does not exist is shown as a defect in the library before spawn. +3. Prose in a Crew definition is never parsed or validated. -- **May Crew members spawn solo Peer Agents?** Deliberately open (Jackson, 2026-08-24) — worth deciding when Crews are being built and a real Crew's behavior is observable, difficult to discern before. Fixed context for whoever closes it: R20 (members cannot spawn Crews) is untouched either way; members' _Subagent_ use is unregulable by construction (glossary, ST4); provenance + placement mean a member-spawned Peer Agent would be visible and contained under the member — the prior-art hazard was invisibility, which no longer exists. Both positions are one-line rulings away. -- **Crew-spawn human UI**: owned by the implementing dev. One requirement recorded: it must be differentiated from solo Role spawn — a Crew is _launched_ as a unit with a brief, not started as a chat. -- **Technical design** (definition schema, wiring format, tool schemas, brief delivery mechanics): owned by the implementing dev, within these product rulings. +### The unit + +4. A Crew spawns as a unit, with membership fixed at spawn and counterpart references resolved at spawn. +5. A Crew lives in exactly one Squadron and renders as one node in the placement tree with its members beneath it. +6. A Crew is launched with a brief, and the launch surface is visibly different from starting a chat with a single agent. +7. Every Crew member can message any participant in the Squadron, and the Crew's contact with the person goes through the inbox or its Captain rather than chat. + +### Captains + +8. An agent with Crews placed under it shows a Captain chip, derived from placement and nothing else. +9. An agent can spawn a Crew from a user-provided definition within its own Squadron; the Crew is placed under the spawner. +10. A Crew member's attempt to spawn a Crew is refused with an error naming escalation to its Captain. +11. A Captain can archive a Crew placed directly under it; it cannot archive a grandchild Crew, a single member, or a solo agent. + +### Lifecycle + +12. A Crew archives only as a unit; no member can be archived or replaced individually. +13. Archiving a Crew never deletes a worktree, branch or checkpoint. +14. Archiving a Crew with open Exchanges shows the count and the list and requires confirmation; every waiter receives a notice. +15. A respawned Crew starts from the definition and the respawner's brief only; nothing from the archived Crew's conversation, obligations or asks is carried over automatically. +16. A Crew shows a drift indicator when any of its definition files changed since it was spawned. + +## Scenarios + +- **A pull-request Crew.** The user defines "PR Crew" — Builder, Reviewer, Sitter — with "escalate CI failures to your Builder" in the Sitter's wiring. A Captain in Billing Migration spawns it with a brief for one pull request; the three agents appear as one node under the Captain, the Sitter's reference already resolved to that Builder. (AC1, AC4, AC5, AC9) +- **More hands.** The Builder wants a helper Crew and tries to spawn one; the tool refuses and names escalation to the Captain. (AC10) +- **A poisoned Crew.** The Reviewer has gone wrong and confused its crewmates. The Captain archives the Crew; the dialog lists two open asks; the Captain confirms after checking with the user, writes a fresh brief from the surviving branch and pull request, and spawns a successor. (AC12, AC14, AC15) + +## History + +- 2026-08-21 — the concept: definition versus instance, archive as a unit, archive never destroys work, agents spawn Crews, one Squadron, Captains as derived status, Captain archive rights, members cannot spawn Crews, "you command what you brief", Captains never routers; former R12–R22 ([record](../design-review-2026-08-21.md)). "Team" retired as a word. +- 2026-08-23 — the product session: structured-only validation, archive and respawn as judgment moments with a fresh brief; former P-E and J1–J3 ([record](../../worklog/roles-crews-session-2026-08-23.md)). +- 2026-08-24 — whether Crew members may spawn solo Peer Agents is deliberately left open until Crews are built and a real Crew's behavior can be observed ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). +- 2026-09-08 — rewritten into the definition shape; "git-versioned" aligned with Roles ("git optional"); posture stated as a lean, not a rule. Former identifiers: R12 → AC1; R14 → AC12; R15 → AC13; R16 → AC9; R17 → AC4–AC5; R18 → AC8; R19 → AC11; R20 → AC10; R21, R22 → Captains; P-E → AC2–AC3; J1–J3 → AC14–AC15. The open question on members spawning solo Peer Agents stays open, recorded above. diff --git a/docs/j5/product/features/memos.md b/docs/j5/product/features/memos.md index 3b896f79395d..61e3e760a8a3 100644 --- a/docs/j5/product/features/memos.md +++ b/docs/j5/product/features/memos.md @@ -1,35 +1,57 @@ --- -title: "Memos — the agent backlog primitive" -kind: spec +title: "Memos" +kind: definition --- # Memos -Feature definition of record, extracted from the problems/goals doc 2026-08-22 (rulings R26, R31–R35 in `../design-review-2026-08-21.md`). The problems it answers (`../problems.md`): coordinators drop things they were supposed to raise later; "let's talk about that later" gets pushed out of context and lost; context is bad memory. +## Problem -## Why the inbox can't do this +An agent in a coordinating role is told "let's talk about that later," and the later never comes: the item is pushed out of its context by everything that happens next and is lost completely. Agents rely on their context as memory when they should be writing things down; a person steering many agents cannot see what each one still intends to do ([problems](../problems.md): "later" gets lost; context as bad memory; human attention). -The inbox is an **obligation queue** — every item blocks a sender, demands a reply, and naturally scales with the number of working agents. A backlog is a **non-blocking store** — nothing waits on it, which is exactly why it can grow without hurting anyone. Routing deferred items through the inbox converts non-blocking items into blocking ones and makes the attention problem worse: an inbox with 100 items hurts. Hence a separate primitive. +The inbox cannot hold this. The inbox is an obligation queue — every item blocks a sender and demands an answer, and it scales with the number of working agents. A backlog is the opposite: a non-blocking store that nothing waits on, which is exactly why it can grow without hurting anyone. Routing deferred items through the inbox turns non-blocking items into blocking ones and makes the attention problem worse. -## The Memo +## Definition -A **Memo** is a small self-addressed message an agent stores via a platform tool — smaller than a ticket, not expected to be worked immediately. Its context is then free to drop the item safely: the durable store remembers, not the context window. +A **Memo** is a small self-addressed note an agent keeps through the platform — smaller than a ticket, not expected to be worked immediately. Once written, the agent's context is free to drop the item safely: the durable store remembers, not the context window. -## Behavior +Every Memo is **visible to the person** — there are no private Memos. The person enters the backlog view with attention to spare, and steering an agent requires seeing everything it intends to do. -- **No per-turn injection.** Re-injecting the list every turn would trade one failure (forgotten notes) for another (context rot) — the back-burner is a feature. The platform's leverage is shaped like _build tools that make agents better, never systems that make them perfect_: the tool's existence makes usage likely; the UI makes lapses visible. -- **All Memos are visible to the user — no private Memos.** The user only enters this view with attention to spare, and steering an agent requires seeing everything it intends to do. -- **`resurface_after`** — the one platform-initiated re-injection: "page me after this time." Before the time, the Memo truly rests; after it, it returns stamped with measured time facts (R25). This field is what distinguishes a _deferral_ from a backlog item. -- **Promotion is deliberate.** When a deferred thing becomes a _now_ thing, the agent opens a real Exchange. Never automatic. -- Per-agent ownership; the owning agent resolves or drops its own Memos; evented like everything else. +A Memo may carry a **resurface time** — "page me after this time." That is the one platform-initiated re-injection: before the time the Memo truly rests; after it, it returns to the agent stamped with the measured time. This is what distinguishes a deferral from a backlog item. -## UI surfacing +**Promotion is deliberate.** When a deferred thing becomes a now thing, the agent opens a real Exchange. The platform never promotes a Memo on its own. -- A **backlog pane** on the dashboard: the pull-based view of all agents' Memos across the fleet — third sibling to the inbox and the observability views (shared UI allowed, shared data model never). -- A badge or status icon on agents whose backlog needs going through. -- A warning when the user is about to archive an agent with open Memos. -- A drawer in the chat for picking the next topic to discuss with that agent. +Memos are **per-agent**: the owning agent resolves or drops its own Memos, and every change is recorded. The person sees them all and nudges through ordinary messages. -## Scope position +The person's surfaces: a **backlog pane** — the pull-based view of all agents' Memos across the fleet, a sibling of the inbox and the Fleet page that may share their look but never their data model; an indicator on agents whose backlog needs going through; a warning when archiving an agent with open Memos; and a drawer in an agent's chat for picking the next topic to discuss with it. -Memos are the **v1 agent data primitive** — shaped, with clear access patterns (append, list-open, resolve, defer), per the platform boundary. A generic agent-provisionable store stays parked with its named trigger (R30/R34): revisit when cross-machine sync or repeated setup pain makes hand-rolled stores hurt. Backlog candidate, not yet prioritized. +Memos are the shaped **first agent data primitive** — append, list what is open, resolve, defer — and earn their place through those clear access patterns. A generic store that agents can provision for themselves is not part of this; it waits until cross-machine sync or repeated setup pain makes hand-rolled stores actually hurt. + +## Acceptance criteria + +### The Memo + +1. An agent can write a Memo, list its open Memos, resolve one, and set a resurface time on one, through platform tools. +2. A Memo is never delivered to its agent on a turn unless its resurface time has passed. +3. A Memo whose resurface time has passed is delivered to its agent once, stamped with the measured time. +4. Only the owning agent can resolve or drop a Memo, and every change is recorded in the ledger. +5. No Memo is ever promoted to an Exchange by the platform. + +### The person + +6. The backlog pane shows every agent's open Memos across the fleet, and no other kind of item. +7. Every Memo is visible to the person; there is no private Memo. +8. An agent with open Memos shows an indicator. +9. Archiving an agent with open Memos shows them in the archive dialog. +10. An agent's chat offers a drawer listing its open Memos as topics to discuss. + +## Scenarios + +- **"Later."** During an incident, the user tells the Captain in Support Rotation "let's talk about the logging improvements later." The Captain writes a Memo; the incident consumes its context; the Memo is untouched. That evening the user opens the Captain's chat drawer, sees "logging improvements", and picks it up. (AC1, AC2, AC7, AC10) +- **Page me.** An agent defers a check with a resurface time of two days; nothing happens for two days; then the Memo returns to the agent with the elapsed time stated, and the agent opens an ask to the user about it. (AC3, AC5) +- **Archiving with a backlog.** The user archives an agent that holds three open Memos; the dialog lists them before confirmation. (AC9) + +## History + +- 2026-08-22 — the concept, extracted from the problems and goals; former R26 and R31–R35 ([record](../design-review-2026-08-21.md)). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: R26 → Problem (why not the inbox); R31 → Definition (no per-turn injection), AC2; R32 → AC3; R33 → AC7; R34 → Definition (the first data primitive); R35 → AC4. The parked generic agent store (former R30) is recorded in the last Definition paragraph as not part of Memos. diff --git a/docs/j5/product/features/playbooks.md b/docs/j5/product/features/playbooks.md index bc93c5811b1e..1ed0a2b25e93 100644 --- a/docs/j5/product/features/playbooks.md +++ b/docs/j5/product/features/playbooks.md @@ -1,30 +1,40 @@ --- -title: "Playbooks — step-by-step work with fresh instructions and honest progress" -kind: spec +title: "Playbooks" +kind: definition --- # Playbooks -Feature definition of record. The problems it serves ([problems doc](../problems.md)): agents executing long playbooks forget later steps — they read them once at the beginning and the instructions decay into the context's back pages; and users can't see the progress of long-running work at a glance (spinners, not state). Ruling baked in: R27 in [the register](../design-review-2026-08-21.md). Backlog candidate, not yet prioritized. +## Problem -## The Playbook +An agent following a long procedure reads it once at the beginning and the later steps decay into the back pages of its context; by step nine it has forgotten what step nine said. A person watching long-running work cannot see progress at a glance — they see a spinner, not a state ([problems](../problems.md): context as bad memory; fleet observability). -A **Playbook** is user-authored, step-by-step content for a piece of work, targeted at either a single [Role](roles.md) or a [Crew](crews.md) — either can be spawned and prompted to follow one. In a Crew Playbook, each step carries **per-Role instruction blocks**: what the Builder does in this step, what the Sitter does. A single-agent Playbook is just the one-participant case. +## Definition -**The engine is platform; the steps are content** (the brief-container pattern). The platform never owns the flow — it holds the pointer, keeps instructions fresh, and renders progress. The steps, their content, and the decision that a step is done all belong to the user's Playbook and the agents executing it. This is how workflows like the PR Group's become _expressible_ on the platform without being codified into it. +A **Playbook** is user-authored, step-by-step content for a piece of work, aimed at either a single Role or a Crew; either can be spawned and told to follow one. In a Crew Playbook each step carries instructions per Role — what the Builder does in this step, what the Sitter does. A single-agent Playbook is the one-participant case. -## How it runs +**The engine is the platform's; the steps are the user's.** The platform holds the step pointer, keeps instructions fresh, and renders progress. The steps, their content, and the judgment that a step is done belong to the Playbook and the agents following it. This is how a workflow like the PR Group becomes expressible on the platform without being codified into it. -1. **An agent declares a step complete via tool call.** "What step are they on" is therefore a cheap, honest, _measured_ fact (with visible asserted-by-agent provenance) — never parsed from output, never inferred. Advancement is always agent-declared, never platform-judged ([facts, never judgment](../principles.md)). -2. **On advance, the platform delivers the next step's instructions to every participant** — each Role receiving its own instruction block for that step, fresh in context. This is what defeats the read-once-and-forget failure: instructions arrive when they're needed, not at turn one. -3. **The UI renders progress** from the step pointer: which step each Crew is on, at a glance — feeding the item-4 progress panes. +It runs in three moves. **An agent declares a step complete** through a tool call, so "what step are they on" is a cheap, honest, measured fact — asserted by the agent, visibly so, never parsed from output or inferred by the platform. **On advance, the platform delivers the next step's instructions to every participant**, each Role receiving its own block for that step, fresh in context; this is what defeats read-once-and-forget. **The interface renders progress** from the step pointer: which step each Crew is on, at a glance. -## Scope fences +Playbooks are linear sequences. The initiative-level view — a plan whose nodes are Crews' Playbook positions — is the same idea one level up and is designed as one family with it, but linear ships first. A Playbook is not a workflow engine: no platform-owned branching, retries or step-level automation. Where a step needs judgment, an agent judges. -- **Linear step sequences first.** The initiative-level milestone/DAG view is the same primitive one level up — a plan whose nodes are Crews' Playbook positions — designed as one family, shipped linear-first ([simple tools at the frontier](../principles.md)). -- **Skills-per-step is parked, unproven** — it needs the Roles skill story first, and observed need. -- A Playbook is not a workflow engine: no platform-owned branching, retries, or step-level automation. Where a step needs judgment, an agent judges. +## Acceptance criteria -## Open — for the Playbooks design session +1. A Playbook is a user-authored file the platform reads; it never generates or edits steps. +2. A Role or a Crew can be spawned with a Playbook and told to follow it. +3. An agent advances a Playbook by declaring a step complete through a tool call; the platform never advances a step on its own. +4. The current step of every agent and Crew following a Playbook is a recorded fact, attributed to the agent that declared it. +5. On advance, every participant receives its own instructions for the new step in its context. +6. The interface shows which step each Crew and agent is on. +7. A Playbook has no branching, retry, or automation owned by the platform. -The step/instruction-block schema; how Playbooks attach at spawn (the Role/Crew definition's Playbook reference); the delivery channel for step advancement (relation to the envelope pipeline); the initiative-level view's shape; what "step declared complete by one member vs. the Crew" means for multi-agent steps. +## Scenarios + +- **A release Playbook.** The user writes a five-step release Playbook with per-Role blocks and launches a Crew in Website Redesign with it. The Fleet page shows "step 2 of 5". When the Builder declares step 2 complete, the Sitter's next turn opens with its step-3 instructions. (AC2, AC3, AC5, AC6) +- **A judgment step.** Step 4 says "decide whether the migration is safe to run"; the platform delivers the instruction and waits — the agent decides, and declares. (AC3, AC7) + +## History + +- 2026-08-22 — the concept; former R27 ([record](../design-review-2026-08-21.md)). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: R27(a) → AC3–AC4; R27(b) → Definition (linear first); R27(c), skills per step → not part of the definition, parked. The questions for the Playbooks design session — the step schema, how a Playbook attaches at spawn, the delivery channel for step advancement, the initiative-level view, what "declared complete" means for a multi-agent step — are that session's, not this definition's. diff --git a/docs/j5/product/features/roles.md b/docs/j5/product/features/roles.md index a5a0b76be146..83229fe2bd9e 100644 --- a/docs/j5/product/features/roles.md +++ b/docs/j5/product/features/roles.md @@ -1,56 +1,77 @@ --- -title: "Roles — reusable agent definitions in platform tooling" -kind: spec +title: "Roles" +kind: definition --- # Roles -Feature definition of record. The problems and goals it serves ([problems doc](../problems.md)): fleets naturally end up with many agents performing the same type of job, and managing those definitions today means self-built solutions — Jackson built one for the prior-art fleets and managing it was a mess. Rulings baked in: R8, R28 in [the register](../design-review-2026-08-21.md), plus the item-3 product session ([worklog record](../../worklog/roles-crews-session-2026-08-23.md)). +## Problem -## The Role +A fleet ends up with many agents doing the same kind of job — reviewers, sitters, builders, monitors. Without a reusable definition, every one of them is set up by hand, drifts from the others, and cannot be handed to another person or another agent to spawn. The user who ran the prior-art fleet built a definition system themselves, and managing it was a mess ([problems](../problems.md): Roles defined in platform tooling). Agents also spawn agents, and an agent choosing a kind of helper for the user's budget needs something better than a guess. -A **Role** is a reusable, user-authored definition of a kind of agent. It defines: +## Definition -- **A required one-line purpose** — the sentence that answers "what is this kind of agent for." It serves both pickers (human dropdown and agent tool listing); a Role without it is not spawnable-by-choice, only by accident. -- **Identity content in two sections**, both plain markdown, both persistent in the agent's context for its whole life: - - **Identity** — who this agent is: values, voice, standing norms. The part the user lets solidify and rarely edits. - - **Operating Principles** — how it works at a high level: principles, what it looks for and does in general. Evolves with the user's methodology. - - There is deliberately **no prompt in the definition** — the spawner's brief is the prompt, written per instance. Step-by-step operation belongs to [Playbooks](playbooks.md), not the Role. -- **A model and reasoning-level allowlist** — so agents that spawn other agents with Roles choose the right ones. Ordered; the first entry is the default. -- **A skill allowlist** — the set of skills exposed to the agent. This is the platform-only part: nobody can gate an agent's tool surface from a markdown file. -- **Posture on the [human-contact spectrum](../principles.md)** — Foreground or Background, so the agent's communication norms are set at spawn. +A **Role** is a reusable, user-authored definition of a kind of agent. It is the user's content — a file, portable and shareable — that the platform reads so that spawning the right kind of agent is easy for people and for agents alike. -Roles make it easy for users _and agents_ to spawn the right kind of agent for a task. A Role is spawnable solo, or composed into a [Crew definition](crews.md) as one of its seats. +A Role defines: -## Authoring: the app is an editing surface +- **A one-line purpose** — the sentence that answers "what is this kind of agent for." It serves every picker, human and agent; a Role without one cannot be chosen deliberately. +- **Identity content**, in two plain-markdown sections that stay in the agent's context for its whole life: **Identity** (who this agent is — values, voice, standing norms; the part that solidifies and is rarely edited) and **Operating Principles** (how it works at a high level; the part that evolves with the user's practice). There is deliberately **no prompt in the definition**: the spawner's brief is the prompt, written per instance, and step-by-step operation belongs to a Playbook. +- **A model and reasoning allowlist**, ordered. It constrains the choice at spawn; it never chooses silently for an agent. +- **A skill allowlist** — the skills exposed to the agent. This is the one part only the platform can enforce: nobody can gate a tool surface from a markdown file. +- **A posture on the human-contact spectrum** — how much this kind of agent talks with the person through chat, from Foreground to Background, with the middle allowed — so its communication norms are set at spawn. -Users author and edit Roles **in the app** — a simple markdown editing surface; nobody is pushed out to an external editor to participate. The substance remains **files** (R28): portable, shareable, versionable however the user wants. Git is **optional** — a plain folder works with everything except the git UI; users who point the library at a git repo get exactly three operations in-app — **commit, push, pull** — plus nudges ("you have uncommitted Role changes", "remote is ahead"). Anything difficult — merge conflicts, failed pushes — punts to the user's editor with the error shown (the app already opens it in one click). This is deliberately not a differentiator; minimal effort, forever. One library location in v1 (a default path, configurable); multiple sources are deferred until wanted. +Roles are authored and edited **in the app**, in a simple markdown editing surface; nobody is pushed out to an external editor to participate. The files remain the substance. Git is optional: a plain folder works with everything except the git controls, and a library pointed at a git repository gets exactly three operations — commit, push, pull — plus nudges when there are uncommitted changes or the remote is ahead. Anything difficult, such as a conflict or a failed push, goes to the user's editor with the error shown. This is deliberately not a differentiator. One library location, configurable. -The **Role Library** view lists every definition with its purpose, posture, and where it's in use ("3 agents running, 1 Crew references this"). **No memory in the bundle** (R8): provider memory is accepted as non-portable local seasoning; what an agent must never forget belongs in its definition. +The **Role Library** lists every Role with its purpose, its posture, and where it is in use. No memory travels in a Role: provider memory is accepted as non-portable local seasoning; what an agent must never forget belongs in its definition. -## Spawning with a Role +**Spawning with a Role.** A person picks a Role in the composer's Role dropdown (none selected by default — plain agents remain the default path); selecting one constrains the model and reasoning selectors to the allowlist, with disallowed entries visible but disabled and labeled with the Role that excludes them, and switches an invalid current model to the first allowed one with a visible cue. The spawned thread carries a Role chip. An agent picks a Role from the spawn listing, which shows each Role's purpose, posture and cost tier, because the choosing agent decides on the person's behalf and budget; provider, model and reasoning stay explicit on every agent spawn, constrained by the allowlist and never defaulted for it. A Role is spawnable solo or composed into a Crew. -**Human — folded into the existing new-chat composer:** a Role dropdown below the worktree row, **none selected by default** (plain agents remain the default path). Selecting a Role: +**Editing a definition never silently changes a running agent.** New spawns get the new definition; running agents keep what they absorbed. What the platform owes is visibility: every agent, and every Crew as a unit, shows a measured **drift** indicator when its definition has changed since it was spawned. The remedy — respawn, or message the agent — is always a person's or Captain's judgment. -- **constrains** the model and effort selectors to the Role's allowlist — disallowed entries stay visible but disabled, labeled with the Role that excludes them (impossible to re-select into an invalid state); -- **auto-switches** the current model to the first allowlisted one if it's invalid — with a visible cue on the model chip (the change must be watched, not discovered); -- shows each Role in the dropdown as name + one-line purpose. +A Role is **not** a runtime object (the agent is), **not** a permission boundary beyond skill gating, and **not** a behavior guarantee: it raises the odds and sets expectations; behavior remains a prompting matter. Prose in a Role ("escalate to your Builder") is never parsed or validated. -The spawned thread carries a **Role chip**. Crew spawning is a **separate surface** (a Crew is launched, not chatted with) — its human UI is deferred to the implementing dev, with the differentiation requirement recorded. +## Acceptance criteria -**Agent — the spawn tool listing** shows purpose + posture + cost tier per Role, because the choosing agent decides on the user's behalf and budget. +### The definition -## Definition changes and drift +1. A Role is a file the user can read, copy, and share; the platform reads it and never rewrites it. +2. A Role has a required one-line purpose; a Role without one is not offered by any picker. +3. A Role's identity content is two markdown sections, Identity and Operating Principles, and both are present in the agent's context for its whole life. +4. A Role contains no prompt; the spawner's brief is the first-turn prompt. +5. A Role's model and reasoning allowlist is ordered, and its skill allowlist is enforced by the platform at spawn. +6. A Role declares a posture on the human-contact spectrum, and the spawned agent's communication norms follow it. -**Editing a definition never silently changes a running agent.** New spawns get the new definition; running agents keep what they absorbed — anything else lies about how agents work. What the platform owes instead is visibility: every agent (and Crew, as a unit — any of its definition files) shows a measured **drift indicator** when its definition has changed since spawn. The remedy — respawn, or message the agent — is always human/Captain judgment. +### Authoring -## What a Role is not +7. Roles can be created and edited in the app; the app never requires an external editor for ordinary editing. +8. A library in a plain folder works for everything except the git controls; a library in a git repository offers commit, push and pull and nothing else, and surfaces uncommitted changes and a remote that is ahead. +9. A git operation that fails or conflicts opens the user's editor with the error shown. +10. The Role Library shows every Role's purpose, posture, and current use (agents running, Crews referencing it). -Not a runtime object (the agent is), not a permission boundary beyond skill gating, and not a behavior guarantee — a Role raises the odds and sets expectations ([tools, not guarantees](../principles.md)); behavior remains a prompting problem. Prose in a Role ("escalate to your Builder") is never parsed or validated — wiring correctness at the prose level is a prompting concern. +### Spawning -## Deferred (with reasons) +11. The composer's Role dropdown selects no Role by default and shows each Role as name plus purpose. +12. Selecting a Role in the composer disables disallowed models and reasoning levels, labels each with the Role that excludes it, and switches an invalid current selection to the first allowed entry with a visible cue. +13. The spawned thread carries a Role chip. +14. An agent's spawn listing shows each Role's purpose, posture and cost tier; an agent spawn with a Role still names provider, model and reasoning explicitly, and a choice outside the allowlist is refused naming the Role. -- **Role claims** (Traycer's runtime self-designation): seats inside Crews make responsibility explicit; the loose-agent duplication problem hasn't been observed on-platform. Revisit on evidence. -- **Multiple library locations** (per-project, shared team libraries): extend when wanted. -- **In-app advanced git**: never — the editor owns it. -- **Technical design** (file format, discovery mechanics, tool schemas): owned by the implementing dev, within these product rulings. +### Change + +15. Editing a Role never changes a running agent. +16. An agent whose Role file changed since it was spawned shows a drift indicator; a Crew shows one when any of its definition files changed. +17. Prose in a Role is never parsed or validated. + +## Scenarios + +- **A reviewer Role.** The user writes "Reviewer" — purpose "reviews other agents' pull requests for correctness", Identity and Operating Principles, an allowlist of two frontier models at high reasoning, review-oriented skills, Background posture. In the composer they pick Reviewer; the cheap model they had selected is disabled and labeled "excluded by Reviewer", the first allowed model is selected with a cue, and the new thread wears a Reviewer chip. (AC2, AC6, AC11–AC13) +- **An agent spawns a helper.** A Captain in Billing Migration reads the spawn listing — Reviewer: purpose, Background, high cost tier — and spawns one, naming provider, model and reasoning within the allowlist. (AC14) +- **A definition changes underfoot.** The user tightens Reviewer's Operating Principles while two Reviewers are running; both show drift; the user respawns one and leaves the other to finish. (AC15, AC16) +- **A plain folder.** The user keeps Roles in a folder with no git; everything works and the git controls are simply absent. (AC8) + +## History + +- 2026-08-21 — identity is git-versioned definition files with no memory in the bundle; machine-read fields wrap the prose (former R8, R28; posture rider of former R23) ([record](../design-review-2026-08-21.md)). +- 2026-08-23 — the product session: app as editing surface, composer Role dropdown, two-section identity with no prompt, drift never hot-reloads, structured-only validation, minimal in-app git; former P-A–P-F ([record](../../worklog/roles-crews-session-2026-08-23.md)). +- 2026-08-30 — provider, model and reasoning stay explicit on agent spawns even with a Role; the allowlist constrains ([record](../../worklog/spawning-guide-session-2026-08-30.md)). +- 2026-09-08 — rewritten into the definition shape; posture stated with the middle of the spectrum allowed, matching the lens. Former identifiers: R8 → AC1, Definition (no memory); R28 → AC1, AC5; P-A, P-F → AC7–AC9; P-B(h) → AC11–AC13; P-B(a) → AC14; P-C → AC3–AC4; P-D → AC15–AC16; P-E → AC17. Deferred items that lived here (Role claims, multiple library locations) are backlog candidates. diff --git a/docs/j5/product/features/shared-squadrons.md b/docs/j5/product/features/shared-squadrons.md index 207b87b1e99c..c2402c609ffc 100644 --- a/docs/j5/product/features/shared-squadrons.md +++ b/docs/j5/product/features/shared-squadrons.md @@ -1,37 +1,44 @@ --- -title: "Shared Squadrons — multiple people, one server" -kind: spec +title: "Shared Squadrons" +kind: definition --- # Shared Squadrons -Feature definition of record for the multi-user capability. The goal it serves ([problems doc](../problems.md), [use cases 2a](../use-cases.md)): a team shares Squadrons — when one person goes off shift, the next picks up the Squadron immediately with **no context transfer**; and two humans stand in front of the same agent, removing the Slack/Teams relay from human↔human↔agent workflows. Rulings baked in: R9 and R29 in [the register](../design-review-2026-08-21.md). Backlog candidate — likely post-item-4 (the fleet must be observable by one person before it's shareable between several), and a **deep architecture session is required before any build**. +## Problem -## What this is — and the two things it is not +As agents do more of the work, the need to share them between people grows. A level-2 support team hands a Squadron from one shift to the next and wants **no context transfer**. Two developers already relay agent output to each other over chat — one asks their agent, pastes the answer to the other — and would rather stand in front of the same agent together ([problems](../problems.md): Shared Squadrons; [use cases](../use-cases.md)). -Shared Squadrons is a **distinct third capability** in the cross-machine space: +## Definition -| Capability | Shape | Where it's defined | -| -------------------- | ----------------------------------------------------------------------- | -------------------------------------------------- | -| Cross-device | one person, several servers; read-models merge in the client | [cross-device position](../cross-device.md), X1–X5 | -| Federation | two people's _servers_ exchange messages via the peer registry | X4 — the designated cross-person seam | -| **Shared Squadrons** | **several people on one server, sharing the same Squadrons and agents** | this document | +**Shared Squadrons** is several people on one server sharing the same Squadrons and the same agents. It is one of three distinct capabilities in the multi-machine, multi-person space, and the only one where no state crosses machines and no server peers with another: -Neither of the other two answers it: no state crosses machines here, and no peering is involved. It's multi-user, co-located. +| Capability | Shape | Defined in | +| -------------------- | ---------------------------------------------------------------- | ---------------------------------- | +| Cross-device | one person, several servers; views merge in the client | [cross-device](../cross-device.md) | +| Federation | two people's servers exchange messages through the peer registry | [cross-device](../cross-device.md) | +| **Shared Squadrons** | **several people on one server, sharing Squadrons and agents** | this document | -## Settled now, binding now +Two constraints are in force **now**, on everything built, because retrofitting multiple people onto single-person assumptions is the expensive path this avoids: -These constraints are in force **today**, on everything built from here on — retrofitting multi-user onto singleton assumptions is the expensive path this avoids: +- **Nothing may assume exactly one person.** Every person-facing surface — the inbox, the backlog pane, notifications, addressing — is scoped to a person, never to "the user." +- **Every person has a durable person id**, minted locally at first run and carried on every ledger row and envelope. External authentication binds to that id later; the id is stable without being authenticated, which is what keeps login deferred today. Where the binding happens is a later design. +- **An agent addresses a specific person or every person on the server.** There is no group management: one server has a practical ceiling on people and work, and groups are complexity with no identified need. -- **The multi-human invariant** (R29): nothing may assume exactly one human. Every human-facing surface — inbox, backlog pane, notifications, addressing — is person-scoped, never singleton-scoped. -- **Person ids** (R9): every ledger row and envelope carries a durable local person id (`human:`). External auth (e.g. Clerk) _binds to_ the existing id later, at whichever seam the architecture session lands on — the id is stable without being authenticated, which is what keeps app login deferred today. -- **Delivery targets are one user or all users** (R29): an agent addresses a specific person, or every person on the server. **No human group management** — one server has a practical ceiling on people and work, and group semantics are complexity with no identified need. +Doors deliberately left open and undesigned: addressing a _duty_ rather than a person ("the on-call", resolving to whoever holds it now); two people in one agent conversation, presence, and per-person attribution in shared chats. -## Recorded doors (open, deliberately undesigned) +## Acceptance criteria -- **Duty-based addressing**: shift work implies exchanges addressed to a _duty_ rather than a person — "the on-call," resolving to whoever holds the duty now. Written on the door next to external-systems-as-nodes; not designed. -- Multi-user chat mechanics (two people in one agent conversation), presence, and per-person attribution in shared chats — the architecture session's territory. +1. No surface, projection or tool assumes exactly one person; each is scoped by person id. +2. Every ledger row and envelope carries the person id of any person it involves. +3. An ask can be addressed to one person or to every person on the server, and to nothing in between. +4. A person's id is stable across restarts and does not depend on authentication. -## What the architecture session must answer +## Scenarios -How multiple authenticated people attach to one server (auth binding, transport, T3's single-user assumptions); attribution and read-state in shared surfaces; what "all users" delivery means for the inbox model; whether shift handoff needs any state beyond what person-scoped surfaces already give. Until that session, this document is the vision plus the invariants — nothing more is designed. +- **Shift handoff.** The on-shift engineer for Support Rotation goes home; the next engineer opens the same server, sees the same Squadron, the same agents, and the same open asks in their own inbox, and continues without a handover conversation. (AC1, AC3) + +## History + +- 2026-08-22 — the multi-person invariant and person ids ruled binding now; the capability defined and set apart from cross-device and federation; former R9, R29, and the cross-device position ([record](../design-review-2026-08-21.md)). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: R9 → AC2, AC4; R29 → AC1, AC3. The architecture session this capability needs before any build — how several authenticated people attach to one server, attribution and read state in shared surfaces, what "every person" delivery means for the inbox — is that session's agenda, not this definition's. diff --git a/docs/j5/product/features/spawning-guide.md b/docs/j5/product/features/spawning-guide.md index 8bec938a8cf5..b60d22511194 100644 --- a/docs/j5/product/features/spawning-guide.md +++ b/docs/j5/product/features/spawning-guide.md @@ -1,78 +1,46 @@ --- -title: "The Spawning Guide — selection and brief guidance for whoever spawns" -kind: spec +title: "Spawning Guide" +kind: definition --- -# The Spawning Guide +# Spawning Guide -Feature definition of record ([worklog record](../../worklog/spawning-guide-session-2026-08-30.md)). Origin: the rebuilt `spawn_agent` contract ([agent-tools.md](../a2a/agent-tools.md), PR #15) makes provider/model/reasoning **required** on every Peer Agent spawn (Jackson, 2026-08-29: inheriting the spawner's setup is wrong more often than right) — which turns every spawn into an explicit choice, and an explicit choice needs somewhere to learn from. That contract carries a come-back note reserving exactly this territory; this document closes it. +## Problem -Prior art is Jackson's own fleet ([interview synthesis](../../research/jackson-prior-art/fleet-interviews-synthesis.md)): its selection guide was the department's **main cost instrument**, updated mid-program from observed need (the Sitter tier change — identical mechanical reliability on the cheaper tier, at the cost of channel noise; a real, measured tradeoff). Its one recorded failure was **silence**: a spawner had to pick a tier the guide didn't cover, and the retro judged the gap itself worth a line. Traycer's agent selection guide is the same mechanism in the wild — guidance the spawn tooling tells you to read before creating an agent. +Every Peer Agent spawn is an explicit choice of provider, model and reasoning — the platform never inherits the spawner's setup, because inheriting is wrong more often than right — and an explicit choice needs somewhere to learn from. The prior-art fleet ran on exactly such a guide: it was the operation's main cost instrument, updated mid-program from observed need, and its one recorded failure was silence — a spawner had to pick a tier the guide did not cover, and the retrospective judged the gap itself worth a line. Agents that spawn agents also write briefs, and a bad brief is the most expensive mistake a spawner can make ([problems](../problems.md): what is this fleet costing me; large unsupervised groups). -## SP1 — Ownership split: platform ships mechanism, user ships judgment +## Definition -- The guide is **user-authored markdown**, living with the Role library (same substance rules as Roles, R28: a file — portable, shareable, git optional; edited in-app like any library content). One guide in v1. -- The **platform's layer is factual**: the provider/model/reasoning catalog is platform truth (`orchestrator_capabilities` — ids, labels, option descriptors, cost tiers where known). The guide never restates the catalog; it **assigns it to kinds of work**. The judgment layer — which tier for which work — is the user's, evolved from observed need the way Jackson's fleet evolved theirs. -- The **spawn surface points at the guide**: `spawn_agent`'s contract directs the spawner to consult it before choosing. How it is delivered to the agent (tool, listing, resource) is technical design, dev-owned. Humans read it where they read everything else in the library. -- Any example guide the product ships is **user-space content, never the product's opinion** — the same law that governs Playbooks and the PR Group Crew definition. +The **Spawning Guide** is a user-authored document consulted at the moment of spawning. The platform ships the mechanism and the facts; the user ships the judgment. -## SP2 — Scope: two sections, deliberately no third +- The guide is markdown that lives with the Role library, under the same rules as a Role: a file, portable and shareable, git optional, edited in the app. One guide per library. +- The platform's layer is factual: the catalog of providers, models and reasoning levels — ids, labels, options, cost tiers where known — is platform truth. The guide never restates the catalog; it assigns it to kinds of work. +- The spawn surface points at the guide: the spawn tool tells a spawner to consult it before choosing. People read it where they read everything else in the library. +- Any example guide the product ships is user-space content, never the product's opinion. -1. **Selection guidance** — which provider, model, and reasoning effort for which kinds of work, and which Role to reach for when one fits. This is the user's cost instrument. The quality bar comes from the prior art: tier guidance earns its place by **observed behavior per tier**, not vibes — and a good guide **states what it does not cover**, so a spawner facing a gap knows to flag it rather than guess (never-guess applies to guide readers too). -2. **Brief conventions** — what a good first-turn brief contains. This includes the **report-back contract**: the brief itself states what the spawn reports and when (completion, blockers, decision points). When you spawn, you hear back when your brief says you will — the contract travels in the brief, not in platform law. +The guide has two sections. -**Communication norms are deliberately not in the guide** (Jackson, 2026-08-30). How agents converse after spawn is governed by A2A law (Exchanges, delivery receipts, typed silence) and by operator content (Role Operating Principles, Playbooks). The guide governs the moment of spawning; it does not regulate the relationship afterward. +**Selection guidance**: which provider, model and reasoning effort for which kinds of work, and which Role to reach for when one fits. This is the user's cost instrument. Tier guidance earns its place by observed behavior per tier, and a good guide states what it does not cover, so a spawner facing a gap flags it rather than guessing. -## SP3 — Roles compose, never collide +**Brief conventions**: what a good first-turn brief contains — including the report-back contract, so the brief itself says what the spawn reports and when. When you spawn, you hear back when your brief says you will; the contract travels in the brief, not in platform law. The spawn tool's only coaching is one sentence reminding the spawner to write it. -Provider/model/reasoning stay **required and explicit** on every agent-invoked spawn, Role or no Role. A Role's allowlist **constrains** the required choice (an out-of-list pick is an error naming the Role that excludes it); it never silently substitutes a default on the tool surface. The human composer keeps its ruled behavior unchanged ([roles.md](roles.md): first allowlisted entry as visible-cue default). The guide's territory is what the allowlist cannot decide: role-less spawns, and **which Role to pick** — cross-Role comparison lives here, complementing the per-Role purpose/posture/cost-tier the spawn listing already carries. +Roles compose with the guide rather than replacing it: with a Role, the allowlist constrains the required choice; the guide governs role-less spawns and _which Role to pick_. -## SP4 — Closing `spawn_agent`'s held slot _(settled 2026-08-30, as amended by Jackson)_ +## Acceptance criteria -The contract's come-back note deliberately left the description with "no spawn-then-ask steering until that guide rules." Ruled: +1. The Spawning Guide is a user-authored file in the Role library, editable in the app, with git optional. +2. The spawn tool's description directs the spawner to consult the guide before choosing provider, model and reasoning. +3. The platform provides the provider, model and reasoning catalog as facts; the guide is never the source of that catalog. +4. A spawn without an explicit provider, model and reasoning is refused; nothing is inherited from the spawner. +5. Any example guide shipped with the product is marked as user-space content. -- **The description gains exactly one sentence of brief steering** (Jackson's amendment to the proposed empty closure): _"In your brief, tell the new agent what it should do first and whether it should reply to you."_ The report-back contract still travels in the brief (SP2.2) — the tool's only coaching is the reminder to write it. Folding the sentence into the contract is with the Architecture agent (the `agent-tools.md` owner); the implementation string change rides wherever that contract lands. -- **There is no spawn-then-ask sequence.** The initial brief carries the task and whether and what reply is expected. A reply-expected `send_message` opens an Exchange only for later work owed by an existing participant. -- **Receipt-ACKs: nothing is written anywhere.** The platform measures delivery (ledger receipts) — a social "got it" message is structurally redundant, and the prior-art fleet had to ban exactly that noise once courtesy-acks took hold. If ack noise appears in dogfood, the remedy is a line in the _user's_ guide then, added from observed need — not platform law now. -- **Mid-first-turn delivery mechanics** (what happens when a send lands while a fresh spawn is still working its brief) are A2A delivery design — the Architecture lane's question, never guide content. +## Scenarios -## Requirements on landing +- **A gap in the guide.** A Captain in Billing Migration needs a long-context research helper; the guide's selection table has no row for it and says so under "not covered"; the Captain picks conservatively, says so in its thread, and the user adds a row that evening. (AC2, AC3) +- **Retuning a tier.** The user moves mechanical watch-and-report work to a cheaper tier after observing identical reliability and only more narration; the guide changes; nothing in the product does. (AC1) -- The build that ships the guide mechanism **must update the `spawn_agent` contract in [agent-tools.md](../a2a/agent-tools.md) and the tool implementation together** — the come-back note is closed by this feature, not orphaned. -- **This feature does not block PR #15** (Jackson, 2026-08-29, via the Architecture agent). +## History -## Example guide (user-space content — a seed for Jackson to edit, not a spec) - -The shape below is seeded from the prior-art fleet's observed guide behavior. Everything in it is the user's judgment to change. - -```markdown -# Spawning guide — - -## Selection - -| Kind of work | Provider/model | Reasoning | Why (observed) | -| ----------------------------------------------------------- | ---------------- | --------- | ----------------------------------------------------- | -| Review, judgment calls, anything that rules on others' work | | high | Misses at lower tiers showed up in re-review cost | -| Building against a written spec | | medium | Equal outcomes to frontier on spec'd work; cheaper | -| Mechanical watch/report loops (sitter-shaped) | | low | Identical reliability; narrates more — accepted noise | - -Role-ful spawns: pick from the Role's allowlist; first entry unless the task says otherwise. - -## Not covered (flag it, don't guess) - -Long-context research tiers; anything security-sensitive. If your work isn't on this table, -say so in your thread and pick conservatively — the gap is guide feedback. - -## Brief conventions - -- Lead with intent — why this work exists, not only what to do. -- Tag what you know as measured vs inferred; the spawn cannot tell the difference otherwise. -- Rules that must survive the spawn's whole life go in the brief explicitly. -- State the report-back contract: what to report, when (completion, blockers, decision points). -- Record traps as open questions in the brief, never as silent assumptions. -``` - -## Deferred (with reasons) - -- **Per-Squadron or per-Crew guide overlays**: one guide in v1, like one Role library location — extend when wanted. -- **Technical design** (file discovery, how the guide reaches the spawning agent, capabilities cost-tier plumbing): owned by the implementing dev, within these rulings. +- 2026-08-29 — provider, model and reasoning become required on every spawn. +- 2026-08-30 — the guide defined: ownership split, two sections, Roles compose, one sentence of brief steering in the spawn tool; former SP1–SP4 ([record](../../worklog/spawning-guide-session-2026-08-30.md)). +- 2026-09-08 — rewritten into the definition shape. Former identifiers: SP1 → Definition (ownership), AC1–AC3, AC5; SP2 → Definition (two sections); SP3 → Definition (Roles compose), AC4; SP4 → Definition (brief conventions; acknowledgements). The example guide that lived in this document is user-space content and belongs with the example Role library, not in a definition. From e1f3314c49e83a99f144d802d726a8fbb589daba Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Thu, 10 Sep 2026 20:16:04 -0400 Subject: [PATCH 10/15] docs(j5): dogfood plan consolidated under plans/; decision log, design review and backlog become records; principles' cases point at definitions by name; GitHub milestones carry the backlog Co-Authored-By: Claude Fable 5.1 --- docs/j5/README.md | 4 +- docs/j5/backlog.md | 37 -------- docs/j5/dogfood-runtime.md | 2 +- docs/j5/plans/dogfood-v0.md | 56 ++++++++++++ docs/j5/product/a2a/index.md | 2 +- docs/j5/product/decision-log.md | 38 -------- docs/j5/product/design-review-2026-08-21.md | 63 ------------- docs/j5/product/dogfood-v0.md | 24 ----- docs/j5/product/features/archive-flow.md | 2 +- docs/j5/product/features/crews.md | 2 +- docs/j5/product/features/memos.md | 2 +- docs/j5/product/features/playbooks.md | 2 +- docs/j5/product/features/roles.md | 2 +- docs/j5/product/features/shared-squadrons.md | 2 +- docs/j5/product/features/squadron.md | 2 +- docs/j5/product/principles.md | 18 ++-- docs/j5/product/problems.md | 2 +- docs/j5/research/synthesis.md | 4 +- docs/j5/worklog/2026-08-14-backlog.md | 6 ++ docs/j5/worklog/2026-08-14-decision-log.md | 6 ++ docs/j5/worklog/2026-08-21-design-review.md | 6 ++ .../a2a-tickets/a10-silence-fact-bundles.md | 2 +- docs/j5/worklog/a2a-tickets/a4-human-node.md | 2 +- .../worklog/a2a-tickets/a5-graph-read-api.md | 2 +- .../a2a-tickets/a8-envelope-true-up.md | 2 +- .../a2a-tickets/a9-lifecycle-closure.md | 2 +- .../dogfood-tickets/b1-inbox-true-up.md | 2 +- .../e7-squadron-picker-conversion.md | 2 +- .../dogfood-tickets/sq1-creation-surface.md | 2 +- docs/j5/worklog/dogfood-v0.md | 90 ------------------- docs/j5/worklog/priority-input-2026-08-30.md | 2 +- 31 files changed, 106 insertions(+), 284 deletions(-) delete mode 100644 docs/j5/backlog.md create mode 100644 docs/j5/plans/dogfood-v0.md delete mode 100644 docs/j5/product/decision-log.md delete mode 100644 docs/j5/product/design-review-2026-08-21.md delete mode 100644 docs/j5/product/dogfood-v0.md create mode 100644 docs/j5/worklog/2026-08-14-backlog.md create mode 100644 docs/j5/worklog/2026-08-14-decision-log.md create mode 100644 docs/j5/worklog/2026-08-21-design-review.md delete mode 100644 docs/j5/worklog/dogfood-v0.md diff --git a/docs/j5/README.md b/docs/j5/README.md index f3da48c7465e..c7bc69fe2ab7 100644 --- a/docs/j5/README.md +++ b/docs/j5/README.md @@ -30,7 +30,7 @@ matches the workspace's folder structure — content, not paths, is what mirrors 6. `research/jackson-prior-art/fleet-interviews-synthesis.md` — field lessons from a real production agent fleet, and the platform/non-platform boundary that governs scope decisions. -7. `product/decision-log.md` — every settled product decision, one row each. +7. `worklog/2026-08-14-decision-log.md` — every settled product decision, one row each. 8. `product/a2a/` — the A2A (agent-to-agent communication) design: decision register, grounding model, and `plan.md` with the milestone plan. 9. `product/features/` — the feature definitions of record: Squadrons, Crews, @@ -38,7 +38,7 @@ matches the workspace's folder structure — content, not paths, is what mirrors ## Contents -- `backlog.md` — the prioritized roadmap. +- `worklog/2026-08-14-backlog.md` — the prioritized roadmap. - `product/features/` — feature definitions of record: `squadron.md`, `crews.md`, `roles.md`, `playbooks.md`, `memos.md`, `shared-squadrons.md`, `pr-pane.md`. diff --git a/docs/j5/backlog.md b/docs/j5/backlog.md deleted file mode 100644 index 0beb0f97c8f1..000000000000 --- a/docs/j5/backlog.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "Prioritized backlog (Jackson, 2026-08-14)" -kind: story -status: 1 ---- - -# Prioritized backlog - -Decision of record: **fork T3 Code from the orchestration-v2 branch** (`t3code/codex-turn-mapping`; rationale in `research/t3code/fork-viability.md` + `research/synthesis.md`). Priorities set by Jackson 2026-08-14: - -## 1. Fork & setup app ✅ _(complete 2026-08-15 — plan + evidence at `worklog/fork-setup-plan/index.md`)_ - -Delivered: public fork `Jacksondr5/j5code` (`j5/main` @ `e7597dac8`), pnpm/fnm/Rust-1.95 toolchain recorded, zero-failure 8,598-test baseline, J5 Code rebrand with empirically verified state isolation from installed T3, CI gates + weekly full-build, installed ad-hoc DMG (`/Applications/J5 Code.app`), relay/PlanetScale confirmed skippable, and a 30-agent load test PASS (30-thread dispatch p50 0.7 ms, +5.6 MiB RSS) with a reusable harness at `scripts/j5/fleet-load.sh`. Providers ready day one: Codex, Claude Agent. - -## 2. A2A communication - -Spawn peer agents, communication layer, inbox, communication graph. Steal targets: Traycer's typed silence (7-reason taxonomy), thread-scoped idempotent responseIds, broker-owns-delivery/store-owns-identity split, Communication Graph (exactly-once, gap-free, playback). Base: v2's Orchestrator MCP toolkit pattern + `ThreadManagementService`. - -## 3. Agent roles / types - -Define agent types, easily spawnable, configurable prompts, "soul" (SOUL.md-style identity). Prior art: Claude `.claude/agents/*.md`, Traycer role claims (runtime dedup half), T3 v2 role labels (one-sentence prompt prefix). The _definition layer_ is ours alone — no one has it. - -## 4. PR / Agent dashboard _(scope expanded by Jackson; 4a PR pane opening 2026-08-17 for human engineers)_ - -Not just PRs: at-a-glance visibility into what all agents are doing — critical for long-running tasks and large fleets. PRs are one pane of that story. Inputs: Jackson's pr-group-dashboard (now running locally), per-PR sitter pattern, T3's AgentsPanel + relationship graph, Traycer's Communication Graph. - -**Product principle (Jackson, 2026-08-17): build the PRIMITIVES that make workflows like PR Groups successful — the agent DB storing exchanges + human escalations (= the A2A ledger), a role system geared to multi-agent groups (item 3), PR visibility + work-this-PR nudges (this item) — but do NOT codify the PR Group methodology into the product. Users build their own workflows on the primitives; Jackson's playbook is one expression, never the product's opinion.** - -## New candidates (2026-08-22 — recorded from the foundations round, not yet prioritized by Jackson) - -- **Playbooks & progress** — platform step pointer + fresh-step injection + crew/initiative progress views (R27, `product/design-review-2026-08-21.md`). Feeds item 4's panes; is not item 4. -- **Memos** — the agent backlog primitive: tool + `resurface_after` + backlog pane/badges/archive-warning/chat-drawer surfacing (R26, R31–R35). -- **Shared squadrons (multi-user)** — the L2-support vision (R29, `product/problems.md`). Deep architecture session first; likely post-item-4 — the fleet must be observable by one person before it's shareable between several. The multi-human invariant is in force _now_ regardless. - -## 5. Cross-machine fleets _(deliberately deferred)_ - -Includes a broader cross-_person_ A2A story. Jackson's call: both T3 and Traycer will likely make cross-machine/cross-person advances in the coming months — wait and see before making our move. Keep the door open architecturally (routing above the environment boundary; nothing that assumes single-host A2A forever). diff --git a/docs/j5/dogfood-runtime.md b/docs/j5/dogfood-runtime.md index e2a462966913..91783deefea2 100644 --- a/docs/j5/dogfood-runtime.md +++ b/docs/j5/dogfood-runtime.md @@ -1,6 +1,6 @@ # Dogfood runtime: self-hosted J5 Code server and clients -How Jackson's solo dogfood (phase 3 of [dogfood v0](worklog/dogfood-v0.md)) actually runs: one +How Jackson's solo dogfood (phase 3 of [dogfood v0](plans/dogfood-v0.md)) actually runs: one source-built J5 Code server on a Linux box, reached over Tailscale, with the browser as the client. This document is self-contained on purpose — dogfood agents have no access to the design sessions that produced it. Decisions and their load-bearing reasons are recorded inline. diff --git a/docs/j5/plans/dogfood-v0.md b/docs/j5/plans/dogfood-v0.md new file mode 100644 index 000000000000..bf5a67a5d57d --- /dev/null +++ b/docs/j5/plans/dogfood-v0.md @@ -0,0 +1,56 @@ +--- +title: "Dogfood v0 — build J5 Code from J5 Code" +kind: plan +status: active +--- + +# Dogfood v0 + +A plan (see [how the docs are organized](../process/docs.md)): it sequences the work and states what the current build narrows; the definitions it builds are in `product/`, and where this plan and a definition disagree, the definition wins. + +**Goal (2026-08-23):** get J5 Code to the state where development of J5 Code happens inside J5 Code — the second step, after the docs, toward other people being able to help. Once this milestone completes, well-defined work is farmable to any contributor. + +**Definition of dogfood-ready:** crews run as J5 threads, communicate over the ledger, and reach a person in the in-app inbox whose verbatim answer closes the Exchange — with archives ending obligations loudly instead of stranding them. + +## Milestones + +| Milestone | Work | Status | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------- | +| Dogfood v0 M1 | Registrar, placement and provenance, the wrapper-path live proof | Done (2026-08-29) | +| Dogfood v0 M2 | The person as a participant (inbox) and lifecycle closure (loud archive) | Done (2026-08-31) | +| Dogfood v0 M3 | Squadron creation and the composer chip; thread rendering; the v0 interactive surface | Done (2026-09-01, #23 merged after Jackson's live acceptance) | +| Dogfood v0 M4 | Jackson's solo dogfood: a real task inside J5 Code — spawn, exchange, ask, answer, archive — with a friction list as the retrospective input | Done (2026-09-01 onward; friction list in the worklog) | +| Dogfood v0 M5 | The fleet inside J5 Code: the core agents migrated (2026-09-01), lanes spawned as J5 threads, the coordinator working in J5 | Done (2026-09-04); the Director moved last, per the original line | +| Dogfood v0 M6 | Silence notices as fact bundles ([#30](https://github.com/Jacksondr5/j5code/issues/30)) and the envelope true-up ([#29](https://github.com/Jacksondr5/j5code/issues/29)) | Open — A2A completion milestone | + +The next outcomes after v0 are tracked as GitHub milestones, in order: Fleet observability, Monitoring delivery, A2A completion, Roles, Memos, Crews, Playbooks. Shared Squadrons stays vision; hosting on a corporate server rides Jackson's own timeline. + +## The dogfood work queue + +Tickets held as J5-native work, staffed from GitHub (label `dogfood-queue`), each self-contained on repository paths. Done: DQ1 ([#25](https://github.com/Jacksondr5/j5code/issues/25)), DQ5 ([#33](https://github.com/Jacksondr5/j5code/issues/33)), Squadron-first thread cards ([#47](https://github.com/Jacksondr5/j5code/issues/47)). Open: [#26](https://github.com/Jacksondr5/j5code/issues/26) envelope role marker, [#27](https://github.com/Jacksondr5/j5code/issues/27) palette reuse-or-create hardening, [#28](https://github.com/Jacksondr5/j5code/issues/28) the Fleet page, [#29](https://github.com/Jacksondr5/j5code/issues/29), [#30](https://github.com/Jacksondr5/j5code/issues/30), [#31](https://github.com/Jacksondr5/j5code/issues/31) graph read API, [#38](https://github.com/Jacksondr5/j5code/issues/38) and [#39](https://github.com/Jacksondr5/j5code/issues/39) picker follow-ups, [#40](https://github.com/Jacksondr5/j5code/issues/40) mobile parity, [#41](https://github.com/Jacksondr5/j5code/issues/41) spawn-brief cards, [#45](https://github.com/Jacksondr5/j5code/issues/45) coalescing surfaces. + +## What the current build narrows + +Each row names the definition and the criteria it narrows, and when the full behavior returns. The definitions describe the end state; this table is the only place a cut is stated. + +| Definition and criteria | Current build | Returns | +| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | +| Squadron AC5 (one or more folders) | Exactly one folder, implemented as a Squadron→project reference — never identity. Guards that must hold: membership is assigned by the Registrar, never derived from the project; two Squadrons over the same folder work (an acceptance criterion, not a later feature); the folder relation is stored ready to become a list | The multi-folder milestone: a list, with the palette-first worktree row | +| Squadron AC6 (everything else reachable) | "Browse elsewhere" may be absent; if project reuse makes it cheap, keep it, otherwise it is backlog rather than blocking. Never-a-wall is untouched at end state | Backlog item if cut; at latest with the multi-folder milestone | +| Squadron AC7 (every picker offers Squadrons) | The new-thread flow and the command palette are converted; remaining pickers convert by inventory ([#38](https://github.com/Jacksondr5/j5code/issues/38), [#39](https://github.com/Jacksondr5/j5code/issues/39)) | As the inventory closes | +| Squadron AC3 (Squadron required to create an agent) — exemptions | The hard refusal binds the interactive user-origin creation path only. Exempt, each with its return: mobile new thread and offline drain; scheduled new-thread creation, which hits the refusal and must surface as a visible scheduled-task error; the server's bootstrap creation; plan-to-implementation inherits the parent's home, and a no-home parent yields a no-home child. Squadron creation is primary-environment-only with a state-naming refusal elsewhere | Per row: a mobile Squadron ticket; a truthful scheduler-origin carrier; multi-environment work | +| Thread rendering AC4 ("You · via Inbox" for the reader who sent it) | Renders neutral `Via Inbox · ⟨person⟩` — "You" is a factual claim that the viewer is that person, and the merged auth principal is session-scoped with no person binding, so the claim cannot be made truthfully. Rendering on exact equality is already built, so the upgrade needs no renderer rework | The auth-subject-to-person binding session (queued after v0) | +| Sidebar (SB5 membership by provenance; pin/hide overrides; roster-and-removal ship together) | The sidebar is unchanged: no automatic hiding of agent-spawned threads, no overrides, no pairing rule; the Fleet page is purely additive. The rule was too harsh — Jackson asks the Director to spawn most agents he talks with — and the human-contact-spectrum story is not strong enough to build a filter yet. Accepted gap | With Crews (the first thing a user explicitly expects not to talk to) or a settled spectrum representation | +| A2A AC7–AC8 (several open asks to a person; explicit follow-ups) | The shipped behavior refuses a second ask to a person while one is open ([#111](https://github.com/Jacksondr5/j5code/issues/111)) | With #111 | +| A2A AC20 (silence notices as measured facts) | Notices are stored with a label chosen when written; a notice with several open asks records only its first match; no surface shows the stored label as current status | With #30 | + +Retired cuts: "folder required at creation" was a v0 cut until 2026-09-05, when the Squadron definition made one-or-more folders the end state; it is no longer a narrowing. + +## Standing guards + +- **Squadron-first creation**: name the work, then attach the folder. Reusing the project-creation flow wholesale rebuilds upstream's one-to-one shape with a rename — the exact thing the Squadron definition exists to not be. The composer heading stays Squadron-named; the first-run gate stays "create your first Squadron". +- The composer's Squadron chip is in force: context-inherited, changeable until send, immutable after, and what the Registrar receives; no automatic default Squadron. + +## History + +- 2026-08-23 — goal, phases and the Traycer-to-J5 cutover line set (Jackson's reorientation); 2026-08-25 — one file for v0 overrides (former DV1–DV3); 2026-08-31 — the reserved dogfood queue and DV4–DV5; 2026-09-04 — the sidebar rule set aside (former DV6, on the Fleet-page contract); 2026-09-09 — the overrides file (`product/dogfood-v0.md`) and the phases story (`worklog/dogfood-v0.md`) merged into this plan; overrides keyed by definition and criterion; the DV letters retired. diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index 0cdc9948808b..a723543738b3 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -148,7 +148,7 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel - 2026-08-14 — the communication graph drafted; former open questions 1–4 ([record](../../worklog/2026-08-14-communication-graph-draft.md)). - 2026-08-16 — design settled; former D1–D10, this file's earlier form. -- 2026-08-21 — design review: former R3 (closure is mechanical, completeness is the sender's judgment), R4 (notices are measured facts; labels are read-time policy), R10 (a follow-up may name an earlier Exchange), R22 (Captains are never routers), R25 (time facts in envelopes) ([record](../design-review-2026-08-21.md)). +- 2026-08-21 — design review: former R3 (closure is mechanical, completeness is the sender's judgment), R4 (notices are measured facts; labels are read-time policy), R10 (a follow-up may name an earlier Exchange), R22 (Captains are never routers), R25 (time facts in envelopes) ([record](../../worklog/2026-08-21-design-review.md)). - 2026-08-24 — Subagent and Peer Agent distinguished; `delegate_task` excluded, so former D1's delegation edges no longer exist ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). - 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). diff --git a/docs/j5/product/decision-log.md b/docs/j5/product/decision-log.md deleted file mode 100644 index 537584c0f2ca..000000000000 --- a/docs/j5/product/decision-log.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: "Product decision log" -kind: spec ---- - -> **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. - -# Product decision log - -Running record of product-level decisions from Jackson. One row per decision; status distinguishes settled calls from directions still being pressure-tested. - -| Date | Area | Decision | Status | -| ---------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 2026-08-14 | A2A / Dashboard | **The human is a first-class node in the communication graph.** Jackson's personal PR dashboard already has a "send a question/task to the human" mechanism, proving the need — but it lives outside any graph. Fold it in. Human UX will differ from agent UX (inbox, not prompt injection). | Directional — closes once the communication-graph definition (`../worklog/2026-08-14-communication-graph-draft.md`) is agreed | -| 2026-08-14 | Agent roles / identity | **No new memory store.** Providers already ship memory systems and skills are ubiquitous; a third store is unwise. Identity is a document users iterate on early, then let solidify — a versioned definition file. | Directional | -| 2026-08-14 | Agent roles / identity | **Counter (Jackson's own):** provider memory + skills are provider-local and live outside our app, which hurts identity portability. Likely shape: identity = SOUL.md/AGENTS.md-style file **plus** a portable bundle (own skills, maybe own memory) that travels with it. | Open — needs a dedicated working session | -| 2026-08-14 | Dashboard | **Attention-queue first, but only slightly** — the status wall is an important component, not an afterthought. | Settled as priority ordering | -| 2026-08-14 | Dashboard | Dashboard design work is **parked** until Jackson gets his personal PR-dashboard site onto this machine for study as prior art. | Parked — repos studied 2026-08-15 (`../research/jackson-prior-art/`); pane inventory now in the interviews synthesis | -| 2026-08-16 | Product principles | **The platform/non-platform boundary.** "AI as a DB" is a fundamental limitation — durable stores with clear access patterns are platform work. Group cohesion, channel discipline, verbosity, and work-sizing are fixed by roles, prompting, and right-sized work — never by tooling. Make parts of the system code; AI fails like humans fail. | Settled — the classification lens for all backlog work (`../research/jackson-prior-art/fleet-interviews-synthesis.md`) | -| 2026-08-16 | Roles / review | **A perfect Reviewer is a non-goal.** The PR process layers more review (AI + human) on top of imperfect review; complexity spent perfecting one agent makes things worse. | Settled | -| 2026-08-16 | Platform scope | **Interview classification ratified**: 13 platform items (P1–P13), operator-lore list, and five boundary rulings (brief container = platform / content = methodology; capability heartbeats composed from schedules+queue; facts register deferred; evidence TTL non-platform; message kind tags cut). | Settled — full sort in the interviews synthesis | -| 2026-08-16 | Platform scope | **New primitive: durable schedules + named status checks** (host-owned cron surviving session death, run history, missed-run alarms; registered checks rendering outcome + staleness on the dashboard). Motivated by session-scoped monitors dying semi-randomly and the watchdog's 80-hour silent outage. | Settled — build; T3 v2 scheduled tasks as the base | -| 2026-08-16 | Workspaces | **Tracking worktree for reviewer seats** (turn-start sync: clean + fast-forward + narrated delta; confirmation required if mid-turn): plausible, but workflow-specific. | Shelved for V2 — design recorded in the interviews synthesis | -| 2026-08-17 | Product principles | **Primitives, not methodology.** J5 Code builds the primitives that make workflows like the PR Groups successful — the exchanges/escalations ledger, the role system, PR visibility + "work this PR" nudges — but must NOT codify Jackson's PR Group methodology into the product. The playbook is one workflow expressible on the primitives, never the product's opinion. Every design asks "what generic capability does this need," never "how do I productize prg." | Settled — governs all dashboard/roles design | -| 2026-08-19 | Cross-device (item 5) | **X1–X5 settled** (`cross-device.md`): authority never replicates — messages cross, read-models merge in the client. X1 squadron-on-one-server is a permanent non-goal to violate; X2 item-4 panes multi-environment from day one (incl. notifications); X3 dashboard merge ships with item 4, peer exchanges wait for a real trigger; X4 the peer registry is the cross-person seam (door open, deliberately undesigned); X5 client-pulled backups as the history-durability direction. | Settled | -| 2026-08-17 | Epic concept | **The grouping concept defined (E1–E5,** `features/squadron.md`**):** a grouping, never a boundary; single home, no movement (membership fixed at creation; agents spawn within their own epic); full container over time; user-only creation; org tree lives inside one epic. Consequence: agent-facing `join_epic` should not exist — the A2 exclusive-join semantic is ratified-out. | Settled — E6 **settled 2026-08-17: named the "Squadron"** (fleet-native, names the group of agents, empty collision map); code rename scheduled with the Director | -| 2026-08-16 | A2A | **A2A design fully settled — D1–D10** (`a2a/index.md`): unified ledger with delegation edges but not provider-subagents; per-epic ledgers with cross-epic double-entry; log-first delivery; five v1 silence states; "exchange" naming; hierarchy decoupled into provenance / delegation bindings / free org placement (re-parent human-only in v1). Builder plan at `../plans/a2a.md` against `j5/main` @ `e7597dac8`; Director reviewing before staffing. | Settled | -| 2026-08-21 | Full-design review | **R1–R23 settled** (`design-review-2026-08-21.md`): lifecycle closure for participants and squadrons (archive terminates obligations loudly; ledgers readable forever); sender-judged exchange closure + `regarding` linkage; silence notices as fact bundles with labels in projections; inbox/observability split; `trigger.fired` roots; cost = squadron→agent only; identity = git-versioned files, no memory bundle; durable local person id. **Crew/Manifest/Captain defined**: nautical-civil naming family (team retired); crews spawn and archive as units, members never replaced; agents spawn crews, captains archive their direct crews, crew members cannot spawn crews; captain = derived status, never an entity or a router. | Settled | -| 2026-08-21 | Hierarchy (amends D10) | **"You command what you brief."** The spawn-time placement parameter (sibling/other-parent/new-root) is deleted — placement = spawner, always; spawning-and-briefing a crew for someone else is ratified as an anti-pattern (proxy management). Human-only re-parent survives as the sole divergence mechanism; captaincy follows placement. Provenance unchanged: separate, immutable. | Settled — amends D10's placement leg | -| 2026-08-21 | Product principles | **Three named principles adopted** (`principles.md`): (1) communication flows peer-to-peer, decisions flow through the hierarchy — captains are never routers; (2) the human-contact spectrum (chat-contact specifically) — manifests declare posture, chattiness gets measured (item 4), platform never enforces position; (3) prompting problems are not platform problems — elevation of the 2026-08-16 platform/non-platform boundary. | Settled — check all designs against these | -| 2026-08-22 | Foundations | **Problems & goals doc adopted** (`problems.md`) with foundations register R24–R35 (`design-review-2026-08-21.md`): time-stamped envelopes for time-blind agents; the inbox≠backlog distinction and the **memo primitive** (per-agent self-messages, all user-visible, no per-turn injection, `resurface_after` paging, dashboard/badge/archive-warning/chat-drawer surfacing); playbook engine direction (step pointer + fresh-step injection = platform, steps = content; linear first, DAG same family); manifests = platform schema in git-versioned files (user's content — portability/shareability must not be un-solved); agent cron/DB primitives parked with named trigger. | Settled | -| 2026-08-22 | Shared squadrons | **Ratified as a distinct third capability** — several people on one server (L2-support shift handoff, two humans before one agent), not cross-device (X1–X5), not federation (X4). Settled now: the multi-human invariant (nothing may assume exactly one human; surfaces are person-scoped), delivery targets are one-user-or-all-users (no human group management), duty-addressing recorded as a door. Deep architecture session before any build; backlog candidate, likely post-item-4. | Settled — invariant in force immediately | -| 2026-08-22 | Product principles | **Two principles added** (`principles.md`): _status is read, never asked_ — if the user must ask an agent for a fact, the platform is missing a surface; and _build tools that make agents better, never systems that make them perfect_ — elevated from the perfect-Reviewer non-goal and "AI fails like humans fail." | Settled — check all designs against these | -| 2026-08-22 | Product principles | **Principle added** (`principles.md`): _the platform delivers facts, never judgment_ — it fixes the mechanical half of agent unawareness (deliver the measured fact) but never converts facts into conclusions ("crew done" vs "crew waiting" is undecidable); where discernment is required, the move is a nudge to a mind carrying the facts. Problems restructured into themes the same day (`problems.md`): fleet observability; human attention; agent weaknesses (async-blindness / context-as-memory / large unsupervised groups); cleanup at scale; Traycer/T3 inheritances. Roles moved from problems to goals. | Settled | -| 2026-08-23 | Docs | **Docs reorganized and the evergreen/worklog convention adopted.** Single-doc folders flattened to `topic.md`; feature definitions of record live under `product/features/` (Squadron, Crews, Roles, Playbooks, Memos, Shared Squadrons, PR pane); build-time records (tickets, reviews, retros, fork-setup evidence) live under `worklog/` — historical by nature, read product docs for current truth. Use-cases doc written (`use-cases.md` — agentic software development; production monitoring with L2 support as an elevated chapter). Principles restructured into the beliefs/lenses/principles machine (`principles.md`). | Settled — conventions govern all future docs | -| 2026-08-23 | Product principles | **Principle added** (`principles.md`): _simple tools at the frontier_ — we are pushing the bounds of how AI agents work, so build the smallest thing that solves the _observed_ problem; machinery earns its place through observed need, never anticipated completeness. Elevated from the R10 guardrail; the working test: "what did we actually observe needing?" Same session: Manifest demoted to implementation vocabulary (the artifact form of a Crew definition; Roles carry per-agent fields incl. posture); Title Case convention adopted for named concepts (glossary); Playbook advancement enriched — agent declares step completion, platform fans out per-Role instructions to all participants; Memos extracted to their own feature doc (`features/memos.md`). | Settled — Jackson editing the principle text | -| 2026-08-29 | Substrate | **Upstream substrate ruling settled** (`a2a/substrate.md`): the Subagent/Peer Agent species line sorts all upstream orchestration code — consume topology-free plumbing (adapters, event core, thread commands, `sendToThread` delivery, checkpoints), consume lineage as record only (forks/Subagents; never Peer Agent semantics), rebuild the org opinion J5-side (root-thread spawn + Registrar + placement, Exchanges for result binding, placement cascade, hierarchy display), build what neither side has (Exchange re-surfacing, orphan observability). ST5's `delegate_task` exclusion gets its mechanism: a J5-owned subset toolkit (`J5OrchestratorSurface`) replaces the upstream orchestrator registration — `delegate_task`/`task_status`/`task_cancel`/`t3_thread_send`/`t3_thread_interrupt` off the agent surface (raw thread-send is transport without the law; A2A = transport + envelope + ledger + Exchange + silence). Ownership rule: upstream owns existence/lifecycle state, J5 overlays org facts, participanthood by explicit registration only (Codex shadow-thread guard). Evidence that retired the alternatives: the lineage cascade never killed children (projection bookkeeping only), and the A6 proof's "delivery failed to wake the child" was an instructed silence — asks steered into the live turn in both retained databases. Session: `worklog/substrate-session-2026-08-29.md`. Open: `create_threads`/`t3_thread_start` on the agent surface (drop recommended). | Settled — substrate.md governs | -| 2026-08-31 | Peer Agent steering | **The spawn brief carries the initial task plus whether and what reply is expected.** There is no spawn-then-ask sequence: `send_message(expect_reply=true)` opens an Exchange only for later work owed by an existing participant. SP4's one brief-coaching sentence remains exactly once in the `spawn_agent` description. | Settled — amends the result-binding wording in the 2026-08-29 substrate row; `a2a/agent-tools.md` and `features/spawning-guide.md` govern | diff --git a/docs/j5/product/design-review-2026-08-21.md b/docs/j5/product/design-review-2026-08-21.md deleted file mode 100644 index 28630110115c..000000000000 --- a/docs/j5/product/design-review-2026-08-21.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "Design review 2026-08-21 — settled register (R1–R23)" -kind: spec ---- - -# Design review 2026-08-21 — settled register - -A full-design grilling session (Jackson + Product, 2026-08-21): every open branch of the design tree visited round-by-round until the frontier was empty. This register holds the rulings; the three principles adopted in the same session live at `principles.md`. Nothing here reopens D1–D10, E1–E6, or X1–X5 — these rulings compose with them. One row per decision, all SETTLED 2026-08-21. - -## The register - -| ID | Area | Ruling | -| --- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| R1 | Exchanges / lifecycle | **Archiving a participant terminates its obligations loudly.** Archive appends a platform-authored terminal notice per open inbound exchange (`receiver-retired`, mapped to Dropped, carries do-not-retry), delivered to each waiter through the normal pipeline. Sender-side open outbound exchanges get the same retirement disposition. No exchange ever waits forever on a node that can no longer answer. | -| R2 | Squadron / lifecycle | **Squadron archive is user-only, loud, and evented.** It force-closes the squadron's open exchanges via the R1 mechanism (notices reach cross-squadron waiters); human-inbox rows from the squadron leave with a visible record, never silently. | -| R3 | Exchanges / closure | **The sender judges completeness, prompted at closure.** When a reply lands, the reply-delivery envelope (third rendering of the one formatter) states: this reply closed the exchange entirely; if anything you asked remains unanswered, open a new exchange — nothing else is tracked. Completeness is a judgment call and therefore never code's (prompting problems are not platform problems). | -| R4 | Silence / notices | **Notices record facts; projections assign labels.** `silence.notice` carries the full measured bundle — turn ended, no closing reply, every open outbound exchange listed structurally (generalizing D6's structural peer id). Which single state labels an edge (awaiting-human vs blocked-on-peer vs turn-ended) is projection/display policy: disposable, tunable without ledger migration. States are evaluated at the recipient's turn-end over durable ledger facts regardless of which turn created them. | -| R5 | Dashboard / inbox | **Two features, not one.** The inbox is pure: letters agents deliberately sent to the human — no inferred mail, no auto-promoted stalls. The observability dashboard is where the human investigates "why isn't X done": it highlights e.g. an IC blocked-on-peer for 2 hours with the peer idle, prompting a nudge to whichever agent coordinates X. They may share a UI, never a data model. | -| R6 | Ledger / triggers | **Machine triggers are recorded roots, not participants.** Schedule/check fires append a ledger event (`trigger.fired`-kind: source id + run id) so machine-initiated chains have a recorded origin in playback. Triggers mint no exchanges and emit no silence; participant = has a thread, unchanged. External-systems-as-nodes stays an open door. | -| R7 | Cost | **Cost rolls up squadron → agent, nothing between.** Cost is measured per agent; the squadron is the only aggregation (membership immutable, so accounting is stable). No org-subtree or sub-squadron cost accounting — the re-parent attribution problem is thereby deleted, not solved. | -| R8 | Identity (item 3 seed) | **Identity = git-versioned definition files; no memory in the bundle (v1).** Closes the 2026-08-14 open counter in favor of the original no-new-memory-store call: portability comes from git (per X-register direction); provider memory is accepted as non-portable local seasoning; what an agent must never forget belongs in its definition. The Role/manifest system (item 3) carries this fully. | -| R9 | Human identity | **Durable local person id from day one.** The ledger needs a _stable_ id, not an _authenticated_ one: mint `human:` at first run, use it in every row and envelope. External auth (e.g. Clerk) binds to it later at the peer registry — X4's designated cross-person seam. App login stays deferred. | -| R10 | Exchanges / linkage | **Optional `regarding: exchange_id` on open.** A follow-on exchange (R3 reopen) links to the exchange it survives; envelope tells reopeners to carry it. One nullable column now vs a migration later. Guardrail noted with it: simple tools over completeness-striving — we are pushing the bounds of how AI works; this field passed only because it is one field. | -| R11 | Ledger / retention | **Archived ledgers are readable forever.** Archive removes a squadron from active views only; its ledger stays immutable and readable indefinitely; playback works forever; X5 client-pulled backups include archived ledgers. No deletion story in v1. | -| R12 | Crews / concept | **Two concepts: the manifest (definition) and the crew (instance).** The platform ships the machinery — author, spawn, render; every playbook (e.g. Jackson's PR Group) is one user-authored manifest, never the product's opinion. Manifests are git-versioned files (same mechanism as R8 identity). | -| R13 | Naming | **Fleet / Squadron / Crew, definition = Manifest — the nautical-civil family.** A fleet is all vessels; a squadron is a detachment grouped under a shared purpose; a crew is the hands running one vessel, each with a named station; a manifest lists a crew's roles. Simple enough to teach at onboarding. Crew is the least military word in the family (film/pit/flight/road crew) and is role-native. "Team" is retired as a reserved term. | -| R14 | Crews / lifecycle | **Crews archive as a unit; members are never individually archived or replaced.** Rationale: agent death is usually recoverable (message them again), and an irrecoverably poisoned member has likely contaminated its crewmates. Recovery = respawn the crew from the manifest. Continuity is cheap because work lives in durable artifacts outside the agents (worktree, branch, PR): the successor crew picks up where the old one left off. Solo agents (no crew) stay individually archivable. | -| R15 | Crews / workspace | **Archive never destroys work.** Archiving a crew (or any agent) never deletes worktrees, branches, or checkpoints by default; workspace cleanup is a separate explicit act. (Broader management of durable items outside the platform: deferred to those systems' build-time.) | -| R16 | Crews / spawn | **Agents can spawn crews** (within their own squadron, from user-provided manifests) — a deliberate, recorded asymmetry with user-only squadron creation (E4). The middle-management thesis requires it. | -| R17 | Crews / boundaries | **A crew lives entirely inside one squadron; a crew renders as one org node** with members beneath it, so cascade operations (D10) treat it as a unit. Membership is fixed at spawn (composes with R14) — an agent is in exactly one crew by construction; counterpart references resolve once at spawn to agent ids (no seat indirection needed). | -| R18 | Captain / concept | **Captain is a derived status, not a platform entity or a fourth tier.** The hierarchy is arbitrary-depth (managers of managers), so the management layer is made of agents in the placement tree, not container objects. A captain is any agent with crews placed under it — measured, never asserted. UI: captain chip + crews rendered as collapsible groups under their captain. ("Flotilla" reserved if a true container need ever materializes; none is expected.) | -| R19 | Captain / rights | **A captain may archive crews placed directly under it** — the only agent-invocable archive. Symmetric with R16 (retire what you command); safe because it triggers the same loud platform machinery (R1/R2). Not grandchild crews (route through the child captain or the human), not individual members (R14), not solo child agents (no identified need). | -| R20 | Crews / constraint | **Crew members cannot spawn crews — enforced in the tool surface**, not by convention: the spawn-crew tool refuses callers holding a crew seat, with an error naming the next command ("escalate to your captain"). Crews are leaf teams; wanting more hands is an escalation. | -| R21 | Hierarchy (amends D10) | **Placement parameter deleted; "you command what you brief."** Spawn-time placement (sibling/other-parent/new-root) is removed: placement = spawner, always. The scenario that motivated it — spawning-and-briefing a crew for someone else — is ratified as an anti-pattern (proxy management; the hierarchy carries decisions, never messages): the decider sends decision + brief to the future captain, who spawns its own crew. Provenance stays separately and immutably recorded; human-only re-parent survives as the sole divergence mechanism; captaincy follows placement. | -| R22 | Communication invariant | **Any participant may message any participant; captains are never routers.** No permission check may ever enforce communication routing or spectrum position (the hierarchy carries decisions, never messages; the human-contact spectrum). The graph, not the hierarchy, is how you see through a middle manager. | -| R23 | Principles | **Three principles adopted as named product docs** (`principles.md`): peer communication / hierarchical decisions; the human-contact spectrum (with riders: manifests declare posture; chattiness is measured — item 4; density lens directional); prompting-vs-platform elevated from the 2026-08-16 boundary ruling. | - -## Foundations round (2026-08-22) — R24–R35 - -The session continued with a step back to foundations: Jackson's problem statement and goals, now captured in `problems.md` (the doc these rulings assume). Two principles were adopted in this round — _status is read, never asked_ and _build tools that make agents better_ — (`principles.md`). - -| ID | Area | Ruling | -| --- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| R24 | Principle | **Status is read, never asked** — adopted as a principle. If the user must ask an agent for a fact, the platform is missing a surface. | -| R25 | Envelopes / time | **The platform stamps measured time facts into everything it delivers** — open-durations, delivery timestamps, elapsed-since-request — because agents are time-blind. Versioned envelope config, M2-adjacent. Expected to convert into proactive behavior ("it's been 8 hours, let me check"; "it _is_ tomorrow, let me raise it") — behavior to study and tune, not assume. | -| R26 | Attention model | **Inbox ≠ backlog.** The inbox is an obligation queue: every item blocks a sender, demands a reply, scales with working agents. A backlog is non-blocking and may grow freely. Deferred items must never route through the inbox (an inbox with 100 items hurts the attention problem); a separate primitive is required — the memo (R31–R35). Amends R5's surface list: inbox / observability views / backlog pane — shared UI allowed, shared data model never. | -| R27 | Playbooks | **The playbook engine is platform; the steps are content** (brief-container precedent). Rulings: (a) the agent advances the step pointer by tool call — "on step 3" is a measured fact of the call with visible asserted-by provenance, never output-parsing; (b) linear sequences first, the initiative-level milestone/DAG view is the same primitive one level up — one family, linear ships first; (c) skills-per-step parked, unproven. New backlog candidate "playbooks & progress" — feeds item 4's panes, is not item 4. This is how PR Group and monitoring playbooks become expressible without being codified. | -| R28 | Manifests | **Platform schema, file storage.** Machine-read fields (model, reasoning effort, skill allow-list, posture, playbook ref) wrap the prose role text; the platform enforces mechanics because it reads them. Riders: it is the _user's_ content — portability and shareability are requirements; git currently solves both; the implementation must not un-solve them. Skill gating is platform-only work. | -| R29 | Shared squadrons | **A distinct third capability** — not cross-device (X1–X5), not federation (X4 joins two servers; this is several people on one server, the L2-support vision: shift handoff without context transfer, two humans in front of one agent). Settled now: the **multi-human invariant** — nothing built from here on may assume exactly one human; every human-facing surface is person-scoped (R9 person ids). Delivery targets are **one user or all users** — no human group management on a single server. Duty-addressing ("the on-call") recorded as an open door, undesigned. Deep architecture session required before any build. | -| R30 | Agent primitives | **Agent-provisionable cron/DB parked with a named trigger**: revisit when cross-machine sync or repeated agent-setup pain makes hand-rolled stores hurt. The monitoring fleet's scraper and incident DB stay outside the platform. (Platform-owned durable schedules remain settled-build, unchanged.) | -| R31 | Memos | **No per-turn injection** — that would trade forgotten notes for context rot; the back-burner is a feature. The platform's leverage (_build tools that make agents better_): the tool's existence makes usage likely; the UI makes lapses visible — dashboard backlog view, badge on agents whose backlog needs working, a warning when archiving an agent with open memos, a chat drawer for picking the next topic. | -| R32 | Memos / deferral | **`resurface_after` is the one platform-initiated re-injection** — "page me after this time." Before the time the memo truly rests; after it, it returns stamped with R25 time facts. This field is what distinguishes a deferral from a backlog item. | -| R33 | Memos / visibility | **All memos are visible to the user — no private memos.** The backlog pane is pull-based (no clutter concern; the user arrives with attention to spare) and steering requires seeing everything the agent intends. Promotion to a real exchange is a deliberate agent act, never automatic. | -| R34 | Memos / scope | **Shaped, not generic — memos are the v1 agent data primitive.** Clear access patterns (append, list-open, resolve, defer) earn the store its place; a generic agent DB waits for R30's trigger. | -| R35 | Memos / boundaries | Per-agent ownership (no crew-shared memos until a need shows); the owning agent resolves or drops its own memos, evented; the human sees all and nudges via normal messages. Name: **memo** ("slate" runner-up). | - -## Glossary - -The vocabulary this session introduced (crew, manifest, captain, memo, near/far, and the retirement of "team") lives in the product glossary of record: `glossary.md`. - -## Deliberately deferred (recorded, not designed) - -Manifest file format + role-text authoring + posture declaration schema → item 3's working session. Blocked-on-peer cycle detection, chattiness metric, density lens, human unanswered-count metrics → item 4. Peer registry + auth binding → X3's trigger. Worktree/durable-externals management → build-time of those systems. Seat-addressing sugar, multi-crew agents, captain-archive of solo children → no identified need; wait for one. diff --git a/docs/j5/product/dogfood-v0.md b/docs/j5/product/dogfood-v0.md deleted file mode 100644 index c62838f2053c..000000000000 --- a/docs/j5/product/dogfood-v0.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "Dogfood v0 — scope overrides to settled product law" -kind: spec ---- - -# Dogfood v0 overrides - -The single home for phase-3/MVP scope cuts (Jackson's rule, 2026-08-25: overrides live HERE, never sprinkled through product docs). Each entry names the settled law it overrides and the milestone where the full behavior returns. **The feature docs remain the end-state truth; this file wins only for the v0 build.** When v0 ships and a later milestone lifts an override, delete its row. - -| ID | v0 override | Overrides | Returns | -| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | -| DV1 | **A Squadron has exactly one folder**, implemented as a Squadron→project **reference — never identity**. Reuses existing project machinery cleanly; the Squadron row is a light layer ready to take over multi-folder later. Non-negotiable guards: (a) squadron membership is **Registrar-assigned, never derived from the project**; (b) **two Squadrons over the same folder must work** — this is a v0 acceptance criterion, not a later feature (the shortcut of keying Squadron off project is the known trap); (c) data model stores the folder relation ready to become a list (a join or list-shaped column), so the later milestone lifts a cap rather than migrating a concept | SC1/SC2/SC4 (multi-folder targeting, palette-first worktree dropdown, editable folder list) | Multi-folder milestone: folders become zero-or-more with the palette dropdown | -| DV2 | **Folder is required at Squadron creation** — the name-only Squadron is deferred. Named casualty, accepted as temporary: the no-repo Squadron (ops/L2-support shape) is a real future persona and this dents the beyond-coding bar until it returns | SC2's name-only fast path | With DV1's lift, as zero-or-more | -| DV3 | **"Browse elsewhere" is not required in v0.** If project reuse makes it cheap, keep it; if not, it goes to the backlog rather than blocking — accepted by Jackson. The **never-a-wall principle is untouched at end-state** (E1); v0 merely may not ship the escape hatch | SC1's "Browse elsewhere…" affordance | Backlog item if cut; at latest with the multi-folder milestone | -| DV4 | **TA2 attribution renders neutral `Via Inbox · ` — never "You"** (ruled 2026-08-31). "You" is a factual claim that the viewer IS the answering person; the merged auth principal is session/device-scoped with no person binding, so the claim cannot be made truthfully (proven by convergent B3/B6 measurement; B6 returns `viewer: unavailable` with a named reason). Exact-equality rendering is already built, so the upgrade needs zero renderer rework | TA2's "You · via Inbox" acceptance | Auth-subject→person binding product session (queued post-v0) | - -| DV5 | **SC3's hard Squadron refusal binds the interactive user-origin creation path only** (ruled 2026-08-31). Named native/nonparticipant exemptions, each with its return: mobile new + offline drain (→ future mobile-Squadron ticket), scheduled new-thread creation UNSUPPORTED-refused in v0 — the scheduled cohort has no distinguishing creation signature to exempt truthfully (measured: real scheduled launches carry user/web or agent signatures; `createdBy:system` is bootstrap-only), so it hits the squadron-required refusal, which must surface as a visible scheduled-task error (→ truthful scheduler-origin carrier in future scheduling-context work), server `createdBy:system` bootstrap (→ permanently native unless a product session rules otherwise), agent-spawn bypass (→ closed by A2's `spawn_agent`). Plan→implementation inherits the parent's home when present; a no-home parent yields a no-home child (legacy cohort, no refusal, no default). Squadron creation is primary-environment-only with a state-naming refusal on non-primary (→ multi-environment work) | SC3 enforcement universality | Per-row returns as listed | - -## Standing guards (not overrides — v0 must keep these) - -- **Squadron-first creation**: name the work, then attach the folder. Reusing the project-creation flow wholesale (open-folder-then-it's-a-Squadron) rebuilds T3's 1:1 shape with a rename — the exact thing the design exists to not be. The composer heading stays Squadron-named; the first-run gate stays "create your first Squadron." -- SC3 is fully in force **as amended 2026-08-29 (SB3)**: Squadron **scope dropdown** in the sidebar (not grouping — superseded by the sidebar/roster rulings), context-inherited composer chip (changeable until send, immutable after, feeding the Registrar), no auto-Default Squadron. - -Session trail: the MVP discussion (2026-08-25) amending the squadron-creation session (2026-08-24); challenge points and their acceptance recorded in the Product lead's session log. diff --git a/docs/j5/product/features/archive-flow.md b/docs/j5/product/features/archive-flow.md index 2c614451712f..78735c2c61c7 100644 --- a/docs/j5/product/features/archive-flow.md +++ b/docs/j5/product/features/archive-flow.md @@ -56,7 +56,7 @@ This is **not** a delete, **not** a way to archive a single Crew member, and **n ## History -- 2026-08-21 — archive is loud and never destroys work; Crews archive as units; archiving with open Exchanges warns with count, list and confirmation ([record](../design-review-2026-08-21.md); former R1, R14, R15 and the Roles/Crews session's J1–J3). +- 2026-08-21 — archive is loud and never destroys work; Crews archive as units; archiving with open Exchanges warns with count, list and confirmation ([record](../../worklog/2026-08-21-design-review.md); former R1, R14, R15 and the Roles/Crews session's J1–J3). - 2026-08-29 — the flow designed; former AR1–AR4 ([record](../../worklog/archive-flow-session-2026-08-29.md)). - 2026-09-01 — ask-row anatomy mirrors the inbox item; former AR5 (Jackson's live review of the archive build). - 2026-09-08 — rewritten into the definition shape. Former identifiers: AR1 → AC11; AR2 → AC1; AR3 → AC2–AC5; AR4 → AC6–AC9; AR5 → AC3–AC4; J1–J3 → AC3, AC5. Build sequencing that lived here (the dialog shipping ahead of waiter notices) is history. diff --git a/docs/j5/product/features/crews.md b/docs/j5/product/features/crews.md index 70a4d1b65530..d5fb1e1cad45 100644 --- a/docs/j5/product/features/crews.md +++ b/docs/j5/product/features/crews.md @@ -75,7 +75,7 @@ The platform ships the machinery — define, spawn, render, warn, archive. The P ## History -- 2026-08-21 — the concept: definition versus instance, archive as a unit, archive never destroys work, agents spawn Crews, one Squadron, Captains as derived status, Captain archive rights, members cannot spawn Crews, "you command what you brief", Captains never routers; former R12–R22 ([record](../design-review-2026-08-21.md)). "Team" retired as a word. +- 2026-08-21 — the concept: definition versus instance, archive as a unit, archive never destroys work, agents spawn Crews, one Squadron, Captains as derived status, Captain archive rights, members cannot spawn Crews, "you command what you brief", Captains never routers; former R12–R22 ([record](../../worklog/2026-08-21-design-review.md)). "Team" retired as a word. - 2026-08-23 — the product session: structured-only validation, archive and respawn as judgment moments with a fresh brief; former P-E and J1–J3 ([record](../../worklog/roles-crews-session-2026-08-23.md)). - 2026-08-24 — whether Crew members may spawn solo Peer Agents is deliberately left open until Crews are built and a real Crew's behavior can be observed ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). - 2026-09-08 — rewritten into the definition shape; "git-versioned" aligned with Roles ("git optional"); posture stated as a lean, not a rule. Former identifiers: R12 → AC1; R14 → AC12; R15 → AC13; R16 → AC9; R17 → AC4–AC5; R18 → AC8; R19 → AC11; R20 → AC10; R21, R22 → Captains; P-E → AC2–AC3; J1–J3 → AC14–AC15. The open question on members spawning solo Peer Agents stays open, recorded above. diff --git a/docs/j5/product/features/memos.md b/docs/j5/product/features/memos.md index 61e3e760a8a3..43e229ed2c49 100644 --- a/docs/j5/product/features/memos.md +++ b/docs/j5/product/features/memos.md @@ -53,5 +53,5 @@ Memos are the shaped **first agent data primitive** — append, list what is ope ## History -- 2026-08-22 — the concept, extracted from the problems and goals; former R26 and R31–R35 ([record](../design-review-2026-08-21.md)). +- 2026-08-22 — the concept, extracted from the problems and goals; former R26 and R31–R35 ([record](../../worklog/2026-08-21-design-review.md)). - 2026-09-08 — rewritten into the definition shape. Former identifiers: R26 → Problem (why not the inbox); R31 → Definition (no per-turn injection), AC2; R32 → AC3; R33 → AC7; R34 → Definition (the first data primitive); R35 → AC4. The parked generic agent store (former R30) is recorded in the last Definition paragraph as not part of Memos. diff --git a/docs/j5/product/features/playbooks.md b/docs/j5/product/features/playbooks.md index 1ed0a2b25e93..617f44d9cb46 100644 --- a/docs/j5/product/features/playbooks.md +++ b/docs/j5/product/features/playbooks.md @@ -36,5 +36,5 @@ Playbooks are linear sequences. The initiative-level view — a plan whose nodes ## History -- 2026-08-22 — the concept; former R27 ([record](../design-review-2026-08-21.md)). +- 2026-08-22 — the concept; former R27 ([record](../../worklog/2026-08-21-design-review.md)). - 2026-09-08 — rewritten into the definition shape. Former identifiers: R27(a) → AC3–AC4; R27(b) → Definition (linear first); R27(c), skills per step → not part of the definition, parked. The questions for the Playbooks design session — the step schema, how a Playbook attaches at spawn, the delivery channel for step advancement, the initiative-level view, what "declared complete" means for a multi-agent step — are that session's, not this definition's. diff --git a/docs/j5/product/features/roles.md b/docs/j5/product/features/roles.md index 83229fe2bd9e..d1eb230b158a 100644 --- a/docs/j5/product/features/roles.md +++ b/docs/j5/product/features/roles.md @@ -71,7 +71,7 @@ A Role is **not** a runtime object (the agent is), **not** a permission boundary ## History -- 2026-08-21 — identity is git-versioned definition files with no memory in the bundle; machine-read fields wrap the prose (former R8, R28; posture rider of former R23) ([record](../design-review-2026-08-21.md)). +- 2026-08-21 — identity is git-versioned definition files with no memory in the bundle; machine-read fields wrap the prose (former R8, R28; posture rider of former R23) ([record](../../worklog/2026-08-21-design-review.md)). - 2026-08-23 — the product session: app as editing surface, composer Role dropdown, two-section identity with no prompt, drift never hot-reloads, structured-only validation, minimal in-app git; former P-A–P-F ([record](../../worklog/roles-crews-session-2026-08-23.md)). - 2026-08-30 — provider, model and reasoning stay explicit on agent spawns even with a Role; the allowlist constrains ([record](../../worklog/spawning-guide-session-2026-08-30.md)). - 2026-09-08 — rewritten into the definition shape; posture stated with the middle of the spectrum allowed, matching the lens. Former identifiers: R8 → AC1, Definition (no memory); R28 → AC1, AC5; P-A, P-F → AC7–AC9; P-B(h) → AC11–AC13; P-B(a) → AC14; P-C → AC3–AC4; P-D → AC15–AC16; P-E → AC17. Deferred items that lived here (Role claims, multiple library locations) are backlog candidates. diff --git a/docs/j5/product/features/shared-squadrons.md b/docs/j5/product/features/shared-squadrons.md index c2402c609ffc..c5bd43549aee 100644 --- a/docs/j5/product/features/shared-squadrons.md +++ b/docs/j5/product/features/shared-squadrons.md @@ -40,5 +40,5 @@ Doors deliberately left open and undesigned: addressing a _duty_ rather than a p ## History -- 2026-08-22 — the multi-person invariant and person ids ruled binding now; the capability defined and set apart from cross-device and federation; former R9, R29, and the cross-device position ([record](../design-review-2026-08-21.md)). +- 2026-08-22 — the multi-person invariant and person ids ruled binding now; the capability defined and set apart from cross-device and federation; former R9, R29, and the cross-device position ([record](../../worklog/2026-08-21-design-review.md)). - 2026-09-08 — rewritten into the definition shape. Former identifiers: R9 → AC2, AC4; R29 → AC1, AC3. The architecture session this capability needs before any build — how several authenticated people attach to one server, attribution and read state in shared surfaces, what "every person" delivery means for the inbox — is that session's agenda, not this definition's. diff --git a/docs/j5/product/features/squadron.md b/docs/j5/product/features/squadron.md index f68131730af7..4a6c82c7efab 100644 --- a/docs/j5/product/features/squadron.md +++ b/docs/j5/product/features/squadron.md @@ -53,7 +53,7 @@ End of life is archive; its details arrive with the container's growth. ## Scope -The current build ([dogfood v0](../dogfood-v0.md)) narrows this definition in three places: a Squadron has exactly one folder (AC5 narrowed, stored ready to become a list); "Browse elsewhere" may be absent (AC6 narrowed); and the surfaces converted to Squadron choice are the new-thread flow and the command palette first, with the remaining pickers converted by inventory (AC7 in progress). Later: multi-folder targeting, Squadron archive, colors and avatars, migration of pre-Squadron projects. Never: cross-machine targeting; anything boundary-shaped; a Squadron with no folder. +The current build ([dogfood v0](../../plans/dogfood-v0.md)) narrows this definition in three places: a Squadron has exactly one folder (AC5 narrowed, stored ready to become a list); "Browse elsewhere" may be absent (AC6 narrowed); and the surfaces converted to Squadron choice are the new-thread flow and the command palette first, with the remaining pickers converted by inventory (AC7 in progress). Later: multi-folder targeting, Squadron archive, colors and avatars, migration of pre-Squadron projects. Never: cross-machine targeting; anything boundary-shaped; a Squadron with no folder. ## History diff --git a/docs/j5/product/principles.md b/docs/j5/product/principles.md index ae98f5d1e47d..1d549bc32857 100644 --- a/docs/j5/product/principles.md +++ b/docs/j5/product/principles.md @@ -59,7 +59,7 @@ J5 Code has multiple use cases, defined in [use-cases.md](use-cases.md). These a The principles in this document are what guide us when designing, architecting, and building J5 Code. They frame our thinking when we come up with features. Most importantly, they help us decide what to build and what NOT to build. -Each principle states its rule, what it stands on (beliefs and lenses above), its jurisdiction — the kind of question it decides — and the cases it has already decided. R-numbers point into the [design-review register](./design-review-2026-08-21.md). A principle you cannot cite to kill or reshape a proposal is not pulling its weight. +Each principle states its rule, what it stands on (beliefs and lenses above), its jurisdiction — the kind of question it decides — and the cases it has already decided. Each case names the definition where its outcome now lives; the case is a pointer, never a second statement of the rule. A principle you cannot cite to kill or reshape a proposal is not pulling its weight. ## The hierarchy carries decisions, never messages @@ -69,7 +69,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** communication topology and command structure — who may talk to whom, who spawns and briefs whom. -**Cases:** any-to-any messaging is a platform invariant and Captains are never routers (R22); "you command what you brief" — placement = spawner, and spawning-and-briefing a Crew for someone else is proxy management (R21); lateral-coordination norms are Role content, never permission checks. +**Cases:** any-to-any messaging is a platform invariant and Captains are never routers ([agent-to-agent communication](./a2a/index.md), [Crews](./features/crews.md)); "you command what you brief" — placement equals the spawner, and spawning-and-briefing a Crew for someone else is proxy management ([Squadron](./features/squadron.md), [Crews](./features/crews.md)); lateral-coordination norms are Role content, never permission checks ([Roles](./features/roles.md)). ## Prompting problems are not platform problems @@ -79,7 +79,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** where a solution lives. When a design wants the platform to enforce a behavior, this is the objection to answer first. -**Cases:** reply completeness is judged by the sender, taught by envelope text, never checked by code (R3); communication-routing norms and human-contact posture live in Role definitions (R23); group cohesion, verbosity, and register are content, not tooling. +**Cases:** reply completeness is judged by the sender, taught by envelope text, never checked by code ([agent-to-agent communication](./a2a/index.md)); communication-routing norms and human-contact posture live in Role definitions ([Roles](./features/roles.md)); group cohesion, verbosity, and register are content, not tooling. ## Build tools that make agents better, never systems that make them perfect @@ -89,7 +89,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** a tool's ambition — what any feature is allowed to promise. -**Cases:** Memos are a tool plus visibility (badges, archive warnings, the backlog pane), not forced context injection (R31); Exchange semantics are envelope-taught, not schema-coerced; recovery is cheap by design — respawn a Crew from its definition (R14), reopen an Exchange with `regarding` (R10), nudge from a pane. +**Cases:** Memos are a tool plus visibility (badges, archive warnings, the backlog pane), not forced context injection ([Memos](./features/memos.md)); Exchange semantics are envelope-taught, not schema-coerced ([agent-to-agent communication](./a2a/index.md)); recovery is cheap by design — respawn a Crew from its definition ([Crews](./features/crews.md)), open a new Exchange about an earlier one ([agent-to-agent communication](./a2a/index.md)), nudge from a pane. ## The platform delivers facts, never judgment @@ -99,7 +99,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** what the platform may output or automate. Anything phrased as "the platform detects…" gets tested here: is that a measurement or a verdict? -**Cases:** silence notices inform and never auto-close Exchanges; notices carry fact bundles while labels are projection policy (R4); Playbook advancement is agent-declared, never platform-judged (R27); "Crew done" vs "Crew waiting" is structurally the Captain's or human's call, not a gap to engineer away. +**Cases:** silence notices inform and never auto-close Exchanges, and they carry measured facts while labels are read-time policy ([agent-to-agent communication](./a2a/index.md)); Playbook advancement is agent-declared, never platform-judged ([Playbooks](./features/playbooks.md)); "Crew done" versus "Crew waiting" is structurally the Captain's or the person's call, not a gap to engineer away ([Crews](./features/crews.md)). ## Status is read, never asked @@ -109,7 +109,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** what the human must do to learn the fleet's state. -**Cases:** the observability dashboard and PR pane exist so "how's it going" is a read; cost rolls up per Squadron on a surface (R7); chattiness is a measured metric, not a vibe (R23). +**Cases:** the Fleet page and the PR pane exist so "how's it going" is a read ([sidebar and roster](./features/sidebar-and-roster.md), [PR pane](./features/pr-pane.md)); cost rolls up per Squadron on a surface, nothing between ([sidebar and roster](./features/sidebar-and-roster.md)); chattiness is a measured metric, not a vibe. ## Never guess — a plausible fake is worse than a visible gap @@ -119,7 +119,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** how unknowns, staleness, and degraded measurement render, on every surface. -**Cases:** `mergeable: UNKNOWN` renders as "?", never as mergeable; a broken poller goes quiet with a staleness clock, never loud-wrong; PR↔agent association is conservative — ambiguity shows unassociated rather than guessed (PR pane v1). +**Cases:** an unknown mergeability renders as "?", never as mergeable; a broken poller goes quiet with a staleness clock, never loud-wrong; PR-to-agent association is conservative — ambiguity shows unassociated rather than guessed ([PR pane](./features/pr-pane.md)). ## State changes are loud; nothing vanishes silently @@ -129,7 +129,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** lifecycle transitions, terminations, and failures. -**Cases:** archiving a participant or Squadron terminates its obligations with notices to every waiter (R1, R2); an undelivered message is a visible alarm, never a silent loss (A2A M2); membership changes are lifecycle events; archiving an agent with open Memos warns first (R31). +**Cases:** archiving a participant ends its obligations with notices to every waiter ([archive flow](./features/archive-flow.md)); an undelivered message is a visible alarm, never a silent loss ([agent-to-agent communication](./a2a/index.md)); membership changes are lifecycle events ([Squadron](./features/squadron.md)); archiving an agent with open Memos warns first ([Memos](./features/memos.md)). ## Simple tools at the frontier @@ -139,7 +139,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** how much to build. -**Cases:** `regarding` shipped because it is one nullable field (R10); Memos are a shaped store, not a generic agent DB (R34); Playbooks ship linear before any DAG (R27); Crews archive as units instead of growing seat-replacement machinery (R14); agent cron/DB primitives wait for a named trigger (R30). +**Cases:** a follow-up references an earlier Exchange with one field rather than a linking system ([agent-to-agent communication](./a2a/index.md)); Memos are a shaped store, not a generic agent database ([Memos](./features/memos.md)); Playbooks ship linear before any DAG ([Playbooks](./features/playbooks.md)); Crews archive as units instead of growing seat-replacement machinery ([Crews](./features/crews.md)); agent cron and database primitives wait for a named trigger ([Memos](./features/memos.md)). ## Scoped principles diff --git a/docs/j5/product/problems.md b/docs/j5/product/problems.md index 7e6239fa475e..4950b95c1342 100644 --- a/docs/j5/product/problems.md +++ b/docs/j5/product/problems.md @@ -5,7 +5,7 @@ kind: spec # Problems & goals -Captured verbatim-in-spirit from Jackson during the foundations round of the design review (2026-08-22; rulings R24–R35 in `design-review-2026-08-21.md`). Companion to `fleet-vision.md`: that document says _how Jackson operates_; this one says _what hurts and what he wants beyond fixing it_. Every design should trace back to one of the two. Principles referenced live in `principles.md`. +Captured verbatim-in-spirit from Jackson during the foundations round of the design review (2026-08-22; rulings R24–R35 in `../worklog/2026-08-21-design-review.md`). Companion to `fleet-vision.md`: that document says _how Jackson operates_; this one says _what hurts and what he wants beyond fixing it_. Every design should trace back to one of the two. Principles referenced live in `principles.md`. ## Problems diff --git a/docs/j5/research/synthesis.md b/docs/j5/research/synthesis.md index a016edac5445..d97b8be10ebc 100644 --- a/docs/j5/research/synthesis.md +++ b/docs/j5/research/synthesis.md @@ -57,8 +57,8 @@ kind: spec ## Our headline design work (neither app has it) 1. **Cross-machine fleets**: T3 proved the remote transport + auth layer; Traycer proved single-host orchestration; nobody routes A2A across hosts or syncs fleet state across environments. This is the flagship differentiator — design it into the event/message layer from day one. -2. **PR dashboard** (`../backlog.md`) — fleet-level PR state fed by sitter agents; study Jackson's personal site when available. -3. **Agent types/roles** (`../backlog.md`) — definition half (SOUL.md-style) + Traycer's role-claims runtime half. +2. **PR dashboard** (`../worklog/2026-08-14-backlog.md`) — fleet-level PR state fed by sitter agents; study Jackson's personal site when available. +3. **Agent types/roles** (`../worklog/2026-08-14-backlog.md`) — definition half (SOUL.md-style) + Traycer's role-claims runtime half. ## Open questions for the design phase diff --git a/docs/j5/worklog/2026-08-14-backlog.md b/docs/j5/worklog/2026-08-14-backlog.md new file mode 100644 index 000000000000..07a5d1ce91f1 --- /dev/null +++ b/docs/j5/worklog/2026-08-14-backlog.md @@ -0,0 +1,6 @@ +--- +title: "The initial prioritized backlog (2026-08-14)" +kind: record +--- + +> **Record.** The backlog is now the GitHub milestones on the repository, in outcome order; this is the 2026-08-14 priority statement that started the project, kept as history. diff --git a/docs/j5/worklog/2026-08-14-decision-log.md b/docs/j5/worklog/2026-08-14-decision-log.md new file mode 100644 index 000000000000..c3feb1a207aa --- /dev/null +++ b/docs/j5/worklog/2026-08-14-decision-log.md @@ -0,0 +1,6 @@ +--- +title: "Product decision log, 2026-08-14 to 2026-08-31" +kind: record +--- + +> **Record.** This was the running decision log until 2026-09-09. Under [how the docs are organized](../process/docs.md), settled decisions live in the definitions that hold them (each definition carries a History section linking the record of how it was decided), so the log is retired rather than maintained. Kept unedited as the story of the first three weeks. diff --git a/docs/j5/worklog/2026-08-21-design-review.md b/docs/j5/worklog/2026-08-21-design-review.md new file mode 100644 index 000000000000..2dc5c5faf918 --- /dev/null +++ b/docs/j5/worklog/2026-08-21-design-review.md @@ -0,0 +1,6 @@ +--- +title: "Design review 2026-08-21 — the R register" +kind: record +--- + +> **Record.** The register R1–R35 was the definition of record for much of the product until 2026-09-08, when each ruling moved into the definition that owns it. Where each landed: R1–R2, R11, R14–R15 → [archive flow](../product/features/archive-flow.md); R3–R4, R10, R25 → [agent-to-agent communication](../product/a2a/index.md); R5, R26 → [inbox](../product/features/inbox.md); R6 (external systems as nodes) → a door recorded in [shared Squadrons](../product/features/shared-squadrons.md); R7 (cost rolls up per Squadron) → the Fleet page definition when its contract lands; R8, R23 (posture), R28 → [roles](../product/features/roles.md); R9, R29 → [shared Squadrons](../product/features/shared-squadrons.md); R12–R13, R16–R22 → [crews](../product/features/crews.md); R21 (placement) → [squadron](../product/features/squadron.md); R24 → [principles](../product/principles.md); R27 → [playbooks](../product/features/playbooks.md); R30–R35 → [memos](../product/features/memos.md). Kept unedited as the session it was. diff --git a/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md b/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md index b0932c5a27e3..e9b9b1662905 100644 --- a/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md +++ b/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md @@ -31,4 +31,4 @@ A2/A3 merged. Coordinate with A8 (envelope true-up) on the formatter — sequenc Same-fixture proof: a scenario with turn-ended + open human exchange + open peer exchange yields ONE notice row whose bundle contains all three facts, from which the projection derives a label — and changing the label-policy function re-labels the SAME historical row differently with zero migration (the R4 test made executable); dual-decode proven against pre-amendment rows; A3's original five scenario tests still pass end-to-end through the new path; zero-notices-for-healthy-idle negative control retained; baseline suite green. -> **Currency note (2026-08-31, reserved for dogfood):** anchors cite the A3-era SilenceDetector; re-measure all anchors at your base (the detector has survived several merges unchanged in substance, but verify). The R4 law this implements is stated in `docs/j5/product/design-review-2026-08-21.md` and the fact-bundle philosophy now also governs shipped surfaces (e.g. inbox terminal_disposition) — keep vocabularies consistent with `docs/j5/product/a2a/agent-tools.md`. +> **Currency note (2026-08-31, reserved for dogfood):** anchors cite the A3-era SilenceDetector; re-measure all anchors at your base (the detector has survived several merges unchanged in substance, but verify). The R4 law this implements is stated in `docs/j5/worklog/2026-08-21-design-review.md` and the fact-bundle philosophy now also governs shipped surfaces (e.g. inbox terminal_disposition) — keep vocabularies consistent with `docs/j5/product/a2a/agent-tools.md`. diff --git a/docs/j5/worklog/a2a-tickets/a4-human-node.md b/docs/j5/worklog/a2a-tickets/a4-human-node.md index 062b88684991..f1ff9abe9aaf 100644 --- a/docs/j5/worklog/a2a-tickets/a4-human-node.md +++ b/docs/j5/worklog/a2a-tickets/a4-human-node.md @@ -12,7 +12,7 @@ status: 0 > 2. **Inbox purity (R5):** the inbox contains ONLY open Exchanges deliberately addressed to a person — nothing else. No merging of stall escalations / awaiting-input observability into the attention queue (that surface is item 4's; the older communication-graph idea of merging is superseded). > 3. Base SHA is whatever `j5/main` resolves to at staffing. "Cross-ledger" reads as "cross-Squadron, per person." -**Governing artifacts:** `../../plans/a2a.md` (§Human node; grounding: human as first-class node; D2), design-review register R5/R9/R29 (`../../product/design-review-2026-08-21.md`). +**Governing artifacts:** `../../plans/a2a.md` (§Human node; grounding: human as first-class node; D2), design-review register R5/R9/R29 (`../2026-08-21-design-review.md`). ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md index 060dd62e161c..15fdd8cef4c4 100644 --- a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md +++ b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md @@ -11,7 +11,7 @@ status: 0 > 1. **Person-keyed human nodes (R9/R29):** graph nodes for humans are person-scoped (`human:`), never a singleton. > 2. **Labels derive in the projection (R4):** edge states (`open | stalled(reason, trust) | answered | dropped`) are computed at projection time from ledger fact bundles (A3 notices + lifecycle facts) — never read from a write-time-chosen label as authoritative. Consumes A10's fact-bundle shape + label function once landed. > 3. **`regarding` linkage (R10):** where an Exchange carries the nullable `regarding` field (ships with A8), expose it as edge metadata for survives-from chains. Optional — degrade gracefully, no dependency on A8. -> 4. Base SHA is whatever `j5/main` resolves to at staffing. Staffing is opportunistic per the Dogfood v0 plan (`../dogfood-v0.md`). +> 4. Base SHA is whatever `j5/main` resolves to at staffing. Staffing is opportunistic per the Dogfood v0 plan (`../../plans/dogfood-v0.md`). **Governing artifacts:** `../../plans/a2a.md` (§Graph projection + read API), `../../plans/a2a.md` (D1, D8; grounding §Projections). Base: historical, see amendment. diff --git a/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md b/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md index 928d37c53044..fad5a4e5dd23 100644 --- a/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md +++ b/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md @@ -6,7 +6,7 @@ status: 0 # A8 — Envelope true-up -**Governing artifacts:** design-review register R3, R10, R25 (../../product/design-review-2026-08-21.md); A2's envelope formatter (one formatter, per-channel renderings, versioned config Jackson owns). Staff against current `j5/main` head. +**Governing artifacts:** design-review register R3, R10, R25 (../2026-08-21-design-review.md); A2's envelope formatter (one formatter, per-channel renderings, versioned config Jackson owns). Staff against current `j5/main` head. ## Goal diff --git a/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md b/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md index 59786a22e123..5ecc7c81b72e 100644 --- a/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md +++ b/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md @@ -6,7 +6,7 @@ status: 1 # A9 — Lifecycle closure -**Governing artifacts:** design-review register R1 and participant-side R11 (../../product/design-review-2026-08-21.md). Staff against current `j5/main` head. **Hazard note (why this is blocking-tier): participant retirement already happens in practice and currently strands open obligations silently.** +**Governing artifacts:** design-review register R1 and participant-side R11 (../2026-08-21-design-review.md). Staff against current `j5/main` head. **Hazard note (why this is blocking-tier): participant retirement already happens in practice and currently strands open obligations silently.** ## Goal diff --git a/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md b/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md index 9971b69f67b5..dd08fa71ee78 100644 --- a/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md +++ b/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md @@ -6,7 +6,7 @@ status: 0 # B1 — Inbox true-up -**Governing artifacts:** `../../product/features/inbox.md` (IB1–IB7, definition-of-record), gap-analysis conformance report (Director log 2026-08-30), `../../product/dogfood-v0.md`. Base: `j5/main` after PR #11 merges — #11's projection/answer API is the contract; this ticket reshapes the view and closes two platform gaps. +**Governing artifacts:** `../../product/features/inbox.md` (IB1–IB7, definition-of-record), gap-analysis conformance report (Director log 2026-08-30), `../../plans/dogfood-v0.md`. Base: `j5/main` after PR #11 merges — #11's projection/answer API is the contract; this ticket reshapes the view and closes two platform gaps. ## Scope diff --git a/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md b/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md index de58c712abf1..073d93726c62 100644 --- a/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md +++ b/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md @@ -6,7 +6,7 @@ status: 1 # E7 — Squadron picker conversion -**Governing artifacts:** `../../product/features/squadron.md` §E7 (definitional law, ruled 2026-08-31), `../picker-and-self-messaging-rulings-2026-08-31.md`, DV1/DV3 (`../../product/dogfood-v0.md`). Origin: Jackson's #20 acceptance pass — the new-thread flow still presented the upstream PROJECT picker before the prompt. +**Governing artifacts:** `../../product/features/squadron.md` §E7 (definitional law, ruled 2026-08-31), `../picker-and-self-messaging-rulings-2026-08-31.md`, DV1/DV3 (`../../plans/dogfood-v0.md`). Origin: Jackson's #20 acceptance pass — the new-thread flow still presented the upstream PROJECT picker before the prompt. ## Goal diff --git a/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md b/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md index c468157c18ae..ed491e881985 100644 --- a/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md +++ b/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md @@ -6,7 +6,7 @@ status: 0 # SQ1 — Squadron creation surface -**Governing artifacts:** `../../product/features/squadron.md` §Creation UX (SC1–SC4, definition-of-record, as amended by SB3), **`../../product/dogfood-v0.md` (DV1–DV3 — the single home for v0 overrides; it WINS over feature docs for this build)**, session trail `../squadron-creation-session-2026-08-24.md`, `../dogfood-v0.md` §Phase-3 prerequisite. Mockups in the design workspace (`product/squadron-creation-mockups/`) are decision aids, not pixel specs. Backend receiving contract: the Registrar (PR #10) — creation-time attachment of a thread to an explicit **existing** Squadron, once, immutably. +**Governing artifacts:** `../../product/features/squadron.md` §Creation UX (SC1–SC4, definition-of-record, as amended by SB3), **`../../plans/dogfood-v0.md` (DV1–DV3 — the single home for v0 overrides; it WINS over feature docs for this build)**, session trail `../squadron-creation-session-2026-08-24.md`, `../../plans/dogfood-v0.md` §Phase-3 prerequisite. Mockups in the design workspace (`product/squadron-creation-mockups/`) are decision aids, not pixel specs. Backend receiving contract: the Registrar (PR #10) — creation-time attachment of a thread to an explicit **existing** Squadron, once, immutably. ## Goal diff --git a/docs/j5/worklog/dogfood-v0.md b/docs/j5/worklog/dogfood-v0.md deleted file mode 100644 index eb74bb32d37c..000000000000 --- a/docs/j5/worklog/dogfood-v0.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Dogfood v0 — build J5 Code from J5 Code" -kind: story -status: 1 ---- - -# Dogfood v0 - -**Goal (Jackson, 2026-08-23):** get J5 Code to the state where development of J5 Code happens _inside_ J5 Code — the second critical step (after the docs effort) toward other people being able to help. Once this milestone completes, well-ticketed work is farmable to any contributor in the right order. - -**Definition of dogfood-ready:** crews run as J5 threads, communicate over the A2A ledger, and reach a person in the in-app inbox whose verbatim answer closes the exchange — with archives terminating obligations loudly instead of stranding them. - -## Phases - -| Phase | Work | Runs in | Gate to next | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------ | -| **0** (in motion) | Registrar service → A6 rebase + wrapper-path live proof + runbook | Traycer | Proof passes; membership provisioning real | -| **1** | **A4** (person node + inbox) ∥ **A9** (lifecycle closure) — parallel crews | Traycer | Both merged | -| **2** | **A10** (silence fact bundles) + **A8** (envelope true-up) — coordinated pair (shared formatter surface) | Traycer | Both merged | -| **3** | **Jackson's solo dogfood**: Jackson personally runs a small real task inside J5 Code — spawns agents, they exchange over the ledger, asks land in his inbox, he answers in-app, archives behave. No crew, no hand-off — his own shakedown. Friction list captured as the retro input. | **J5 Code** (Jackson only) | Jackson satisfied | -| **4** | **First crew inside J5**: one real ticket (A5 if still open, else next priority) run with Builder/Reviewer/Sitter as J5 threads over A2A. Director still directs from Traycer. Crew retro = the prioritizer for Roles/Crews (item 3), Memos, and item-4 panes. | **J5 Code** (crew) / Traycer (Director) | Retro delivered | - -## The line: when development moves from Traycer to J5 - -- **Phases 0–2 run entirely in Traycer** — current PR-group practice, unchanged. -- **The cutover is phase 3, and it is Jackson-first**: he dogfoods personally before anything is handed to crews or other people. Nothing else migrates until he's satisfied. -- **Crews move at phase 4; the Director moves last** — Traycer remains the command deck until the phase-4 retro says J5 Code can hold it. Migrating the Director is explicitly OUT of v0 scope and is decided by that retro. -- Sharing tickets/designs with other human devs: later, Jackson's call — not part of v0. - -## Phase-3 prerequisite (discovered 2026-08-24; design settled same day) - -**Squadron-creation + agent-creation UX.** Phase 3 requires Jackson to create a Squadron and create agents under it in-app, but no in-flight work builds that surface — the registrar (#10) deliberately takes an explicit _existing_ Squadron and E4 makes creation user-only. T3's project flow is not reusable: it assumes a 1:1 open-folder→agents shape, while Squadrons↔folders is many-to-many. **Design session complete (SC1–SC4, `../product/features/squadron.md` §Creation UX); build ticket scoped: [SQ1](dogfood-tickets/sq1-creation-surface.md)** — staffs when lane capacity allows, must merge before phase 3. Phases 0–2 are unaffected and do not pause. - -## Opportunistic / standing (any phase) - -- **A5** (graph read API) staffs whenever lane capacity allows — approved, amended, no dependencies beyond A2. -- **A7** (upstream rebase) fires whenever pingdotgg#2829 merges and briefly preempts everything (expected: days). -- 4a (PR pane, issue #6) continues with the human engineers independently. - -## Phase-3 day-one itinerary (Jackson, start 2026-09-01) - -1. **Morning board**: overnight summary; #23 at formal READY on the full-surface head; B4/E7/archive-slice lane states. -2. **#23 hands-on acceptance** (integrated environment, built on Jackson's word): full arc — create Squadron via UI → `spawn_agent` a real Luna Peer Agent → its ask arrives (live bell count) → answer inline → closed envelope observed → agent `clear_own_ask`. Bell alignment + the six error-message fixes verified visually. Then **merge #23** — the v0 interactive surface is complete on main. -3. **Runtime setup** per `docs/j5/dogfood-runtime.md` (session output; proposal-form if the session hasn't closed): server on the Linux box over Tailscale, UI on the laptop, update/rollback/backup pattern confirmed. -4. **Phase-3 first act**: create the real dogfood Squadron in the REAL environment (not a test dir), spawn the first working agent, and hand it **DQ1 (issue #25)** — the first J5-native ticket. DQ2 (#26) follows at Jackson's pace. -5. **Friction list starts immediately** — every rough edge goes in the phase-3 retro record (the input the plan's phase-4 gate requires). Traycer lanes (E7, B4, archive slice) keep landing in parallel; the Director remains in Traycer per the ratified line. - -## Dogfood work queue (RESERVED — Jackson, 2026-08-31) - -Tickets deliberately held as the first J5-native work: NOT staffable in Traycer regardless of free slots, except DQ5, which is being built in Traycer as a phase-3 runtime prerequisite. Every ticket is self-contained on repo paths only — dogfood agents have no access to Traycer artifacts or agents. Ladder order: - -Tickets live as GitHub issues (label `dogfood-queue`) so dogfood agents and future humans staff from the forge; durable context stays in this repo's docs, which each issue cites. - -| Tier | Ticket | Size | -| ------------------------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | -| Starter | [DQ1 — SQ1 cleanup pair (#25)](https://github.com/Jacksondr5/j5code/issues/25) | single agent, hours | -| Starter | [DQ2 — envelope role marker (#26)](https://github.com/Jacksondr5/j5code/issues/26) | single agent, hours | -| Prerequisite (in-build Traycer) | [DQ5 — server default base dir → ~/.j5code (#33)](https://github.com/Jacksondr5/j5code/issues/33) | single agent, hours; required before phase 3 runtime setup | -| Starter (conditional) | List-own-asks agent read — ticket written if the in-flight measurement confirms no such read exists | small | -| Middle | [A8 — envelope true-up (#29)](https://github.com/Jacksondr5/j5code/issues/29) | small crew | -| Middle | [DQ3 — palette reuse-or-create hardening (#27)](https://github.com/Jacksondr5/j5code/issues/27) | small crew | -| Meaty | [A10 — silence fact bundles (#30)](https://github.com/Jacksondr5/j5code/issues/30) | crew | -| Meaty | [A5 — graph read API (#31)](https://github.com/Jacksondr5/j5code/issues/31) | crew | -| Meaty | [DQ4 — Fleet page pair (#28)](https://github.com/Jacksondr5/j5code/issues/28) | crew (natural phase-4 first-crew ticket) | - -NOT held: B4 (archive dialog — phase-3-blocking), and all mid-flight Traycer lanes (B6/B7/E7/#22/#23 finish where they started). - -## Queued post-v0 (ratified, waiting on the milestone) - -- **Coalescing UX (Jackson live session, 2026-08-31):** the unique-open-pair law folds a second ask into the open exchange as a followup — truthful, but three surfaces don't say so: the sender's card still shows "Awaiting reply" for the folded ask; the sending agent isn't told its ask coalesced; and the receiving human never sees the followup's text — it rides the open exchange invisibly until the agent explains. One product candidate, three parts; `clear_own_ask` semantics were confirmed correct in the same session. - -- **Squadron-first agent cards ([#47](https://github.com/Jacksondr5/j5code/issues/47), Jackson 2026-09-01):** thread cards lead with the Squadron, the folder demotes to the hover card; dogfood-queue only, not Traycer-staffable. - -- **Creation-dialog picker sizing ([#48](https://github.com/Jacksondr5/j5code/issues/48)):** the folder source picker renders at two sizes depending on its entry door and the create form is cramped — pre-existing shared-primitive layout, measured during the #35 live review. - -- **Reply-card copy unification (Jackson, 2026-09-01):** rides the paired-cards ticket ([#41](https://github.com/Jacksondr5/j5code/issues/41)) — reader-facing cards use the standard "Expects reply"/"Replied" vocabulary; exchange-closure language stays in the agent-facing envelope. The split is deliberate: agents get mechanics, humans get plain words. - -- **Naming audit (Jackson, 2026-08-28):** examine the naming of everything against the settled glossary (Squadron et al.) — headline case: the `j5/a2a` module / `j5_a2a_*` table namespace has grown into the whole fleet-coordination substrate (Squadrons, membership, placement/provenance, messaging), so "a2a" now under-describes it. Rename cost grows with every milestone; run the audit immediately post-dogfood. - -- **Auth-subject→person binding (recorded 2026-08-31):** merged #11 authenticates but deliberately does not bind auth subjects to person ids — `resolvePersonId()` is explicit-or-local-default, per R9's "future auth binds to it" design. The binding becomes a product session when multi-person or remote access gets real; no current lane owns it. - -- **Claude read-only/dontAsk tool allowlist vs J5 verbs (recorded 2026-08-31):** the provider-side allowlist predates J5 and omits `list_participants`, now a primary steered verb — whether J5 verbs join it is a deliberate product/protected-seam session, not a drive-by on any PR. - -- **Orphan policy (re-affirmed at #21 merge, 2026-08-31):** archiving a participant leaves its placed children working but parked under the retired node — no auto-re-parenting (platform composes nothing, per the Roles/Crews ruling; re-parent is human-only per R21, and even that mechanism awaits its rebuild in the placement-display/Fleet-page lane, recovery-recorded from #18). The substrate session's orphan-policy design pass decides what the platform SURFACES about orphans; runs before or with the Fleet page work. Jackson wants follow-up ensured. - -- **Agent self-retirement (recorded 2026-09-01):** archive_agent refuses self-targets fail-closed (same identity law as send_message's self-reject; a caller torn down mid-call can neither receive its response nor keep fact-keyed claims truthful). A finished agent retiring itself IS a legitimate future workflow — it needs a deliberate design (own verb or brief-carried contract solving the last-response problem), a product session candidate alongside the list-own-asks read. - -## Explicitly NOT v0 - -Roles/Crews implementation (item 3 — design session completed 2026-08-23 ahead of the retro; feature docs are the build-ready contract, rulings at [roles-crews-session-2026-08-23.md](roles-crews-session-2026-08-23.md); staffing is a separate call), Memos, Playbooks, Shared Squadrons, item-4 panes, Director migration, multi-dev ticket sharing. diff --git a/docs/j5/worklog/priority-input-2026-08-30.md b/docs/j5/worklog/priority-input-2026-08-30.md index 86fc9af97039..906315940953 100644 --- a/docs/j5/worklog/priority-input-2026-08-30.md +++ b/docs/j5/worklog/priority-input-2026-08-30.md @@ -29,4 +29,4 @@ Deferrable-with-owner: open-Exchanges-vs-settle (A9 surfaces it); member-Peer-sp ## Standing coordination flags -A4/A6 both claim migration id 006 (relayed to Director); the dogfood-v0.md overrides file governs all v0 scope questions — anything cut during build goes THERE, never inline in feature docs. +A4/A6 both claim migration id 006 (relayed to Director); the ../plans/dogfood-v0.md overrides file governs all v0 scope questions — anything cut during build goes THERE, never inline in feature docs. From 8f489ed32a2548f5a12afb28beee6f9972b655e3 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Thu, 10 Sep 2026 20:26:46 -0400 Subject: [PATCH 11/15] docs(j5): problems, use cases, fleet vision, cross-device and the PR pane as definitions; the posted PR-pane brief kept as a record Co-Authored-By: Claude Fable 5.1 --- docs/j5/product/cross-device.md | 120 +++++++----------- docs/j5/product/features/pr-pane.md | 132 ++++++-------------- docs/j5/product/fleet-vision.md | 19 +-- docs/j5/product/problems.md | 51 ++++---- docs/j5/product/use-cases.md | 17 ++- docs/j5/worklog/2026-08-17-pr-pane-brief.md | 6 + 6 files changed, 143 insertions(+), 202 deletions(-) create mode 100644 docs/j5/worklog/2026-08-17-pr-pane-brief.md diff --git a/docs/j5/product/cross-device.md b/docs/j5/product/cross-device.md index 107966468149..be9063547e7d 100644 --- a/docs/j5/product/cross-device.md +++ b/docs/j5/product/cross-device.md @@ -1,77 +1,49 @@ --- -kind: spec -title: "Cross-device (backlog item 5) — position paper" +title: "Cross-device" +kind: definition --- -# Cross-device: what crosses, what merges, what stays home - -Explored with Jackson 2026-08-19, grounded in the remote-hosting review (`../research/remote-hosting.md`), the A2A design (`a2a/index.md`), and the squadron definition (`features/squadron.md`). **All rulings settled 2026-08-19** — this is the item-5 position of record. Jackson's framing notes: cross-person fleets are a great feature but far off — leave the door open, do NOT design it yet; squadron-spanning is a documented permanent non-goal. - -## The organizing principle - -State can do exactly three things across devices: **authority can replicate, messages can cross, or read-models can merge.** J5's position: **authority never replicates.** Messages cross (server-to-server delivery of exchanges) and read-models merge (in the client). This dodges Traycer's trap (replicated identity, unbuilt transport, `RECEIVER_NOT_LOCAL`), avoids CRDT/multi-master entirely (anti-constitution), and was pre-built into D5 (log-first) and D8 (async double-entry — "collapsing to one transaction would smuggle in a single-host assumption"). - -```mermaid -flowchart LR - subgraph AZURE["Azure server (work)"] - SA["squadrons + ledgers
(authority)"] - end - subgraph LOCAL["Laptop server (personal)"] - SB["squadrons + ledgers
(authority)"] - end - C["Client (desktop app)
merged inbox · merged dashboard
(read-models merge)"] - SA -. "exchanges cross
(peer delivery, correlation ids)" .-> SB - SA --> C - SB --> C -``` - -## The four capabilities assessed - -| Capability | Architecture verdict | Value verdict | -| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Cross-device exchanges between squadrons** | **Fits.** D8's async double-entry is the seam: the delivery worker gains a remote-peer adapter; the receiver's server writes its own `message.received` row. New machinery: a peer registry (URL + bearer token — the fully-local pairing machinery mints these) and the adapter. Log-first delivery gaps, receiver-side silence notices, and correlation-id graph stubs all carry over unchanged | Low _immediately_ (post-migration, work squadrons co-locate; work↔personal crossing is policy-forbidden). High _later_: multi-box personal setups, per-OS squadrons, and the **cross-person door** — the peer registry is where another person's server attaches, with capability scoping on what may cross | -| **One squadron spanning devices** | **Requires a different architecture** — replicated authority (CRDT/multi-master) or remote-execution daemons. Both rejected | Negative. The E2 argument one level up: why split a squadron when squadrons can exchange across devices? A Mac-needing agent gets a small Mac-homed squadron. Proposed permanent invariant: **a squadron lives entirely on one server** (X1) | -| **Combined dashboards/inbox** | **Fits cleanly, needs no server-to-server anything.** T3's client already connects to all saved environments concurrently and merges threads + attention pills; our per-server read APIs (graph cursor streams, inbox projection, stall report) merge the same way. Answers route to origin servers like thread sends already do; offline servers render cached-with-staleness (existing behavior) | **Highest value, nearest term.** Works even before peer messaging exists: one inbox and one board across the Azure fleet + personal fleet. Imposes one cheap constraint today (X2) | -| **Other sync** | Deliberately none. Worktrees, provider creds, settings, schedules/checks, cost meters: server-local by design; the dashboard merges readouts. Role/identity definitions travel as **git-versioned files** (item 3's direction — now an argument for it, cross-device free). History durability = per-server `state.sqlite` backup (operations, not sync) | Refusing to sync is the feature | - -## The X-register (all settled with Jackson, 2026-08-19) - -| ID | Ruling | Status | -| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| X1 | **A squadron lives entirely on one server — permanent invariant / documented non-goal.** Buys ledger-consistency, recovery, and A2A simplifications forever; the cross-device need is met by squadron-per-device + exchanges | SETTLED | -| X2 | **Item-4 dashboard panes are multi-environment from day one** (merge feeds like the sidebar merges threads; environment tags on rows; includes future desktop notifications firing for any connected environment). Retrofit is expensive; day-one is nearly free | SETTLED | -| X3 | **Sequencing:** dashboard/inbox merge ships with item 4; cross-device exchanges (peer registry + remote delivery adapter) wait for a real trigger (second personal box, Mac-squadron need, or cross-person) rather than being built speculatively | SETTLED | -| X4 | **The peer registry is the designated cross-person seam** — person boundaries, capability scoping on what may cross, and trust live there when the time comes; nothing else in the architecture needs to anticipate cross-person. Jackson: "likely to work" — held as the working assumption, revisited only if the seam proves wrong | SETTLED | -| X5 | **Client-pulled backups** (Jackson's proposal): each connected client periodically pulls a state snapshot from every connected server — the client's existing always-connected fan-out becomes the backup fabric, with no new infrastructure. Design later: server snapshot endpoint (SQLite online-backup API for a consistent copy), pull cadence, client-side retention, restore path. Recorded as the settled direction for history durability | SETTLED (direction; design deferred) | - -## What this deliberately does not do - -No CRDTs anywhere. No multi-master. No squadron migration between servers. No global agent registry (peering is pairwise). No relay dependency (direct HTTPS peering; a relay could later be _one transport option_ for NAT-crossed personal boxes, never a required service). - -## Landed: cross-environment reads for Squadrons and the inbox (2026-09-12, #125, issue #105) - -The read-model-merge half of the position above is now built for the web and desktop client. The -Squadron picker, the sidebar scope dropdown, and the inbox combine results from every connected -environment; each server keeps its own Squadrons, threads, ledgers, and inbox identity, and no data -moves between servers. Creation, thread launch, inbox navigation, and replies all carry the owning -environment with the item (`ScopedSquadronRef`, `ScopedThreadRef`) rather than routing through the -primary environment. - -Behavior worth knowing: - -- **Labels appear only when needed.** Environment labels show on picker rows, scope choices, inbox - items, and the create form only once results actually span more than one environment; a - single-environment client looks exactly as it did before. -- **Read-only connections read but cannot act.** A connection without the operate scope displays - that environment's Squadrons and questions but cannot create a Squadron, launch into one, or send - an answer; the controls say so. -- **Disconnected sources keep their last results.** An environment that drops or fails to refresh - keeps its loaded items visible with a per-environment notice; an asterisk on the inbox count - means the total is incomplete, and a question mark means no positive count is available while - some environment cannot be refreshed. Servers without the J5 routes are reported as unsupported - rather than empty. -- **Mobile is deferred.** The native app does not yet include these screens. - -FORK case 34 records the upstream-owned files this touches (two optional capability keys, the -contracts and client-runtime export entries) and the shared authenticated transport the client -reads reuse. +# Cross-device + +## Problem + +A person's fleet does not live on one machine. Work agents run on a work server that only the work network can reach; personal agents run at home; a laptop is the client for both. The person wants one inbox and one Fleet page, not one per machine — and eventually wants an agent on one server to be able to ask an agent on another. The prior-art platform tried to replicate identity across machines, never built the transport, and rejected deliveries that were not local ([problems](problems.md): fleet observability, human attention). + +## Definition + +State can do exactly three things across machines: **authority can replicate, messages can cross, or views can merge.** J5's position is that **authority never replicates.** Messages cross — an Exchange can be delivered from one server to another — and views merge in the client. This avoids replicated identity and multi-master state entirely, and it was built into the communication protocol from the start: delivery is log-first, and a message that crosses Squadrons is two writes, never one transaction, because collapsing them would assume a single host. + +The four capabilities, and what each is: + +| Capability | Position | +| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Exchanges between Squadrons on different servers** | Fits the protocol as designed: the delivery pipeline gains a remote-peer step, and the receiving server writes its own received row. What is new is a **peer registry** — which servers may talk, with what credential — and the delivery step. Waits for a real trigger (a second personal machine, a Squadron that must live on a specific OS, or another person) rather than being built ahead of one. | +| **One Squadron spanning servers** | **A permanent non-goal.** It would require replicated authority or remote execution. A Squadron lives entirely on one server; an agent that needs a particular machine gets a small Squadron homed there, and Squadrons exchange across servers. | +| **Merged inbox and Fleet page** | **The highest-value, nearest capability, needing nothing server-to-server**: the client already connects to every saved environment at once, and each server's reads merge in the client. Answers route to the server they came from. An unreachable server renders its last-known state with a staleness clock, never as empty and never as fine. | +| **Any other synchronization** | Deliberately none. Worktrees, provider credentials, settings, schedules, cost meters stay server-local by design; views merge their readouts. Role and Crew definitions travel as files. Refusing to sync is the feature. | + +**The peer registry is where another person's server attaches**, when that time comes — person boundaries, what may cross, and trust live there, and nothing else in the architecture needs to anticipate other people. + +History durability is **client-pulled backup**: each connected client periodically pulls a consistent snapshot from every server it connects to, so the client's existing always-connected fan-out is the backup fabric, with no new infrastructure. Its design — the snapshot endpoint, cadence, retention, restore — is later; the direction is settled. + +What this never does: no replicated state, no multi-master, no Squadron migration between servers, no global agent registry (peering is pairwise), no dependence on a relay (direct peering; a relay could later be one transport among others, never a required service). + +## Acceptance criteria + +1. A Squadron, its agents, and its ledger exist on exactly one server; nothing moves a Squadron between servers. +2. Every person-facing surface that shows fleet state — the inbox, the Fleet page, notifications — merges every connected environment from day one, and each item names its environment. +3. An answer or action taken on a merged surface is routed to the server the item came from. +4. An unreachable server's items render with their last-known state and a staleness clock; they never disappear and never render as healthy. +5. Nothing that is server-local by design — worktrees, provider credentials, settings, schedules, cost meters — is synchronized between servers. +6. Server-to-server Exchange delivery, when built, goes through a pairwise peer registry, and the receiving server records its own received row. + +## Scenarios + +- **Two servers, one inbox.** The user's client connects to the work server and the home server. An ask from an agent in Billing Migration (work) and one from Support Rotation (home) appear in one inbox, each tagged with its environment; answering each reaches the right server. (AC2, AC3) +- **A server goes dark.** The home server is asleep; its rows stay on the Fleet page with "last seen 40m ago" and never vanish. (AC4) +- **A Mac-only job.** An agent that must run on a Mac gets its own Squadron homed on the Mac server; it is asked for results by a Squadron elsewhere through a cross-server Exchange, once peering exists. (AC1, AC6) + +## History + +- 2026-08-19 — the position settled with Jackson: authority never replicates; former X1–X5 (this file's earlier form was the register). Grounded in the remote-hosting research and the A2A design. +- 2026-09-10 — rewritten into the definition shape. Former identifiers: X1 → AC1; X2 → AC2; X3 → the sequencing sentence in the first capability row; X4 → the peer-registry paragraph, AC6; X5 → the client-pulled backup paragraph. Personal deployment details (which server is where) removed from the definition. diff --git a/docs/j5/product/features/pr-pane.md b/docs/j5/product/features/pr-pane.md index e475e7ce4337..d39f47eb6347 100644 --- a/docs/j5/product/features/pr-pane.md +++ b/docs/j5/product/features/pr-pane.md @@ -1,118 +1,66 @@ --- -title: "PR Pane v1 — product brief (draft for Jackson's review)" -kind: spec +title: "PR pane" +kind: definition --- -# PR Pane v1 brief +# PR pane -**Status: APPROVED by Jackson and POSTED 2026-08-17 → [https://github.com/Jacksondr5/j5code/issues/6](https://github.com/Jacksondr5/j5code/issues/6)** (issues were disabled on the repo; enabled with Jackson's authorization to post). The issue body below is the published text of record; revisions happen on the GitHub issue from here, with this artifact as the design-rationale companion. Written self-contained for human engineers who cannot see this epic's artifacts. +## Problem -Rulings baked in (Jackson, 2026-08-17): association auto-first, agent-driven explicit attach deferred (raises broader agent↔DB design questions); nudge v1 = message-an-associated-agent only; GitHub-only with forge abstraction kept; universe = agent-associated PRs only; pr-review.jackson.codes ignored; readiness gates do not ship (future generic successor: named status checks). +When a fleet of agents works many pull requests at once, the person cannot tell at a glance who has reviewed what, whether a PR can be merged, whether the agents are still working it, or what they decided in response to reviews. Asking an agent means getting a recollection instead of a fact ([problems](../problems.md): PR management is difficult; status is read, never asked). The prior-art dashboard solved this for one workflow and taught two lessons the product keeps: every fact must be measured, and a plausible fake is worse than a visible gap. -## ISSUE BODY START +## Definition -# PR Pane v1: agent-associated PR visibility + "work this PR" nudge +The **PR pane** shows the pull requests the fleet is working on, as measured facts, with one action: send a message to an agent about a PR. -## Context (read this first) +A PR appears on the pane when it is **associated with an agent**. The platform infers the association from what it already knows — an open PR whose head branch matches a branch an agent pushed from its worktree — and shows that provenance as inferred; the person can associate or dissociate a PR by hand, shown as asserted. Inference is conservative: an ambiguous match shows the PR unassociated rather than guessing, because a wrong association would render one agent's liveness against another's PR. Pull requests belong to a Squadron through the agents working them. -J5 Code is a fork of T3 Code being extended into a **fleet-management platform**: one person running many long-lived AI agents that build code, open PRs, and watch production. This issue is the first workstream of the fleet dashboard: a pane inside the app showing the **pull requests the agent fleet is working on**, with one action — nudging an agent about a PR. +Every fact on the pane is **measured from the forge by the platform, on a cadence, never recalled by an agent**: state, draft, title, author, branches, head commit, mergeability, review decision, the check rollup with failed check names, unresolved review threads, timestamps, and when it was last measured. The pane **never guesses**: an unknown mergeability shows as "?", a PR not yet measured shows as measuring, and an unreachable forge leaves the last-known facts in place with a staleness clock — never an outage rendered as "everything is fine" or "everything is dead." Measured facts are rebuildable from scratch; a person's associations are not lost when they are rebuilt. -**The governing product principle — this shapes every choice below:** J5 Code builds _primitives_ that make agent workflows successful. It must never codify any particular workflow's methodology into the product. The prior art below comes from a specific three-agent PR workflow ("PR Groups") with its own playbook rules and readiness gates — that playbook is _one workflow expressible on the primitives_, never the product's opinion. When you face a design choice, ask "what generic capability does this need," not "how do I productize that workflow." Concretely: the prior-art dashboard computes ten workflow-specific "readiness gates" — **those do not ship**. The pane shows raw measured facts; workflow-defined checks become a separate, generic primitive later. +The pane is **read-only toward the forge**. It never merges, comments, closes or re-runs anything. Its one action opens the ordinary message composer to an associated agent, prefilled with the PR, its head commit, and a compact snapshot of the measured state, for the person to edit and send through the same path as any other message — so the pane can never hold state the agents do not know about. -**Prior art (public, study it):** `github.com/Jacksondr5/pr-group-dashboard` — a zero-dependency Node/SQLite board built to run a real fleet of PR-working agents. Its README is a compressed field manual of operational lessons; the design principles below are distilled from it and from interviews with the agents that used it. +Rows are ordered attention-first — needs something (failing checks, conflicts, changes requested), then waiting (checks running, review pending), then green — and **stable within a group**: rows update in place and never move under the cursor. Closed and merged PRs stay briefly, then leave. Like every fleet surface, the pane merges every connected environment and names each PR's environment. -## Principles (inherited from prior art; treat as requirements) +The pane carries **no workflow methodology**. The prior-art dashboard computed readiness gates for one three-agent workflow; those do not ship. Whether a PR is "ready" by some workflow's rules is the workflow's content; the generic successor — named status checks any workflow can define, rendered with outcome and staleness — is a separate primitive, later. GitHub is the only forge today, behind a thin seam so a second one can follow. -1. **Measured, not recalled.** Every fact on screen is measured from GitHub or from platform state by code — never asserted by an agent from memory, never cached silently past its freshness. -2. **Never guess.** `mergeable: UNKNOWN` renders as "?", a not-yet-polled row renders as "measuring…", an unreachable API renders as a loud staleness clock. A plausible fake is strictly worse than a visible gap. No state may ever _look_ green because data was missing. -3. **Provenance is visible.** Measured facts (from GitHub) and asserted facts (a human clicked "associate") are stored and rendered distinguishably. Measured tables must be safely wipe-and-rebuildable. -4. **A broken poller goes quiet, not loud-wrong.** If GitHub or platform state is unreachable, keep the last data with a staleness indicator — never render an outage as "everything is fine" or "everything is dead." -5. **State is read-only; actions route through agents.** The pane never acts on GitHub (no merge, no comment, no close). Its one action sends a _message to an agent_ through the app's normal agent-messaging path, so the UI can never hold state the agents don't know about. +The pane is **not** a place to act on pull requests, **not** a readiness or gating system, and **not** the fleet-attention view; it is one pane beside the Fleet page and the inbox, designed so siblings can join it. -## Scope - -### 1. PR ↔ agent association - -A PR appears on the pane when it is **associated with an agent**. Two association sources in v1: +## Acceptance criteria -- **Auto-inferred (primary):** the app owns agents' worktrees and branches. When an open PR's head branch (+repo) matches a branch an agent worked on/pushed from its worktree, associate automatically. Provenance: `inferred`. This must be conservative — a wrong association that renders agent liveness against the wrong PR is the "plausible fake" failure principle 2 forbids. If inference is ambiguous, show unassociated rather than guessing. -- **User-asserted:** the user manually associates a PR with an agent in the UI (and can remove either kind of association). Provenance: `user`. +### Association -Explicitly **deferred**: agents associating PRs themselves via a tool (raises broader agent↔platform-state design questions owned elsewhere). +1. A PR opened from a branch an agent pushed from its worktree appears on the pane within one measurement cycle, associated to that agent with provenance shown as inferred. +2. A PR with no inferable agent does not appear until a person associates it; that association shows provenance as asserted; either kind can be removed. +3. When inference is ambiguous, the PR shows as unassociated. -### 2. PR state acquisition +### Measurement -- **GitHub only in v1**, authenticated with the user's existing credentials. Keep a thin forge-abstraction seam (the prior art supports a second forge; we will again) — but build nothing Bitbucket-specific. -- **Poll, don't webhook** (local desktop app; polling is self-healing). Reasonable cadence, configurable. One batched/GraphQL query per PR like the prior art; re-ask for GitHub's lazily-computed mergeability when it returns UNKNOWN. -- Track per PR: state, draft, title, author, base/head refs, head SHA, mergeability, review decision, check-run rollup (state/total/failed/pending + failed names), unresolved review-thread count, timestamps, last-polled-at. Note: **check-run completions do not bump the PR's `updated_at`** — poll checks explicitly (prior-art lesson, learned the hard way). -- Closed/merged PRs stay visible briefly (retention window, config), then drop. +4. Check completions are reflected within one measurement cycle even when the PR's own updated timestamp did not change. +5. An unknown mergeability renders as "?" and never as mergeable; a PR not yet measured renders as measuring. +6. When the forge is unreachable, every row keeps its last-known facts with a visible staleness clock, nothing renders green by default, and measurement resumes without a restart when the forge returns. +7. Wiping the measured facts and re-measuring loses no person-asserted association. -### 3. The pane +### The pane -- A pane in the app's dashboard area, designed as **one pane among future siblings** (a fleet-attention pane will arrive later, fed by a different data source) — don't hardcode a single-pane layout. -- One row per PR: number/title/repo; state pills (CI, mergeability, review decision, unresolved threads); the associated agent(s) with their current platform liveness chip; staleness clock when polling degrades. -- **Attention-first ordering**: needs-something (failing CI, conflicting, changes-requested) above waiting (CI running, review pending) above green; **stable ordering within groups — rows update in place, never jump under the cursor.** Fixed-height rows; no per-second React re-renders (elapsed timers write to the DOM directly); no animated status dots. These are perf rules the codebase already follows (see `AgentsPanel.tsx` and AGENTS.md's performance notes — match that discipline). -- Follow existing codebase conventions for fork-added code: new files under the `j5/` surfaces (e.g. `apps/server/src/j5/...`), pnpm + `vp` toolchain, see `FORK.md`. +8. Rows order attention-first and stay in stable order within a group; a row updates in place and never moves under the cursor. +9. Twenty or more PRs render with fixed-height rows and no continuous repaint. +10. Each row names its environment, and PRs from every connected environment appear on one pane. +11. Closed and merged PRs remain for a bounded time, then leave. -### 4. The nudge (v1's single action) +### The action -A "Message agent" action on each PR row: opens the normal agent-message composer **prefilled** with the PR reference, head SHA, and a compact snapshot of the measured state (CI/mergeability/review/threads), for the user to edit and send. It's a proof-of-concept for "work this PR" — richer verbs (e.g. spawn-an-agent-onto-a-PR) come later. The send goes through the app's existing agent messaging path; the pane adds no new channel. +12. "Message agent" opens the composer to the associated agent, prefilled with the PR, its head commit and the measured state, and sends through the ordinary agent-message path; the pane performs no write to the forge of any kind. +13. No readiness gate or workflow rule is computed or shown. -## Non-goals (explicit) +## Scenarios -- **No readiness gates or any workflow-methodology logic.** Raw measured facts only. -- No agent-tool-driven association (deferred, owned elsewhere). -- No spawn-agent-on-PR nudge (later). -- No Bitbucket/GitLab (abstraction seam only). -- No acting on PRs from the pane (no merge/comment/close/re-run). -- No fleet-attention/communication pane (separate workstream; just don't preclude a sibling pane). -- No webhooks, no public endpoints. +- **A PR appears.** The Builder in Billing Migration pushes `billing/schema-v2` and opens a PR; within a cycle the pane shows it, associated to the Builder as inferred, with checks running. (AC1) +- **Checks finish quietly.** CI completes without touching the PR; the row's check pill updates on the next cycle. (AC4) +- **The forge goes away.** GitHub is unreachable for ten minutes; every row keeps its facts and shows "measured 10m ago"; nothing turns green; measurement resumes on its own. (AC6) +- **Nudging.** The user clicks "Message agent" on a conflicting PR; the composer opens to the Builder with the PR, its head commit and "conflicting · 2 checks failing" prefilled; the user edits and sends. (AC12) -## Acceptance criteria +## History -1. An agent pushes a branch from its worktree; a PR opened from that branch appears on the pane within one poll cycle, associated, provenance `inferred`. -2. A PR with no inferable agent does not appear until the user associates it; the association shows provenance `user`. -3. CI completion is reflected within one poll cycle even though the PR's `updated_at` did not change. -4. Kill the network: rows keep last-known state with a visible staleness clock; nothing renders green-by-default; restore network → self-heals with no restart. -5. `mergeable: UNKNOWN` renders as "?" and resolves after the re-ask; it never renders as mergeable. -6. The nudge composer opens prefilled and sends through the existing agent-message path; the pane performs no GitHub write of any kind. -7. 20+ PRs: rows update in place with stable order and fixed heights; no continuous repaint (verify against the repo's performance rules). -8. Wipe the measured tables; they rebuild from polling with zero loss of user-asserted associations. - -Negative controls required: for each "never" above (never guess, never write to GitHub, never reorder under cursor), demonstrate the check can fail — e.g., feed the UI a null mergeability and show it would catch a green rendering. - -## ISSUE BODY END - -## Wireframe (review aid only — not part of the issue) - -```wireframe - - -

Pull Requests

7 PRs · polled 12s ago
-
#9384 remove OTel SDK & local stackCI ✗ 2CONFLICTINGthreads 3otel-builder · working
-
#9412 env-aware severitychanges requestedCI ✓sev-builder · stalled 41m
-
#9401 wide-event tags per appCI runningreview pendingchart-builder · idle 6m
-
#9418 probe suppressionmergeable ?measuring…probe-builder · working
-
#9377 dead value cleanupCI ✓APPROVEDMERGEABLEcleanup-builder · idle 2h
- -``` - -## Seams recorded for later (not in the issue) - -- **Fleet-attention pane**: arrives after A2A M5's graph read API; the pane shell must allow siblings — that's the only constraint this brief imposes. -- **Named status checks (P8)** is the generic successor to prg's readiness gates — a future primitive where any workflow defines its own checks and the dashboard renders outcome + staleness. Jackson: "we need to figure out how to convert that to a primitive" — queued as its own design session. -- **Agent-driven association** joins the broader "how do agents write platform state" design (same family as the deferred agent↔DB questions). +- 2026-08-17 — the brief approved by Jackson and posted as issue #6 ([record](../../worklog/2026-08-17-pr-pane-brief.md)): association auto-first, one nudge action, GitHub only behind a seam, no readiness gates. +- 2026-08-19 — every fleet surface merges environments from day one (the cross-device position). +- 2026-09-10 — rewritten as a definition: the Squadron dimension and the multi-environment requirement stated; repository tooling and the wireframe left to the record. Former brief acceptance criteria 1–8 → AC1, AC2, AC4, AC6, AC5, AC12, AC9, AC7. diff --git a/docs/j5/product/fleet-vision.md b/docs/j5/product/fleet-vision.md index d7555dad1d73..3019f842b7b5 100644 --- a/docs/j5/product/fleet-vision.md +++ b/docs/j5/product/fleet-vision.md @@ -1,11 +1,11 @@ --- title: "Fleet vision — how Jackson actually operates, and what the platform must make possible" -kind: spec +kind: definition --- # Fleet vision -Captured verbatim-in-spirit from Jackson (2026-08-14). This is the intent behind the whole product — the context every design decision should be checked against. Companion research: `../research/jackson-prior-art/` (pr-group and pr-group-dashboard repo studies). +Captured verbatim-in-spirit from Jackson (2026-08-14). This is the intent behind the whole product — the context every design decision should be checked against. Companion research: the [prior-art studies](../research/jackson-prior-art/index.md). ## The journey that led here @@ -25,7 +25,7 @@ flowchart TD NB["Dynatrace Notebook/Dashboard agent
dashboards + notebooks for incidents"] J(("Jackson")) - subgraph LEADS["Big-picture leads (each runs teams of PR Groups)"] + subgraph LEADS["Big-picture leads (each runs several PR Groups)"] L1["Logging & tracing improvement"] L2["Observability scorecard methodology"] L3["Cost reduction (keep it in budget)"] @@ -42,7 +42,7 @@ flowchart TD ## The PR Group — the canonical unit of the vision -Each big-picture lead runs teams of **PR Groups**: 3 agents that build code changes and manage PRs end-to-end. +Each big-picture lead runs several **PR Groups**: 3 agents that build code changes and manage PRs end-to-end. | Role | Responsibility | | ------------ | ------------------------------------------------------------------ | @@ -64,7 +64,12 @@ The human sits at the top of a management hierarchy, not at the center of a hub- 1. **Roles + A2A are one load-bearing pair, not two features.** The PR Group only works because role definitions tell agents how to interact _with each other_. Role definitions should be able to reference counterpart roles ("as Sitter, escalate CI failures to Builder; only escalate to your lead when…"). Backlog items 2 and 3 must be designed together. 2. **Machine events are first-class fleet inputs.** The Dynatrace fleet is _driven by a cron job_, not by a human prompt. Work enters the fleet from schedules, alerts, PR comments, CI results. The platform needs non-human triggers as real citizens — and the communication graph should show them as sources (the "external systems as nodes" door we left open). -3. **Fleets are long-lived organizations, not task executions.** Leads and their teams persist for weeks. This validates: durable communication log, idle-as-real-state, stall detection over completion tracking. -4. **The hierarchy is deep — attention must aggregate.** Jackson ↔ Director ↔ leads ↔ PR Groups is 3+ levels. The attention queue can't just be "threads addressed to Jackson"; escalations bubble through middle managers, and the dashboard must make _the whole tree's_ blocked-state legible, not just the top edge. -5. **Cost is a product surface.** One lead exists specifically to keep the fleet within budget. Token/cost rollups per team/subtree belong in the dashboard, not in a settings page. +3. **Fleets are long-lived organizations, not task executions.** Leads and their Crews persist for weeks. This validates: durable communication log, idle-as-real-state, stall detection over completion tracking. +4. **The hierarchy is deep — attention must aggregate.** Jackson ↔ Director ↔ leads ↔ PR Groups is 3+ levels. Escalations bubble through middle managers, so the Fleet page must make _the whole tree's_ state legible, not just the top edge. (The inbox itself stays pure — only asks deliberately sent to the person; the tree-wide view is the Fleet page's job, not the inbox's.) +5. **Cost is a product surface.** One lead exists specifically to keep the fleet within budget. Cost rollups belong on the Fleet page, not in a settings page — per Squadron, with the agents beneath it. 6. **Beyond-coding is the bar.** Every design should pass the test: "does this work for the monitoring fleet, or only for coding fleets?" (E.g. PR panes are one instantiation of a more general "external artifact an agent team is responsible for" — incidents and dashboards are others.) + +## History + +- 2026-08-14 — captured from Jackson at the start of the project. +- 2026-09-10 — implications 4 and 5 aligned with later definitions (the inbox is pure, so tree-wide attention is the Fleet page's job; cost rolls up per Squadron, nothing between); "teams" replaced by Crews; content otherwise unchanged. diff --git a/docs/j5/product/problems.md b/docs/j5/product/problems.md index 4950b95c1342..53b74f777ca5 100644 --- a/docs/j5/product/problems.md +++ b/docs/j5/product/problems.md @@ -1,11 +1,11 @@ --- title: "Problems & goals — what hurts, and what the platform is for" -kind: spec +kind: definition --- # Problems & goals -Captured verbatim-in-spirit from Jackson during the foundations round of the design review (2026-08-22; rulings R24–R35 in `../worklog/2026-08-21-design-review.md`). Companion to `fleet-vision.md`: that document says _how Jackson operates_; this one says _what hurts and what he wants beyond fixing it_. Every design should trace back to one of the two. Principles referenced live in `principles.md`. +Captured verbatim-in-spirit from Jackson during the foundations round of the design review (2026-08-22). Companion to `fleet-vision.md`: that document says _how Jackson operates_; this one says _what hurts and what he wants beyond fixing it_. Every design should trace back to one of the two. Principles referenced live in `principles.md`. ## Problems @@ -96,7 +96,7 @@ Crews are meant to work the task they're assigned with a high degree of independ Crews are deliberately disposable: when their task is done, the user or spawner archives them. They archive only as a unit, members are never individually replaced, and recovery from a poisoned Crew is respawning a fresh one from its definition — cheap because the real work lives in durable artifacts (worktree, branch, PR) that survive the agents. Agents can spawn Crews themselves (Captains running Crews without the human in the loop is the point), Captains can archive the Crews they command, and Crew members can't spawn Crews of their own — wanting more hands is an escalation. -The platform ships the machinery — define, spawn, render, archive; the Playbook a Crew executes and the Roles it contains are always the user's content. The PR Group is one Crew definition someone wrote, never the product's opinion. (R12–R20; the definition schema is item 3's design session.) +The platform ships the machinery — define, spawn, render, archive; the Playbook a Crew executes and the Roles it contains are always the user's content. The PR Group is one Crew definition someone wrote, never the product's opinion. (The definition of record is [Crews](features/crews.md).) ### Playbooks @@ -114,28 +114,33 @@ As we start to work more and more with agents, the need to share them between hu ### Supporting tools: cron + DB for agents (parked) -The monitoring fleet's scraper and incident database (see the working fleet in `fleet-vision.md`) stay outside the platform — too use-case-specific. The generic observation stands: both the PR and monitoring systems needed cron jobs and databases that agents had to laboriously self-provision. Parked with a named trigger (R30/R34): revisit when cross-machine sync or repeated setup pain makes hand-rolled stores actually hurt. Agents are perfectly capable of setting these up themselves today; Memos (`features/memos.md`) are the v1 data primitive. +The monitoring fleet's scraper and incident database (see the working fleet in `fleet-vision.md`) stay outside the platform — too use-case-specific. The generic observation stands: both the PR and monitoring systems needed cron jobs and databases that agents had to laboriously self-provision. Parked with a named trigger: revisit when cross-machine sync or repeated setup pain makes hand-rolled stores actually hurt. Agents are perfectly capable of setting these up themselves today; Memos (`features/memos.md`) are the v1 data primitive. ## Traceability One row per problem theme / goal; the pointer is where the answer is designed or tracked. -| Problem / goal | Answered by | Status | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- | -| Fleet observability — agent/Crew state | Silence taxonomy + ledger projections (A2A M3/M5); Playbook step pointer (R27); dashboard surfaces (R5); status is read, never asked | A2A v1 plan; item 4; Playbooks candidate | -| Fleet observability — PR management | PR pane v1; playback for review-decision audit (M5) | Pane approved, issue #6 | -| Fleet observability — cost | R7 Squadron→agent rollups | Item 4 | -| Human attention — lost/telephoned asks | Inbox + urgency (A2A M4); spectrum posture (the human-contact spectrum lens) | A2A v1 plan | -| Human attention — drowned conversations | Spectrum posture + delegation to Crews (the human-contact spectrum lens) | Principle adopted; manifest posture is item 3 | -| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | -| Async-event blindness | Silence notices to waiters (M3); `trigger.fired` (R6); time-stamped envelopes (R25) | A2A v1 plan | -| Context as bad memory | Status-is-read surfaces; R25; Memos; Playbook step injection (R27) | Principles adopted; candidates queued | -| Large, unsupervised groups | Exchanges + sender-judged closure (R3); silence machinery; memo visibility for drift steering (R33); observability dashboard | A2A v1 plan; item 4 | -| More work needs more cleanup | Archive never destroys work (R15); Crews archive as units (R14); Captain archive rights (R19); workspace cleanup tooling deferred | Register settled; tooling later | -| Traycer/T3 inheritances | Durable ledger vs RAM loss (M1); R15 vs over-eager cleanup; A2A + Squadrons vs parent-child-only flat list | A2A v1 plan | -| Roles in platform tooling | R28 platform-schema-in-git frame | Item 3 session | -| Crews | R12–R20 | Register settled; manifest schema is item 3 | -| Playbooks | R27 engine/content split | Backlog candidate | -| Shared Squadrons | R29 — multi-human invariant in force now; one-user-or-all-users delivery; architecture session before build | Backlog candidate | -| Agent cron/DB | Parked with named trigger (R30/R34) | Parked | -| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | +| Problem / goal | Answered by | Status | +| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| Fleet observability — agent/Crew state | Silence notices and the ledger's projections ([agent-to-agent communication](a2a/index.md)); the Playbook step pointer ([Playbooks](features/playbooks.md)); the Fleet page ([sidebar and roster](features/sidebar-and-roster.md)); status is read, never asked | A2A v1 plan; item 4; Playbooks candidate | +| Fleet observability — PR management | The [PR pane](features/pr-pane.md); playback of the ledger for review-decision audit | Pane approved, issue #6 | +| Fleet observability — cost | Cost rolls up per Squadron on the Fleet page | Item 4 | +| Human attention — lost/telephoned asks | The [inbox](features/inbox.md) with urgency; posture on the human-contact spectrum | A2A v1 plan | +| Human attention — drowned conversations | Spectrum posture + delegation to Crews (the human-contact spectrum lens) | Principle adopted; manifest posture is item 3 | +| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | +| Async-event blindness | Silence notices to waiters and time facts in envelopes ([agent-to-agent communication](a2a/index.md)); machine triggers as work sources (a recorded door) | A2A v1 plan | +| Context as bad memory | Status-is-read surfaces; time facts in envelopes; [Memos](features/memos.md); step injection ([Playbooks](features/playbooks.md)) | Principles adopted; candidates queued | +| Large, unsupervised groups | Exchanges with sender-judged completeness; silence measurement; Memo visibility for drift steering; the Fleet page | A2A v1 plan; item 4 | +| More work needs more cleanup | Archive never destroys work and is loud ([archive flow](features/archive-flow.md)); Crews archive as units and Captains archive what they command ([Crews](features/crews.md)); workspace cleanup tooling deferred | Register settled; tooling later | +| Traycer/T3 inheritances | A durable ledger instead of in-memory state; archive that never destroys work instead of over-eager cleanup; A2A and Squadrons instead of a parent-child-only flat list | A2A v1 plan | +| Roles in platform tooling | [Roles](features/roles.md): user-authored files the platform reads | Item 3 session | +| Crews | [Crews](features/crews.md) | Register settled; manifest schema is item 3 | +| Playbooks | [Playbooks](features/playbooks.md): the engine is the platform's, the steps are the user's | Backlog candidate | +| Shared Squadrons | [Shared Squadrons](features/shared-squadrons.md): the multi-person invariant in force now; an architecture session before any build | Backlog candidate | +| Agent cron/DB | Parked with a named trigger ([Memos](features/memos.md) records it) | Parked | +| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | + +## History + +- 2026-08-22 — captured in the foundations round of the design review ([record](../worklog/2026-08-21-design-review.md)). +- 2026-09-10 — register identifiers replaced by the definitions that now answer each problem; content unchanged. diff --git a/docs/j5/product/use-cases.md b/docs/j5/product/use-cases.md index 4c3d8d4127d4..1cea6cf7f967 100644 --- a/docs/j5/product/use-cases.md +++ b/docs/j5/product/use-cases.md @@ -1,11 +1,11 @@ --- title: "Use cases — the concrete fleets J5 Code must serve" -kind: spec +kind: definition --- # Use cases -This is the library behind lens 3 of [the machine](principles.md): run every feature through each use case here. A design that only serves one of them is suspect — the platform builds primitives, and a primitive proves itself by serving fleets that look nothing alike. These are the use cases of record today; more will be added as they become real. +This is the library behind the use-cases lens in [the principles](principles.md): run every feature through each use case here. A design that only serves one of them is suspect — the platform builds primitives, and a primitive proves itself by serving fleets that look nothing alike. These are the use cases of record today; more will be added as they become real. Both use cases are live prior art, not aspirations: rough versions of each already run (see [fleet-vision](fleet-vision.md) and the [prior-art studies](../research/jackson-prior-art/index.md)), which is what makes them useful stress tests — they come with observed failure modes, not imagined ones. @@ -13,13 +13,13 @@ Both use cases are live prior art, not aspirations: rough versions of each alrea One person runs many long-lived agents that build code, open PRs, and carry them to merge. The canonical unit is the **PR Group**: a Crew of three Roles — a Builder who writes and tests the code, a Reviewer who reviews independently and responds to human/agent review comments in the PR thread, and a Sitter who monitors the PR, communicates outside the group, and triages CI. Captains run several such Crews in parallel; the human sets direction, makes the calls that bubble up, and watches a dozen open PRs at a time. -What this use case demands of the platform: Crews spawned from definitions and worked with high independence; A2A Exchanges so groups coordinate without the human relaying; PR visibility measured from GitHub, never recalled by agents; Playbooks so long multi-step flows (build → review → babysit → merge) survive context decay; the inbox for the asks that genuinely need the human; the observability dashboard for "why isn't this PR moving." +What this use case demands of the platform: Crews spawned from definitions and worked with high independence; A2A Exchanges so groups coordinate without the human relaying; PR visibility measured from GitHub, never recalled by agents; Playbooks so long multi-step flows (build → review → babysit → merge) survive context decay; the inbox for the asks that genuinely need the person; the Fleet page for "why isn't this PR moving." -Characteristic load: mostly Background agents; work enters from humans _and_ from machine events (CI results, review comments); the scarce resource is the human's attention across many parallel work streams. Critically, however, the Captain is a Foreground agent that understands the build targets for its Crews, and may coordinate between them and other agents and the human. +Characteristic load: mostly Background agents; work enters from humans _and_ from machine events (CI results, review comments); the scarce resource is the human's attention across many parallel work streams. Critically, however, the Captain is usually a Foreground agent that understands the build targets for its Crews, and may coordinate between them and other agents and the person. ## 2. Production monitoring -A fleet that watches production software using observability data (Dynatrace today). Scraping code runs on a schedule, applies heuristics, and flags anomalies worth an AI's attention; a triage agent investigates, discards false positives, and routes real problems; a Director agent serves as the human's point of contact and spawns Incident Commanders per incident; standing Captains run longer-term programs (logging improvement, cost control, cleanup) with their own Crews. The structure is a long-lived organization, not a task execution — Captains and teams persist for weeks. +A fleet that watches production software using observability data (Dynatrace today). Scraping code runs on a schedule, applies heuristics, and flags anomalies worth an AI's attention; a triage agent investigates, discards false positives, and routes real problems; a Director agent serves as the human's point of contact and spawns Incident Commanders per incident; standing Captains run longer-term programs (logging improvement, cost control, cleanup) with their own Crews. The structure is a long-lived organization, not a task execution — Captains and their Crews persist for weeks. What this use case demands of the platform: durable schedules and machine triggers as first-class work sources (`trigger.fired` roots — no human prompt starts the chain); typed silence and the stall report, because almost every agent is Background and nobody watches their chats; deep hierarchy with attention that aggregates upward; cost visibility (one Captain exists specifically to stay in budget); supporting stores (the scraper, the incident DB) living _outside_ the platform. @@ -29,4 +29,9 @@ This use case is the standing test from the fleet vision: **"does this work for A chapter of the monitoring story that brings enough differentiating requirements to stand on its own: a level-2 support team shares Squadrons, so when one person goes off shift the next picks up the Squadron immediately — **no context transfer**. It also puts **two humans in front of the same agent**: today developers relay agent output to each other over Slack/Teams; putting both people in the same conversation removes the relay entirely. -What it demands beyond monitoring: everything in [Shared Squadrons](features/shared-squadrons.md) — the multi-human invariant, person-scoped surfaces, one-user-or-all-users delivery, and eventually duty-based addressing ("the on-call"). It is the reason multi-human constraints bind _today_ even though the capability ships later. +What it demands beyond monitoring: everything in [Shared Squadrons](features/shared-squadrons.md) — the multi-person invariant, person-scoped surfaces, one-person-or-everyone delivery, and eventually duty-based addressing ("the on-call"). It is the reason multi-person constraints bind _today_ even though the capability ships later. + +## History + +- 2026-08-23 — written as the library behind the use-cases lens. +- 2026-09-10 — vocabulary aligned with the glossary (Crews, the Fleet page, person); content unchanged. diff --git a/docs/j5/worklog/2026-08-17-pr-pane-brief.md b/docs/j5/worklog/2026-08-17-pr-pane-brief.md new file mode 100644 index 000000000000..574bdbaf67fc --- /dev/null +++ b/docs/j5/worklog/2026-08-17-pr-pane-brief.md @@ -0,0 +1,6 @@ +--- +title: "PR Pane v1 — the brief as posted (2026-08-17)" +kind: record +--- + +> **Record.** The product brief for the PR pane as approved by Jackson and posted to [issue #6](https://github.com/Jacksondr5/j5code/issues/6) on 2026-08-17, with the review wireframe and the seams noted then. The definition of record is now [`../product/features/pr-pane.md`](../product/features/pr-pane.md). Kept unedited. From ad9bcea1f548a95775c6f44178f61c2c72fee410 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Thu, 10 Sep 2026 20:40:41 -0400 Subject: [PATCH 12/15] =?UTF-8?q?docs(j5):=20mechanical=20sweep=20?= =?UTF-8?q?=E2=80=94=20records=20renamed=20date-first=20with=20frontmatter?= =?UTF-8?q?,=20research=20stamped=20as=5Fof,=20runbooks=20under=20runbooks?= =?UTF-8?q?/,=20process=20classified,=20README=20rewritten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- FORK.md | 2 +- docs/j5/README.md | 78 +++++-------------- docs/j5/process/index.md | 2 +- docs/j5/process/working-in-the-repo.md | 2 +- docs/j5/product/a2a/agent-tools.md | 8 +- docs/j5/product/a2a/index.md | 10 +-- docs/j5/product/a2a/substrate.md | 6 +- docs/j5/product/features/archive-flow.md | 2 +- docs/j5/product/features/crews.md | 4 +- docs/j5/product/features/inbox.md | 4 +- docs/j5/product/features/roles.md | 4 +- .../j5/product/features/sidebar-and-roster.md | 2 +- docs/j5/product/features/spawning-guide.md | 2 +- docs/j5/product/features/squadron.md | 6 +- .../product/features/thread-a2a-rendering.md | 4 +- docs/j5/product/glossary.md | 2 +- docs/j5/product/principles.md | 4 +- docs/j5/research/index.md | 4 +- .../fleet-interviews-synthesis.md | 3 +- docs/j5/research/jackson-prior-art/index.md | 3 +- .../jackson-prior-art/live-fleet-questions.md | 3 +- .../jackson-prior-art/pr-group-dashboard.md | 3 +- .../j5/research/jackson-prior-art/pr-group.md | 3 +- docs/j5/research/remote-hosting.md | 3 +- docs/j5/research/synthesis.md | 3 +- docs/j5/research/t3code/architecture.md | 3 +- docs/j5/research/t3code/feature-inventory.md | 3 +- docs/j5/research/t3code/fork-viability.md | 3 +- docs/j5/research/t3code/index.md | 3 +- .../t3code/multi-agent-and-providers.md | 3 +- docs/j5/research/t3code/orchestration-v2.md | 3 +- .../t3code/performance-and-quality.md | 3 +- docs/j5/research/t3code/remote.md | 3 +- docs/j5/research/traycer/agent-to-agent.md | 3 +- docs/j5/research/traycer/index.md | 3 +- .../j5/research/traycer/organization-model.md | 3 +- docs/j5/research/traycer/performance.md | 3 +- docs/j5/{ => runbooks}/agent-migration.md | 6 +- docs/j5/{ => runbooks}/dogfood-runtime.md | 9 ++- docs/j5/{ => runbooks}/macos-packaging.md | 5 ++ ...26-08-23-pr-8-coderabbit-triage-review.md} | 2 +- ...-08-23.md => 2026-08-23-priority-input.md} | 5 ++ ...3.md => 2026-08-23-roles-crews-session.md} | 5 ++ ...> 2026-08-24-spawn-terminology-session.md} | 5 ++ ...> 2026-08-24-squadron-creation-session.md} | 5 ++ ....md => 2026-08-29-archive-flow-session.md} | 5 ++ ...6-08-29.md => 2026-08-29-inbox-session.md} | 5 ++ ...d => 2026-08-29-sidebar-roster-session.md} | 5 ++ ...-29.md => 2026-08-29-substrate-session.md} | 5 ++ ...29.md => 2026-08-29-thread-a2a-session.md} | 5 ++ ...-upstream-settled-vs-archived-research.md} | 5 ++ ...-08-30.md => 2026-08-30-priority-input.md} | 5 ++ ...d => 2026-08-30-spawning-guide-session.md} | 5 ++ ...8-31-picker-and-self-messaging-rulings.md} | 5 ++ ...26-08-31-thread-a2a-prominence-session.md} | 5 ++ ...026-09-02-human-addressed-sends-ruling.md} | 5 ++ ...md => 2026-09-03-queue-vs-steer-ruling.md} | 7 +- ...4.md => 2026-09-04-astra-peer-delivery.md} | 5 ++ .../a1-ledger-epic-entity/index.md | 3 +- .../a1-ledger-epic-entity/migration-lane.md | 2 +- .../a2a-tickets/a1-ledger-epic-entity/pr-4.md | 3 +- .../a1-ledger-epic-entity/sitter-retro.md | 2 +- .../a2a-tickets/a10-silence-fact-bundles.md | 5 +- .../a2-send-deliver-reply/index.md | 3 +- .../a2a-tickets/a2-send-deliver-reply/pr-7.md | 3 +- .../a2-send-deliver-reply/proof.md | 2 +- .../a2-send-deliver-reply/retrospective.md | 2 +- .../squadron-rename-pr.md | 3 +- .../upstream-dedup-ground-truth.md | 2 +- .../a2a-tickets/a3-silence-detector/index.md | 3 +- .../a2a-tickets/a3-silence-detector/pr-9.md | 3 +- .../a2a-tickets/a3-silence-detector/review.md | 2 +- .../sitter-initial-audit.md | 2 +- docs/j5/worklog/a2a-tickets/a4-human-node.md | 3 +- .../worklog/a2a-tickets/a5-graph-read-api.md | 5 +- .../feasibility-audit.md | 2 +- .../a6-placement-provenance/index.md | 3 +- .../reviewer-feasibility.md | 2 +- .../reviewer-verdict-core.md | 2 +- .../reviewer-verdict-integration.md | 2 +- .../worklog/a2a-tickets/a7-upstream-rebase.md | 3 +- .../a2a-tickets/a8-envelope-true-up.md | 5 +- .../a2a-tickets/a9-lifecycle-closure.md | 5 +- docs/j5/worklog/a2a-tickets/index.md | 2 +- .../dogfood-tickets/b1-inbox-true-up.md | 3 +- .../b3-thread-a2a-rendering.md | 3 +- .../dogfood-tickets/b6-client-reads.md | 3 +- .../b7-thread-card-treatment.md | 5 +- .../e7-squadron-picker-conversion.md | 5 +- .../dogfood-tickets/sq1-creation-surface.md | 7 +- docs/j5/worklog/fork-setup-plan/baseline.md | 2 +- docs/j5/worklog/fork-setup-plan/index.md | 2 +- docs/j5/worklog/fork-setup-plan/load-test.md | 2 +- .../fork-setup-plan/relay-assessment.md | 2 +- .../fork-setup-plan/tickets/build-baseline.md | 3 +- .../fork-setup-plan/tickets/ci-packaging.md | 3 +- .../tickets/fleet-load-test.md | 3 +- .../worklog/fork-setup-plan/tickets/index.md | 2 +- .../tickets/planetscale-investigation.md | 3 +- .../fork-setup-plan/tickets/rebrand.md | 3 +- .../fork-setup-plan/tickets/repo-setup.md | 3 +- scripts/j5/dogfood-local.sh | 2 +- scripts/j5/dogfood-snapshot.sh | 2 +- scripts/j5/dogfood-update.sh | 4 +- 104 files changed, 250 insertions(+), 198 deletions(-) rename docs/j5/{ => runbooks}/agent-migration.md (99%) rename docs/j5/{ => runbooks}/dogfood-runtime.md (98%) rename docs/j5/{ => runbooks}/macos-packaging.md (98%) rename docs/j5/worklog/{pr-8-coderabbit-triage-review.md => 2026-08-23-pr-8-coderabbit-triage-review.md} (99%) rename docs/j5/worklog/{priority-input-2026-08-23.md => 2026-08-23-priority-input.md} (97%) rename docs/j5/worklog/{roles-crews-session-2026-08-23.md => 2026-08-23-roles-crews-session.md} (99%) rename docs/j5/worklog/{spawn-terminology-session-2026-08-24.md => 2026-08-24-spawn-terminology-session.md} (98%) rename docs/j5/worklog/{squadron-creation-session-2026-08-24.md => 2026-08-24-squadron-creation-session.md} (98%) rename docs/j5/worklog/{archive-flow-session-2026-08-29.md => 2026-08-29-archive-flow-session.md} (97%) rename docs/j5/worklog/{inbox-session-2026-08-29.md => 2026-08-29-inbox-session.md} (98%) rename docs/j5/worklog/{sidebar-roster-session-2026-08-29.md => 2026-08-29-sidebar-roster-session.md} (98%) rename docs/j5/worklog/{substrate-session-2026-08-29.md => 2026-08-29-substrate-session.md} (98%) rename docs/j5/worklog/{thread-a2a-session-2026-08-29.md => 2026-08-29-thread-a2a-session.md} (97%) rename docs/j5/worklog/{upstream-settled-vs-archived-research-2026-08-29.md => 2026-08-29-upstream-settled-vs-archived-research.md} (98%) rename docs/j5/worklog/{priority-input-2026-08-30.md => 2026-08-30-priority-input.md} (96%) rename docs/j5/worklog/{spawning-guide-session-2026-08-30.md => 2026-08-30-spawning-guide-session.md} (98%) rename docs/j5/worklog/{picker-and-self-messaging-rulings-2026-08-31.md => 2026-08-31-picker-and-self-messaging-rulings.md} (96%) rename docs/j5/worklog/{thread-a2a-prominence-session-2026-08-31.md => 2026-08-31-thread-a2a-prominence-session.md} (98%) rename docs/j5/worklog/{human-addressed-sends-ruling-2026-09-02.md => 2026-09-02-human-addressed-sends-ruling.md} (98%) rename docs/j5/worklog/{queue-vs-steer-ruling-2026-09-03.md => 2026-09-03-queue-vs-steer-ruling.md} (98%) rename docs/j5/worklog/{astra-peer-delivery-2026-09-04.md => 2026-09-04-astra-peer-delivery.md} (98%) diff --git a/FORK.md b/FORK.md index c3358544c44e..d5afca5cca9e 100644 --- a/FORK.md +++ b/FORK.md @@ -266,7 +266,7 @@ Fork-owned workflows use the Node version in `.nvmrc`, pnpm `11.10.0`, the froze the repo-local Vite Plus binary. `J5 CI` is the push/PR gate for `j5/**`; `J5 Weekly Full Build` is the scheduled and manually dispatchable pre-rebase suite plus Apple Silicon desktop build. -See [`docs/j5/macos-packaging.md`](docs/j5/macos-packaging.md) for the local build, signature +See [`docs/j5/runbooks/macos-packaging.md`](docs/j5/runbooks/macos-packaging.md) for the local build, signature verification, install, Gatekeeper approval, and workflow runbook. ## Final upstream-file review — 2026-09-06 diff --git a/docs/j5/README.md b/docs/j5/README.md index c7bc69fe2ab7..8ad70e5f6c38 100644 --- a/docs/j5/README.md +++ b/docs/j5/README.md @@ -1,69 +1,27 @@ -# J5 design docs — mirrored from the design workspace +# J5 documentation -This tree mirrors the durable product, research, and planning documents for the -J5 fleet-management effort. They were authored in the team's agent design -workspace (Traycer epic artifacts) and are mirrored here so anyone working in -this repo — human or agent — can read the reasoning behind the build without -access to that workspace. +Everything about J5 Code — the product built on this fork of T3 Code — lives under `docs/j5/`. Upstream's own documentation (`docs/user/`, `docs/internals/`, `docs/operations/`) is left as upstream wrote it; J5 never edits it. -**The mirror is a snapshot, not the working medium.** Design sessions continue -in the workspace; settled changes land here through docs PRs. Each document -describes the codebase and decisions _as of when it was written_ — check dates -before treating details as current. Documents carry YAML frontmatter from the -source system (`kind`: spec = durable context, ticket/story = work items with -`status` 0/1/2 = todo/in-progress/done); it is preserved for fidelity. -Note: this tree was reorganized 2026-08-23 (single-doc folders flattened to -`topic.md`, feature docs grouped under `features/`), so its layout no longer -matches the workspace's folder structure — content, not paths, is what mirrors. +Every document here is one of five kinds, and the kind tells you how far to trust it: **definitions** describe the product and are kept true; **plans** sequence work and are history once executed; **research** reports what we learned as of a date; **records** say what happened on a day; **runbooks** tell an operator what to do. The kinds, their lifetimes, the identifier scheme, and the rules for changing a definition are in [how the docs are organized](process/docs.md) — read it before writing anything here. ## Reading order for newcomers -1. `product/problems.md` — what hurts and what's wanted: the problem statement - and goals, in Jackson's voice. -2. `product/fleet-vision.md` — why this exists: the operating model and thesis. -3. `product/principles.md` — the beliefs, lenses, and principles: the machine - that turns the problems and goals into product. -4. `product/use-cases.md` — the concrete fleets every feature is tested - against. -5. `research/synthesis.md` — what we learned from T3 Code and Traycer, and the - engineering principles adopted from each. -6. `research/jackson-prior-art/fleet-interviews-synthesis.md` — field lessons - from a real production agent fleet, and the platform/non-platform boundary - that governs scope decisions. -7. `worklog/2026-08-14-decision-log.md` — every settled product decision, one row each. -8. `product/a2a/` — the A2A (agent-to-agent communication) design: decision - register, grounding model, and `plan.md` with the milestone plan. -9. `product/features/` — the feature definitions of record: Squadrons, Crews, - Roles, Playbooks, Memos, Shared Squadrons, and the PR pane. +1. [Problems and goals](product/problems.md) — what hurts and what is wanted, in Jackson's voice. +2. [Fleet vision](product/fleet-vision.md) — why this exists: the operating model and the thesis. +3. [Principles](product/principles.md) — the beliefs, lenses and principles that turn the problems into product. +4. [Use cases](product/use-cases.md) — the concrete fleets every feature is tested against. +5. [Glossary](product/glossary.md) — the vocabulary; every name in these docs resolves here. +6. [Agent-to-agent communication](product/a2a/index.md), then [Squadron](product/features/squadron.md) — the two definitions everything else stands on. +7. The rest of [`product/features/`](product/features/) — the feature definitions of record. +8. [Research synthesis](research/synthesis.md) — what we learned from T3 Code and Traycer. ## Contents -- `worklog/2026-08-14-backlog.md` — the prioritized roadmap. -- `product/features/` — feature definitions of record: `squadron.md`, - `crews.md`, `roles.md`, `playbooks.md`, `memos.md`, `shared-squadrons.md`, - `pr-pane.md`. -- `product/` — product designs and decisions: problems & goals, the - beliefs/lenses/principles machine, use cases, decision log, fleet vision, - glossary, the A2A design + plan, communication graph, cross-device position, - and the 2026-08-21 design-review register that defined Crews/Roles/Captains. -- `research/` — the studies behind the decisions: T3 Code deep dives (the - upstream this repo forks), Traycer's A2A/organization model, and the - prior-art fleet studies. A quarantined, superseded early T3 snapshot was - deliberately not mirrored. -- `process/` — contributor-facing rules for working in this repository. How the - agent fleet is run is Jackson's personal practice and lives outside the product - repo, in his playbooks. -- `worklog/` — build-time records, kept out of the evergreen docs: the A2A - implementation tickets with their reviews and retros (`a2a-tickets/`), how - this fork was established (`fork-setup-plan/` — base pin, rebrand, CI, - load-test baseline), and PR triage reviews. Historical by nature; read the - product docs for current truth. +- **`product/`** — definitions: the core documents above, the [A2A trio](product/a2a/) (the communication protocol, the upstream substrate, the agent tool contracts), and [`features/`](product/features/) (Squadron, inbox, thread rendering, archive flow, Roles, Crews, Memos, Playbooks, Spawning Guide, sidebar and roster, PR pane, Shared Squadrons). +- **`plans/`** — the [dogfood v0 plan](plans/dogfood-v0.md) and the [A2A plan](plans/a2a.md). Build status against a definition's criteria lives only here. The backlog beyond these is the repository's GitHub milestones, in outcome order. +- **`research/`** — the studies behind the decisions: T3 Code, Traycer, the prior-art fleets, remote hosting. Each carries an `as_of` date; none is a source of truth about the product. +- **`worklog/`** — records, named date-first: design sessions and rulings, the tickets and reviews of the A2A build and the dogfood queue, how the fork was set up, the phase-3 friction list. +- **`runbooks/`** — operating the software: the [dogfood runtime](runbooks/dogfood-runtime.md), [agent migration](runbooks/agent-migration.md), [macOS packaging](runbooks/macos-packaging.md). +- **`process/`** — rules for working in this repository: [how the docs are organized](process/docs.md) and [working in the repo](process/working-in-the-repo.md). How the fleet is run day to day is the operator's own practice and lives outside the repository. -Cross-references between documents use relative paths and survive within this -tree. References to `interviews/` point at the public -`Jacksondr5/pr-group` repository. - -## Not part of the mirror - -Hand-written fork docs coexist in this directory (currently `macos-packaging.md`). -Mirror refreshes must exclude them — they are owned in-repo, not in the workspace. +Cross-references are relative paths and survive within this tree. diff --git a/docs/j5/process/index.md b/docs/j5/process/index.md index 1e511268c248..ccb809f77915 100644 --- a/docs/j5/process/index.md +++ b/docs/j5/process/index.md @@ -1,6 +1,6 @@ --- title: "Process" -kind: spec +kind: process --- # Process diff --git a/docs/j5/process/working-in-the-repo.md b/docs/j5/process/working-in-the-repo.md index e30d4f88ce33..5c32a45280b0 100644 --- a/docs/j5/process/working-in-the-repo.md +++ b/docs/j5/process/working-in-the-repo.md @@ -1,6 +1,6 @@ --- title: "Working in the repo — tool traps, repo facts, and contributor rules" -kind: spec +kind: process --- # Working in the repo diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index d30d9f1e7df2..bf061c926499 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -142,10 +142,10 @@ No inputs. Read-only; no events. ## History -- 2026-08-29 — contracts adopted: descriptions as part of the contract, the toolsmith rule, single-target stop and archive, the confirmation-token archive ([record](../../worklog/substrate-session-2026-08-29.md)). -- 2026-08-30 — the spawn brief carries the task and the reply expectation; one sentence of brief steering in `spawn_agent` ([record](../../worklog/spawning-guide-session-2026-08-30.md)). -- 2026-08-31 — self-send refused; the `self` row; identity facts in the spawn's first turn; `display_name` on every row; `create_threads` and `t3_thread_start` omitted ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). -- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-08-29 — contracts adopted: descriptions as part of the contract, the toolsmith rule, single-target stop and archive, the confirmation-token archive ([record](../../worklog/2026-08-29-substrate-session.md)). +- 2026-08-30 — the spawn brief carries the task and the reply expectation; one sentence of brief steering in `spawn_agent` ([record](../../worklog/2026-08-30-spawning-guide-session.md)). +- 2026-08-31 — self-send refused; the `self` row; identity facts in the spawn's first turn; `display_name` on every row; `create_threads` and `t3_thread_start` omitted ([record](../../worklog/2026-08-31-picker-and-self-messaging-rulings.md)). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/2026-09-02-human-addressed-sends-ruling.md)). - 2026-09-08 — a person receives asks only; the reply form toward a person is retired with the person-originated ask. - 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). - 2026-09-05 — a committed stop wins over restart continuation (upstream integration, PR #112). diff --git a/docs/j5/product/a2a/index.md b/docs/j5/product/a2a/index.md index a723543738b3..47def44ba3d6 100644 --- a/docs/j5/product/a2a/index.md +++ b/docs/j5/product/a2a/index.md @@ -149,9 +149,9 @@ message, ask, reply, plain message, Exchange, intent, urgency, obligation, envel - 2026-08-14 — the communication graph drafted; former open questions 1–4 ([record](../../worklog/2026-08-14-communication-graph-draft.md)). - 2026-08-16 — design settled; former D1–D10, this file's earlier form. - 2026-08-21 — design review: former R3 (closure is mechanical, completeness is the sender's judgment), R4 (notices are measured facts; labels are read-time policy), R10 (a follow-up may name an earlier Exchange), R22 (Captains are never routers), R25 (time facts in envelopes) ([record](../../worklog/2026-08-21-design-review.md)). -- 2026-08-24 — Subagent and Peer Agent distinguished; `delegate_task` excluded, so former D1's delegation edges no longer exist ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). -- 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). -- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). -- 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)). 2026-09-05 — the person-side default returns to upstream's (steer on send, an explicit queue shortcut) with the upstream integration (PR #112); the agent-side queue policy, the Astra exception and the truthful-steer guard stand, and the two policies are recorded as independent. -- 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)); 2026-09-08 — a person never opens an ask through the platform; their only ledger act is the closing answer (the 2026-08-14 design's person-as-sender is dropped; the unused person-origin envelope channel goes with it, issue #119). Same day, the delivery guidance that path appended ("continue the unfinished task… change course only when the user's instructions require it") is removed: an agent told by a peer that it should change course should not wait for a user who may never come; the model's behavior is observed instead (issue filed). +- 2026-08-24 — Subagent and Peer Agent distinguished; `delegate_task` excluded, so former D1's delegation edges no longer exist ([record](../../worklog/2026-08-24-spawn-terminology-session.md)). +- 2026-08-31 — self-send refused; identity facts stated by the platform ([record](../../worklog/2026-08-31-picker-and-self-messaging-rulings.md)). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/2026-09-02-human-addressed-sends-ruling.md)). +- 2026-09-03 — agent deliveries queue; only the person steers; former QS1–QS4 ([record](../../worklog/2026-09-03-queue-vs-steer-ruling.md)). 2026-09-05 — the person-side default returns to upstream's (steer on send, an explicit queue shortcut) with the upstream integration (PR #112); the agent-side queue policy, the Astra exception and the truthful-steer guard stand, and the two policies are recorded as independent. +- 2026-09-04 — the Codex Astra exception ([record](../../worklog/2026-09-04-astra-peer-delivery.md)); 2026-09-08 — a person never opens an ask through the platform; their only ledger act is the closing answer (the 2026-08-14 design's person-as-sender is dropped; the unused person-origin envelope channel goes with it, issue #119). Same day, the delivery guidance that path appended ("continue the unfinished task… change course only when the user's instructions require it") is removed: an agent told by a peer that it should change course should not wait for a user who may never come; the model's behavior is observed instead (issue filed). - 2026-09-05 — rewritten into the definition shape; 2026-09-07 — provenance and placement moved to the Squadron definition (they are organization, not communication). One change of substance: an agent may hold several open asks to a person, with explicit follow-ups shown in the inbox — reversing the one-ask-per-person rule of 2026-09-02 (issue #111). Former identifiers: D1 → Participants (delegation half retired); D2 → Participants; D3, D8 → The ledger, AC3; D4 → AC5; D5 → Delivery, AC1; D6 → Silence, AC20; D7 → the A2A plan; D9 → The Exchange; D10 → the Squadron definition (placement and provenance), with its obligation half being the Exchange; R3 → How an Exchange works, AC9; R4 → Silence; R21 → the Squadron definition; R22 → Participants; R25 → Envelopes, AC22; QS1–QS4 → Delivery, AC13–AC15. diff --git a/docs/j5/product/a2a/substrate.md b/docs/j5/product/a2a/substrate.md index f0a5600b098a..f1f8e33e78af 100644 --- a/docs/j5/product/a2a/substrate.md +++ b/docs/j5/product/a2a/substrate.md @@ -67,8 +67,8 @@ Agents spawned through upstream's delegation path before the spawn verb existed ## History -- 2026-08-24 — Subagent and Peer Agent distinguished; delegation excluded from the product surface ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). -- 2026-08-29 — the substrate line drawn: the four dispositions, the ownership rule, the fail-closed tool subset ([record](../../worklog/substrate-session-2026-08-29.md)). +- 2026-08-24 — Subagent and Peer Agent distinguished; delegation excluded from the product surface ([record](../../worklog/2026-08-24-spawn-terminology-session.md)). +- 2026-08-29 — the substrate line drawn: the four dispositions, the ownership rule, the fail-closed tool subset ([record](../../worklog/2026-08-29-substrate-session.md)). - 2026-08-31 — `create_threads` and `t3_thread_start` omitted; `clear_own_ask` built. -- 2026-09-03 — delivery queues behind an active turn; steering is the person's act ([record](../../worklog/queue-vs-steer-ruling-2026-09-03.md)); 2026-09-04 — the Codex Astra exception ([record](../../worklog/astra-peer-delivery-2026-09-04.md)). +- 2026-09-03 — delivery queues behind an active turn; steering is the person's act ([record](../../worklog/2026-09-03-queue-vs-steer-ruling.md)); 2026-09-04 — the Codex Astra exception ([record](../../worklog/2026-09-04-astra-peer-delivery.md)). - 2026-09-07 — rewritten into the definition shape; stale rows (the open `create_threads` row, "needed-but-unbuilt" `clear_own_ask`, the pending prompt-text edit, Squadron creation as "nothing exists") corrected to the current state. diff --git a/docs/j5/product/features/archive-flow.md b/docs/j5/product/features/archive-flow.md index 78735c2c61c7..7cb6821e1173 100644 --- a/docs/j5/product/features/archive-flow.md +++ b/docs/j5/product/features/archive-flow.md @@ -57,6 +57,6 @@ This is **not** a delete, **not** a way to archive a single Crew member, and **n ## History - 2026-08-21 — archive is loud and never destroys work; Crews archive as units; archiving with open Exchanges warns with count, list and confirmation ([record](../../worklog/2026-08-21-design-review.md); former R1, R14, R15 and the Roles/Crews session's J1–J3). -- 2026-08-29 — the flow designed; former AR1–AR4 ([record](../../worklog/archive-flow-session-2026-08-29.md)). +- 2026-08-29 — the flow designed; former AR1–AR4 ([record](../../worklog/2026-08-29-archive-flow-session.md)). - 2026-09-01 — ask-row anatomy mirrors the inbox item; former AR5 (Jackson's live review of the archive build). - 2026-09-08 — rewritten into the definition shape. Former identifiers: AR1 → AC11; AR2 → AC1; AR3 → AC2–AC5; AR4 → AC6–AC9; AR5 → AC3–AC4; J1–J3 → AC3, AC5. Build sequencing that lived here (the dialog shipping ahead of waiter notices) is history. diff --git a/docs/j5/product/features/crews.md b/docs/j5/product/features/crews.md index d5fb1e1cad45..4f4f440f55dc 100644 --- a/docs/j5/product/features/crews.md +++ b/docs/j5/product/features/crews.md @@ -76,6 +76,6 @@ The platform ships the machinery — define, spawn, render, warn, archive. The P ## History - 2026-08-21 — the concept: definition versus instance, archive as a unit, archive never destroys work, agents spawn Crews, one Squadron, Captains as derived status, Captain archive rights, members cannot spawn Crews, "you command what you brief", Captains never routers; former R12–R22 ([record](../../worklog/2026-08-21-design-review.md)). "Team" retired as a word. -- 2026-08-23 — the product session: structured-only validation, archive and respawn as judgment moments with a fresh brief; former P-E and J1–J3 ([record](../../worklog/roles-crews-session-2026-08-23.md)). -- 2026-08-24 — whether Crew members may spawn solo Peer Agents is deliberately left open until Crews are built and a real Crew's behavior can be observed ([record](../../worklog/spawn-terminology-session-2026-08-24.md)). +- 2026-08-23 — the product session: structured-only validation, archive and respawn as judgment moments with a fresh brief; former P-E and J1–J3 ([record](../../worklog/2026-08-23-roles-crews-session.md)). +- 2026-08-24 — whether Crew members may spawn solo Peer Agents is deliberately left open until Crews are built and a real Crew's behavior can be observed ([record](../../worklog/2026-08-24-spawn-terminology-session.md)). - 2026-09-08 — rewritten into the definition shape; "git-versioned" aligned with Roles ("git optional"); posture stated as a lean, not a rule. Former identifiers: R12 → AC1; R14 → AC12; R15 → AC13; R16 → AC9; R17 → AC4–AC5; R18 → AC8; R19 → AC11; R20 → AC10; R21, R22 → Captains; P-E → AC2–AC3; J1–J3 → AC14–AC15. The open question on members spawning solo Peer Agents stays open, recorded above. diff --git a/docs/j5/product/features/inbox.md b/docs/j5/product/features/inbox.md index b1d4b27f95e0..8019dd380992 100644 --- a/docs/j5/product/features/inbox.md +++ b/docs/j5/product/features/inbox.md @@ -65,8 +65,8 @@ The inbox is **not** a backlog (a non-blocking note an agent wants to keep is a ## History -- 2026-08-29 — designed; former IB1–IB7 ([record](../../worklog/inbox-session-2026-08-29.md)). +- 2026-08-29 — designed; former IB1–IB7 ([record](../../worklog/2026-08-29-inbox-session.md)). - 2026-08-31 — the bell moves to the rail header (Jackson's review of the inbox build). -- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/human-addressed-sends-ruling-2026-09-02.md)). +- 2026-09-02 — a person receives only asks and replies ([record](../../worklog/2026-09-02-human-addressed-sends-ruling.md)). - 2026-09-05 — several open asks per agent and person, with follow-ups shown beneath the original (issue #111); the shelf is named "Replied", the one word for a closed Exchange on every surface (glossary). - 2026-09-08 — rewritten into the definition shape. Former identifiers: IB1 → Answering, AC8–AC9; IB2 → AC13; IB3–IB4 → AC5–AC6; IB5 → AC10; IB6 → AC11; IB7 → AC12. The "clear-own-ask has no build ticket" note is gone: the verb shipped. The deferred items that lived here (a platform-alerts lane, the asker's current state on items, smaller inbox forms) are backlog candidates, not part of this definition. diff --git a/docs/j5/product/features/roles.md b/docs/j5/product/features/roles.md index d1eb230b158a..826dd2fb458b 100644 --- a/docs/j5/product/features/roles.md +++ b/docs/j5/product/features/roles.md @@ -72,6 +72,6 @@ A Role is **not** a runtime object (the agent is), **not** a permission boundary ## History - 2026-08-21 — identity is git-versioned definition files with no memory in the bundle; machine-read fields wrap the prose (former R8, R28; posture rider of former R23) ([record](../../worklog/2026-08-21-design-review.md)). -- 2026-08-23 — the product session: app as editing surface, composer Role dropdown, two-section identity with no prompt, drift never hot-reloads, structured-only validation, minimal in-app git; former P-A–P-F ([record](../../worklog/roles-crews-session-2026-08-23.md)). -- 2026-08-30 — provider, model and reasoning stay explicit on agent spawns even with a Role; the allowlist constrains ([record](../../worklog/spawning-guide-session-2026-08-30.md)). +- 2026-08-23 — the product session: app as editing surface, composer Role dropdown, two-section identity with no prompt, drift never hot-reloads, structured-only validation, minimal in-app git; former P-A–P-F ([record](../../worklog/2026-08-23-roles-crews-session.md)). +- 2026-08-30 — provider, model and reasoning stay explicit on agent spawns even with a Role; the allowlist constrains ([record](../../worklog/2026-08-30-spawning-guide-session.md)). - 2026-09-08 — rewritten into the definition shape; posture stated with the middle of the spectrum allowed, matching the lens. Former identifiers: R8 → AC1, Definition (no memory); R28 → AC1, AC5; P-A, P-F → AC7–AC9; P-B(h) → AC11–AC13; P-B(a) → AC14; P-C → AC3–AC4; P-D → AC15–AC16; P-E → AC17. Deferred items that lived here (Role claims, multiple library locations) are backlog candidates. diff --git a/docs/j5/product/features/sidebar-and-roster.md b/docs/j5/product/features/sidebar-and-roster.md index 0a361457d842..10d2477d16e7 100644 --- a/docs/j5/product/features/sidebar-and-roster.md +++ b/docs/j5/product/features/sidebar-and-roster.md @@ -6,7 +6,7 @@ kind: spec # Sidebar & roster Feature definition of record, settled 2026-08-29 with Jackson -([session rulings SB1–SB7](../../worklog/sidebar-roster-session-2026-08-29.md)). +([session rulings SB1–SB7](../../worklog/2026-08-29-sidebar-roster-session.md)). The problems it serves ([problems doc](../problems.md)): fleet observability ("it's hard to see what agents you aren't talking to are doing") and scarce human attention. Approved mockups live in the design diff --git a/docs/j5/product/features/spawning-guide.md b/docs/j5/product/features/spawning-guide.md index b60d22511194..5cfe8917bba2 100644 --- a/docs/j5/product/features/spawning-guide.md +++ b/docs/j5/product/features/spawning-guide.md @@ -42,5 +42,5 @@ Roles compose with the guide rather than replacing it: with a Role, the allowlis ## History - 2026-08-29 — provider, model and reasoning become required on every spawn. -- 2026-08-30 — the guide defined: ownership split, two sections, Roles compose, one sentence of brief steering in the spawn tool; former SP1–SP4 ([record](../../worklog/spawning-guide-session-2026-08-30.md)). +- 2026-08-30 — the guide defined: ownership split, two sections, Roles compose, one sentence of brief steering in the spawn tool; former SP1–SP4 ([record](../../worklog/2026-08-30-spawning-guide-session.md)). - 2026-09-08 — rewritten into the definition shape. Former identifiers: SP1 → Definition (ownership), AC1–AC3, AC5; SP2 → Definition (two sections); SP3 → Definition (Roles compose), AC4; SP4 → Definition (brief conventions; acknowledgements). The example guide that lived in this document is user-space content and belongs with the example Role library, not in a definition. diff --git a/docs/j5/product/features/squadron.md b/docs/j5/product/features/squadron.md index 4a6c82c7efab..3b76d18e6089 100644 --- a/docs/j5/product/features/squadron.md +++ b/docs/j5/product/features/squadron.md @@ -58,8 +58,8 @@ The current build ([dogfood v0](../../plans/dogfood-v0.md)) narrows this definit ## History - 2026-08-17 — defined and named; former E1–E6 ([record](../../worklog/2026-08-17-squadron-naming.md); decision log). -- 2026-08-24 — creation and agent-creation experience; former SC1–SC4 ([record](../../worklog/squadron-creation-session-2026-08-24.md)). -- 2026-08-29 — sidebar scope replaces Squadron grouping in the sidebar; former SB3 ([record](../../worklog/sidebar-roster-session-2026-08-29.md)). -- 2026-08-31 — the Squadron is the unit of user choice; former E7 ([record](../../worklog/picker-and-self-messaging-rulings-2026-08-31.md)). +- 2026-08-24 — creation and agent-creation experience; former SC1–SC4 ([record](../../worklog/2026-08-24-squadron-creation-session.md)). +- 2026-08-29 — sidebar scope replaces Squadron grouping in the sidebar; former SB3 ([record](../../worklog/2026-08-29-sidebar-roster-session.md)). +- 2026-08-31 — the Squadron is the unit of user choice; former E7 ([record](../../worklog/2026-08-31-picker-and-self-messaging-rulings.md)). - 2026-09-07 — placement and provenance moved here from the A2A definition (former D10 and R21): they are organization, not communication. - 2026-09-05 — rewritten into the definition shape. Two changes of substance: a Squadron targets one or more folders, so a folder is required at creation (the name-only Squadron is no longer planned — it would complicate upstream integration) and the folder-required v0 override becomes end-state truth; messages to people are no longer listed as Squadron contents (they belong to the inbox, which is person-scoped, not Squadron-scoped). Former identifiers: E1 → AC1; E2 → AC2; E3 → Definition; E4 → AC3; E5 → AC10; E6 → Definition; E7 → AC7; SC1 → AC5, AC6; SC2 → AC3, AC4; SC3 → AC8, AC9; SC4 → Scope; the A2 `join_epic` consequences → AC2, AC11. diff --git a/docs/j5/product/features/thread-a2a-rendering.md b/docs/j5/product/features/thread-a2a-rendering.md index cbf58a0fe641..e305fd419f93 100644 --- a/docs/j5/product/features/thread-a2a-rendering.md +++ b/docs/j5/product/features/thread-a2a-rendering.md @@ -76,8 +76,8 @@ This is **not** a change to what agents receive, **not** a summary layer, and ** ## History -- 2026-08-29 — the four treatments designed; former TA1–TA5 ([record](../../worklog/thread-a2a-session-2026-08-29.md)). -- 2026-08-31 — three amendments from Jackson's live test of the first build: no envelope expander on parsed cards (the raw fallback stays), no Squadron sub-line, badge copy "Expects reply", clickable sender name. Same day, the prominence session settled card anatomy, states, clamp, alignment, time and linking; former TA6–TA10 ([record](../../worklog/thread-a2a-prominence-session-2026-08-31.md)). +- 2026-08-29 — the four treatments designed; former TA1–TA5 ([record](../../worklog/2026-08-29-thread-a2a-session.md)). +- 2026-08-31 — three amendments from Jackson's live test of the first build: no envelope expander on parsed cards (the raw fallback stays), no Squadron sub-line, badge copy "Expects reply", clickable sender name. Same day, the prominence session settled card anatomy, states, clamp, alignment, time and linking; former TA6–TA10 ([record](../../worklog/2026-08-31-thread-a2a-prominence-session.md)). - 2026-09-01 — reader copy uses the "Expects reply" / "Replied" family, never closure mechanics (Jackson's final review of the inbox build). - 2026-09-05 — "Replied" becomes the one word for a closed Exchange on every surface, replacing "Reply received" on sent cards and "Answered" on the inbox shelf (glossary). - 2026-09-08 — rewritten into the definition shape. Former identifiers: TA1 → AC1–AC3; TA2 → AC4; TA3 → AC5; TA4, TA8 → AC6, AC8; TA5 → AC13; TA6 → AC7; TA7 → AC9; TA9 → Definition (time); TA10 → AC11–AC12. The v0 rendering of the person's inbox reply as `Via Inbox · ⟨person⟩` (the "You" claim needs a person binding the auth principal does not yet have) is build status and lives in the dogfood plan. diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 8421348b2e93..3fdf9f8e68d4 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -84,7 +84,7 @@ These entries are the distinctions the whole team must share; the glossary owns | archive | Retiring an agent for good; its record stays readable, its open Exchanges end loudly | [features/archive-flow.md](features/archive-flow.md) | | retired | The state of an archived participant | [features/archive-flow.md](features/archive-flow.md) | | orphan | A working agent whose placement parent has been archived | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | -| settled | Upstream's thread-triage state ("I'm done looking at this") and nothing else. J5 docs no longer use "settled" to mean a decision was made | upstream mechanics; see [worklog](../worklog/upstream-settled-vs-archived-research-2026-08-29.md) for the confusion this line resolves | +| settled | Upstream's thread-triage state ("I'm done looking at this") and nothing else. J5 docs no longer use "settled" to mean a decision was made | upstream mechanics; see [worklog](../worklog/2026-08-29-upstream-settled-vs-archived-research.md) for the confusion this line resolves | ## Retired names diff --git a/docs/j5/product/principles.md b/docs/j5/product/principles.md index 1d549bc32857..81a1ffd65f64 100644 --- a/docs/j5/product/principles.md +++ b/docs/j5/product/principles.md @@ -1,6 +1,6 @@ --- title: "Beliefs, lenses, and principles - the machine that turns problems and goals into product" -kind: spec +kind: definition --- This document covers the beliefs, lenses, and principles used to design and architect features for J5 Code. Taken together, these 3 things form the machine that transforms the [problems and goals](./problems.md) into [features](features/). Never restate the problems and goals here. @@ -143,4 +143,4 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it ## Scoped principles -Principles with narrower jurisdiction live with their stories, not here. Currently two: **authority never replicates — messages cross, read-models merge**, which governs all distributed-state design and lives in [the cross-device position paper](./cross-device.md); and **steering is a controller's act, and in J5 the only controller of a turn is the human** — agent deliveries queue by default, with the September 4 Astra exception for peer messages into an already-running Codex turn, delivered as ordinary envelopes. The person's own send follows upstream's default; J5 adds that the person is always told what a steer does on that provider and is refused truthfully when nothing can be steered — which governs mid-turn message dispatch and lives in [the queue-vs-steer ruling record](../worklog/queue-vs-steer-ruling-2026-09-03.md). +Principles with narrower jurisdiction live with their stories, not here. Currently two: **authority never replicates — messages cross, read-models merge**, which governs all distributed-state design and lives in [the cross-device position paper](./cross-device.md); and **steering is a controller's act, and in J5 the only controller of a turn is the human** — agent deliveries queue by default, with the September 4 Astra exception for peer messages into an already-running Codex turn, delivered as ordinary envelopes. The person's own send follows upstream's default; J5 adds that the person is always told what a steer does on that provider and is refused truthfully when nothing can be steered — which governs mid-turn message dispatch and lives in [the queue-vs-steer ruling record](../worklog/2026-09-03-queue-vs-steer-ruling.md). diff --git a/docs/j5/research/index.md b/docs/j5/research/index.md index f96e776c617e..5465789f19eb 100644 --- a/docs/j5/research/index.md +++ b/docs/j5/research/index.md @@ -1,7 +1,7 @@ --- title: "Research: T3 Code & Traycer deep dives" -kind: story -status: 2 +kind: research +as_of: 2026-08-19 --- # Research: T3 Code & Traycer diff --git a/docs/j5/research/jackson-prior-art/fleet-interviews-synthesis.md b/docs/j5/research/jackson-prior-art/fleet-interviews-synthesis.md index fefef45afdd3..aff153a17f6a 100644 --- a/docs/j5/research/jackson-prior-art/fleet-interviews-synthesis.md +++ b/docs/j5/research/jackson-prior-art/fleet-interviews-synthesis.md @@ -1,6 +1,7 @@ --- title: "Fleet interviews — synthesis and the platform/non-platform classification" -kind: spec +kind: research +as_of: 2026-08-23 --- # Fleet interviews: synthesis diff --git a/docs/j5/research/jackson-prior-art/index.md b/docs/j5/research/jackson-prior-art/index.md index 7d3e5e58496a..41b0889dc021 100644 --- a/docs/j5/research/jackson-prior-art/index.md +++ b/docs/j5/research/jackson-prior-art/index.md @@ -1,4 +1,5 @@ --- title: "Jackson Prior Art" -kind: spec +kind: research +as_of: 2026-08-19 --- diff --git a/docs/j5/research/jackson-prior-art/live-fleet-questions.md b/docs/j5/research/jackson-prior-art/live-fleet-questions.md index 595c22566e86..68de7f35b983 100644 --- a/docs/j5/research/jackson-prior-art/live-fleet-questions.md +++ b/docs/j5/research/jackson-prior-art/live-fleet-questions.md @@ -1,6 +1,7 @@ --- title: "Questions for the live PR-Group fleet (forward via Jackson)" -kind: spec +kind: research +as_of: 2026-08-23 --- # Questions for the live fleet diff --git a/docs/j5/research/jackson-prior-art/pr-group-dashboard.md b/docs/j5/research/jackson-prior-art/pr-group-dashboard.md index d54e058d4970..c7121c89449d 100644 --- a/docs/j5/research/jackson-prior-art/pr-group-dashboard.md +++ b/docs/j5/research/jackson-prior-art/pr-group-dashboard.md @@ -1,6 +1,7 @@ --- title: "Prior art: Jackson's pr-group-dashboard" -kind: spec +kind: research +as_of: 2026-08-23 --- # Prior art: pr-group-dashboard diff --git a/docs/j5/research/jackson-prior-art/pr-group.md b/docs/j5/research/jackson-prior-art/pr-group.md index 1a875efdd5ca..438f66ad5ac8 100644 --- a/docs/j5/research/jackson-prior-art/pr-group.md +++ b/docs/j5/research/jackson-prior-art/pr-group.md @@ -1,6 +1,7 @@ --- title: "Prior art: Jackson's pr-group" -kind: spec +kind: research +as_of: 2026-08-23 --- # Prior art: Jackson's `pr-group` diff --git a/docs/j5/research/remote-hosting.md b/docs/j5/research/remote-hosting.md index f3f53a31592e..7f422e30e91a 100644 --- a/docs/j5/research/remote-hosting.md +++ b/docs/j5/research/remote-hosting.md @@ -1,6 +1,7 @@ --- -kind: spec title: "Remote hosting review — J5 server on corporate Azure" +kind: research +as_of: 2026-08-23 --- # Remote hosting review — J5 server on corporate Azure diff --git a/docs/j5/research/synthesis.md b/docs/j5/research/synthesis.md index d97b8be10ebc..6672a0471bbb 100644 --- a/docs/j5/research/synthesis.md +++ b/docs/j5/research/synthesis.md @@ -1,6 +1,7 @@ --- title: "Research synthesis: what we build, what we steal, what we design fresh" -kind: spec +kind: research +as_of: 2026-08-23 --- # Research synthesis (v2 — verified against current code) diff --git a/docs/j5/research/t3code/architecture.md b/docs/j5/research/t3code/architecture.md index ea8971606940..a66d16506aef 100644 --- a/docs/j5/research/t3code/architecture.md +++ b/docs/j5/research/t3code/architecture.md @@ -1,6 +1,7 @@ --- title: "T3 Code — architecture map" -kind: spec +kind: research +as_of: 2026-08-23 --- # Architecture map diff --git a/docs/j5/research/t3code/feature-inventory.md b/docs/j5/research/t3code/feature-inventory.md index ed0ba4a0b881..8f3aa6cd79c4 100644 --- a/docs/j5/research/t3code/feature-inventory.md +++ b/docs/j5/research/t3code/feature-inventory.md @@ -1,6 +1,7 @@ --- title: "T3 Code — feature inventory" -kind: spec +kind: research +as_of: 2026-08-23 --- # Feature inventory diff --git a/docs/j5/research/t3code/fork-viability.md b/docs/j5/research/t3code/fork-viability.md index ca924319556e..76563eaa865f 100644 --- a/docs/j5/research/t3code/fork-viability.md +++ b/docs/j5/research/t3code/fork-viability.md @@ -1,6 +1,7 @@ --- title: "Fork viability: T3 Code as foundation" -kind: spec +kind: research +as_of: 2026-08-23 --- # Fork viability: T3 Code as foundation diff --git a/docs/j5/research/t3code/index.md b/docs/j5/research/t3code/index.md index b012bce2071a..4e3fdfd8c0c1 100644 --- a/docs/j5/research/t3code/index.md +++ b/docs/j5/research/t3code/index.md @@ -1,6 +1,7 @@ --- title: "T3 Code research (current main)" -kind: spec +kind: research +as_of: 2026-08-23 --- # T3 Code — research report (current `main`) diff --git a/docs/j5/research/t3code/multi-agent-and-providers.md b/docs/j5/research/t3code/multi-agent-and-providers.md index dadc1f06f049..531b8ce34ca7 100644 --- a/docs/j5/research/t3code/multi-agent-and-providers.md +++ b/docs/j5/research/t3code/multi-agent-and-providers.md @@ -1,6 +1,7 @@ --- title: "T3 Code — multi-agent & providers deep dive" -kind: spec +kind: research +as_of: 2026-08-23 --- # Multi-agent & providers diff --git a/docs/j5/research/t3code/orchestration-v2.md b/docs/j5/research/t3code/orchestration-v2.md index 74bcea4e000d..cd8d7c1eb5e8 100644 --- a/docs/j5/research/t3code/orchestration-v2.md +++ b/docs/j5/research/t3code/orchestration-v2.md @@ -1,6 +1,7 @@ --- title: "T3 orchestration-v2: what it is, why, and how far along" -kind: spec +kind: research +as_of: 2026-08-23 --- # Orchestration-v2 (researched 2026-08-14, subagent read of main `196c8ea0d` + branch `t3code/codex-turn-mapping` @ `77168d081`) diff --git a/docs/j5/research/t3code/performance-and-quality.md b/docs/j5/research/t3code/performance-and-quality.md index 587a8ff83281..c68fb0d303db 100644 --- a/docs/j5/research/t3code/performance-and-quality.md +++ b/docs/j5/research/t3code/performance-and-quality.md @@ -1,6 +1,7 @@ --- title: "T3 Code — performance, quality & fork viability" -kind: spec +kind: research +as_of: 2026-08-23 --- # Performance, quality & fork viability diff --git a/docs/j5/research/t3code/remote.md b/docs/j5/research/t3code/remote.md index 12ed46c94800..0daacf69b3ca 100644 --- a/docs/j5/research/t3code/remote.md +++ b/docs/j5/research/t3code/remote.md @@ -1,6 +1,7 @@ --- title: "T3 Code — remote & multi-machine deep dive" -kind: spec +kind: research +as_of: 2026-08-23 --- # Remote & multi-machine diff --git a/docs/j5/research/traycer/agent-to-agent.md b/docs/j5/research/traycer/agent-to-agent.md index 9171d341494a..3f3e9caaf464 100644 --- a/docs/j5/research/traycer/agent-to-agent.md +++ b/docs/j5/research/traycer/agent-to-agent.md @@ -1,6 +1,7 @@ --- title: "Traycer A2A deep dive" -kind: spec +kind: research +as_of: 2026-08-23 --- # Deep dive: agent-to-agent messaging diff --git a/docs/j5/research/traycer/index.md b/docs/j5/research/traycer/index.md index c5fa70852345..6c6f1ed53a5d 100644 --- a/docs/j5/research/traycer/index.md +++ b/docs/j5/research/traycer/index.md @@ -1,6 +1,7 @@ --- title: "Traycer research" -kind: spec +kind: research +as_of: 2026-08-23 --- # Traycer research diff --git a/docs/j5/research/traycer/organization-model.md b/docs/j5/research/traycer/organization-model.md index 950011224878..0bab7e29c3b1 100644 --- a/docs/j5/research/traycer/organization-model.md +++ b/docs/j5/research/traycer/organization-model.md @@ -1,6 +1,7 @@ --- title: "Traycer organization model deep dive" -kind: spec +kind: research +as_of: 2026-08-23 --- # Deep dive: the organization model diff --git a/docs/j5/research/traycer/performance.md b/docs/j5/research/traycer/performance.md index bd33b1243474..596ad87962f7 100644 --- a/docs/j5/research/traycer/performance.md +++ b/docs/j5/research/traycer/performance.md @@ -1,6 +1,7 @@ --- title: "Traycer performance root-cause analysis" -kind: spec +kind: research +as_of: 2026-08-23 --- # Deep dive: performance problems diff --git a/docs/j5/agent-migration.md b/docs/j5/runbooks/agent-migration.md similarity index 99% rename from docs/j5/agent-migration.md rename to docs/j5/runbooks/agent-migration.md index d2024191d363..2a74a775fad7 100644 --- a/docs/j5/agent-migration.md +++ b/docs/j5/runbooks/agent-migration.md @@ -1,6 +1,6 @@ --- title: "Agent migration runbook — moving a live agent into J5 with memory intact" -kind: spec +kind: runbook --- # Agent migration runbook @@ -224,9 +224,9 @@ repo already answers, retired-seat corrections, or durable content whose right h every agent reads (the source dir was a cwd-keyed commons written by every agent that ever ran with that cwd, including disposable crew seats — never per-agent). The durable content now lives in: -- [`process/working-in-the-repo.md`](process/working-in-the-repo.md) — tool traps and repo facts +- [`process/working-in-the-repo.md`](../process/working-in-the-repo.md) — tool traps and repo facts (grep on large files, formatting docs before commit, what web tests can and cannot prove). -- [`operations/deployment-preferences.md`](operations/deployment-preferences.md) — Jackson's +- `operations/deployment-preferences.md` (kept in the operator\'s playbooks, outside the repository) — Jackson's deployment-design preferences (state stays in `dogfood-runtime.md`). - Fleet process law (gates, evidence, staffing, operating rules) — in the operator's playbooks outside the repo, never a `docs/j5` page: a docs/j5 page holds facts about the product or the diff --git a/docs/j5/dogfood-runtime.md b/docs/j5/runbooks/dogfood-runtime.md similarity index 98% rename from docs/j5/dogfood-runtime.md rename to docs/j5/runbooks/dogfood-runtime.md index 91783deefea2..a59c8d4031fe 100644 --- a/docs/j5/dogfood-runtime.md +++ b/docs/j5/runbooks/dogfood-runtime.md @@ -1,6 +1,11 @@ +--- +title: "Dogfood runtime: self-hosted J5 Code server and clients" +kind: runbook +--- + # Dogfood runtime: self-hosted J5 Code server and clients -How Jackson's solo dogfood (phase 3 of [dogfood v0](plans/dogfood-v0.md)) actually runs: one +How Jackson's solo dogfood (phase 3 of [dogfood v0](../plans/dogfood-v0.md)) actually runs: one source-built J5 Code server on a Linux box, reached over Tailscale, with the browser as the client. This document is self-contained on purpose — dogfood agents have no access to the design sessions that produced it. Decisions and their load-bearing reasons are recorded inline. @@ -8,7 +13,7 @@ that produced it. Decisions and their load-bearing reasons are recorded inline. Pin-advance note (2026-09-06): restart and Codex-version guidance below reflects the selected upstream integration. This advance did not execute these Linux deployment procedures or verify second-machine/relay/tunnel behavior; the deployment instructions retain their earlier environment -assumptions. See [FORK.md](../../FORK.md#verification-and-review-at-the-recorded-source) for the +assumptions. See [FORK.md](../../../FORK.md#verification-and-review-at-the-recorded-source) for the exact source and verification limits. ## Shape and rationale diff --git a/docs/j5/macos-packaging.md b/docs/j5/runbooks/macos-packaging.md similarity index 98% rename from docs/j5/macos-packaging.md rename to docs/j5/runbooks/macos-packaging.md index c85cdd72071b..69791d87f8ab 100644 --- a/docs/j5/macos-packaging.md +++ b/docs/j5/runbooks/macos-packaging.md @@ -1,3 +1,8 @@ +--- +title: "Build and install J5 Code for macOS" +kind: runbook +--- + # Build and install J5 Code for macOS The local personal-use build below is ad-hoc signed. It has a valid local code signature but no Apple diff --git a/docs/j5/worklog/pr-8-coderabbit-triage-review.md b/docs/j5/worklog/2026-08-23-pr-8-coderabbit-triage-review.md similarity index 99% rename from docs/j5/worklog/pr-8-coderabbit-triage-review.md rename to docs/j5/worklog/2026-08-23-pr-8-coderabbit-triage-review.md index 348dd29221bd..0f1674d1b31b 100644 --- a/docs/j5/worklog/pr-8-coderabbit-triage-review.md +++ b/docs/j5/worklog/2026-08-23-pr-8-coderabbit-triage-review.md @@ -1,6 +1,6 @@ --- title: "PR #8 CodeRabbit triage — independent verification" -kind: review +kind: record --- Independent review of PR #8 (`refactor(j5): rename A2A epics to squadrons`) at head `48e66c932a03a216a0f25d27d8a76b342f739489`. Scope: verify the two open CodeRabbit findings and judge whether the drafted refutations are truthful and sufficient to post. No source, test, or GitHub state was changed. diff --git a/docs/j5/worklog/priority-input-2026-08-23.md b/docs/j5/worklog/2026-08-23-priority-input.md similarity index 97% rename from docs/j5/worklog/priority-input-2026-08-23.md rename to docs/j5/worklog/2026-08-23-priority-input.md index 076b42096d65..6f3aad8c2f0d 100644 --- a/docs/j5/worklog/priority-input-2026-08-23.md +++ b/docs/j5/worklog/2026-08-23-priority-input.md @@ -1,3 +1,8 @@ +--- +title: "Priority input for the reprioritization — Product lead, 2026-08-23" +kind: record +--- + # Priority input for the reprioritization — Product lead, 2026-08-23 One page for Jackson + the Manager. State as of the design review (R1–R35, commits diff --git a/docs/j5/worklog/roles-crews-session-2026-08-23.md b/docs/j5/worklog/2026-08-23-roles-crews-session.md similarity index 99% rename from docs/j5/worklog/roles-crews-session-2026-08-23.md rename to docs/j5/worklog/2026-08-23-roles-crews-session.md index 87bce507beb0..77d0549369a3 100644 --- a/docs/j5/worklog/roles-crews-session-2026-08-23.md +++ b/docs/j5/worklog/2026-08-23-roles-crews-session.md @@ -1,3 +1,8 @@ +--- +title: "Roles/Crews product session — rulings record (2026-08-23)" +kind: record +--- + # Roles/Crews product session — rulings record (2026-08-23) Jackson + Product lead. Scope: the WHAT/WHY of Roles and Crews (backlog item 3), against the design-review inheritance (R8, R12–R22, R28). Technical design deliberately NOT produced — handed to the implementing dev, bounded by these rulings. Feature docs of record updated same day: `product/features/roles.md`, `product/features/crews.md`. diff --git a/docs/j5/worklog/spawn-terminology-session-2026-08-24.md b/docs/j5/worklog/2026-08-24-spawn-terminology-session.md similarity index 98% rename from docs/j5/worklog/spawn-terminology-session-2026-08-24.md rename to docs/j5/worklog/2026-08-24-spawn-terminology-session.md index 94a77ff27d86..780c82776126 100644 --- a/docs/j5/worklog/spawn-terminology-session-2026-08-24.md +++ b/docs/j5/worklog/2026-08-24-spawn-terminology-session.md @@ -1,3 +1,8 @@ +--- +title: "Spawn terminology session — rulings record (2026-08-24)" +kind: record +--- + # Spawn terminology session — rulings record (2026-08-24) Jackson + Product lead. Origin: the "may Crew members spawn solo helpers?" question exposed that "spawn" was covering several different contracts with the human. Method: three-source inventory — the Product lead's first-hand tools (Claude Code `Agent`/`Workflow`, Traycer `create_agent`/`fork_agent`), a **live Codex agent probe** (spawned on the Codex harness and interviewed about its own tools), and a **code inventory of upstream T3's spawn surfaces** with file:line evidence (orchestrator MCP toolkit, provider-native subagent paths for Claude/Codex/Cursor/ACP, scheduled tasks). An upstream terminology check preceded naming, per Jackson: adopt over redefine. diff --git a/docs/j5/worklog/squadron-creation-session-2026-08-24.md b/docs/j5/worklog/2026-08-24-squadron-creation-session.md similarity index 98% rename from docs/j5/worklog/squadron-creation-session-2026-08-24.md rename to docs/j5/worklog/2026-08-24-squadron-creation-session.md index afda4b373c12..8e4f64751038 100644 --- a/docs/j5/worklog/squadron-creation-session-2026-08-24.md +++ b/docs/j5/worklog/2026-08-24-squadron-creation-session.md @@ -1,3 +1,8 @@ +--- +title: "Squadron creation UX session — rulings record (2026-08-24)" +kind: record +--- + # Squadron creation UX session — rulings record (2026-08-24) Jackson + Product lead; dogfood phase-3 prerequisite, front-end before back-end per Jackson. Scope: how a user creates a Squadron and creates agents under it. Designed WITHIN the law in force (E1/E2/E4/E6, R21, the creation-time Registrar as the receiving end, primitives-not-methodology) — nothing relitigated. Feature doc updated same day: `product/features/squadron.md` ("Creation UX" section, SC1–SC4). Technical design deliberately not produced — the phase-3 ticket's dev owns it within these rulings. diff --git a/docs/j5/worklog/archive-flow-session-2026-08-29.md b/docs/j5/worklog/2026-08-29-archive-flow-session.md similarity index 97% rename from docs/j5/worklog/archive-flow-session-2026-08-29.md rename to docs/j5/worklog/2026-08-29-archive-flow-session.md index 8f052503843a..6c1332876524 100644 --- a/docs/j5/worklog/archive-flow-session-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-archive-flow-session.md @@ -1,3 +1,8 @@ +--- +title: "Archive-flow design session — rulings record (2026-08-29)" +kind: record +--- + # Archive-flow design session — rulings record (2026-08-29) Jackson + UI/UX design agent; dogfood-v0 UX workstream (area 7), closing diff --git a/docs/j5/worklog/inbox-session-2026-08-29.md b/docs/j5/worklog/2026-08-29-inbox-session.md similarity index 98% rename from docs/j5/worklog/inbox-session-2026-08-29.md rename to docs/j5/worklog/2026-08-29-inbox-session.md index 640792d7432e..2cf60cc82f70 100644 --- a/docs/j5/worklog/inbox-session-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-inbox-session.md @@ -1,3 +1,8 @@ +--- +title: "Inbox design session — rulings record (2026-08-29)" +kind: record +--- + # Inbox design session — rulings record (2026-08-29) Jackson + UI/UX design agent; dogfood-v0 UX workstream (area 5 of the diff --git a/docs/j5/worklog/sidebar-roster-session-2026-08-29.md b/docs/j5/worklog/2026-08-29-sidebar-roster-session.md similarity index 98% rename from docs/j5/worklog/sidebar-roster-session-2026-08-29.md rename to docs/j5/worklog/2026-08-29-sidebar-roster-session.md index 87a9d6bd23ed..73299697ae8b 100644 --- a/docs/j5/worklog/sidebar-roster-session-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-sidebar-roster-session.md @@ -1,3 +1,8 @@ +--- +title: "Sidebar/roster design session — rulings record (2026-08-29)" +kind: record +--- + # Sidebar/roster design session — rulings record (2026-08-29) Jackson + UI/UX design agent; dogfood-v0 UX workstream (area 3 of the diff --git a/docs/j5/worklog/substrate-session-2026-08-29.md b/docs/j5/worklog/2026-08-29-substrate-session.md similarity index 98% rename from docs/j5/worklog/substrate-session-2026-08-29.md rename to docs/j5/worklog/2026-08-29-substrate-session.md index aa8b4f174227..186a76909297 100644 --- a/docs/j5/worklog/substrate-session-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-substrate-session.md @@ -1,3 +1,8 @@ +--- +title: "Substrate session — rulings record (2026-08-29)" +kind: record +--- + # Substrate session — rulings record (2026-08-29) Jackson + architecture evaluator. Origin: Jackson's zoom-out challenge on the A6/#12 evaluation — diff --git a/docs/j5/worklog/thread-a2a-session-2026-08-29.md b/docs/j5/worklog/2026-08-29-thread-a2a-session.md similarity index 97% rename from docs/j5/worklog/thread-a2a-session-2026-08-29.md rename to docs/j5/worklog/2026-08-29-thread-a2a-session.md index 817acea64dbe..4f0fd5634afc 100644 --- a/docs/j5/worklog/thread-a2a-session-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-thread-a2a-session.md @@ -1,3 +1,8 @@ +--- +title: "Thread-view A2A rendering session — rulings record (2026-08-29)" +kind: record +--- + # Thread-view A2A rendering session — rulings record (2026-08-29) Jackson + UI/UX design agent; dogfood-v0 UX workstream (area 6), same-day diff --git a/docs/j5/worklog/upstream-settled-vs-archived-research-2026-08-29.md b/docs/j5/worklog/2026-08-29-upstream-settled-vs-archived-research.md similarity index 98% rename from docs/j5/worklog/upstream-settled-vs-archived-research-2026-08-29.md rename to docs/j5/worklog/2026-08-29-upstream-settled-vs-archived-research.md index 323c0942a29e..02f6afc12759 100644 --- a/docs/j5/worklog/upstream-settled-vs-archived-research-2026-08-29.md +++ b/docs/j5/worklog/2026-08-29-upstream-settled-vs-archived-research.md @@ -1,3 +1,8 @@ +--- +title: 'Upstream research: "settled" vs "archived" (2026-08-29)' +kind: record +--- + # Upstream research: "settled" vs "archived" (2026-08-29) Commissioned by Jackson; code inventory of the upstream orchestration-v2 pin with file:line evidence (full detail in the research transcript; this records the essence + J5 implications). Directly relevant to A9 (lifecycle-closure), the Crews archive machinery (R1/R2/R19), and the glossary. diff --git a/docs/j5/worklog/priority-input-2026-08-30.md b/docs/j5/worklog/2026-08-30-priority-input.md similarity index 96% rename from docs/j5/worklog/priority-input-2026-08-30.md rename to docs/j5/worklog/2026-08-30-priority-input.md index 906315940953..ed97b6bfd2cd 100644 --- a/docs/j5/worklog/priority-input-2026-08-30.md +++ b/docs/j5/worklog/2026-08-30-priority-input.md @@ -1,3 +1,8 @@ +--- +title: "Priority input for the v0 reorientation — Product lead, 2026-08-30" +kind: record +--- + # Priority input for the v0 reorientation — Product lead, 2026-08-30 For Jackson + the Director. State: A1–A3 landed; A4/A6 PRs in flight (built pre-design/pre-substrate); dogfood UX map complete (SB/IB/TA/AR); SQ1 shrunk by DV1–DV3; substrate ruling landed. diff --git a/docs/j5/worklog/spawning-guide-session-2026-08-30.md b/docs/j5/worklog/2026-08-30-spawning-guide-session.md similarity index 98% rename from docs/j5/worklog/spawning-guide-session-2026-08-30.md rename to docs/j5/worklog/2026-08-30-spawning-guide-session.md index 288098fa0e74..2c315c715cde 100644 --- a/docs/j5/worklog/spawning-guide-session-2026-08-30.md +++ b/docs/j5/worklog/2026-08-30-spawning-guide-session.md @@ -1,3 +1,8 @@ +--- +title: "Spawning-guide session — rulings record (2026-08-30)" +kind: record +--- + # Spawning-guide session — rulings record (2026-08-30) Jackson + Product lead. Origin: commissioned by Jackson via the Architecture agent after the PR #15 review, where provider/model/reasoning became **required** `spawn_agent` params (inherit-default ruled wrong more often than right). The rebuilt contract in `product/a2a/agent-tools.md` carries a come-back note reserving this territory. Feature doc created same day: `product/features/spawning-guide.md`. Constraints set at commissioning: does not block PR #15; the guide's requirements include updating the `agent-tools.md` contract and the tool implementation when the mechanism lands. diff --git a/docs/j5/worklog/picker-and-self-messaging-rulings-2026-08-31.md b/docs/j5/worklog/2026-08-31-picker-and-self-messaging-rulings.md similarity index 96% rename from docs/j5/worklog/picker-and-self-messaging-rulings-2026-08-31.md rename to docs/j5/worklog/2026-08-31-picker-and-self-messaging-rulings.md index e80b9257465c..06d126875842 100644 --- a/docs/j5/worklog/picker-and-self-messaging-rulings-2026-08-31.md +++ b/docs/j5/worklog/2026-08-31-picker-and-self-messaging-rulings.md @@ -1,3 +1,8 @@ +--- +title: "Two rulings from the #20 acceptance pass (2026-08-31)" +kind: record +--- + # Two rulings from the #20 acceptance pass (2026-08-31) Jackson + Product lead, async in the Product thread; relayed for framing by the Director after Jackson's #20 live acceptance pass (the flow passed — both items are forward questions from it). Both framed by Product with recommendations; Jackson ruled "agree" on each, unamended. diff --git a/docs/j5/worklog/thread-a2a-prominence-session-2026-08-31.md b/docs/j5/worklog/2026-08-31-thread-a2a-prominence-session.md similarity index 98% rename from docs/j5/worklog/thread-a2a-prominence-session-2026-08-31.md rename to docs/j5/worklog/2026-08-31-thread-a2a-prominence-session.md index 267cc3a4b6ac..48f9b7ba187e 100644 --- a/docs/j5/worklog/thread-a2a-prominence-session-2026-08-31.md +++ b/docs/j5/worklog/2026-08-31-thread-a2a-prominence-session.md @@ -1,3 +1,8 @@ +--- +title: "Thread-A2A prominence session — rulings record (2026-08-31)" +kind: record +--- + # Thread-A2A prominence session — rulings record (2026-08-31) Jackson + UI/UX design agent, commissioned by the Director from Jackson's diff --git a/docs/j5/worklog/human-addressed-sends-ruling-2026-09-02.md b/docs/j5/worklog/2026-09-02-human-addressed-sends-ruling.md similarity index 98% rename from docs/j5/worklog/human-addressed-sends-ruling-2026-09-02.md rename to docs/j5/worklog/2026-09-02-human-addressed-sends-ruling.md index 94d9c3fe973d..76c2c51fee43 100644 --- a/docs/j5/worklog/human-addressed-sends-ruling-2026-09-02.md +++ b/docs/j5/worklog/2026-09-02-human-addressed-sends-ruling.md @@ -1,3 +1,8 @@ +--- +title: "Human-addressed sends: asks only (2026-09-02)" +kind: record +--- + # Human-addressed sends: asks only (2026-09-02) Jackson + Product lead, in the Product thread inside J5 (first ruling made from inside the product). Origin: issue #44 — plain messages to a person were found invisible in Jackson's 2026-09-01 session (durable ledger records, no human surface), then reproduced by two migrated agents including Product itself; PR #57 proposed a truthful "invisible in v0" description plus an A/B/C disposition for where such messages should eventually live (A: sender's thread card; B: an inbox lane; C: no ruling). The Director relayed the options; Product brought A as the recommendation. diff --git a/docs/j5/worklog/queue-vs-steer-ruling-2026-09-03.md b/docs/j5/worklog/2026-09-03-queue-vs-steer-ruling.md similarity index 98% rename from docs/j5/worklog/queue-vs-steer-ruling-2026-09-03.md rename to docs/j5/worklog/2026-09-03-queue-vs-steer-ruling.md index 54a2932c49d3..26854f43897b 100644 --- a/docs/j5/worklog/queue-vs-steer-ruling-2026-09-03.md +++ b/docs/j5/worklog/2026-09-03-queue-vs-steer-ruling.md @@ -1,3 +1,8 @@ +--- +title: "Queue vs steer — ruling record (2026-09-03)" +kind: record +--- + # Queue vs steer — ruling record (2026-09-03) Jackson + Product lead, in the Product thread. Origin: issue #73 (agent deliveries steered a mid-turn Claude recipient; the CLI's "now"-priority abort produced fabricated human-refusal text on sibling tool calls) and the two live observations of 2026-09-02 (a composer send interrupting a stalled run and jumping three queued agent messages; five agent messages steered into a live turn and read by the recipient as "queued"). PR #91 implements the ruling; Jackson wanted it right in one PR. Everything below was measured in code before ruling; unmeasured items are marked. @@ -42,7 +47,7 @@ Jackson authorized an Astra-only experiment after Fleet A spent a 36-minute run This changes message admission, not model attention: the provider decides when accepted input reaches the model. Adapter acceptance does not prove the model read it or preserved its original task. Model behavior still needs dogfood evaluation. -Implementation and verification are recorded in [the Astra delivery worklog](./astra-peer-delivery-2026-09-04.md). +Implementation and verification are recorded in [the Astra delivery worklog](2026-09-04-astra-peer-delivery.md). ## September 5 integration decision diff --git a/docs/j5/worklog/astra-peer-delivery-2026-09-04.md b/docs/j5/worklog/2026-09-04-astra-peer-delivery.md similarity index 98% rename from docs/j5/worklog/astra-peer-delivery-2026-09-04.md rename to docs/j5/worklog/2026-09-04-astra-peer-delivery.md index 1935377cc7a4..ce7d88233378 100644 --- a/docs/j5/worklog/astra-peer-delivery-2026-09-04.md +++ b/docs/j5/worklog/2026-09-04-astra-peer-delivery.md @@ -1,3 +1,8 @@ +--- +title: "Astra peer delivery — September 4, 2026" +kind: record +--- + # Astra peer delivery — September 4, 2026 Jackson authorized an Astra-only QS1 exception and direct implementation by the coordinator. No peer or subagent was staffed or contacted. Base: `9209e0b3b53fb98591b958077848ffdabee07b49`; branch: `j5/astra-peer-delivery`. diff --git a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md index 37be1637710b..54d08f943226 100644 --- a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md +++ b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/index.md @@ -1,7 +1,6 @@ --- title: "A1 — Epic entity + communication ledger (M1)" -kind: ticket -status: 2 +kind: record --- > **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `../../../product/features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. diff --git a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/migration-lane.md b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/migration-lane.md index 3b126601ff55..4e62537e2766 100644 --- a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/migration-lane.md +++ b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/migration-lane.md @@ -1,6 +1,6 @@ --- title: "A1 decision — J5 migrations run in their own lane, not upstream's registry" -kind: spec +kind: record --- # J5 migrations run in their own lane diff --git a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/pr-4.md b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/pr-4.md index eb270beb8355..368cf3869408 100644 --- a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/pr-4.md +++ b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/pr-4.md @@ -1,7 +1,6 @@ --- title: "A1 PR #4 sitter log" -kind: story -status: 2 +kind: record --- # A1 PR #4 sitter log diff --git a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/sitter-retro.md b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/sitter-retro.md index ca5c08f1f62d..bc108db5fad7 100644 --- a/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/sitter-retro.md +++ b/docs/j5/worklog/a2a-tickets/a1-ledger-epic-entity/sitter-retro.md @@ -1,6 +1,6 @@ --- title: "A1 sitter retirement notes" -kind: spec +kind: record --- # A1 sitter retirement notes diff --git a/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md b/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md index e9b9b1662905..57a01fd1980c 100644 --- a/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md +++ b/docs/j5/worklog/a2a-tickets/a10-silence-fact-bundles.md @@ -1,9 +1,10 @@ --- title: "A10 — Silence notices become fact bundles; labels move to projection (R4 amendment of A3)" -kind: ticket -status: 0 +kind: record --- +> **Record.** The work item of record is [issue #30](https://github.com/Jacksondr5/j5code/issues/30); this ticket text is the history behind it and is not maintained. + # A10 — Silence fact bundles **Governing artifacts:** design-review register R4; R4 compliance audit of merged A3 (Director log, 2026-08-23 — verdict AMENDMENT REQUIRED on all three test parts, evidence at `SilenceDetector.ts:44-79, 233-333, 372-390`, `LedgerService.ts:408-411`). D6's five-state taxonomy is settled and unchanged — this ticket only moves WHERE labels live and completes the facts. Staff against current `j5/main` head. diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md index b29f165bef1d..4cd45d45c6b9 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/index.md @@ -1,7 +1,6 @@ --- title: "A2 — Send/deliver/reply loop: exchanges, pipeline, envelopes, tools (M2)" -kind: ticket -status: 1 +kind: record --- # A2 — Send/deliver/reply loop diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/pr-7.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/pr-7.md index c646f17e59a4..8efb964c015c 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/pr-7.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/pr-7.md @@ -1,7 +1,6 @@ --- title: "A2 PR #7 sitting log" -kind: story -status: 1 +kind: record --- > **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `../../../product/features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/proof.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/proof.md index b39ef770e565..52731afe4add 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/proof.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/proof.md @@ -1,6 +1,6 @@ --- title: "A2 live proof — real Codex to Claude exchange" -kind: spec +kind: record --- # A2 live proof — historical pipeline PASS diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/retrospective.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/retrospective.md index ab2033c51d5f..8ba75ef26745 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/retrospective.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/retrospective.md @@ -1,6 +1,6 @@ --- title: "A2 retrospective — live provider proof isolation" -kind: spec +kind: record --- # Live provider proof isolation diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/squadron-rename-pr.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/squadron-rename-pr.md index dd8cd0875004..dc215e055818 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/squadron-rename-pr.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/squadron-rename-pr.md @@ -1,7 +1,6 @@ --- title: "A2 Squadron mechanical rename PR" -kind: ticket -status: 1 +kind: record --- # A2 Squadron mechanical rename PR diff --git a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md index e01ff86808e6..adc3ffd5d7bc 100644 --- a/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md +++ b/docs/j5/worklog/a2a-tickets/a2-send-deliver-reply/upstream-dedup-ground-truth.md @@ -1,6 +1,6 @@ --- title: "A2 gate — how upstream dedup actually works at pin 521c50aa9" -kind: spec +kind: record --- # Upstream exactly-once mechanics (reviewer-verified) diff --git a/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md b/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md index 1d180aa9eb19..783570ce8d4c 100644 --- a/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md +++ b/docs/j5/worklog/a2a-tickets/a3-silence-detector/index.md @@ -1,7 +1,6 @@ --- title: "A3 — Silence detector: five typed states (M3)" -kind: ticket -status: 0 +kind: record --- # A3 — Silence detector diff --git a/docs/j5/worklog/a2a-tickets/a3-silence-detector/pr-9.md b/docs/j5/worklog/a2a-tickets/a3-silence-detector/pr-9.md index a05bbc686ce0..fc562c71f5de 100644 --- a/docs/j5/worklog/a2a-tickets/a3-silence-detector/pr-9.md +++ b/docs/j5/worklog/a2a-tickets/a3-silence-detector/pr-9.md @@ -1,7 +1,6 @@ --- -kind: ticket title: "PR #9 — A3 silence detector" -status: 1 +kind: record --- # PR #9 — A3 silence detector diff --git a/docs/j5/worklog/a2a-tickets/a3-silence-detector/review.md b/docs/j5/worklog/a2a-tickets/a3-silence-detector/review.md index 7d8c722f24bd..615016f18d73 100644 --- a/docs/j5/worklog/a2a-tickets/a3-silence-detector/review.md +++ b/docs/j5/worklog/a2a-tickets/a3-silence-detector/review.md @@ -1,6 +1,6 @@ --- title: "A3 review — independent verdict, rounds 1–3" -kind: review +kind: record --- # A3 silence detector — Reviewer verdict diff --git a/docs/j5/worklog/a2a-tickets/a3-silence-detector/sitter-initial-audit.md b/docs/j5/worklog/a2a-tickets/a3-silence-detector/sitter-initial-audit.md index d40997ebf4f9..80ceb9870f8d 100644 --- a/docs/j5/worklog/a2a-tickets/a3-silence-detector/sitter-initial-audit.md +++ b/docs/j5/worklog/a2a-tickets/a3-silence-detector/sitter-initial-audit.md @@ -1,6 +1,6 @@ --- -kind: spec title: "A3 sitter initial audit" +kind: record --- # A3 sitter initial audit diff --git a/docs/j5/worklog/a2a-tickets/a4-human-node.md b/docs/j5/worklog/a2a-tickets/a4-human-node.md index f1ff9abe9aaf..dbae1fb24f84 100644 --- a/docs/j5/worklog/a2a-tickets/a4-human-node.md +++ b/docs/j5/worklog/a2a-tickets/a4-human-node.md @@ -1,7 +1,6 @@ --- title: "A4 — Human node: person-scoped inbox, verbatim answers (M4)" -kind: ticket -status: 0 +kind: record --- # A4 — Human node diff --git a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md index 15fdd8cef4c4..b0ec468f8614 100644 --- a/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md +++ b/docs/j5/worklog/a2a-tickets/a5-graph-read-api.md @@ -1,9 +1,10 @@ --- title: "A5 — Graph projection + read API (M5)" -kind: ticket -status: 0 +kind: record --- +> **Record.** The work item of record is [issue #31](https://github.com/Jacksondr5/j5code/issues/31); this ticket text is the history behind it and is not maintained. + # A5 — Graph projection + read API > **Amended 2026-08-23 (pre-staffing, register-reviewed):** reconciled against design-review register and approved by the design-review authority. diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/feasibility-audit.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/feasibility-audit.md index 1fc3728b376c..af7e73367b48 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/feasibility-audit.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/feasibility-audit.md @@ -1,6 +1,6 @@ --- title: "A6 feasibility audit — placement integration boundary" -kind: spec +kind: record --- # A6 feasibility audit — placement integration boundary diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md index 4cce7b28ca87..c4153faf0946 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/index.md @@ -1,7 +1,6 @@ --- title: "A6 — Spawn placement + provenance (D10)" -kind: ticket -status: 0 +kind: record --- # A6 — Spawn placement + provenance diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-feasibility.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-feasibility.md index 8e5e9cb6df1d..e0d6296ab902 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-feasibility.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-feasibility.md @@ -1,6 +1,6 @@ --- title: "A6 reviewer verdict — feasibility seams, independently measured" -kind: review +kind: record --- # A6 reviewer verdict — feasibility seams diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-core.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-core.md index 8e8c5bcf6847..4a711e3fa787 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-core.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-core.md @@ -1,6 +1,6 @@ --- title: "A6 core review — verdict at d65acfdca (changes requested)" -kind: review +kind: record --- # A6 core review — verdict diff --git a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-integration.md b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-integration.md index 82f7e080f4f8..ca6ac795294e 100644 --- a/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-integration.md +++ b/docs/j5/worklog/a2a-tickets/a6-placement-provenance/reviewer-verdict-integration.md @@ -1,6 +1,6 @@ --- title: "A6 integration review — verdict at d44fad9ad (changes requested)" -kind: review +kind: record --- > **Terminology note (post-E6):** the grouping concept was renamed **epic → squadron** on 2026-08-17 (definition: `../../../product/features/squadron.md`); the code rename landed in PR #8. "Epic" below is preserved as dated historical record — read it as "squadron." Filesystem paths are literal. diff --git a/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md b/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md index a4059baaa04d..d43cfa6a0801 100644 --- a/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md +++ b/docs/j5/worklog/a2a-tickets/a7-upstream-rebase.md @@ -1,7 +1,6 @@ --- title: "A7 — Planned rebase when upstream #2829 merges (event-triggered)" -kind: ticket -status: 0 +kind: record --- # A7 — Planned upstream base advance diff --git a/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md b/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md index fad5a4e5dd23..4f89d0a9e74e 100644 --- a/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md +++ b/docs/j5/worklog/a2a-tickets/a8-envelope-true-up.md @@ -1,9 +1,10 @@ --- title: "A8 — Envelope true-up: reply-delivery rendering, regarding linkage, time facts (R3/R10/R25)" -kind: ticket -status: 0 +kind: record --- +> **Record.** The work item of record is [issue #29](https://github.com/Jacksondr5/j5code/issues/29); this ticket text is the history behind it and is not maintained. + # A8 — Envelope true-up **Governing artifacts:** design-review register R3, R10, R25 (../2026-08-21-design-review.md); A2's envelope formatter (one formatter, per-channel renderings, versioned config Jackson owns). Staff against current `j5/main` head. diff --git a/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md b/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md index 5ecc7c81b72e..24dd884d4c9b 100644 --- a/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md +++ b/docs/j5/worklog/a2a-tickets/a9-lifecycle-closure.md @@ -1,7 +1,6 @@ --- title: "A9 — Lifecycle closure: participant retirement terminates obligations, loudly (R1/R11)" -kind: ticket -status: 1 +kind: record --- # A9 — Lifecycle closure @@ -23,7 +22,7 @@ Retiring a participant terminates its open obligations as a loud, evented act ## Scope amendment — Squadron archive deferred -The settled archive-flow work ([product contract](../../product/features/archive-flow.md), [session ruling](../archive-flow-session-2026-08-29.md)) and Squadron SC4 ([feature definition](../../product/features/squadron.md)) supersede A9's original R2/Squadron half. All Squadron-archive-shaped work is deferred to SC4 polished-later: no operation, HTTP/MCP/server surface, warning/confirmation path, event, schema column, or projection dimension ships here. Migration `008_LifecycleClosure` contains no Squadron schema. Existing append-only ledgers already remain readable; a future SC4 implementation can compose the R1 participant termination machinery after its user contract ships. +The settled archive-flow work ([product contract](../../product/features/archive-flow.md), [session ruling](../2026-08-29-archive-flow-session.md)) and Squadron SC4 ([feature definition](../../product/features/squadron.md)) supersede A9's original R2/Squadron half. All Squadron-archive-shaped work is deferred to SC4 polished-later: no operation, HTTP/MCP/server surface, warning/confirmation path, event, schema column, or projection dimension ships here. Migration `008_LifecycleClosure` contains no Squadron schema. Existing append-only ledgers already remain readable; a future SC4 implementation can compose the R1 participant termination machinery after its user contract ships. Known migration cost: rebuilding `j5_a2a_exchange` activates A4's `ON DELETE CASCADE`, so 008 snapshots and restores every A4 inbox column opaquely inside the one migration transaction. Any future rebuild of this parent faces the same hazard; recurring snapshot code must become a separately reviewed migration-framework helper rather than another copy-paste. diff --git a/docs/j5/worklog/a2a-tickets/index.md b/docs/j5/worklog/a2a-tickets/index.md index cbd9a0f7dccd..559cb4b1ae8c 100644 --- a/docs/j5/worklog/a2a-tickets/index.md +++ b/docs/j5/worklog/a2a-tickets/index.md @@ -1,4 +1,4 @@ --- title: "Tickets" -kind: spec +kind: record --- diff --git a/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md b/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md index dd08fa71ee78..b1cc3ed15843 100644 --- a/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md +++ b/docs/j5/worklog/dogfood-tickets/b1-inbox-true-up.md @@ -1,7 +1,6 @@ --- title: "B1 — Inbox surface true-up to IB1–IB7 (post-#11)" -kind: ticket -status: 0 +kind: record --- # B1 — Inbox true-up diff --git a/docs/j5/worklog/dogfood-tickets/b3-thread-a2a-rendering.md b/docs/j5/worklog/dogfood-tickets/b3-thread-a2a-rendering.md index 1488d31814e6..415a5a224756 100644 --- a/docs/j5/worklog/dogfood-tickets/b3-thread-a2a-rendering.md +++ b/docs/j5/worklog/dogfood-tickets/b3-thread-a2a-rendering.md @@ -1,7 +1,6 @@ --- title: "B3 — Thread-view A2A rendering (TA1–TA5 static treatments)" -kind: ticket -status: 0 +kind: record --- # B3 — Thread A2A rendering diff --git a/docs/j5/worklog/dogfood-tickets/b6-client-reads.md b/docs/j5/worklog/dogfood-tickets/b6-client-reads.md index a6b8108ca60a..0ade634778ee 100644 --- a/docs/j5/worklog/dogfood-tickets/b6-client-reads.md +++ b/docs/j5/worklog/dogfood-tickets/b6-client-reads.md @@ -1,7 +1,6 @@ --- title: "B6 — Small client-read endpoints (labels, names, counts)" -kind: ticket -status: 0 +kind: record --- # B6 — Client reads bundle diff --git a/docs/j5/worklog/dogfood-tickets/b7-thread-card-treatment.md b/docs/j5/worklog/dogfood-tickets/b7-thread-card-treatment.md index a17cea0b913d..c7ca33044990 100644 --- a/docs/j5/worklog/dogfood-tickets/b7-thread-card-treatment.md +++ b/docs/j5/worklog/dogfood-tickets/b7-thread-card-treatment.md @@ -1,12 +1,11 @@ --- title: "B7 — Thread A2A card treatment (TA6–TA10 final design)" -kind: ticket -status: 0 +kind: record --- # B7 — Card treatment true-up -**Governing artifacts:** `../../product/features/thread-a2a-rendering.md` §Card anatomy and states (TA6–TA10; TA4 superseded by TA8), session `../thread-a2a-prominence-session-2026-08-31.md`, approved all-states mockup at design workspace `product/thread-a2a/final-treatment/` (decision aid, not pixel spec). Designer available for render questions. +**Governing artifacts:** `../../product/features/thread-a2a-rendering.md` §Card anatomy and states (TA6–TA10; TA4 superseded by TA8), session `../2026-08-31-thread-a2a-prominence-session.md`, approved all-states mockup at design workspace `product/thread-a2a/final-treatment/` (decision aid, not pixel spec). Designer available for render questions. ## Scope diff --git a/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md b/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md index 073d93726c62..cf09298cb1be 100644 --- a/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md +++ b/docs/j5/worklog/dogfood-tickets/e7-squadron-picker-conversion.md @@ -1,12 +1,11 @@ --- title: "E7 build — Squadron becomes the unit of user choice in every picker" -kind: ticket -status: 1 +kind: record --- # E7 — Squadron picker conversion -**Governing artifacts:** `../../product/features/squadron.md` §E7 (definitional law, ruled 2026-08-31), `../picker-and-self-messaging-rulings-2026-08-31.md`, DV1/DV3 (`../../plans/dogfood-v0.md`). Origin: Jackson's #20 acceptance pass — the new-thread flow still presented the upstream PROJECT picker before the prompt. +**Governing artifacts:** `../../product/features/squadron.md` §E7 (definitional law, ruled 2026-08-31), `../2026-08-31-picker-and-self-messaging-rulings.md`, DV1/DV3 (`../../plans/dogfood-v0.md`). Origin: Jackson's #20 acceptance pass — the new-thread flow still presented the upstream PROJECT picker before the prompt. ## Goal diff --git a/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md b/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md index ed491e881985..ab839125134e 100644 --- a/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md +++ b/docs/j5/worklog/dogfood-tickets/sq1-creation-surface.md @@ -1,12 +1,11 @@ --- title: "SQ1 — Squadron creation surface & composer context (phase-3 minimal)" -kind: ticket -status: 0 +kind: record --- # SQ1 — Squadron creation surface -**Governing artifacts:** `../../product/features/squadron.md` §Creation UX (SC1–SC4, definition-of-record, as amended by SB3), **`../../plans/dogfood-v0.md` (DV1–DV3 — the single home for v0 overrides; it WINS over feature docs for this build)**, session trail `../squadron-creation-session-2026-08-24.md`, `../../plans/dogfood-v0.md` §Phase-3 prerequisite. Mockups in the design workspace (`product/squadron-creation-mockups/`) are decision aids, not pixel specs. Backend receiving contract: the Registrar (PR #10) — creation-time attachment of a thread to an explicit **existing** Squadron, once, immutably. +**Governing artifacts:** `../../product/features/squadron.md` §Creation UX (SC1–SC4, definition-of-record, as amended by SB3), **`../../plans/dogfood-v0.md` (DV1–DV3 — the single home for v0 overrides; it WINS over feature docs for this build)**, session trail `../2026-08-24-squadron-creation-session.md`, `../../plans/dogfood-v0.md` §Phase-3 prerequisite. Mockups in the design workspace (`product/squadron-creation-mockups/`) are decision aids, not pixel specs. Backend receiving contract: the Registrar (PR #10) — creation-time attachment of a thread to an explicit **existing** Squadron, once, immutably. ## Goal @@ -16,7 +15,7 @@ SC4's phase-3 minimal line as cut by DV1–DV3, working in the app: Jackson can - **Create Squadron** (SC2 as cut by DV1/DV2): name AND **exactly one folder** required; description optional. The folder is a Squadron→project **reference — never identity** — reusing the existing project machinery; folder picked via the existing open/clone affordances, no new picker. The relation is **stored list-ready** (join or list-shaped column) so the multi-folder milestone lifts a cap, not migrates a concept. Name-only creation is a DV2 named casualty — do not build it. - **First-run gate** (SC2): first run gates on creating the first Squadron; the gate states plainly that agents need a home and asks for a name plus one folder (DV2). **No auto-created "Default" Squadron anywhere.** -- **Squadron scope dropdown** (SC3 _as amended 2026-08-29, SB3 — [session record](../sidebar-roster-session-2026-08-29.md)_): upstream's project-scope dropdown becomes a Squadron scope dropdown; the sidebar is scoped, never grouped. +- **Squadron scope dropdown** (SC3 _as amended 2026-08-29, SB3 — [session record](../2026-08-29-sidebar-roster-session.md)_): upstream's project-scope dropdown becomes a Squadron scope dropdown; the sidebar is scoped, never grouped. - **Composer context inheritance** (SC3): heading becomes "What should we build in _⟨Squadron⟩_?"; explicit **Squadron chip** in the sub-bar beside the worktree row — visible, changeable until send, immutable after. What the chip shows at send is exactly what the Registrar receives. The inherited context comes from the scope-dropdown selection (SC3 as amended). - **Worktree row** (SC1 as cut by DV1/DV3): offers the Squadron's single folder. "Browse elsewhere…" ships only if project reuse makes it cheap; otherwise it goes to the backlog, not onto the critical path (DV3 — the never-a-wall principle is end-state law, untouched). No permission semantics, no pre-provisioning; worktrees stay per-agent. - Agent-spawned agents see none of this: they inherit the spawner's Squadron (R21) through the existing path. diff --git a/docs/j5/worklog/fork-setup-plan/baseline.md b/docs/j5/worklog/fork-setup-plan/baseline.md index e5e212b832e2..cb0ba131fe0e 100644 --- a/docs/j5/worklog/fork-setup-plan/baseline.md +++ b/docs/j5/worklog/fork-setup-plan/baseline.md @@ -1,6 +1,6 @@ --- title: "J5 Code build and test baseline" -kind: spec +kind: record --- # J5 Code build and test baseline diff --git a/docs/j5/worklog/fork-setup-plan/index.md b/docs/j5/worklog/fork-setup-plan/index.md index 39ad93cf38d2..68a3a3ace2ab 100644 --- a/docs/j5/worklog/fork-setup-plan/index.md +++ b/docs/j5/worklog/fork-setup-plan/index.md @@ -1,6 +1,6 @@ --- title: "Plan: fork & setup (backlog item 1)" -kind: spec +kind: record --- # Plan — Fork & setup diff --git a/docs/j5/worklog/fork-setup-plan/load-test.md b/docs/j5/worklog/fork-setup-plan/load-test.md index 4c90b0144a71..0808e4a15476 100644 --- a/docs/j5/worklog/fork-setup-plan/load-test.md +++ b/docs/j5/worklog/fork-setup-plan/load-test.md @@ -1,6 +1,6 @@ --- title: "J5 Code fleet load test and provider smoke" -kind: spec +kind: record --- # J5 Code fleet load test and provider smoke diff --git a/docs/j5/worklog/fork-setup-plan/relay-assessment.md b/docs/j5/worklog/fork-setup-plan/relay-assessment.md index 953ebcc5b4e1..c9dabd117b80 100644 --- a/docs/j5/worklog/fork-setup-plan/relay-assessment.md +++ b/docs/j5/worklog/fork-setup-plan/relay-assessment.md @@ -1,6 +1,6 @@ --- title: "Relay and PlanetScale assessment" -kind: spec +kind: record --- # Relay and PlanetScale assessment diff --git a/docs/j5/worklog/fork-setup-plan/tickets/build-baseline.md b/docs/j5/worklog/fork-setup-plan/tickets/build-baseline.md index 011cdbf6ec4b..ec179cfe8ec0 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/build-baseline.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/build-baseline.md @@ -1,7 +1,6 @@ --- title: "T2 — Build up & test baseline" -kind: ticket -status: 2 +kind: record --- # T2 — Build up & test baseline diff --git a/docs/j5/worklog/fork-setup-plan/tickets/ci-packaging.md b/docs/j5/worklog/fork-setup-plan/tickets/ci-packaging.md index eb407960a4ff..4e28c56fb772 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/ci-packaging.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/ci-packaging.md @@ -1,7 +1,6 @@ --- title: "T5 — Light CI & desktop packaging" -kind: ticket -status: 2 +kind: record --- # T5 — Light CI & desktop packaging diff --git a/docs/j5/worklog/fork-setup-plan/tickets/fleet-load-test.md b/docs/j5/worklog/fork-setup-plan/tickets/fleet-load-test.md index 57f599093660..469fe7601c96 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/fleet-load-test.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/fleet-load-test.md @@ -1,7 +1,6 @@ --- title: "T6 — Fleet load test & provider smoke" -kind: ticket -status: 2 +kind: record --- # T6 — Fleet load test & provider smoke diff --git a/docs/j5/worklog/fork-setup-plan/tickets/index.md b/docs/j5/worklog/fork-setup-plan/tickets/index.md index cbd9a0f7dccd..559cb4b1ae8c 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/index.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/index.md @@ -1,4 +1,4 @@ --- title: "Tickets" -kind: spec +kind: record --- diff --git a/docs/j5/worklog/fork-setup-plan/tickets/planetscale-investigation.md b/docs/j5/worklog/fork-setup-plan/tickets/planetscale-investigation.md index 090d0b9ddb0a..7b7183296ffa 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/planetscale-investigation.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/planetscale-investigation.md @@ -1,7 +1,6 @@ --- title: "T4 — PlanetScale / relay investigation" -kind: ticket -status: 2 +kind: record --- # T4 — PlanetScale / relay investigation diff --git a/docs/j5/worklog/fork-setup-plan/tickets/rebrand.md b/docs/j5/worklog/fork-setup-plan/tickets/rebrand.md index 10157d28ec2a..282e02b85866 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/rebrand.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/rebrand.md @@ -1,7 +1,6 @@ --- title: "T3 — Rebrand to J5 Code (minimal-churn)" -kind: ticket -status: 2 +kind: record --- # T3 — Rebrand to J5 Code diff --git a/docs/j5/worklog/fork-setup-plan/tickets/repo-setup.md b/docs/j5/worklog/fork-setup-plan/tickets/repo-setup.md index 67c18097c6f0..f4ba2b9be828 100644 --- a/docs/j5/worklog/fork-setup-plan/tickets/repo-setup.md +++ b/docs/j5/worklog/fork-setup-plan/tickets/repo-setup.md @@ -1,7 +1,6 @@ --- title: "T1 — Repo setup: fork, pin, FORK.md" -kind: ticket -status: 2 +kind: record --- # T1 — Repo setup diff --git a/scripts/j5/dogfood-local.sh b/scripts/j5/dogfood-local.sh index 010d7811f54d..5b5c4e42ea86 100755 --- a/scripts/j5/dogfood-local.sh +++ b/scripts/j5/dogfood-local.sh @@ -5,7 +5,7 @@ # scripts/j5/dogfood-local.sh --no-update # serve the already-built runtime (fast restart) # scripts/j5/dogfood-local.sh --fresh # set the state dir aside (renamed, not deleted) and start clean # -# This is the local-first counterpart of the Linux runbook (docs/j5/dogfood-runtime.md): +# This is the local-first counterpart of the Linux runbook (docs/j5/runbooks/dogfood-runtime.md): # same layout, same state dir, same snapshot-before-update rule, minus systemd/Tailscale. # # runtime checkout : ~/.j5code-runtime/src (detached at origin/j5/main — the server's own diff --git a/scripts/j5/dogfood-snapshot.sh b/scripts/j5/dogfood-snapshot.sh index 0608fc272219..bcd14c3668d2 100755 --- a/scripts/j5/dogfood-snapshot.sh +++ b/scripts/j5/dogfood-snapshot.sh @@ -2,7 +2,7 @@ # Snapshot the dogfood server's SQLite state with VACUUM INTO, which is safe # while the server is running and yields one consistent file. Called by # dogfood-update.sh before every update and by the nightly snapshot timer. -# See docs/j5/dogfood-runtime.md. +# See docs/j5/runbooks/dogfood-runtime.md. set -euo pipefail diff --git a/scripts/j5/dogfood-update.sh b/scripts/j5/dogfood-update.sh index b3ac23c02610..3ff1c613ec18 100755 --- a/scripts/j5/dogfood-update.sh +++ b/scripts/j5/dogfood-update.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Update the self-hosted J5 Code dogfood server from source and restart it. # Run on the server box as the dogfood user; prefer a quiet fleet, since the -# restart cancels in-flight agent turns. See docs/j5/dogfood-runtime.md. +# restart cancels in-flight agent turns. See docs/j5/runbooks/dogfood-runtime.md. set -euo pipefail @@ -39,5 +39,5 @@ for _ in $(seq 1 30); do done echo "Server did not answer after 30 probes (2s request limit, 1s retry delay). Inspect: journalctl --user -u $service -e" >&2 -echo "Rollback: git checkout $previous_ref, rebuild, restore the pre-update snapshot (docs/j5/dogfood-runtime.md)." >&2 +echo "Rollback: git checkout $previous_ref, rebuild, restore the pre-update snapshot (docs/j5/runbooks/dogfood-runtime.md)." >&2 exit 1 From cda46fe4da80808ff3acfb16b8a2670b9b8c1fcc Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Thu, 10 Sep 2026 20:54:49 -0400 Subject: [PATCH 13/15] docs(j5): fold the Fleet page contract into a definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites sidebar-and-roster as the Fleet page and sidebar definition (AC1–AC26, scenarios, History mapping SB1–SB7, FV1–FV11 and DV6), moves the 2026-09-04 fleet-visibility session record to its date-first name with a pointer to the definition, re-keys the dogfood plan's narrowing table by criterion, and gives the glossary's Fleet page, Squadron scope, orphan and delivery alarm terms their owners. Supersedes PR #107. Co-Authored-By: Claude Fable 5.1 --- docs/j5/plans/dogfood-v0.md | 21 ++-- docs/j5/product/cross-device.md | 2 +- docs/j5/product/features/fleet-page.md | 112 ++++++++++++++++++ .../j5/product/features/sidebar-and-roster.md | 84 ------------- docs/j5/product/glossary.md | 14 +-- docs/j5/product/principles.md | 2 +- docs/j5/product/problems.md | 38 +++--- .../2026-08-29-sidebar-roster-session.md | 2 +- .../2026-09-04-fleet-visibility-session.md | 66 +++++++++++ 9 files changed, 216 insertions(+), 125 deletions(-) create mode 100644 docs/j5/product/features/fleet-page.md delete mode 100644 docs/j5/product/features/sidebar-and-roster.md create mode 100644 docs/j5/worklog/2026-09-04-fleet-visibility-session.md diff --git a/docs/j5/plans/dogfood-v0.md b/docs/j5/plans/dogfood-v0.md index bf5a67a5d57d..fc2d32749a4c 100644 --- a/docs/j5/plans/dogfood-v0.md +++ b/docs/j5/plans/dogfood-v0.md @@ -33,16 +33,17 @@ Tickets held as J5-native work, staffed from GitHub (label `dogfood-queue`), eac Each row names the definition and the criteria it narrows, and when the full behavior returns. The definitions describe the end state; this table is the only place a cut is stated. -| Definition and criteria | Current build | Returns | -| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | -| Squadron AC5 (one or more folders) | Exactly one folder, implemented as a Squadron→project reference — never identity. Guards that must hold: membership is assigned by the Registrar, never derived from the project; two Squadrons over the same folder work (an acceptance criterion, not a later feature); the folder relation is stored ready to become a list | The multi-folder milestone: a list, with the palette-first worktree row | -| Squadron AC6 (everything else reachable) | "Browse elsewhere" may be absent; if project reuse makes it cheap, keep it, otherwise it is backlog rather than blocking. Never-a-wall is untouched at end state | Backlog item if cut; at latest with the multi-folder milestone | -| Squadron AC7 (every picker offers Squadrons) | The new-thread flow and the command palette are converted; remaining pickers convert by inventory ([#38](https://github.com/Jacksondr5/j5code/issues/38), [#39](https://github.com/Jacksondr5/j5code/issues/39)) | As the inventory closes | -| Squadron AC3 (Squadron required to create an agent) — exemptions | The hard refusal binds the interactive user-origin creation path only. Exempt, each with its return: mobile new thread and offline drain; scheduled new-thread creation, which hits the refusal and must surface as a visible scheduled-task error; the server's bootstrap creation; plan-to-implementation inherits the parent's home, and a no-home parent yields a no-home child. Squadron creation is primary-environment-only with a state-naming refusal elsewhere | Per row: a mobile Squadron ticket; a truthful scheduler-origin carrier; multi-environment work | -| Thread rendering AC4 ("You · via Inbox" for the reader who sent it) | Renders neutral `Via Inbox · ⟨person⟩` — "You" is a factual claim that the viewer is that person, and the merged auth principal is session-scoped with no person binding, so the claim cannot be made truthfully. Rendering on exact equality is already built, so the upgrade needs no renderer rework | The auth-subject-to-person binding session (queued after v0) | -| Sidebar (SB5 membership by provenance; pin/hide overrides; roster-and-removal ship together) | The sidebar is unchanged: no automatic hiding of agent-spawned threads, no overrides, no pairing rule; the Fleet page is purely additive. The rule was too harsh — Jackson asks the Director to spawn most agents he talks with — and the human-contact-spectrum story is not strong enough to build a filter yet. Accepted gap | With Crews (the first thing a user explicitly expects not to talk to) or a settled spectrum representation | -| A2A AC7–AC8 (several open asks to a person; explicit follow-ups) | The shipped behavior refuses a second ask to a person while one is open ([#111](https://github.com/Jacksondr5/j5code/issues/111)) | With #111 | -| A2A AC20 (silence notices as measured facts) | Notices are stored with a label chosen when written; a notice with several open asks records only its first match; no surface shows the stored label as current status | With #30 | +| Definition and criteria | Current build | Returns | +| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | +| Squadron AC5 (one or more folders) | Exactly one folder, implemented as a Squadron→project reference — never identity. Guards that must hold: membership is assigned by the Registrar, never derived from the project; two Squadrons over the same folder work (an acceptance criterion, not a later feature); the folder relation is stored ready to become a list | The multi-folder milestone: a list, with the palette-first worktree row | +| Squadron AC6 (everything else reachable) | "Browse elsewhere" may be absent; if project reuse makes it cheap, keep it, otherwise it is backlog rather than blocking. Never-a-wall is untouched at end state | Backlog item if cut; at latest with the multi-folder milestone | +| Squadron AC7 (every picker offers Squadrons) | The new-thread flow and the command palette are converted; remaining pickers convert by inventory ([#38](https://github.com/Jacksondr5/j5code/issues/38), [#39](https://github.com/Jacksondr5/j5code/issues/39)) | As the inventory closes | +| Squadron AC3 (Squadron required to create an agent) — exemptions | The hard refusal binds the interactive user-origin creation path only. Exempt, each with its return: mobile new thread and offline drain; scheduled new-thread creation, which hits the refusal and must surface as a visible scheduled-task error; the server's bootstrap creation; plan-to-implementation inherits the parent's home, and a no-home parent yields a no-home child. Squadron creation is primary-environment-only with a state-naming refusal elsewhere | Per row: a mobile Squadron ticket; a truthful scheduler-origin carrier; multi-environment work | +| Thread rendering AC4 ("You · via Inbox" for the reader who sent it) | Renders neutral `Via Inbox · ⟨person⟩` — "You" is a factual claim that the viewer is that person, and the merged auth principal is session-scoped with no person binding, so the claim cannot be made truthfully. Rendering on exact equality is already built, so the upgrade needs no renderer rework | The auth-subject-to-person binding session (queued after v0) | +| Fleet page AC4–AC25 (the page itself) | Not built; the first build is [#28](https://github.com/Jacksondr5/j5code/issues/28) in the Fleet observability milestone, which reads the primary environment only and says so ([#105](https://github.com/Jacksondr5/j5code/issues/105) carries the merge that cross-device AC2 defines) | With #28; environment merging with #105 | +| Fleet page AC26 (cost per Squadron) | Not in the first build | A later Fleet observability milestone | +| A2A AC7–AC8 (several open asks to a person; explicit follow-ups) | The shipped behavior refuses a second ask to a person while one is open ([#111](https://github.com/Jacksondr5/j5code/issues/111)) | With #111 | +| A2A AC20 (silence notices as measured facts) | Notices are stored with a label chosen when written; a notice with several open asks records only its first match; no surface shows the stored label as current status | With #30 | Retired cuts: "folder required at creation" was a v0 cut until 2026-09-05, when the Squadron definition made one-or-more folders the end state; it is no longer a narrowing. diff --git a/docs/j5/product/cross-device.md b/docs/j5/product/cross-device.md index be9063547e7d..570827f842df 100644 --- a/docs/j5/product/cross-device.md +++ b/docs/j5/product/cross-device.md @@ -40,7 +40,7 @@ What this never does: no replicated state, no multi-master, no Squadron migratio ## Scenarios - **Two servers, one inbox.** The user's client connects to the work server and the home server. An ask from an agent in Billing Migration (work) and one from Support Rotation (home) appear in one inbox, each tagged with its environment; answering each reaches the right server. (AC2, AC3) -- **A server goes dark.** The home server is asleep; its rows stay on the Fleet page with "last seen 40m ago" and never vanish. (AC4) +- **A server goes dark.** The home server is asleep; its rows stay on the Fleet page with "as of 40m ago" and never vanish. (AC4) - **A Mac-only job.** An agent that must run on a Mac gets its own Squadron homed on the Mac server; it is asked for results by a Squadron elsewhere through a cross-server Exchange, once peering exists. (AC1, AC6) ## History diff --git a/docs/j5/product/features/fleet-page.md b/docs/j5/product/features/fleet-page.md new file mode 100644 index 000000000000..c20dba7a2951 --- /dev/null +++ b/docs/j5/product/features/fleet-page.md @@ -0,0 +1,112 @@ +--- +title: "Fleet page and sidebar" +kind: definition +--- + +# Fleet page and sidebar + +## Problem + +The more agents a person runs, the less they can see. Upstream's sidebar is a recency-sorted list of conversations, which serves the agents a person is talking to and hides everything else: an agent spawned by another agent, an agent that stopped an hour ago, an agent waiting on a reply nobody knows it sent. Asking an agent how it is doing does not work either, because agents answer from context rather than measurement ([problems](../problems.md): fleet observability; human attention is scarce). The Fleet page is where the state of every agent the person is not talking to can be read. + +## Definition + +A person's attention splits across three surfaces, each with one job: + +- The **sidebar** holds conversations in motion: the agents the person is actively talking to, sorted by recency the way upstream users expect. +- The **inbox** holds what needs the person: open asks, and nothing else ([inbox](inbox.md)). +- The **Fleet page** holds the health of everything else: every agent in a Squadron, with facts the platform measured, whether or not anyone is talking to it. + +**The sidebar** is upstream's sidebar, with its mechanics for snoozing, settling and pinning untouched. J5 changes two things. The project-scope dropdown becomes the **Squadron scope**: the sidebar shows one Squadron or all of them, and agent creation takes its Squadron from that scope ([Squadron](squadron.md)). And each row speaks J5's language: the Squadron, the title, and a status label. Nothing is hidden from the sidebar by how an agent came to exist; a person who asks one agent to spawn most of the agents they talk with still finds them there. Which agents a person is expected not to talk to is a question for [Crews](crews.md), not for a filter. + +**The Fleet page** is a full-width page in the main view, reached from an entry at the foot of the rail that carries a badge, and from the command palette. It shows **one Squadron at a time**. While the page is open, the sidebar is replaced by a list of every Squadron, each with its count of measured problems, and the page shows the Squadron chosen there. The choice is the page's own: it does not change the sidebar's Squadron scope, and leaving the page brings the sidebar back as it was. + +The rows are the Squadron's **agents**: every registered agent participant whose home is that Squadron, arranged as the placement tree with siblings in creation order. People are never rows; they appear as counterparties in an agent's asks. Provider-native Subagents never appear; upstream's own panel is their home. Rows keep their positions. A problem marks a row; it never moves one. + +Each row answers four questions, and the page's job is done when every row answers all four or says plainly that it cannot: + +1. **Is it doing anything right now?** Its status, as the runtime reports it. +2. **Is anyone waiting on it, or is it waiting on anyone?** Its open asks, owed and awaited. +3. **When did it last do anything?** Its latest measured event, labeled by what the event was. +4. **Is there a measured problem?** A failed run, a delivery alarm, a run that never started. + +Everything on the page is a **measurement**. There is no health score, no "stalled", no reordering by urgency, and no guess: an unknown fact renders as unknown with its reason, because a visible gap beats a plausible fake ([principles](../principles.md): never guess; status is read, never asked). Silence notices are not shown here: with several open asks a notice is ambiguous, and "ended without replying" is a judgment the person makes, so the age of the open ask carries the fact instead. The page states which environment it read and as of when. Clicking a row opens the agent's thread. + +The **badge** on the rail entry counts agents with a measured problem across every Squadron the page can read, so the person learns that something is broken somewhere even while looking at one Squadron. It never counts what the inbox bell counts: the bell is where agents tell the person something, the badge is where the platform does, and one fact is counted once. + +A retired agent still matters on the page when it has working descendants. Such an **orphan** keeps its parent visible as a dimmed placeholder holding its place in the tree, so the children are never re-parented and the shape of what happened stays readable. A retired agent with no active descendants is not shown. + +Cost is a product surface: what a Squadron costs, and what each of its agents contributed, rolls up on this page and nowhere in between ([fleet vision](../fleet-vision.md)). + +The Fleet page is **not** the inbox: it never demands a reply. It is **not** a permission or visibility boundary: any agent stays reachable and messageable whatever surface it appears on. It is **not** a Squadron container view: the Squadron scope filters and the Squadron list selects, and neither walls. + +## Acceptance criteria + +### The sidebar + +1. The sidebar's scope control offers the Squadrons of the environment and "all", and the list shows only threads whose Squadron home matches the selection. +2. A sidebar row shows the agent's Squadron and a relative time on its first line, the title on its second, and the status label with the provider icon on its third; worktree and branch live in the hover tooltip, which also carries a measured status line. +3. No agent thread is hidden from the sidebar on account of how it was created; snooze, settle and pin behave as upstream defines them. + +### Entering the page + +4. The Fleet page opens from a rail-footer entry and from the command palette, as a full-width page in the main view. +5. While the page is open, the sidebar is replaced by a list of every Squadron in the environment, each with its count of agents that have a measured problem. +6. The page shows exactly one Squadron, the one selected in that list; it opens on the sidebar's scoped Squadron when there is one and otherwise on the list with nothing selected. +7. Selecting a Squadron on the page does not change the sidebar's Squadron scope, and leaving the page restores the sidebar unchanged. + +### The rows + +8. The rows are every registered agent participant whose home is the selected Squadron, with no cap on their number; a large Squadron is paged or virtualized, never silently truncated. +9. Rows are arranged as the placement tree, siblings in creation order, and are never reordered by activity or by problems. +10. People are never rows; a person appears only as the counterparty on an agent's asks. Provider-native Subagents never appear. +11. Every retired agent on the path from the Squadron to an active agent renders as a dimmed placeholder in its tree position, with its cells marked not applicable rather than unknown; its descendants stay beneath it; a retired agent with no active descendant is not shown. +12. Each row shows its provenance as a fact: spawned by which agent, forked, or unrecorded. +13. Threads in the environment that have no Squadron home are not rows; one footer line states how many there are (unarchived, excluding provider-native Subagents), and no Squadron is invented for them. +14. Clicking a row opens the agent's thread. + +### The four facts + +15. Status shows the runtime's own fact: Working, Waiting, Approval, Input or Failed; "Waiting to start · Nm" takes precedence while a run has been requested and not dispatched; "Idle since ⟨time⟩" appears only when nothing is active and no background work remains. +16. Read and snooze bookkeeping (upstream's Woke and Done) is not a status and does not appear. +17. Silence notices are not shown on the page; the age of an open ask is the visible fact. +18. Open asks show two counts, "Owes N" for open asks the agent must answer and "Awaiting N" for open asks it is waiting on, with a hover list of counterparty, intent and age; a follow-up joined to an open Exchange counts once. +19. Last activity is the latest measured event, labeled by what it was (for example "last turn ended 14:02"); the page never shows a vague "last seen". +20. Any fact the page cannot measure renders as `?` with the reason on hover; the row still renders, and no label is derived from a partial set of facts. + +### Problems and the badge + +21. A row's measured problems are a failed latest run, a delivery alarm, and a run that has waited past the dispatch threshold; the row lists every one it has. +22. A delivery alarm is shown on the sender's row as "Delivery failed · to ⟨receiver⟩ · ⟨time⟩ · ⟨reason⟩" and stays while the fact is true; it is never inferred repaired ([agent-to-agent communication](../a2a/index.md)). +23. The badge counts agents that have at least one measured problem across every Squadron the page reads; an agent counts once however many problems it has, unknowns never count, and the badge never counts open asks to the person or silence notices. +24. A delivery alarm counts toward the badge only while the Exchange it belongs to is open; an alarm on a plain message is shown on the row and never counted; a failed delivery of a platform-authored notice is neither shown nor counted. + +### Freshness and environment + +25. The page header names the environment the facts came from and the time as of which they were read; how several environments merge on the page is defined in [cross-device](../cross-device.md). + +### Cost + +26. The Squadron list shows each Squadron's measured cost, and a Squadron's page shows what each of its agents contributed. + +## Scenarios + +- **Reading one Squadron.** The user selects Billing Migration on the page's Squadron list. The coordinator agent is the first row; the two builders it spawned sit indented beneath it in the order they were created, each showing status, owed and awaited asks, and last activity. Clicking a builder opens its thread. (AC6, AC8, AC9, AC12, AC14) +- **A run that never started.** A builder's run has sat undispatched for seven minutes: its status reads "Waiting to start · 7m" and the badge counts it. When the run starts, the status changes and the badge drops. (AC15, AC21, AC23) +- **Owed and awaited.** An agent owes one answer to its coordinator and is waiting on two peers: "Owes 1 · Awaiting 2", with all three listed on hover with their ages. (AC18) +- **An orphan.** A coordinator is archived while two builders it spawned are still working: its row dims to "retired" in place, and the builders stay beneath it, still Working. (AC11) +- **A fact that cannot be read.** The placement query fails for one agent: its placement cell shows `?` with the reason on hover, the row renders, and the badge is unchanged. (AC20, AC23) +- **Two problems, one agent.** An agent's latest run failed and it also has a delivery alarm: the badge counts it once and its row lists both. (AC21, AC23) +- **Silence.** A silence notice exists for an agent: nothing on the page changes; its status is whatever the runtime says and the owed ask's age is the visible fact. (AC17) +- **Where is the problem?** The rail badge shows 2. Opening the Fleet page replaces the sidebar with the Squadron list, where Billing Migration shows 2 and Website Redesign shows 0. Choosing Billing Migration shows both failing agents; leaving the page restores the sidebar with its scope as it was. (AC5, AC7, AC23) +- **As of when.** The header reads "Fleet · work server · as of 14:02:31"; a saved home server's Squadrons do not appear on this page, and the page does not claim they do. (AC25) +- **Threads without a home.** Three threads created before Squadrons existed have no home: the footer says so, and none is a row. (AC13) +- **A failed delivery.** An agent's ask to its coordinator fails to deliver: its row shows "Delivery failed · to ⟨coordinator⟩ · 14:02 · ⟨reason⟩" and the badge counts it. The agent clears its ask: the chip stays, and the badge no longer counts it. (AC22, AC24) +- **The user is not a row.** An agent in Support Rotation has an ask out to the user: the user is not a row on the page; the ask appears in that agent's "Awaiting" list with the user as counterparty. (AC10, AC18) + +## History + +- 2026-08-29 — the three-surface model, the Squadron scope, row language, and the roster as a Fleet page settled; former SB1–SB7 ([record](../../worklog/2026-08-29-sidebar-roster-session.md)). +- 2026-09-04 — the Fleet page specified: one Squadron at a time from its own Squadron list, agents only, the four facts, silence notices omitted, the global badge, delivery alarms, orphans; the sidebar membership-by-provenance rule dropped; former FV1–FV11 ([record](../../worklog/2026-09-04-fleet-visibility-session.md)). +- 2026-09-05 — status vocabulary corrected against the runtime's resolver (same record). +- 2026-09-10 — rewritten into the definition shape and renamed from "Sidebar & roster". Former identifiers: SB1 → Definition; SB2 → AC3; SB3 → AC1; SB4 → AC2; SB5 → dropped (AC3 says the opposite); SB6 → AC4–AC14; SB7 → the inbox definition; FV1 → Definition, AC20; FV2 → AC15–AC17; FV3 → AC18; FV4 → AC19; FV5 → AC21, AC23; FV6 → AC20, AC25; FV7 → AC5–AC13; FV8 → AC3; FV9 → not a product matter (the server reads belong to the build); FV10 → the deferred items are backlog candidates, not part of this definition, except cost, which the fleet vision requires and AC26 carries; FV11 → AC22, AC24; the v0 override DV6 → AC3. The sidebar label's "extended with silence states" clause is not restated: silence facts are defined by agent-to-agent communication, and where they show is that definition's call. Mockup references are gone: mockups are decision aids in a design workspace, not part of the definition. diff --git a/docs/j5/product/features/sidebar-and-roster.md b/docs/j5/product/features/sidebar-and-roster.md deleted file mode 100644 index 10d2477d16e7..000000000000 --- a/docs/j5/product/features/sidebar-and-roster.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: "Sidebar & roster — how the fleet is presented" -kind: spec ---- - -# Sidebar & roster - -Feature definition of record, settled 2026-08-29 with Jackson -([session rulings SB1–SB7](../../worklog/2026-08-29-sidebar-roster-session.md)). -The problems it serves ([problems doc](../problems.md)): fleet -observability ("it's hard to see what agents you aren't talking to are -doing") and scarce human attention. Approved mockups live in the design -workspace (`product/fleet-sidebar/mockups/`), rendered against real app -references; they are decision aids, not pixel specs. - -## The three-surface attention model (SB1) - -J5 pushes users toward running more agents while talking to fewer. No -single surface serves both facts, so attention splits three ways: - -| Surface | Job | Sort/logic | -| ----------- | -------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Sidebar** | Conversations in motion — the agents the user is actively talking to | Recency, as users expect; upstream mechanics kept | -| **Inbox** | High-certainty "needs me" — decisions and measured failures | Urgency-ranked obligation queue (+ alerts lane, designed later) | -| **Roster** | Overall health and judgment discovery; home of all hidden agents | Placement tree grouped by Squadron, status read never asked | - -The observability dashboard (item 4) grows out of the roster; they are one -surface at two maturities, not two surfaces. - -## The sidebar (SB2–SB5) - -Upstream's default sidebar survives structurally: flat recency list, -snoozed/settled/pinned mechanics untouched (revisit post-dogfood), no -continuous animation, status carried per-row. - -J5's deltas: - -- **Squadron scope dropdown** replaces the project-scope dropdown (SC3 as - amended): scope to one Squadron when focused, zoom out when triaging. - The composer's Squadron context inherits from the scope selection. -- **Row language:** line 1 shows the Squadron (+ relative time, yielding - to snooze/settle actions on hover); line 2 the title; line 3 a status - label — upstream's vocabulary (Working/Approval/Input/Failed/Woke/Done) - extended with J5 silence states — plus the provider icon. - Worktree/branch demote to the existing hover tooltip, which gains a - measured status line (e.g. "Working 4m · turn started 14:02"). -- **Not all agents appear.** Membership follows provenance (v0 rule, - dogfood-refinable): human-created agents show; agent-spawned Peer - Agents are roster-only; pin/hide overrides in both directions. - -## The roster (SB6) - -A full-width **Fleet page** in the main view, opened from a rail-footer -entry that carries an alert badge. Contents: every agent in the scope, -grouped by Squadron, indented by placement (Crews render as collapsible -units under their Captain once Crews exist), with columns for status, -open asks, and last activity. Unknowns render as `?` — a visibly missing -fact always beats a plausible fake ([never-guess](../principles.md)). - -Working assumptions riding to implementation: clicking a row opens the -agent's thread; the alert badge counts measured high-certainty facts -(errored, delivery-alarmed, awaiting-human/human-doesnt-know); row -actions (nudge, archive) are v-next. - -## What this feature is not - -Not the inbox (obligations live there; the roster never demands a reply), -not a permission or visibility boundary (any agent remains reachable and -messageable regardless of surface), and not a Squadron container view — -the scope dropdown filters, it never walls (E1). - -## Deferred (with reasons) - -- **Inbox UI/UX** — designed same day; definition of record at - [`inbox.md`](inbox.md) (IB1–IB7). The two-lane principle (obligation - queue vs measured alerts — R5) stands; the alerts lane itself is - post-v0. -- **Multi-environment scope treatment** — v0 consciously assumes one - environment; the X2 merge question is recorded. -- **Human-contact-spectrum representation** — the sidebar/roster split is - the first cut; mid-spectrum agents need thought. -- **Snooze/settle evolution** — kept as-is deliberately; post-dogfood - review decides which mechanics matter (assessment recorded in the - session worklog). diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 3fdf9f8e68d4..566d9fdea826 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -59,7 +59,7 @@ These entries are the distinctions the whole team must share; the glossary owns | envelope | The platform's wrapper around a delivered message that tells the receiving agent who sent it and what it owes | [a2a/index.md](a2a/index.md) | | communication ledger, ledger | The per-Squadron append-only record of every message, delivery, Exchange and notice — the source of truth for all A2A state | [a2a/index.md](a2a/index.md) | | delivery receipt | The recorded fact that a message reached its receiver's thread | [a2a/index.md](a2a/index.md) | -| delivery alarm | The recorded fact that a delivery failed | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| delivery alarm | The recorded fact that a delivery failed | [a2a/index.md](a2a/index.md) | | silence notice | A platform-authored fact appended when an agent's turn ends without a reply it owed | [a2a/index.md](a2a/index.md) | | queue, steer | The two ways a message reaches an agent mid-turn: queued behind the active turn, or steered into it. Agent deliveries queue; only a person steers, explicitly | [a2a/index.md](a2a/index.md) | | human node | A person as a participant in the communication graph, keyed by person id | [features/inbox.md](features/inbox.md) | @@ -70,12 +70,12 @@ These entries are the distinctions the whole team must share; the glossary owns | -------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | person id | The durable local identity of one person; nothing may assume there is exactly one person | [features/shared-squadrons.md](features/shared-squadrons.md) | | inbox | The person's queue of open asks addressed to them | [features/inbox.md](features/inbox.md) | -| **Fleet page** | The page that shows every agent in a Squadron with its measured status | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | -| Squadron scope | The sidebar's selection of one Squadron, or all | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| **Fleet page** | The page that shows every agent in a Squadron with its measured status | [features/fleet-page.md](features/fleet-page.md) | +| Squadron scope | The sidebar's selection of one Squadron, or all | [features/fleet-page.md](features/fleet-page.md) | | **Memo** | A small self-addressed note an agent keeps through the platform, visible to the person | [features/memos.md](features/memos.md) | | backlog pane | The person's view of all agents' Memos | [features/memos.md](features/memos.md) | | "Expects reply", "Replied" | The two words reader-facing cards use for an open and a closed Exchange, on every surface | [features/thread-a2a-rendering.md](features/thread-a2a-rendering.md) | -| observability dashboard | Retired name: what it described is the Fleet page | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| observability dashboard | Retired name: what it described is the Fleet page | [features/fleet-page.md](features/fleet-page.md) | ## Lifecycle @@ -83,7 +83,7 @@ These entries are the distinctions the whole team must share; the glossary owns | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | archive | Retiring an agent for good; its record stays readable, its open Exchanges end loudly | [features/archive-flow.md](features/archive-flow.md) | | retired | The state of an archived participant | [features/archive-flow.md](features/archive-flow.md) | -| orphan | A working agent whose placement parent has been archived | [features/sidebar-and-roster.md](features/sidebar-and-roster.md) | +| orphan | A working agent whose placement parent has been archived | [features/fleet-page.md](features/fleet-page.md) | | settled | Upstream's thread-triage state ("I'm done looking at this") and nothing else. J5 docs no longer use "settled" to mean a decision was made | upstream mechanics; see [worklog](../worklog/2026-08-29-upstream-settled-vs-archived-research.md) for the confusion this line resolves | ## Retired names @@ -94,7 +94,3 @@ These entries are the distinctions the whole team must share; the glossary owns | team | Not a concept. Crew is the group that works as a unit; there is no other grouping | | thread (as the reply obligation) | Exchange. "Thread" means only upstream's conversation | | delegate_task | Not on the J5 agent surface; a Peer Agent spawn carries its task in the brief, and an Exchange carries any later obligation | - -## Terms still waiting for an owner - -Fleet page, Squadron scope, orphan and delivery alarm are glossed above with a provisional owner; they move into the Fleet page definition when its contract lands. diff --git a/docs/j5/product/principles.md b/docs/j5/product/principles.md index 81a1ffd65f64..dc3088f7aa40 100644 --- a/docs/j5/product/principles.md +++ b/docs/j5/product/principles.md @@ -109,7 +109,7 @@ Each principle states its rule, what it stands on (beliefs and lenses above), it **Jurisdiction:** what the human must do to learn the fleet's state. -**Cases:** the Fleet page and the PR pane exist so "how's it going" is a read ([sidebar and roster](./features/sidebar-and-roster.md), [PR pane](./features/pr-pane.md)); cost rolls up per Squadron on a surface, nothing between ([sidebar and roster](./features/sidebar-and-roster.md)); chattiness is a measured metric, not a vibe. +**Cases:** the Fleet page and the PR pane exist so "how's it going" is a read ([Fleet page](./features/fleet-page.md), [PR pane](./features/pr-pane.md)); cost rolls up per Squadron on a surface, nothing between ([Fleet page](./features/fleet-page.md)); chattiness is a measured metric, not a vibe. ## Never guess — a plausible fake is worse than a visible gap diff --git a/docs/j5/product/problems.md b/docs/j5/product/problems.md index 53b74f777ca5..ac6585f24c47 100644 --- a/docs/j5/product/problems.md +++ b/docs/j5/product/problems.md @@ -120,25 +120,25 @@ The monitoring fleet's scraper and incident database (see the working fleet in ` One row per problem theme / goal; the pointer is where the answer is designed or tracked. -| Problem / goal | Answered by | Status | -| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| Fleet observability — agent/Crew state | Silence notices and the ledger's projections ([agent-to-agent communication](a2a/index.md)); the Playbook step pointer ([Playbooks](features/playbooks.md)); the Fleet page ([sidebar and roster](features/sidebar-and-roster.md)); status is read, never asked | A2A v1 plan; item 4; Playbooks candidate | -| Fleet observability — PR management | The [PR pane](features/pr-pane.md); playback of the ledger for review-decision audit | Pane approved, issue #6 | -| Fleet observability — cost | Cost rolls up per Squadron on the Fleet page | Item 4 | -| Human attention — lost/telephoned asks | The [inbox](features/inbox.md) with urgency; posture on the human-contact spectrum | A2A v1 plan | -| Human attention — drowned conversations | Spectrum posture + delegation to Crews (the human-contact spectrum lens) | Principle adopted; manifest posture is item 3 | -| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | -| Async-event blindness | Silence notices to waiters and time facts in envelopes ([agent-to-agent communication](a2a/index.md)); machine triggers as work sources (a recorded door) | A2A v1 plan | -| Context as bad memory | Status-is-read surfaces; time facts in envelopes; [Memos](features/memos.md); step injection ([Playbooks](features/playbooks.md)) | Principles adopted; candidates queued | -| Large, unsupervised groups | Exchanges with sender-judged completeness; silence measurement; Memo visibility for drift steering; the Fleet page | A2A v1 plan; item 4 | -| More work needs more cleanup | Archive never destroys work and is loud ([archive flow](features/archive-flow.md)); Crews archive as units and Captains archive what they command ([Crews](features/crews.md)); workspace cleanup tooling deferred | Register settled; tooling later | -| Traycer/T3 inheritances | A durable ledger instead of in-memory state; archive that never destroys work instead of over-eager cleanup; A2A and Squadrons instead of a parent-child-only flat list | A2A v1 plan | -| Roles in platform tooling | [Roles](features/roles.md): user-authored files the platform reads | Item 3 session | -| Crews | [Crews](features/crews.md) | Register settled; manifest schema is item 3 | -| Playbooks | [Playbooks](features/playbooks.md): the engine is the platform's, the steps are the user's | Backlog candidate | -| Shared Squadrons | [Shared Squadrons](features/shared-squadrons.md): the multi-person invariant in force now; an architecture session before any build | Backlog candidate | -| Agent cron/DB | Parked with a named trigger ([Memos](features/memos.md) records it) | Parked | -| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | +| Problem / goal | Answered by | Status | +| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| Fleet observability — agent/Crew state | Silence notices and the ledger's projections ([agent-to-agent communication](a2a/index.md)); the Playbook step pointer ([Playbooks](features/playbooks.md)); the Fleet page ([Fleet page](features/fleet-page.md)); status is read, never asked | A2A v1 plan; item 4; Playbooks candidate | +| Fleet observability — PR management | The [PR pane](features/pr-pane.md); playback of the ledger for review-decision audit | Pane approved, issue #6 | +| Fleet observability — cost | Cost rolls up per Squadron on the Fleet page | Item 4 | +| Human attention — lost/telephoned asks | The [inbox](features/inbox.md) with urgency; posture on the human-contact spectrum | A2A v1 plan | +| Human attention — drowned conversations | Spectrum posture + delegation to Crews (the human-contact spectrum lens) | Principle adopted; manifest posture is item 3 | +| Human attention — "later" lost | Memos (`features/memos.md`) | Design settled; backlog candidate | +| Async-event blindness | Silence notices to waiters and time facts in envelopes ([agent-to-agent communication](a2a/index.md)); machine triggers as work sources (a recorded door) | A2A v1 plan | +| Context as bad memory | Status-is-read surfaces; time facts in envelopes; [Memos](features/memos.md); step injection ([Playbooks](features/playbooks.md)) | Principles adopted; candidates queued | +| Large, unsupervised groups | Exchanges with sender-judged completeness; silence measurement; Memo visibility for drift steering; the Fleet page | A2A v1 plan; item 4 | +| More work needs more cleanup | Archive never destroys work and is loud ([archive flow](features/archive-flow.md)); Crews archive as units and Captains archive what they command ([Crews](features/crews.md)); workspace cleanup tooling deferred | Register settled; tooling later | +| Traycer/T3 inheritances | A durable ledger instead of in-memory state; archive that never destroys work instead of over-eager cleanup; A2A and Squadrons instead of a parent-child-only flat list | A2A v1 plan | +| Roles in platform tooling | [Roles](features/roles.md): user-authored files the platform reads | Item 3 session | +| Crews | [Crews](features/crews.md) | Register settled; manifest schema is item 3 | +| Playbooks | [Playbooks](features/playbooks.md): the engine is the platform's, the steps are the user's | Backlog candidate | +| Shared Squadrons | [Shared Squadrons](features/shared-squadrons.md): the multi-person invariant in force now; an architecture session before any build | Backlog candidate | +| Agent cron/DB | Parked with a named trigger ([Memos](features/memos.md) records it) | Parked | +| Monitoring fleet | Standing test: "does it work for the monitoring fleet, or only coding fleets?" (`fleet-vision.md` implication 6) | Ongoing design lens | ## History diff --git a/docs/j5/worklog/2026-08-29-sidebar-roster-session.md b/docs/j5/worklog/2026-08-29-sidebar-roster-session.md index 73299697ae8b..7c0f7f25b1a9 100644 --- a/docs/j5/worklog/2026-08-29-sidebar-roster-session.md +++ b/docs/j5/worklog/2026-08-29-sidebar-roster-session.md @@ -12,7 +12,7 @@ conversation first, then HTML mockup options rendered in the design workspace (`product/fleet-sidebar/mockups/`), styled against **real app references** (screenshots captured from a live instance + `apps/web/src/index.css` tokens). Mockups are decision aids, not pixel -specs. Feature doc of record: [`../product/features/sidebar-and-roster.md`](../product/features/sidebar-and-roster.md). +specs. Feature doc of record: [`../product/features/fleet-page.md`](../product/features/fleet-page.md). Research inputs (in the workspace record): a code sweep of upstream's default sidebar (flat list; static creation order — activity never diff --git a/docs/j5/worklog/2026-09-04-fleet-visibility-session.md b/docs/j5/worklog/2026-09-04-fleet-visibility-session.md new file mode 100644 index 000000000000..29359a77ea5c --- /dev/null +++ b/docs/j5/worklog/2026-09-04-fleet-visibility-session.md @@ -0,0 +1,66 @@ +--- +title: "Fleet visibility — acceptance contract session (2026-09-04)" +kind: record +--- + +# Fleet visibility — acceptance contract session (2026-09-04) + +> The rulings below now live in the [Fleet page and sidebar](../product/features/fleet-page.md) definition; its History maps FV1–FV11 to acceptance criteria. + +Jackson + Product lead, in the Product thread; commissioned through the "Prioritize Next Product Work" coordinator as the next outcome after v0's interactive surface. Anchor: issue #28 (the Fleet page); #30 (silence fact bundles) and #31 (graph read API) supply only what the outcome needs. Product settled before Design or Architecture; build decomposition follows separately. Definition of record: [`features/fleet-page.md`](../product/features/fleet-page.md); the v0 sidebar override now lives in the [dogfood v0 plan](../plans/dogfood-v0.md). + +## Stale statements corrected + +- The 2026-08-29 handoff note said nothing counts open exchanges per participant — false since the archive slice: the pre-archive facts read returns, per participant, every open exchange with direction, who owes the reply, counterparty, intent, urgency, and age. It is the source for FV3. +- "Crews render as collapsible units" — moot for v0 (no Crews). +- SB6's badge fact set included awaiting-human, which the inbox bell already counts; resolved by FV5. +- Measured code state at session: no Fleet page, no rail-footer entry, SB5 never implemented; #95 (merged 2026-09-04) added the undispatched-run watchdog fact ("Run waiting Nm, not yet dispatched" after five minutes) and run-start/finalization delay facts; A5 and A10 have no code. + +## Rulings + +| ID | Ruling | +| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FV1 | **Purpose and stop condition.** Four measured questions per agent the user is not talking to — doing anything now; anyone waiting on it / it waiting on anyone; last did anything; a measured problem — plus click-through. Stops when every registered participant in scope shows the four facts or an explicit unknown. Nothing inferred: no health score, no "stalled", no urgency reordering, no row actions. | +| FV2 | **Status = upstream's six-state row machine + named existing facts** ("Waiting to start · Nm" from the watchdog; "Idle since ⟨time⟩"). **Silence notices are not shown on the page.** Jackson's concern, upheld: with multiple asks the detector records a first match only, and "ended without replying" is the judgment case (forgot, or waiting on something first) — showing it invites false attention. Open-ask ages carry the measured fact instead. | +| FV3 | **Open asks = "Owes N · Awaiting N"** with a hover list (counterparty, intent, age); source is the per-participant open-exchange read; coalesced follow-ups count once. | +| FV4 | **Last activity = the latest measured event, labeled by what it is**; v0 uses upstream's last run start/end; ledger-authored recency joins if cheap. Never "last seen". | +| FV5 | **Badge = agents with a measured failure** (failed latest run, delivery alarm, undispatched-run watchdog fact); never what the inbox bell counts, never silence notices; one agent counts once; unknowns never count; rows list every fact. | +| FV6 | **Unknowns explicit (`?` + reason), freshness stated** ("as of ⟨time⟩", environment name); interval/focus refetch acceptable; primary environment only, said so (#105 deferred). | +| FV7 | **One Squadron at a time, no "All" view** (Jackson: keeps it easy and makes provenance/placement possible). Scope picker when the sidebar scope is "All". Registered participants only; provenance rendered as fact incl. unrecorded; provider-native Subagents never; no-home threads counted in a footer line, not rows. **Orphans:** retired parent with working children = dimmed placeholder row holding its tree position, no re-parent; retired without active children = absent. Stable ordering (Squadron → placement tree → creation order). | +| FV8 | **Sidebar unchanged in v0; SB5 set aside (DV6).** Jackson: the provenance filter is too harsh — he asks the Director to spawn most agents he talks with; the human-contact-spectrum story isn't strong enough to build a filter yet; Crews are the first exclusion when they exist. Accepted UI gap. The Fleet page is purely additive; the roster/sidebar pairing rule dissolves. | +| FV9 | **One absorbing server read is the dependency; A5 and A10 are not.** Per participant in the Squadron: identity, home, placement parent, provenance, retired flag, run status + timestamps, watchdog fact, open-ask counts by direction with list, failure facts — assembled from existing reads. It is the dashboard-feed part of A5 delivered small; replay/subscriptions remain A5's later scope; with FV2, A10 has no bearing on the page. No fact semantics trimmed. | +| FV10 | **Deferred, named:** row actions; multi-environment merge; inbox alerts lane; Crew rendering; cost rollups; PR pane; graph rendering/playback; human-contact-spectrum representation; health inference (never); urgency reordering (a "needs attention" filter is v-next). | + +Jackson's answers: F1/F3/F4/F5/F6/F10 agree; F2 concern → revised to drop notices, agreed; F7 amended to single-Squadron, agreed; F8 amended to sidebar-unchanged, agreed; F9 explained in plain words (A5 = the dashboard data feed with replay/subscriptions; A10 = the silence-notice storage rework), agreed. + +## Second round (same day) — Design and Architecture clarifications + +Design's plan and Architecture's brief raised five product choices; Jackson ruled in the Product thread: + +| ID | Ruling | +| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FV5a | **Badge is global** across every Squadron in the primary environment (Design's point upheld: the user must know something is broken somewhere, and the badge is the only place). The scoped-page tension is resolved by FV7a. The inbox rail is not used for platform problems — that rail is where _agents_ tell you something is wrong. | +| FV7a | **On the Fleet page the sidebar is replaced by a Squadron list** with per-Squadron problem counts; the roster shows the Squadron selected there. Selection is page-local (no sync with the ambient sidebar scope — "changing one view would alter another"); leaving the page restores the sidebar unchanged. Default: open on the ambient Squadron when scoped, else on the list unselected — Jackson: agree (explicit, 2026-09-04). | +| FV1a | **Agents only** on the roster; humans are never rows. An agent's ask out to the human surfaces in its asks list like any other counterparty. | +| FV2a | **Status vocabulary corrected**: runtime facts only (Working / Waiting / Approval / Input / Failed; watchdog "Waiting to start" precedence while starting; "Idle since" only when nothing active or background remains). Measured (corrected 2026-09-05; the first enumeration was wrong): the resolver returns approval / failed / input / ready / waiting / working; Woke/Done derive from wake and unread state — read/snooze bookkeeping, omitted deliberately. Jackson: agree (explicit, 2026-09-04). | +| FV11 | **Delivery alarms**: permanent facts, never inferred repaired; attributed to the sender; chip persists; **badge counts only while the alarm's exchange is open**; plain-message failures chip-only; silence-notice and lifecycle-notice delivery failures excluded. Jackson: agree. | + +Batch confirmations (ruled by recommendation): every retired ancestor on the path is preserved as a placeholder with not-applicable cells; no population cap; the no-home footer count is primary-wide, unarchived, excluding provider-native Subagents; last activity is run start/end only; FV9 becomes two reads (per-Squadron roster; fleet-wide problem counts). + +## Acceptance scenarios (for Design, Architecture, builders, verification) + +1. Squadron "J5 Code" selected: the Director row; Relay & Staffing (spawned by the Director) with its lanes indented beneath it; every row shows status, owes/awaiting, last activity; clicking a lane opens its thread. +2. A lane's run sits undispatched past five minutes: status "Waiting to start · 7m"; the badge counts it; when the run starts, both clear. +3. An agent owes one reply to the Director and awaits two from peers: "Owes 1 · Awaiting 2"; hover lists all three with ages. +4. A parent is archived with two working children: dimmed "retired" row, children beneath still Working, no re-parent. +5. The placement query fails for one row: placement `?` with the reason on hover; the row still renders; the badge is unchanged. +6. A run fails and the same agent has a delivery alarm: the badge counts the agent once; the row lists both facts. +7. A silence notice exists for an agent: nothing on the page changes — status stays whatever upstream says; the owed-ask age is the visible fact. +8. The rail badge shows 2; opening the Fleet page replaces the sidebar with the Squadron list, on which "J5 Code" shows 2 and "Production Monitoring" shows 0; choosing "J5 Code" shows the roster with both failing agents chipped; leaving the page restores the normal sidebar with its scope unchanged. +9. Header reads "Fleet · ⟨environment⟩ · as of 14:02:31"; a saved remote environment's Squadrons do not appear and the page does not claim they do. +10. Three native threads without a Squadron home exist: the footer line states the count; none appear as rows. +11. An agent's ask to the Director failed to deliver: its row chips "Delivery failed · to Director · 14:02 · ⟨reason⟩" and the badge counts it; the agent clears its ask; the chip remains, the badge no longer counts it. + +## Not decided here (for the coordinator / Architecture) + +Build decomposition (the coordinator leans small shared contract → vertical slices); the read's transport (HTTP read like the existing client reads vs. an RPC); refresh mechanism. (Ledger-authored recency was removed from the increment in the second round — no longer open.) From 02541e678c8db3197bb4d16dcd546d426ee9d6a3 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sun, 13 Sep 2026 22:11:00 -0400 Subject: [PATCH 14/15] docs(j5): rebase onto main and absorb the landed lifecycle, join, and cross-environment changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebased onto j5/main. Folds main's five doc changes into the rewritten definitions in their own shape: list_squadrons and join_squadron in the agent tools and substrate definitions and as Squadron AC14; reversible archive, unarchive and separate deletion in the archive-flow and tools definitions; the cross-environment merge (#125) as cross-device AC7–AC10 and inbox criteria, with build status in the dogfood plan. Records #126 and #127 as landed in the A2A plan. Moves the Squadron Scope section into the Definition and the plan per the conventions. Co-Authored-By: Claude Fable 5.1 --- docs/j5/plans/a2a.md | 4 +- docs/j5/plans/dogfood-v0.md | 25 +++++++------ docs/j5/product/a2a/agent-tools.md | 47 +++++++++++++++++++++--- docs/j5/product/a2a/substrate.md | 7 ++-- docs/j5/product/cross-device.md | 9 +++++ docs/j5/product/features/archive-flow.md | 19 ++++++++-- docs/j5/product/features/inbox.md | 7 ++-- docs/j5/product/features/squadron.md | 16 ++++---- docs/j5/product/glossary.md | 4 +- 9 files changed, 100 insertions(+), 38 deletions(-) diff --git a/docs/j5/plans/a2a.md b/docs/j5/plans/a2a.md index a326526899b6..ac0bd059ad1a 100644 --- a/docs/j5/plans/a2a.md +++ b/docs/j5/plans/a2a.md @@ -101,8 +101,8 @@ The definition's acceptance criteria ([`../product/a2a/index.md`](../product/a2a | AC4 (projection rebuild) | Built for the inbox and thread projections; the communication-graph projection is A2A M5 (issue #31) | | AC5, AC6, AC9, AC10, AC11 (Exchanges) | Built | | AC7, AC8 (several open asks to a person) | **Not built** — the shipped behavior refuses a second ask to a person while one is open; reversed by ruling on 2026-09-05, issue #111 | -| AC12–AC15 (delivery) | Built, including the Codex Astra exception (#108) | -| AC16–AC19 (the person) | Built | +| AC12–AC15 (delivery) | Built, including the Codex Astra exception (#108); the guidance once appended on that path is gone (#126) | +| AC16–AC19 (the person) | Built; the unused person-origin envelope channel removed (#127) | | AC20, AC21 (silence) | Built with a known gap: notices are stored with a label chosen when written rather than as the pure fact bundle the definition describes, so a notice with several open asks records only its first match — the fact-bundle rework is issue #30; no surface shows the stored label as current status meanwhile | | AC22, AC23 (envelopes) | Built except measured time facts in every channel (A2A M2 envelope true-up, issue #29) | diff --git a/docs/j5/plans/dogfood-v0.md b/docs/j5/plans/dogfood-v0.md index fc2d32749a4c..aa097952d03c 100644 --- a/docs/j5/plans/dogfood-v0.md +++ b/docs/j5/plans/dogfood-v0.md @@ -33,20 +33,23 @@ Tickets held as J5-native work, staffed from GitHub (label `dogfood-queue`), eac Each row names the definition and the criteria it narrows, and when the full behavior returns. The definitions describe the end state; this table is the only place a cut is stated. -| Definition and criteria | Current build | Returns | -| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -| Squadron AC5 (one or more folders) | Exactly one folder, implemented as a Squadron→project reference — never identity. Guards that must hold: membership is assigned by the Registrar, never derived from the project; two Squadrons over the same folder work (an acceptance criterion, not a later feature); the folder relation is stored ready to become a list | The multi-folder milestone: a list, with the palette-first worktree row | -| Squadron AC6 (everything else reachable) | "Browse elsewhere" may be absent; if project reuse makes it cheap, keep it, otherwise it is backlog rather than blocking. Never-a-wall is untouched at end state | Backlog item if cut; at latest with the multi-folder milestone | -| Squadron AC7 (every picker offers Squadrons) | The new-thread flow and the command palette are converted; remaining pickers convert by inventory ([#38](https://github.com/Jacksondr5/j5code/issues/38), [#39](https://github.com/Jacksondr5/j5code/issues/39)) | As the inventory closes | -| Squadron AC3 (Squadron required to create an agent) — exemptions | The hard refusal binds the interactive user-origin creation path only. Exempt, each with its return: mobile new thread and offline drain; scheduled new-thread creation, which hits the refusal and must surface as a visible scheduled-task error; the server's bootstrap creation; plan-to-implementation inherits the parent's home, and a no-home parent yields a no-home child. Squadron creation is primary-environment-only with a state-naming refusal elsewhere | Per row: a mobile Squadron ticket; a truthful scheduler-origin carrier; multi-environment work | -| Thread rendering AC4 ("You · via Inbox" for the reader who sent it) | Renders neutral `Via Inbox · ⟨person⟩` — "You" is a factual claim that the viewer is that person, and the merged auth principal is session-scoped with no person binding, so the claim cannot be made truthfully. Rendering on exact equality is already built, so the upgrade needs no renderer rework | The auth-subject-to-person binding session (queued after v0) | -| Fleet page AC4–AC25 (the page itself) | Not built; the first build is [#28](https://github.com/Jacksondr5/j5code/issues/28) in the Fleet observability milestone, which reads the primary environment only and says so ([#105](https://github.com/Jacksondr5/j5code/issues/105) carries the merge that cross-device AC2 defines) | With #28; environment merging with #105 | -| Fleet page AC26 (cost per Squadron) | Not in the first build | A later Fleet observability milestone | -| A2A AC7–AC8 (several open asks to a person; explicit follow-ups) | The shipped behavior refuses a second ask to a person while one is open ([#111](https://github.com/Jacksondr5/j5code/issues/111)) | With #111 | -| A2A AC20 (silence notices as measured facts) | Notices are stored with a label chosen when written; a notice with several open asks records only its first match; no surface shows the stored label as current status | With #30 | +| Definition and criteria | Current build | Returns | +| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | +| Squadron AC5 (one or more folders) | Exactly one folder, implemented as a Squadron→project reference — never identity. Guards that must hold: membership is assigned by the Registrar, never derived from the project; two Squadrons over the same folder work (an acceptance criterion, not a later feature); the folder relation is stored ready to become a list | The multi-folder milestone: a list, with the palette-first worktree row | +| Squadron AC6 (everything else reachable) | "Browse elsewhere" may be absent; if project reuse makes it cheap, keep it, otherwise it is backlog rather than blocking. Never-a-wall is untouched at end state | Backlog item if cut; at latest with the multi-folder milestone | +| Squadron AC7 (every picker offers Squadrons) | The new-thread flow and the command palette are converted; remaining pickers convert by inventory ([#38](https://github.com/Jacksondr5/j5code/issues/38), [#39](https://github.com/Jacksondr5/j5code/issues/39)) | As the inventory closes | +| Squadron AC3 (Squadron required to create an agent) — exemptions | The hard refusal binds the interactive user-origin creation path only. Exempt, each with its return: mobile new thread and offline drain; scheduled new-thread creation, which hits the refusal and must surface as a visible scheduled-task error; the server's bootstrap creation; plan-to-implementation inherits the parent's home, and a no-home parent yields a no-home child. Squadron creation is primary-environment-only with a state-naming refusal elsewhere | Per row: a mobile Squadron ticket; a truthful scheduler-origin carrier; multi-environment work | +| Thread rendering AC4 ("You · via Inbox" for the reader who sent it) | Renders neutral `Via Inbox · ⟨person⟩` — "You" is a factual claim that the viewer is that person, and the merged auth principal is session-scoped with no person binding, so the claim cannot be made truthfully. Rendering on exact equality is already built, so the upgrade needs no renderer rework | The auth-subject-to-person binding session (queued after v0) | +| Fleet page AC4–AC25 (the page itself) | Not built; the first build is [#28](https://github.com/Jacksondr5/j5code/issues/28) in the Fleet observability milestone, which reads the primary environment only and says so ([#105](https://github.com/Jacksondr5/j5code/issues/105) carries the merge that cross-device AC2 defines) | With #28; environment merging with #105 | +| Fleet page AC26 (cost per Squadron) | Not in the first build | A later Fleet observability milestone | +| A2A AC7–AC8 (several open asks to a person; explicit follow-ups) | The shipped behavior refuses a second ask to a person while one is open ([#111](https://github.com/Jacksondr5/j5code/issues/111)) | With #111 | +| A2A AC20 (silence notices as measured facts) | Notices are stored with a label chosen when written; a notice with several open asks records only its first match; no surface shows the stored label as current status | With #30 | +| Cross-device AC2 (every person-facing surface merges every connected environment) | The Squadron picker, the sidebar's Squadron scope and the inbox merge on web and desktop ([#125](https://github.com/Jacksondr5/j5code/pull/125)); the Fleet page is not built; the mobile app does not yet have these screens | With #28 for the Fleet page; a mobile increment for the native app | Retired cuts: "folder required at creation" was a v0 cut until 2026-09-05, when the Squadron definition made one-or-more folders the end state; it is no longer a narrowing. +Squadron work not yet sequenced: Squadron archive, colors and avatars, and migration of pre-Squadron projects (an agent can now repair its own missing home with `join_squadron`; the person-side migration remains). + ## Standing guards - **Squadron-first creation**: name the work, then attach the folder. Reusing the project-creation flow wholesale rebuilds upstream's one-to-one shape with a rename — the exact thing the Squadron definition exists to not be. The composer heading stays Squadron-named; the first-run gate stays "create your first Squadron". diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index bf061c926499..f33052f663d4 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -44,11 +44,15 @@ An agent learns what it can do from its tools, and it reads a tool's description ### `list_participants` -**Description:** "Your address book: the participants around you — agents and the human — with the display name to recognize them by, the participant_id to address them with, and what each accepts (messages, exchanges, urgency). When you're told to message someone by name or role, resolve them here first. Your own row is marked self=true; it cannot receive messages or open exchanges from you — use schedule_task if you need a future trigger for yourself. Native threads that never received a Squadron home do not appear here and cannot be messaged. The roster changes — after you spawn an agent, or when a participant retires, call this again instead of reusing a stale listing." +**Description:** "Your address book: the participants around you — agents and the human — with the display name to recognize them by, the participant_id to address them with, and what each accepts (messages, exchanges, urgency). When you're told to message someone by name or role, resolve them here first. Your own row is marked self=true; it cannot receive messages or open exchanges from you — use schedule_task if you need a future trigger for yourself. Native threads that never received a Squadron home do not appear here and cannot be messaged. Archived agents are hidden by default; set include_archived=true to see them with archived=true. They cannot receive messages or open Exchanges. The roster changes — after you spawn, archive, unarchive, or delete an agent, call this again instead of reusing a stale listing." -No inputs. Read-only; no events. +| Input | Type | Required | Meaning | +| ------------------ | ------- | -------- | -------------------------------------------------------------- | +| `include_archived` | boolean | no | Also list archived agents, each marked `archived`; default off | -**Result rows:** `display_name` (the agent's thread title, or the Role name once Roles exist), `squadron_id`, `participant_id`, the participant kind, `self`, `can_receive_message`, `can_open_exchange`, `accepts_urgency`, plus `provenance` (spawned by whom, forked from what, unrecorded, or not applicable for a person) and `placement_parent_id`. A person's row reports that it cannot receive a plain message and can be asked. Provenance and placement are carried for callers and the UI; they are not part of the description's pitch. +Read-only; no events. + +**Result rows:** `display_name` (the agent's thread title, or the Role name once Roles exist), `squadron_id`, `participant_id`, the participant kind, `self`, `archived`, `can_receive_message`, `can_open_exchange`, `accepts_urgency`, plus `provenance` (spawned by whom, forked from what, unrecorded, or not applicable for a person) and `placement_parent_id`. A person's row reports that it cannot receive a plain message and can be asked. An archived agent's row, when requested, reports that it can receive nothing. Provenance and placement are carried for callers and the UI; they are not part of the description's pitch. ### `spawn_agent` @@ -87,7 +91,7 @@ No inputs. Read-only; no events. ### `archive_agent` -**Description:** "Retire one Peer Agent for good. A clean archive — no open exchanges, no running turn — completes immediately. Otherwise the call refuses and lists exactly what archiving ends — the asks that will close, the turn that will stop — along with a confirmation_token; call again with that token to proceed. The archived agent leaves the active roster; its ledger and conversation stay readable forever. Requires your current squadron_id. Reuse client_request_id to retry safely." +**Description:** "Archive one Peer Agent reversibly. Unarchive restores the same identity, but does not reopen Exchanges or replay cancelled messages. A clean archive — no open exchanges, no running turn — completes immediately. Otherwise the call refuses and lists exactly what archiving ends — the asks that will close, the turn that will stop — along with a confirmation_token; call again with that token to proceed. The archived agent leaves the active roster; its ledger and conversation stay readable forever. Requires your current squadron_id. Reuse client_request_id to retry safely." | Input | Type | Required | | -------------------- | ------------- | ------------------------------ | @@ -98,7 +102,9 @@ No inputs. Read-only; no events. **Result:** exactly one of `archived` or `already_archived` (no side effect). A consequential target yields a refusal — an error carrying the list of consequences and a `confirmation_token` — never a partial outcome. -**Rules.** The quiet path archives immediately when nothing would be cut short. The loud path is a refusal listing the concrete consequences — the open Exchanges that will close as dropped, the running turn that will be interrupted — plus a token bound to that list: it proves the caller saw the consequences, so a preemptive flag on the first call cannot short-circuit the confirmation. If the target's state changed since the refusal, the stale token is rejected and a fresh refusal lists the current facts. A malformed or unknown token fails closed without disclosing the target's facts, and a token for one target never authorizes another. A partial failure across stores is forward-only: committed archive and ledger facts are re-read on retry, and `already_archived` requires both the participant's departure and completion of every terminal notice. The caller cannot archive itself. +**Rules.** The quiet path archives immediately when nothing would be cut short. The loud path is a refusal listing the concrete consequences — the open Exchanges that will close as dropped, the running turn that will be interrupted — plus a token bound to that list: it proves the caller saw the consequences, so a preemptive flag on the first call cannot short-circuit the confirmation. If the target's state changed since the refusal, the stale token is rejected and a fresh refusal lists the current facts. A malformed or unknown token fails closed without disclosing the target's facts, and a token for one target never authorizes another. A partial failure across stores is forward-only: committed archive and ledger facts are re-read on retry, and `already_archived` requires both the archive fact and completion of every terminal notice. The caller cannot archive itself. + +Archiving is reversible and deletion is not. A person can unarchive an archived agent, which restores the same participant id, Squadron home, placement and provenance and makes it addressable again; the Exchanges that archiving closed stay closed, and deliveries that archiving cancelled are not replayed. Deleting an agent is a separate, permanent act that only a person performs; no agent verb deletes. **Errors**, each naming state and next command: not the caller's Squadron; unknown participant; consequential without a token (the refusal); stale or invalid token; self-target. @@ -119,6 +125,31 @@ No inputs. Read-only; no events. **Events:** an Exchange-closure event distinguishable from a reply's closure, so the inbox, the Exchange projections and the communication graph render the withdrawal honestly. +### `list_squadrons` + +**Description:** "The Squadron directory for this environment: every Squadron's squadron_id, name, and the project ids it references, plus your own thread's project id so you can see which Squadron can home you. Use it to obtain the exact squadron_id before join_squadron. Read-only." + +No inputs. Read-only; no events. Callable by a thread that has no Squadron home — the one listing verb that is, because it exists to bootstrap `join_squadron`. + +**Result:** `caller_project_id` and `squadrons[]`, each with `squadron_id`, `name` and `project_ids`. The verb states facts and never picks: the caller compares the project ids against its own. + +### `join_squadron` + +**Description:** "Join a Squadron when your thread has no Squadron home yet. Pass the exact squadron_id, taken from list_squadrons; that Squadron must reference your thread's project. Your thread, conversation, worktree, and running work stay exactly as they are. Calling it again for the Squadron you already belong to returns your existing registration. Reuse client_request_id to retry safely. Warning: you cannot switch Squadrons once you're assigned, be sure you're joining the right one." + +| Input | Type | Required | Meaning | +| ------------------- | ---------- | -------- | --------------------------------------------------------------------- | +| `squadron_id` | SquadronId | yes | An existing Squadron, chosen explicitly; never inferred from a folder | +| `client_request_id` | string | no | Reuse to retry safely | + +**Result:** `squadron_id`, `participant_id`, `thread_id`, and the placement: at the Squadron root, with provenance recorded as unrecorded, because nothing spawned or forked a native thread. + +**Rules.** The verb acts on the calling thread only and exists for exactly one case: a native thread that was created with no Squadron home ([Squadron](../features/squadron.md)). It establishes an original home; it is never a move, a leave, or a revival. The thread, its provider session, its worktree and any running turn are untouched — no new thread, no injected task, no interrupt. A thread already homed in the requested Squadron gets its existing registration back. Registration and placement commit in one transaction, and a retry with the same `client_request_id`, or concurrent retries with different ids, commit exactly one joined event. + +**Errors**, each naming state and next command: the thread is archived or deleted; the thread already has a home in a different Squadron; the thread's identity was retired; the Squadron does not reference the thread's project; unknown Squadron. + +**Events:** participant joined, placement created. + ### Kept upstream tools - `orchestrator_capabilities` — providers and models (ids, labels, option descriptors) for spawn targeting, plus runtime and interaction-mode facts. It no longer advertises app-owned subagents, child tasks, or delegation; J5 verbs are advertised by their own descriptions. @@ -139,6 +170,10 @@ No inputs. Read-only; no events. 10. `archive_agent` on a target with open Exchanges or a running turn refuses with the list of consequences and a token; the same call with that token archives; a stale token is refused with fresh facts. 11. `clear_own_ask` closes only an Exchange the caller opened and records the closure as sender-cleared. 12. Every error from every verb names the actual state and the next command. +13. `list_participants` omits archived agents unless `include_archived` is set, and then marks each one `archived` and unable to receive a message or an ask. +14. Unarchiving an archived agent restores the same participant id, Squadron home, placement and provenance and makes it addressable again; the Exchanges archiving closed stay closed and no cancelled delivery is replayed. +15. `list_squadrons` can be called by a thread with no Squadron home and returns every Squadron with its project ids and the caller's own project id. +16. `join_squadron` establishes a home only for a thread that has none, only in a Squadron that references the thread's project, leaves the thread and its running work untouched, returns the existing registration when the thread is already homed there, and refuses a thread homed elsewhere, an archived or deleted thread, and a retired identity. ## History @@ -149,4 +184,6 @@ No inputs. Read-only; no events. - 2026-09-08 — a person receives asks only; the reply form toward a person is retired with the person-originated ask. - 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). - 2026-09-05 — a committed stop wins over restart continuation (upstream integration, PR #112). +- 2026-09-12 — archiving is reversible: unarchive restores the same identity without reopening Exchanges; deletion is a separate permanent act for people only; the address book hides archived agents unless asked (PR #132). +- 2026-09-12 — `list_squadrons` and `join_squadron` added for the one case of a native thread with no home (issue #129, PR #131). - 2026-09-07 — rewritten from a stack of dated contract revisions into current-state contracts; every verb's build state true as of this date (all six verbs shipped; `regarding` and the person follow-up rule are issue #111). diff --git a/docs/j5/product/a2a/substrate.md b/docs/j5/product/a2a/substrate.md index f1f8e33e78af..e5f9e4c94bd5 100644 --- a/docs/j5/product/a2a/substrate.md +++ b/docs/j5/product/a2a/substrate.md @@ -36,7 +36,7 @@ Delivery to a busy agent queues behind the active turn; steering is the person's **Upstream owns existence and lifecycle state; J5 tables overlay only organization facts** — Squadron home, placement, provenance, Exchange obligations. J5 writes flow through upstream's public command seams, never into its projections; J5 reads either join upstream state or say explicitly that they may be stale. -**Participanthood is granted only by J5's registration surfaces** — the spawn verb, the composer's Squadron chip, or a controlled seed — and never inferred from a thread's existence or addressability. The case that forces this: Codex-native Subagents get real shadow threads holding live, resumable provider references; they are thread-having and send-capable, and they are still Subagents. Any sweep that absorbs threads into the roster excludes provider-created and Subagent-lineage threads. +**Participanthood is granted only by J5's registration surfaces** — the spawn verb, the composer's Squadron chip, a controlled seed, or the home-join verb for a native thread that never received a home — and never inferred from a thread's existence or addressability. The case that forces this: Codex-native Subagents get real shadow threads holding live, resumable provider references; they are thread-having and send-capable, and they are still Subagents. Any sweep that absorbs threads into the roster excludes provider-created and Subagent-lineage threads. ### The agent tool surface @@ -51,7 +51,7 @@ J5 replaces upstream's orchestrator toolkit registration with its own subset: a Upstream's orchestration prompt text steered agents toward delegation and away from thread creation; J5 carries a small tracked edit to it, recorded in the fork inventory. -The J5 verbs themselves — `send_message`, `list_participants`, `spawn_agent`, `stop_agent`, `archive_agent`, `clear_own_ask` — are defined in [agent-tools](agent-tools.md). +The J5 verbs themselves — `send_message`, `list_participants`, `spawn_agent`, `stop_agent`, `archive_agent`, `clear_own_ask`, and the home-repair pair `list_squadrons` and `join_squadron` — are defined in [agent-tools](agent-tools.md). The pair is the only part of the surface an unregistered native thread can use, and it establishes an original home only, never a move. ### The legacy cohort @@ -62,7 +62,7 @@ Agents spawned through upstream's delegation path before the spawn verb existed 1. No J5 code writes into an upstream projection; every J5 mutation goes through an upstream public command seam or a J5-owned table. 2. The agent surface exposes exactly the J5 verbs and the kept upstream tools listed above; every other upstream tool is absent by construction, and a new upstream tool arriving in a rebase is absent until admitted through a contract change. 3. An agent-to-agent message sent through the platform always has a ledger row, an envelope, and a delivery outcome; no raw thread-send is reachable from the agent surface. -4. A thread becomes a participant only through the spawn verb, the composer's Squadron chip, or a controlled seed; a provider-created thread or a Subagent-lineage thread never becomes one by any sweep. +4. A thread becomes a participant only through the spawn verb, the composer's Squadron chip, a controlled seed, or its own explicit home join when it has no home; a provider-created thread or a Subagent-lineage thread never becomes one by any sweep. 5. A Peer Agent created through the spawn verb has root lineage; nothing about it is derived from upstream's lineage record. ## History @@ -71,4 +71,5 @@ Agents spawned through upstream's delegation path before the spawn verb existed - 2026-08-29 — the substrate line drawn: the four dispositions, the ownership rule, the fail-closed tool subset ([record](../../worklog/2026-08-29-substrate-session.md)). - 2026-08-31 — `create_threads` and `t3_thread_start` omitted; `clear_own_ask` built. - 2026-09-03 — delivery queues behind an active turn; steering is the person's act ([record](../../worklog/2026-09-03-queue-vs-steer-ruling.md)); 2026-09-04 — the Codex Astra exception ([record](../../worklog/2026-09-04-astra-peer-delivery.md)). +- 2026-09-12 — `list_squadrons` and `join_squadron` admitted to the surface (issue #129, PR #131). - 2026-09-07 — rewritten into the definition shape; stale rows (the open `create_threads` row, "needed-but-unbuilt" `clear_own_ask`, the pending prompt-text edit, Squadron creation as "nothing exists") corrected to the current state. diff --git a/docs/j5/product/cross-device.md b/docs/j5/product/cross-device.md index 570827f842df..abf27f967fb1 100644 --- a/docs/j5/product/cross-device.md +++ b/docs/j5/product/cross-device.md @@ -37,13 +37,22 @@ What this never does: no replicated state, no multi-master, no Squadron migratio 5. Nothing that is server-local by design — worktrees, provider credentials, settings, schedules, cost meters — is synchronized between servers. 6. Server-to-server Exchange delivery, when built, goes through a pairwise peer registry, and the receiving server records its own received row. +### Merged surfaces + +7. Environment labels appear on merged items and choices only when the results span more than one environment; a single-environment client shows none. +8. A connection that can only read shows that environment's Squadrons and asks and refuses to create, launch or answer there, with the control saying why. +9. A count over merged environments is marked incomplete when any environment could not be refreshed, and shows no number when none could be. +10. An environment whose server lacks the fleet features is reported as unsupported, never as empty. + ## Scenarios - **Two servers, one inbox.** The user's client connects to the work server and the home server. An ask from an agent in Billing Migration (work) and one from Support Rotation (home) appear in one inbox, each tagged with its environment; answering each reaches the right server. (AC2, AC3) - **A server goes dark.** The home server is asleep; its rows stay on the Fleet page with "as of 40m ago" and never vanish. (AC4) +- **One server is read-only.** The user's connection to the home server has no operate scope: its Squadrons and asks appear in the merged lists, and the answer box for a home-server ask explains that this connection cannot reply. (AC8) - **A Mac-only job.** An agent that must run on a Mac gets its own Squadron homed on the Mac server; it is asked for results by a Squadron elsewhere through a cross-server Exchange, once peering exists. (AC1, AC6) ## History - 2026-08-19 — the position settled with Jackson: authority never replicates; former X1–X5 (this file's earlier form was the register). Grounded in the remote-hosting research and the A2A design. +- 2026-09-12 — the Squadron picker, the sidebar's Squadron scope and the inbox merge every connected environment on web and desktop, with labels only when needed, read-only connections, incomplete counts and unsupported servers stated (PR #125, issue #105); AC7–AC10 added. - 2026-09-10 — rewritten into the definition shape. Former identifiers: X1 → AC1; X2 → AC2; X3 → the sequencing sentence in the first capability row; X4 → the peer-registry paragraph, AC6; X5 → the client-pulled backup paragraph. Personal deployment details (which server is where) removed from the definition. diff --git a/docs/j5/product/features/archive-flow.md b/docs/j5/product/features/archive-flow.md index 7cb6821e1173..d1fb98c59d90 100644 --- a/docs/j5/product/features/archive-flow.md +++ b/docs/j5/product/features/archive-flow.md @@ -11,17 +11,21 @@ Archiving an agent is where obligations get stranded: the agent that was owed a ## Definition -Archiving retires an agent for good. It **never destroys work**: worktrees, branches and pull requests survive, and cleaning them up is a separate act. It is **loud**: every open Exchange the agent holds ends with a notice to the waiter, and every fact that archiving will change is shown before it happens. +Archiving sets an agent aside, and a person can bring it back. It **never destroys work**: worktrees, branches and pull requests survive, and cleaning them up is a separate act. It is **loud**: every open Exchange the agent holds ends with a notice to the waiter, and every fact that archiving will change is shown before it happens. Before the dialog appears, the platform reads the facts: the agent's open asks in both directions, and the agents placed beneath it. A fact it could not read is shown as "couldn't check" — never as an empty, reassuring list. **The dialog appears only when the facts warrant it.** An agent with nothing open and nothing beneath it archives without ceremony. Otherwise the dialog is titled "Archive ⟨agent name⟩?" and shows: the agents beneath it that this affects; each open ask that will be terminated, as a two-line row mirroring an inbox item — urgency badge first, then "To" or "From" and the counterpart's name, then the time open, then the intent verbatim; the section's count and consequence ("N open asks will be terminated — waiters are notified"); a quiet reassurance that the workspace survives; and one destructive-styled confirm. One confirm, no type-to-confirm. Every line is a measured fact; the dialog offers no opinion on whether to proceed. -Afterwards, waiters receive a platform notice that the Exchange ended, the person's inbox items from this agent leave immediately (the dialog was the loud moment), the agent leaves the active sidebar and the Fleet page, and its ledger and conversation stay readable forever. When Memos exist, the agent's open Memos appear as a third section of the dialog. +Afterwards, waiters receive a platform notice that the Exchange ended, the person's inbox items from this agent leave immediately (the dialog was the loud moment), the agent leaves the active sidebar, the Fleet page and the agents' address book, it can no longer be messaged, and its ledger and conversation stay readable forever. + +**Unarchiving** is the way back. It restores the same agent — the same participant id, Squadron home, placement and provenance — and makes it addressable again. It does not undo what archiving ended: the Exchanges that closed stay closed, and deliveries that were cancelled are not replayed. An agent may be archived and unarchived any number of times. + +**Deleting** is a different act, permanent, and only a person performs it. It removes the agent's membership and placement, offers to clean up the worktree, and leaves the agents beneath it, the historical provenance, and the ledger intact. When Memos exist, the agent's open Memos appear as a third section of the dialog. The flow is reached from the agent's thread and from its Fleet page row. Crews archive only as a unit, through their own flow; a Squadron is not archived through this flow. -This is **not** a delete, **not** a way to archive a single Crew member, and **not** a place for platform judgment. +Archiving is **not** deleting, **not** a way to archive a single Crew member, and **not** a place for platform judgment. ## Acceptance criteria @@ -40,7 +44,7 @@ This is **not** a delete, **not** a way to archive a single Crew member, and **n 6. Every waiter on an ended Exchange receives a platform notice rendered as a muted notice line in its thread. 7. The person's inbox items from the archived agent leave immediately, with no terminal row. -8. The archived agent leaves the active sidebar and the Fleet page; its ledger and conversation remain readable. +8. The archived agent leaves the active sidebar and the Fleet page, is hidden from the agents' address book unless archived agents are asked for, and cannot receive a message or an ask; its ledger and conversation remain readable. 9. No worktree, branch, or pull request is deleted by archiving. ### Boundaries @@ -48,10 +52,16 @@ This is **not** a delete, **not** a way to archive a single Crew member, and **n 10. A Crew member cannot be archived individually through this flow. 11. The flow is available from the agent's thread and from its Fleet page row. +### Unarchiving and deleting + +12. Unarchiving restores the same participant id, Squadron home, placement and provenance and makes the agent addressable again; the Exchanges that archiving closed stay closed and no cancelled delivery is replayed. +13. Deleting is permanent, is performed only by a person, removes the agent's membership and placement, and leaves the agents beneath it, historical provenance and the ledger intact; it is the only flow that offers worktree cleanup. + ## Scenarios - **A clean archive.** An agent in Website Redesign has finished, holds no open asks, and has nothing beneath it; "Archive" retires it with no dialog. (AC2) - **A loud archive.** An agent in Billing Migration has an open ask from the Captain (_soon_, "schema target", open 3h) and an ask out to the user, and a helper placed beneath it. The dialog lists the helper, both asks with their rows, "2 open asks will be terminated — waiters are notified", the workspace reassurance, and Confirm. On confirm, the Captain's thread shows a muted notice that the Exchange ended, the user's inbox item is gone, and the agent's branch and pull request are untouched. (AC3, AC4, AC6, AC7, AC9) +- **Bringing one back.** The user unarchives the Billing Migration agent a day later: it reappears with the same name, home and place under its spawner, and its peers can message it again; the Captain's earlier ask is still closed and must be re-asked. (AC12) - **A fact the platform couldn't read.** The placement read fails; the dialog says "couldn't check" for the subtree line and still lists the asks it did read. (AC1) ## History @@ -59,4 +69,5 @@ This is **not** a delete, **not** a way to archive a single Crew member, and **n - 2026-08-21 — archive is loud and never destroys work; Crews archive as units; archiving with open Exchanges warns with count, list and confirmation ([record](../../worklog/2026-08-21-design-review.md); former R1, R14, R15 and the Roles/Crews session's J1–J3). - 2026-08-29 — the flow designed; former AR1–AR4 ([record](../../worklog/2026-08-29-archive-flow-session.md)). - 2026-09-01 — ask-row anatomy mirrors the inbox item; former AR5 (Jackson's live review of the archive build). +- 2026-09-12 — archiving becomes reversible; unarchive defined; deletion separated as the permanent act (PR #132); AC12–AC13 added. - 2026-09-08 — rewritten into the definition shape. Former identifiers: AR1 → AC11; AR2 → AC1; AR3 → AC2–AC5; AR4 → AC6–AC9; AR5 → AC3–AC4; J1–J3 → AC3, AC5. Build sequencing that lived here (the dialog shipping ahead of waiter notices) is history. diff --git a/docs/j5/product/features/inbox.md b/docs/j5/product/features/inbox.md index 8019dd380992..4e686ca91ce5 100644 --- a/docs/j5/product/features/inbox.md +++ b/docs/j5/product/features/inbox.md @@ -13,7 +13,7 @@ The inbox is the one place a person looks to find everything that is waiting on ## Definition -The **inbox** is a person's queue of open asks addressed to them. It is **person-scoped, not Squadron-scoped**: a person has one inbox for the whole server, every item wears the Squadron it came from, and no Squadron selection elsewhere in the app hides an item. +The **inbox** is a person's queue of open asks addressed to them. It is **person-scoped, not Squadron-scoped**: a person has one inbox across every environment the client connects to, every item wears the Squadron it came from and, when more than one environment is connected, its environment, and no Squadron selection elsewhere in the app hides an item. The inbox is **pure**. It holds only asks that agents deliberately sent to the person — nothing inferred, no automatically promoted stalls, no plain messages, no platform alerts. Every item blocks a sender, so the count on the bell means exactly "things waiting on me." The purity has a sender-side mirror: an agent can send a person only an ask; a plain message to a person is refused, because if the person must see something then seeing it is the obligation. The person, in turn, never opens an ask through the platform — their channel to any agent is that agent's thread — and their only act on the ledger is the answer that closes an Exchange. @@ -33,7 +33,7 @@ The inbox is **not** a backlog (a non-blocking note an agent wants to keep is a ### Contents -1. The inbox lists every open ask addressed to the person from every Squadron on the server, and nothing else: no plain messages, no inferred items, no promoted stalls, no platform alerts. +1. The inbox lists every open ask addressed to the person from every Squadron on every connected environment, and nothing else: no plain messages, no inferred items, no promoted stalls, no platform alerts. 2. A plain message from an agent to a person is refused at the tool; the person's row in the address book says it cannot receive one. 3. Several open asks from the same agent to the same person appear as separate items; a follow-up that references an open ask by its Exchange id appears beneath that ask's original text in the same item. 4. The bell's count equals the number of open items. @@ -53,7 +53,7 @@ The inbox is **not** a backlog (a non-blocking note an agent wants to keep is a ### Placement -12. The inbox is not filtered by the sidebar's Squadron scope; each item names its Squadron. +12. The inbox is not filtered by the sidebar's Squadron scope; each item names its Squadron, and its environment when more than one is connected; an answer reaches the environment the ask came from. 13. The bell with its count is present in the rail on every page and opens the inbox page. ## Scenarios @@ -69,4 +69,5 @@ The inbox is **not** a backlog (a non-blocking note an agent wants to keep is a - 2026-08-31 — the bell moves to the rail header (Jackson's review of the inbox build). - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/2026-09-02-human-addressed-sends-ruling.md)). - 2026-09-05 — several open asks per agent and person, with follow-ups shown beneath the original (issue #111); the shelf is named "Replied", the one word for a closed Exchange on every surface (glossary). +- 2026-09-12 — the inbox merges every connected environment (PR #125; the merge rules are the cross-device definition's). - 2026-09-08 — rewritten into the definition shape. Former identifiers: IB1 → Answering, AC8–AC9; IB2 → AC13; IB3–IB4 → AC5–AC6; IB5 → AC10; IB6 → AC11; IB7 → AC12. The "clear-own-ask has no build ticket" note is gone: the verb shipped. The deferred items that lived here (a platform-alerts lane, the asker's current state on items, smaller inbox forms) are backlog candidates, not part of this definition. diff --git a/docs/j5/product/features/squadron.md b/docs/j5/product/features/squadron.md index 3b76d18e6089..68baba6a9f32 100644 --- a/docs/j5/product/features/squadron.md +++ b/docs/j5/product/features/squadron.md @@ -15,7 +15,7 @@ A **Squadron** is the user-created grouping of agents, their work — artifacts A Squadron is **a grouping, never a boundary**. It organizes; it never isolates. It carries no visibility or permission semantics: any agent can message any participant in any Squadron, people are global rather than per-Squadron, the Fleet page reads across Squadrons, and the filesystem is readable regardless of Squadron. -Every agent has exactly one **Squadron home**, recorded by the **Registrar** when the agent is created and never changed afterward. A user-created agent gets the Squadron the user chose; a Peer Agent inherits its spawner's. There is no joining, leaving, or moving between Squadrons; the placement tree of a Squadron lives entirely inside it. +Every agent has exactly one **Squadron home**, recorded by the **Registrar** when the agent is created and never changed afterward. A user-created agent gets the Squadron the user chose; a Peer Agent inherits its spawner's. There is no joining, leaving, or moving between Squadrons; the placement tree of a Squadron lives entirely inside it. The one exception is a thread that was created with no home at all: it may establish its original home once, in a Squadron it chooses explicitly, and from then on the rule applies to it like any other agent. Only a person creates a Squadron. Agents never do, and the platform never creates one automatically — an unnamed default container is the junk drawer that defeats the concept. Creating one is deliberately small: a name and one folder are required; a description and further folders can be added later. First run begins by creating the first Squadron, because agents need a home. @@ -25,12 +25,12 @@ The Squadron is **the unit of user choice**. Every surface where a person choose Within a Squadron, agents are organized in a **placement tree**. An agent's **placement** is where it sits in that tree: under its spawner, unless a person moves it. Whoever briefs an agent commands it, so the tree shows who is running what. An agent's **provenance** is the recorded fact of how it came to exist — created by a person, spawned by a named agent, forked from another, or unrecorded — written once and never changed. Neither placement nor provenance restricts who may message whom; the tree carries decisions, never messages. -End of life is archive; its details arrive with the container's growth. +End of life is archive; its details arrive with the container's growth. What a Squadron never is: it never targets a folder on another environment, it never carries a boundary, and it never exists without a folder. ## Acceptance criteria 1. A Squadron never restricts visibility or messaging: an agent in one Squadron can message any participant in any Squadron, and a message that crosses Squadrons is recorded in both Squadrons' ledgers. -2. Every agent has exactly one Squadron home, recorded at creation and never changed: a user-created agent gets the Squadron the user chose, a Peer Agent gets its spawner's, and no tool or interface joins, leaves, or moves an agent between Squadrons. +2. Every agent has exactly one Squadron home, recorded at creation and never changed: a user-created agent gets the Squadron the user chose, a Peer Agent gets its spawner's, and no tool or interface moves an agent between Squadrons or lets one leave. 3. Only a person can create a Squadron; none is ever created automatically; first run cannot proceed to creating an agent until a Squadron exists. 4. Creating a Squadron requires a name and at least one folder; a description and further folders can be added at creation or later. 5. A Squadron targets one or more folders on one environment, and the same folder can be targeted by several Squadrons that remain distinct in every list and picker. @@ -39,9 +39,10 @@ End of life is archive; its details arrive with the container's growth. 8. The composer shows the Squadron the agent will be created in, in its heading and as a chip, taking its default from the sidebar's Squadron scope; it can be changed until send and not after. 9. Agents never see a Squadron picker; a spawned Peer Agent inherits its spawner's Squadron. 10. The placement tree lives entirely within one Squadron. -11. Membership is recorded in the ledger as lifecycle events only — joined at creation, left at archive — and neither is agent-invocable. +11. Membership is recorded in the ledger as lifecycle events only: joined at registration; archived and unarchived, which change visibility and never identity or home; deleted, which removes membership. No agent appends any of them except joined, through its own home join. 12. An agent's placement equals its spawner at creation and changes only by a person's action; an agent is never placed outside its Squadron. 13. An agent's provenance is recorded at creation and never changes. +14. A thread created with no Squadron home may establish its original home once, in an explicitly chosen Squadron that references the thread's project; a thread that already has a home is refused, and the thread and its running work are untouched by joining. ## Scenarios @@ -49,12 +50,9 @@ End of life is archive; its details arrive with the container's growth. - **First run.** A new install opens on "Create your first Squadron"; the user names it "Billing Migration" and picks the app repository; only then can an agent be created. (AC3, AC4) - **An agent spawns a helper.** A Peer Agent spawned by an agent in "Billing Migration" has Squadron home "Billing Migration", with no picker shown to the spawner. (AC2, AC9) - **A message crosses Squadrons.** An agent in "Billing Migration" asks an agent in "Support Rotation" a question; both Squadrons' ledgers carry the Exchange, and nothing about either Squadron blocked it. (AC1) +- **A thread born without a home.** A thread created from the mobile app before it offered Squadrons has no home; its agent lists the Squadrons, sees that Billing Migration references its repository, and joins it; the conversation and its running turn continue unchanged, and a later attempt to join Website Redesign is refused. (AC11, AC14) - **Picking where to work.** Starting a new task from the command palette offers Squadrons; the user picks one and the composer shows it, changeable until send. (AC7, AC8) -## Scope - -The current build ([dogfood v0](../../plans/dogfood-v0.md)) narrows this definition in three places: a Squadron has exactly one folder (AC5 narrowed, stored ready to become a list); "Browse elsewhere" may be absent (AC6 narrowed); and the surfaces converted to Squadron choice are the new-thread flow and the command palette first, with the remaining pickers converted by inventory (AC7 in progress). Later: multi-folder targeting, Squadron archive, colors and avatars, migration of pre-Squadron projects. Never: cross-machine targeting; anything boundary-shaped; a Squadron with no folder. - ## History - 2026-08-17 — defined and named; former E1–E6 ([record](../../worklog/2026-08-17-squadron-naming.md); decision log). @@ -62,4 +60,6 @@ The current build ([dogfood v0](../../plans/dogfood-v0.md)) narrows this definit - 2026-08-29 — sidebar scope replaces Squadron grouping in the sidebar; former SB3 ([record](../../worklog/2026-08-29-sidebar-roster-session.md)). - 2026-08-31 — the Squadron is the unit of user choice; former E7 ([record](../../worklog/2026-08-31-picker-and-self-messaging-rulings.md)). - 2026-09-07 — placement and provenance moved here from the A2A definition (former D10 and R21): they are organization, not communication. +- 2026-09-13 — the Scope section moved out: the build's narrowings live in the dogfood v0 plan, and the nevers are stated in the Definition. +- 2026-09-12 — a thread born without a home may establish its original home once, AC14 (issue #129, PR #131); archive became reversible and deletion a separate act, so the lifecycle events in AC11 are joined, archived, unarchived and deleted (PR #132). - 2026-09-05 — rewritten into the definition shape. Two changes of substance: a Squadron targets one or more folders, so a folder is required at creation (the name-only Squadron is no longer planned — it would complicate upstream integration) and the folder-required v0 override becomes end-state truth; messages to people are no longer listed as Squadron contents (they belong to the inbox, which is person-scoped, not Squadron-scoped). Former identifiers: E1 → AC1; E2 → AC2; E3 → Definition; E4 → AC3; E5 → AC10; E6 → Definition; E7 → AC7; SC1 → AC5, AC6; SC2 → AC3, AC4; SC3 → AC8, AC9; SC4 → Scope; the A2 `join_epic` consequences → AC2, AC11. diff --git a/docs/j5/product/glossary.md b/docs/j5/product/glossary.md index 566d9fdea826..e0fea41bfc69 100644 --- a/docs/j5/product/glossary.md +++ b/docs/j5/product/glossary.md @@ -81,8 +81,8 @@ These entries are the distinctions the whole team must share; the glossary owns | Term | Gloss | Owner | | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| archive | Retiring an agent for good; its record stays readable, its open Exchanges end loudly | [features/archive-flow.md](features/archive-flow.md) | -| retired | The state of an archived participant | [features/archive-flow.md](features/archive-flow.md) | +| archive | Setting an agent aside: hidden and unmessageable, its open Exchanges ended loudly, its record readable; a person can unarchive it | [features/archive-flow.md](features/archive-flow.md) | +| retired | A participant that is archived or deleted, and so not addressable | [features/archive-flow.md](features/archive-flow.md) | | orphan | A working agent whose placement parent has been archived | [features/fleet-page.md](features/fleet-page.md) | | settled | Upstream's thread-triage state ("I'm done looking at this") and nothing else. J5 docs no longer use "settled" to mean a decision was made | upstream mechanics; see [worklog](../worklog/2026-08-29-upstream-settled-vs-archived-research.md) for the confusion this line resolves | From 6c0180b45b82c34d5ac414fcdfe687f8a1c6de29 Mon Sep 17 00:00:00 2001 From: Jackson Miller Date: Sun, 13 Sep 2026 22:59:17 -0400 Subject: [PATCH 15/15] fix(server): pin the send_message description to the definition's new shape The EnvelopeFormatter test reads the send_message description out of docs/j5/product/a2a/agent-tools.md and compares it byte-for-byte with the runtime string; the docs rewrite changed the heading and label the parser looked for. Update the parser to the definition shape, drop the stale "or a reply" toward a person from the runtime string (a person never opens an ask, so there is nothing to reply to; the channel itself went in #127), and hold the definition's description to the shipped string. The regarding sentence returns with #111. Co-Authored-By: Claude Fable 5.1 --- apps/server/src/j5/a2a/EnvelopeFormatter.test.ts | 6 +++--- apps/server/src/j5/a2a/envelopes.v1.json | 2 +- apps/server/src/j5/a2a/mcp/tools.test.ts | 2 +- docs/j5/plans/a2a.md | 2 +- docs/j5/product/a2a/agent-tools.md | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/server/src/j5/a2a/EnvelopeFormatter.test.ts b/apps/server/src/j5/a2a/EnvelopeFormatter.test.ts index 15993e3f4e1e..acf3710b09e7 100644 --- a/apps/server/src/j5/a2a/EnvelopeFormatter.test.ts +++ b/apps/server/src/j5/a2a/EnvelopeFormatter.test.ts @@ -27,7 +27,7 @@ const readDocumentedSendToolDescription = Effect.fn("readDocumentedSendToolDescr decodeURIComponent(documentedSendToolContract.pathname), ); const description = document.match( - /## `send_message`[\s\S]*?\*\*Description \(contract(?:, [^)]*)?\):\*\* "([\s\S]*?)"\n\n\| Input/, + /## `send_message`[\s\S]*?\*\*Description:\*\* "([\s\S]*?)"\n\n\| Input/, )?.[1]; if (description === undefined) { return yield* Effect.die("send_message contract description is missing from agent-tools.md"); @@ -117,11 +117,11 @@ it("does not interpret caller text as an envelope template", () => { it("keeps the tool descriptions on their documented contracts", () => { assert.equal( A2A_SEND_TOOL_DESCRIPTION, - "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask or a reply: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. A caller without a registered home is refused. Reuse client_request_id to retry the same send safely.", + "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. A caller without a registered home is refused. Reuse client_request_id to retry the same send safely.", ); assert.include( A2A_SEND_TOOL_DESCRIPTION, - "To the human, only an ask or a reply: a plain send to a person is refused", + "To the human, only an ask: a plain send to a person is refused", ); assert.include(A2A_CLEAR_OWN_ASK_TOOL_DESCRIPTION, "Withdraw an ask you sent"); assert.include(A2A_CLEAR_OWN_ASK_TOOL_DESCRIPTION, "sender-cleared"); diff --git a/apps/server/src/j5/a2a/envelopes.v1.json b/apps/server/src/j5/a2a/envelopes.v1.json index 3363219da5e3..ae524530fb35 100644 --- a/apps/server/src/j5/a2a/envelopes.v1.json +++ b/apps/server/src/j5/a2a/envelopes.v1.json @@ -7,7 +7,7 @@ "replyInstruction": "Reply once with send_message(to=\"{{senderId}}\", exchange_id=\"{{exchangeId}}\", message=\"...\") to close the exchange. Follow-ups from the asker carrying this id join the same exchange.", "oneShotInstruction": "No reply is required. Use send_message without exchange_id only if a new message is needed.", "closedExchangeInstruction": "The platform closed this exchange when this reply was sent. No further reply is required.", - "sendToolDescription": "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask or a reply: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. A caller without a registered home is refused. Reuse client_request_id to retry the same send safely.", + "sendToolDescription": "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. A caller without a registered home is refused. Reuse client_request_id to retry the same send safely.", "listToolDescription": "Your address book: the participants around you — agents and the human — with the display name to recognize them by, the participant_id to address them with, and what each accepts (messages, exchanges, urgency). When you're told to message someone by name or role, resolve them here first. Your own row is marked self=true; it cannot receive messages or open exchanges from you — use schedule_task if you need a future trigger for yourself. Native threads that never received a Squadron home do not appear here and cannot be messaged. Archived agents are hidden by default; set include_archived=true to see them with archived=true. They cannot receive messages or open Exchanges. The roster changes — after you spawn, archive, unarchive, or delete an agent, call this again instead of reusing a stale listing.", "clearOwnAskToolDescription": "Withdraw an ask you sent: closes your open exchange without a reply message. Use when the answer already arrived outside the exchange — for example, the human answered you directly in your thread — so the obligation exits their inbox honestly. Only the exchange's sender may clear it; the closure is recorded as sender-cleared, distinct from an answered exchange. Reuse client_request_id to retry safely." } diff --git a/apps/server/src/j5/a2a/mcp/tools.test.ts b/apps/server/src/j5/a2a/mcp/tools.test.ts index 58762611b501..a93ee91fa425 100644 --- a/apps/server/src/j5/a2a/mcp/tools.test.ts +++ b/apps/server/src/j5/a2a/mcp/tools.test.ts @@ -18,7 +18,7 @@ it("publishes the ratified single-target lifecycle contracts fail-closed", () => assert.equal(J5SendMessageTool.description, A2A_SEND_TOOL_DESCRIPTION); assert.include( J5SendMessageTool.description ?? "", - "To the human, only an ask or a reply: a plain send to a person is refused", + "To the human, only an ask: a plain send to a person is refused", ); assert.equal(J5ArchiveAgentTool.description, J5_ARCHIVE_AGENT_DESCRIPTION); assert.equal(J5SpawnAgentTool.description, J5_SPAWN_AGENT_DESCRIPTION); diff --git a/docs/j5/plans/a2a.md b/docs/j5/plans/a2a.md index ac0bd059ad1a..8f8c90ac1d45 100644 --- a/docs/j5/plans/a2a.md +++ b/docs/j5/plans/a2a.md @@ -100,7 +100,7 @@ The definition's acceptance criteria ([`../product/a2a/index.md`](../product/a2a | AC1–AC3 (ledger) | Built (A2A M1, M2) | | AC4 (projection rebuild) | Built for the inbox and thread projections; the communication-graph projection is A2A M5 (issue #31) | | AC5, AC6, AC9, AC10, AC11 (Exchanges) | Built | -| AC7, AC8 (several open asks to a person) | **Not built** — the shipped behavior refuses a second ask to a person while one is open; reversed by ruling on 2026-09-05, issue #111 | +| AC7, AC8 (several open asks to a person) | **Not built** — the shipped behavior refuses a second ask to a person while one is open; reversed by ruling on 2026-09-05, issue #111; when built, the `send_message` description gains the sentence teaching `regarding` | | AC12–AC15 (delivery) | Built, including the Codex Astra exception (#108); the guidance once appended on that path is gone (#126) | | AC16–AC19 (the person) | Built; the unused person-origin envelope channel removed (#127) | | AC20, AC21 (silence) | Built with a known gap: notices are stored with a label chosen when written rather than as the pure fact bundle the definition describes, so a notice with several open asks records only its first match — the fact-bundle rework is issue #30; no surface shows the stored label as current status meanwhile | diff --git a/docs/j5/product/a2a/agent-tools.md b/docs/j5/product/a2a/agent-tools.md index f33052f663d4..809ddcc4e179 100644 --- a/docs/j5/product/a2a/agent-tools.md +++ b/docs/j5/product/a2a/agent-tools.md @@ -21,7 +21,7 @@ An agent learns what it can do from its tools, and it reads a tool's description ### `send_message` -**Description:** "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. You may have several asks open with the same person; to follow up on one that is still open, name it in regarding and your message joins it. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. Reuse client_request_id to retry the same send safely." +**Description:** "Send one durable message. To another agent, three uses: a **plain send** when you don't need a reply; an **ask** — set expect_reply=true with a one-line intent, opening an exchange the receiver owes a reply to; a **reply** — include the exchange_id from the ask you are answering, which closes that exchange. To the human, only an ask: a plain send to a person is refused — if nobody needs to act, say it in your own thread instead. Set urgency only when asking the human. Use this tool only for participants already returned by list_participants; when creating a Peer Agent, put any reply expectation in spawn_agent's brief instead of sending a follow-up ask. Returns once the message is committed; delivery continues asynchronously — carry on with your work, and the reply arrives later as an incoming message. A caller without a registered home is refused. Reuse client_request_id to retry the same send safely." | Input | Type | Required | Meaning | | ------------------- | ----------------- | ------------------------------------ | ------------------------------------------------------------------------------- | @@ -183,6 +183,7 @@ No inputs. Read-only; no events. Callable by a thread that has no Squadron home - 2026-09-02 — a person receives only asks and replies ([record](../../worklog/2026-09-02-human-addressed-sends-ruling.md)). - 2026-09-08 — a person receives asks only; the reply form toward a person is retired with the person-originated ask. - 2026-09-05 — several open asks per person, with explicit follow-ups through `regarding`, replacing the one-ask-per-person refusal of 2026-09-02 (issue #111). +- 2026-09-13 — the `send_message` description is the shipped string, which a test pins byte-for-byte to this definition; the sentence teaching `regarding` joins it when #111 ships, and the stale "or a reply" toward a person is removed from the runtime string. - 2026-09-05 — a committed stop wins over restart continuation (upstream integration, PR #112). - 2026-09-12 — archiving is reversible: unarchive restores the same identity without reopening Exchanges; deletion is a separate permanent act for people only; the address book hides archived agents unless asked (PR #132). - 2026-09-12 — `list_squadrons` and `join_squadron` added for the one case of a native thread with no home (issue #129, PR #131).