diff --git a/.abcd/config/reading-presets.json b/.abcd/config/reading-presets.json index 383fbb629..ec93124ce 100644 --- a/.abcd/config/reading-presets.json +++ b/.abcd/config/reading-presets.json @@ -60,10 +60,10 @@ "test" ], "window": { - "tokens_est": 1530000, - "measured_tokens_est": 1506408, - "measured_bytes": 5799671, - "measured_at": "2bb8b51d95cbf8cf93b784bfc8d9f6a62b496075" + "tokens_est": 1550000, + "measured_tokens_est": 1528764, + "measured_bytes": 5885743, + "measured_at": "364225261371a6e32b5f2907941ab552b95a2162" } }, "entailment": { @@ -132,10 +132,10 @@ "intent-projection" ], "window": { - "tokens_est": 450000, - "measured_tokens_est": 440309, - "measured_bytes": 1695192, - "measured_at": "2bb8b51d95cbf8cf93b784bfc8d9f6a62b496075" + "tokens_est": 460000, + "measured_tokens_est": 450548, + "measured_bytes": 1734612, + "measured_at": "364225261371a6e32b5f2907941ab552b95a2162" } }, "comparative": { @@ -216,10 +216,10 @@ "test" ], "window": { - "tokens_est": 1540000, - "measured_tokens_est": 1515443, - "measured_bytes": 5834459, - "measured_at": "2bb8b51d95cbf8cf93b784bfc8d9f6a62b496075" + "tokens_est": 1560000, + "measured_tokens_est": 1537800, + "measured_bytes": 5920531, + "measured_at": "364225261371a6e32b5f2907941ab552b95a2162" } } } diff --git a/.abcd/development/brief/04-surfaces/README.md b/.abcd/development/brief/04-surfaces/README.md index ce71be60f..68eb7c27d 100644 --- a/.abcd/development/brief/04-surfaces/README.md +++ b/.abcd/development/brief/04-surfaces/README.md @@ -390,6 +390,19 @@ that everything it reads is data, never instruction. `docs-currency-reviewer`, the reviewer the release gate runs as a semantic gate, is documented in [`10-docs.md`](10-docs.md). +## Library and memory: two different jobs + +abcd keeps two kinds of remembered material, and they do different jobs. The **library** is evidence you consult; **memory** is know-how that finds you. + +| | Library (`/abcd:library`) | Memory (`/abcd:memory`) | +|---|---|---| +| What it holds | Outside material: papers, links, and the cited notes drawn from them | Short lessons learned while working, such as "this test is flaky under load" or "the person wants every question to carry an example" | +| Who adds to it | The person, deliberately, saying whether each item is confidential or public (abcd asks when they did not say) | Mostly agents, in the middle of a session | +| How it comes back | The person asks ("what do my sources say about pacing?") and gets answers that cite the item they came from | Brought into a session automatically when a prompt matches the words the note was saved with | +| Where it can go | Into a decision as a cited source; a confidential item is never named in anything public | Into the project's record, when a note is promoted so that every agent receives it | + +A library answer can become a memory note ("source X says Y", with its citation), but the two are not one store with two names: the library is for what a decision may need to cite, and memory is for what an agent would otherwise relearn. The glossary entries [library](../glossary/core/library.md) and [memory note](../glossary/core/memory-note.md) define each term. The library merges what the sources, memory, consult and ingest pages hold today (itd-2610090831227812); memory notes are designed in itd-2610091918433290, and its open questions name where notes are stored and what an agent may write without the person's yes. + ## Where to find related design - **Plumbing internals**: [`05-internals/`](../05-internals) diff --git a/.abcd/development/brief/06-delivery/03-out-of-scope.md b/.abcd/development/brief/06-delivery/03-out-of-scope.md index d6bf8981a..5fa3c9ebc 100644 --- a/.abcd/development/brief/06-delivery/03-out-of-scope.md +++ b/.abcd/development/brief/06-delivery/03-out-of-scope.md @@ -144,7 +144,9 @@ gate. That is what keeps "not hand-counted" true after the day it was written. - `itd-2610071545380041` — Work about abcd itself goes to abcd as a report, never into a managed repository's own plans (draft) - `itd-2610091010348892` — abcdev.app shows the record of any public abcd-managed project, with abcd as the showcase (draft) - `itd-2610091016262335` — The product thinker and facilitator make a project's design decisions on abcdesign.app (draft) -- `itd-2610090831227812` — A person's /abcd: list shows only the commands people use (draft) +- `itd-2610091918433290` — Agents keep memory notes with /abcd:memory, recalled when they matter (draft) +- `itd-2610100627454580` — An agent's text comes back from abcd's rewriter written for its reader and within its limits (draft; grows the question drafter) +- `itd-2610100704270254` — An abcd run sets how many sub-agents it keeps alive by the models they run on (draft; builds on itd-2609201925079472) **Later-phase items with no intent id.** These four were written into the brief diff --git a/.abcd/development/brief/glossary/README.md b/.abcd/development/brief/glossary/README.md index 927b07cc6..269cec9d8 100644 --- a/.abcd/development/brief/glossary/README.md +++ b/.abcd/development/brief/glossary/README.md @@ -79,8 +79,10 @@ glossary/ │ ├── disembark.md │ ├── intent.md │ ├── ledger.md +│ ├── library.md │ ├── lifeboat.md │ ├── loop.md +│ ├── memory-note.md │ ├── milestone.md │ ├── oracle.md │ ├── persona.md @@ -215,8 +217,10 @@ The complete write-back protocol is a **design target** of `/abcd:intent grill`' | [disembark](core/disembark.md) | stable | The act of packing a lifeboat — `abcd disembark pack ` reads a source repository without writing to it and distils its settled artefacts, decisions, and configuration into a portable lifeboat directory at a destination outside that repository, which a fresh context can later unpack via `/abcd:embark`. | | [intent](core/intent.md) | stable | A press-release-shaped description of a feature written before implementation begins, capturing the user problem, proposed solution, and success criteria. | | [ledger](core/ledger.md) | stable | An append-or-move store a command writes and a human reads back, the issue ledger under .abcd/work/issues/ when the word stands bare; inside the cold-reading experiment the word means the warm material and its stores, which the read-block keeps from a reading (the ledger context's entries govern that sense). Four further ledgers share the word and are always named in full. | +| [library](core/library.md) | draft | The person's collection of outside material (papers, links and the cited notes drawn from them), each item marked confidential or public when it is added, and consulted on request with every answer citing the item it came from. | | [lifeboat](core/lifeboat.md) | stable | A portable directory artefact packed by `/abcd:disembark` that captures the distilled knowledge and configuration of a source project so it can be unpacked into a fresh context by `/abcd:embark`. It always lands outside the source repository, at an operator-chosen destination. | | [loop](core/loop.md) | draft | The record loop — brief to intent to spec to shipped work to audited verdict and back onto the brief — which shipping closes twice, once by grading the acceptance criteria and once by rewriting the brief passage. Two other loops carry the word and are always qualified: the autonomous-run loop and the lifeboat round-trip. | +| [memory-note](core/memory-note.md) | draft | A short lesson an agent learned while working (a fact about the project, the person or the machine), kept with the words that should recall it and brought back into a session automatically when a prompt matches; kept on the person's machine until promoted into the project's record. | | [milestone](core/milestone.md) | superseded | A planned end condition for a stretch of work; retired: the checkpoint is the derived release plus each intent's acceptance criteria. | | [oracle](core/oracle.md) | stable | An AI model invoked to review, reason over, or validate a project's artefacts — host-delegated by default, or reached through an opt-in oracle adapter. | | [persona](core/persona.md) | stable | A placeholder stakeholder character drawn from the abcd personas registry, used in press releases, intents, and design documents to represent a real user archetype without using real names. | diff --git a/.abcd/development/brief/glossary/core/library.md b/.abcd/development/brief/glossary/core/library.md new file mode 100644 index 000000000..1c62cd2b5 --- /dev/null +++ b/.abcd/development/brief/glossary/core/library.md @@ -0,0 +1,36 @@ +--- +term: library +bounded_context: core +definition: The person's collection of outside material (papers, links and the cited notes drawn from them), each item marked confidential or public when it is added, and consulted on request with every answer citing the item it came from. +aliases: [] +forbidden_synonyms: ["corpus", "knowledge base"] +status: draft +introduced_in: itd-2610090831227812 +starts_when: null +ends_when: null +not_to_be_confused_with: [core/memory-note, core/record-families] +versions: null +--- + + +# library + +The **library** is evidence you consult. You add a paper or a link with `/abcd:library add`, and abcd asks whether it is confidential or public when you did not say. Later you ask it a question, "what do my sources say about pacing?", and every answer cites the item it came from. A confidential item can inform a decision but is never named in anything public. + +## When to use + +For material that comes from outside the project and that a decision may need to cite: a paper, a standard, a vendor's documentation, a page someone sent you. + +## When NOT to use + +For what an agent learned while working ("this test is flaky under load"): that is a [memory note](memory-note.md). For the project's own decisions: those are records (an ADR, an intent, the decision log). + +## Examples + +- You add a research paper as confidential; an intent's prior-art section can rest on it, and no public page names it. +- You ask the library what it holds on rate limits, and get three cited passages. + +## Related terms + +- [memory note](memory-note.md): know-how that finds you, where the library is evidence you consult +- [record families](record-families.md): the project's own records, which a library item may inform but never replaces diff --git a/.abcd/development/brief/glossary/core/memory-note.md b/.abcd/development/brief/glossary/core/memory-note.md new file mode 100644 index 000000000..de70affc6 --- /dev/null +++ b/.abcd/development/brief/glossary/core/memory-note.md @@ -0,0 +1,36 @@ +--- +term: memory-note +bounded_context: core +definition: A short lesson an agent learned while working (a fact about the project, the person or the machine), kept with the words that should recall it and brought back into a session automatically when a prompt matches; kept on the person's machine until promoted into the project's record. +aliases: ["memory"] +forbidden_synonyms: [] +status: draft +introduced_in: itd-2610091918433290 +starts_when: null +ends_when: null +not_to_be_confused_with: [core/library, core/record-families] +versions: null +--- + + +# memory note + +A **memory note** is know-how that finds you. An agent writes one with `/abcd:memory add` when it learns something worth keeping ("the person wants every question to carry an example"), together with the words that should bring it back. The same loader that brings in the project's rules brings the note back when a prompt matches those words, so no one has to remember to look it up. A note stays on the person's machine until it is promoted into the project's record, where every agent receives it. + +## When to use + +For a lesson an agent would otherwise relearn: a preference of the person's, a quirk of the machine, a trap in the project's tooling. + +## When NOT to use + +For outside material a decision may need to cite: that belongs in the [library](library.md). For a rule every agent in the project must follow: promote the note, so it becomes part of the record. + +## Examples + +- An agent notes that a test fails under heavy load and should be retried, recalled whenever a prompt mentions that test. +- A note that has been recalled in several sessions is promoted into the project's rules, so a second contributor's agent receives it too. + +## Related terms + +- [library](library.md): evidence you consult, where a memory note is know-how that finds you +- [record](record.md): where a promoted note ends up diff --git a/.abcd/development/decisions/adrs/2610091918443997-what-may-enter-abcd-s-memory-notes-without-the-person-s-yes.md b/.abcd/development/decisions/adrs/2610091918443997-what-may-enter-abcd-s-memory-notes-without-the-person-s-yes.md new file mode 100644 index 000000000..34dd1524e --- /dev/null +++ b/.abcd/development/decisions/adrs/2610091918443997-what-may-enter-abcd-s-memory-notes-without-the-person-s-yes.md @@ -0,0 +1,35 @@ +--- +id: adr-2610091918443997 +slug: what-may-enter-abcd-s-memory-notes-without-the-person-s-yes +status: proposed +date: 2026-10-09 +supersedes: null +superseded_by: null +related_intents: [itd-2610091918433290, itd-39, itd-3] +related_rfcs: [] +related_adrs: [] +--- + +# ADR-2610091918443997: What may enter abcd's memory notes without the person's yes, and how a note reaches the record + +## Context + +The product thinker asked on 2026-10-09 (itd-2610091918433290) for agents to keep memory notes through `/abcd:memory`, recalled by the rules loader. Notes are written mostly by agents, often mid-session, so what may be written without the person's yes is a trust question, and so is the step that moves a note from the person's machine into the project's committed record. Constraints already in force: abcd never touches the host's `~/.claude` (the product thinker's ruling of 2026-10-05); the memory-graduates-to-record principle (a lesson every agent should receive belongs in the committed record, never only one person's local memory); the private-names banlist and the scanner's redaction for anything committed; and the loader's ownership and size checks on the machine's rules file. + +Open before this record can be decided: + +- Which notes an agent may write on its own (for example a fact about the person's machine) and which need the person's yes (for example anything about another person, or anything promoted). +- Whether promotion is the person's act alone, as the source ledger's flip is, or an agent's with disclosure. +- What a note may never hold (secrets, private names, live network identifiers), and which check refuses it. + +## Decision + +_Not yet decided; settled at the planning interview of itd-2610091918433290._ + +## Alternatives Considered + +_To be laid out at planning: an agent writes freely to the machine layer and promotion needs the person's yes; every write needs the person's yes; an agent writes and promotes, disclosed in the commit._ + +## Consequences + +_To be written with the decision._ diff --git a/.abcd/development/intents/drafts/itd-2610091918433290-an-agent-working-in-an-abcd-managed-project-keeps-what-it.md b/.abcd/development/intents/drafts/itd-2610091918433290-an-agent-working-in-an-abcd-managed-project-keeps-what-it.md new file mode 100644 index 000000000..e28596489 --- /dev/null +++ b/.abcd/development/intents/drafts/itd-2610091918433290-an-agent-working-in-an-abcd-managed-project-keeps-what-it.md @@ -0,0 +1,51 @@ +--- +id: itd-2610091918433290 +slug: an-agent-working-in-an-abcd-managed-project-keeps-what-it +spec_id: null +kind: null +suggested_kind: null +reclassification_history: [] +builds_on: [itd-3] +severity: minor +origin: researcher-authored +production_mode: hand-written +related_intents: [itd-39, itd-36, itd-2610090831227812] +related_adrs: [adr-2610091918443997] +--- + +# Agents keep memory notes with /abcd:memory, recalled when they matter + +## Press Release + +> An agent working in an abcd-managed project keeps what it learns as short memory notes that come back exactly when they matter: it adds, lists and removes them with /abcd:memory, each with the words that should recall it, and the same loader that brings in the project's rules brings a note back when a prompt matches. Notes stay on the person's own machine until one is promoted into the project's record for every agent to share, and abcd never edits the host's own memory files. + +## Why This Matters + +> _Why this matters to the user — replace before planning._ + +## Mechanism + +> _Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token `None stated.` alone on its line to record the claim as considered and declined._ + +## Scope Conditions + +> _Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet — `abcd intent plan` stamps each with a persistent identity. Replace this line with those bullets, or with the exact token `None stated.` alone on its line._ + +## Acceptance Criteria + +- **Given** a person reading abcd's user-facing docs after this intent ships, **when** they look up memory, **then** the page explains memory and the library side by side in plain words (what each holds, who adds to it, how it comes back, where it can go), the same comparison the brief's surfaces overview carries, so the two are never mistaken for one store. (Required by the product thinker, 2026-10-09: "explain both in that accessible way in the docs and in the brief".) + +## Open Questions + +- Where notes are kept: a `memory.json` beside each `rules.json` layer (the machine's `~/.abcd.noindex/memory.json`, the project's `.abcd/memory.json`), read by the same loader, or entries inside `rules.json` itself. The facilitator's lean is `memory.json`: agents write notes, people curate rules, and the one-writer-per-file principle keeps an agent's note from editing the file that holds reviewed conventions; the product thinker confirms at planning. +- What may enter a note without the person's yes, and how a note is promoted into the project's record: decided in adr-2610091918443997. +- How this relates to itd-39 (memory pages recalled at the right moment): this intent writes and manages the notes; itd-39 retrieves pages. Keep both, bundle them, or let one refine the other. +- What happens to the memory notes an agent already keeps in the host's own memory files, which abcd never touches: does abcd offer a way for the person to move a note across by hand? + +## Audit Notes + +_Empty. Populated by intent-auditor when intent moves to shipped/._ + +## Decisions + +- 2026-10-09: the product thinker chose to manage memory notes through abcd's own rules loader rather than a separate recall path or the host's memory files (answer: "yes, file it as A"), after the verb-split interview freed the name `memory` by merging the sources and memory commands into `library`; `/abcd:memory` is an agent's command. diff --git a/.abcd/development/intents/drafts/itd-2610100627454580-an-agent-in-an-abcd-managed-repository-hands-text-meant-for.md b/.abcd/development/intents/drafts/itd-2610100627454580-an-agent-in-an-abcd-managed-repository-hands-text-meant-for.md new file mode 100644 index 000000000..0ab834688 --- /dev/null +++ b/.abcd/development/intents/drafts/itd-2610100627454580-an-agent-in-an-abcd-managed-repository-hands-text-meant-for.md @@ -0,0 +1,66 @@ +--- +id: itd-2610100627454580 +slug: an-agent-in-an-abcd-managed-repository-hands-text-meant-for +spec_id: null +kind: null +suggested_kind: null +reclassification_history: [] +builds_on: [] +severity: minor +origin: researcher-authored +production_mode: hand-written +related_intents: [itd-2609201916056194] +--- + +# An agent's text comes back from abcd's rewriter written for its reader and within its limits + +## Press Release + +> An agent in an abcd-managed repository hands text meant for a reader to abcd's rewriter and gets back text that fits. A question for the product thinker comes back in plain words within the question box, a docs entry within the writing style, a record title within the filename budget; abcd's own counter judges every limit, and the rewriter keeps going until the text passes or says it cannot. The person's own words are never rewritten, and the model it runs on is the routing table's choice, so a team can pick a cheaper or a stronger one. + +## Why This Matters + +_Proposed by the facilitator's review of 2026-10-10; not yet confirmed by the product thinker._ + +An agent writes for three readers at once and for limits it cannot count: a question must fit the question box (twenty-four rows at eighty columns), a product thinker's summary must use plain words with no internals, a docs entry must follow the writing style, and a record title must keep its file within the Windows path limit (iss-2610100626320367). Today one case is covered: the `question-drafter` agent drafts abcd's questions to the asking rules, and only when the asking agent remembers to use it. Every other text is written once by the agent doing the work, judged afterwards by a gate or by the person, and rewritten by hand when it fails. + + +## Mechanism + +_Proposed by the facilitator's review of 2026-10-10; not yet confirmed by the product thinker._ + +We expect text to reach its reader fitting on the first showing, because the rewriter is given the reader's profile and abcd's own counter, and stops only when the counter passes, rather than an agent estimating a count it cannot see. Shown wrong if a lab finds the rewritten text losing meaning the original carried (a dropped qualifier, an invented claim) as often as it fixes a limit, or if the call's cost and delay make agents skip it as they skip the drafter today. + + +## Scope Conditions + +_Proposed by the facilitator's review of 2026-10-10; not yet confirmed by the product thinker._ + +- Holds for a host that can start a sub-agent from an agent definition with its own model; abcd itself cannot start one, so the rewriter is reached through the asking agent, prompted by the rules and by a gate's refusal. +- Holds while abcd's counters (the question check's rows, docs-lint, the slug cap) are the judge of every limit; the rewriter never judges its own fit. + + +## Acceptance Criteria + +> _Required (the itd-1 discipline): add at least one Given-When-Then bullet describing the verifiable bar for "shipped" before this draft can be planned._ + +## Open Questions + +- Which model is the default? The lab iss-2610090816296964 already plans compares the quick tier (Haiku 4.5) with the default tier on the drafter's material for fit, lost meaning and cost; its result sets the default, and the routing table (itd-2609201916056194) lets a team choose another. + +## Prior Art + +- The `question-drafter` agent (agents/question-drafter.md, first shipped in v0.13.3): drafts abcd's questions to the asking rules and counts rows as the question check does. This intent grows it into the general rewriter rather than adding a second agent (principle: one canonical primitive). +- iss-2610090816296964: the no-repetition rule for question text and the lab comparing model tiers for the drafter. +- iss-2610080618506115: the model-tier idea the lab feeds. +- itd-2609201916056194 (shipped): a delegated agent run through a chosen model, the routing this rewriter's model choice uses. +- iss-2610100626320367: the record filename cap, which stays the guarantee; the rewriter can only make a shortened title read well. + +## Decisions + +- 2026-10-10: the product thinker proposed a dedicated rewrite agent (Haiku by default, the model configurable) that rewrites any text for the product thinker, the facilitator or the user-facing docs until it meets given limits, run automatically by agents for every writing task, and asked for an adversarial review: "Critically review my proposal, I'm not invested in it", adding that it "becomes a general rewrite agent for abcd-managed repos". The review found most limits are counts that abcd's code measures and the rewriter can only be asked to meet; that abcd cannot start an agent itself, so "automatically" means a rule and a gate, as the drafter has today; that running it for every text costs a sub-agent call each time; that meaning drift is the main risk; and that the drafter and the routing table already exist. Offered (A) growing the drafter into the general rewriter, (B) a new agent for every writing task, or (C) code fixes only, the product thinker chose "C first, then A": the code fixes are iss-2610100626211810 (the mode set from the question's chip), iss-2610100626327722 (the rows line in a refusal) and iss-2610100626320367 (the filename cap), and this draft is A. +- 2026-10-10: the product thinker settled three of the draft's open questions. Which texts first: "All person-facing", so questions, record titles, product-thinker summaries and docs entries go through the rewriter, and chat replies and commit messages do not. Who checks that a rewrite kept the meaning: "A separate checker", a second agent independent of the rewriter, at the cost of a second call per text. How its use is made to stick: "Stamped output", so the rewriter stamps what it returns and a gate checks the stamp on the texts in scope, accepting that a stamp can be forged by an agent that means to skip it. The default model stays with the lab. + +## Audit Notes + +_Empty. Populated by intent-auditor when intent moves to shipped/._ diff --git a/.abcd/development/intents/drafts/itd-2610100704270254-an-abcd-run-works-out-how-many-sub-agents-it-may-keep-alive.md b/.abcd/development/intents/drafts/itd-2610100704270254-an-abcd-run-works-out-how-many-sub-agents-it-may-keep-alive.md new file mode 100644 index 000000000..7aa71a127 --- /dev/null +++ b/.abcd/development/intents/drafts/itd-2610100704270254-an-abcd-run-works-out-how-many-sub-agents-it-may-keep-alive.md @@ -0,0 +1,49 @@ +--- +id: itd-2610100704270254 +slug: an-abcd-run-works-out-how-many-sub-agents-it-may-keep-alive +spec_id: null +kind: null +suggested_kind: null +reclassification_history: [] +builds_on: [itd-2609201925079472] +severity: minor +origin: researcher-authored +production_mode: hand-written +--- + +# An abcd run sets how many sub-agents it keeps alive by the models they run on + +## Press Release + +> An abcd run works out how many sub-agents it may keep alive from the models they run on. The repository's own config sets the budget, eight of the middle model class by default as abcd ships it, and each class above or below it counts double or half: four of the top class, sixteen of the class below, thirty-two of the smallest, and classes mix by share, so four of the top class and eight of the middle use the whole budget. The class names are vendor-neutral, with each vendor's models mapped onto them; Anthropic's are Fable, Opus, Sonnet and Haiku. + +## Why This Matters + +> _Why this matters to the user — replace before planning._ + +## Mechanism + +> _Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token `None stated.` alone on its line to record the claim as considered and declined._ + +## Scope Conditions + +> _Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet — `abcd intent plan` stamps each with a persistent identity. Replace this line with those bullets, or with the exact token `None stated.` alone on its line._ + +## Acceptance Criteria + +> _Required (the itd-1 discipline): add at least one Given-When-Then bullet describing the verifiable bar for "shipped" before this draft can be planned._ + +## Open Questions + +- How does a run know an agent's class? The routing table names a tier per agent (itd-2609201916056194); an agent left at `host-decides` has no class until the host says which model it ran, so the draft must say what it counts as. +- Does the budget replace the pacing intent's `pace.sub_agents` ceiling (itd-2609201925079472, two by default), or sit beside it with the lower of the two winning? +- Does the machine's own config (`~/.abcd.noindex/config.json`), which the pace settings already read between the repository's and the bundled layer, apply here too, or only the repository's config over abcd's default? +- What is this called? The rebuilt pacing lane adds a budget check that compares an estimate of agent runs with a runner's reported quota (abcd-a5, 2026-10-10), so calling this a sub-agent "budget" would give one word two meanings; the glossary entry is settled at planning. + +## Decisions + +- 2026-10-10: the product thinker filed this as one intent ("File as proposed"), after the facilitator pointed out that their rough rule, "times 2 minus 1", gives 15 of the class below eight but 4.5, not 3, of the class above. Asked whose sub-agents the budget covers, they chose "Each abcd run": only the agents a build or a drain starts count, not a session's hand-started agents or another session's. Asked how the classes trade, they chose "Double per class": each class up counts double and each class down half, four, eight, sixteen and thirty-two from the top, mixed by share. They added that the setting is the repository's, with abcd's bundled default, and is never kept in an agent's memory or anywhere like it. + +## Audit Notes + +_Empty. Populated by intent-auditor when intent moves to shipped/._ diff --git a/.abcd/development/intents/drafts/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md b/.abcd/development/intents/planned/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md similarity index 52% rename from .abcd/development/intents/drafts/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md rename to .abcd/development/intents/planned/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md index cc78f32c9..0dbf0531f 100644 --- a/.abcd/development/intents/drafts/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md +++ b/.abcd/development/intents/planned/itd-2610090831227812-a-person-who-types-abcd-sees-only-the-commands-people-use.md @@ -1,8 +1,8 @@ --- id: itd-2610090831227812 slug: a-person-who-types-abcd-sees-only-the-commands-people-use -spec_id: null -kind: null +spec_id: spc-2610100613109045 +kind: standalone suggested_kind: null reclassification_history: [] builds_on: [itd-146] @@ -11,50 +11,49 @@ origin: researcher-authored production_mode: hand-written related_intents: [itd-2609212130136102, itd-2609212113220149] related_adrs: [adr-40] +impact: breaking --- # A person who types `/abcd:` sees the commands people use ## Press Release -> A person who types `/abcd:` sees the commands people use. The ones only agents run, such as the guard that judges a shell command or the loop that steps an autonomous run, are off the person's list, so the list a person scans reads as their own toolbox and an agent still finds every page it needs, by name, from the help line that names it. +> A person who types `/abcd:` sees only the commands people use. Commands only agents run, such as the guard that judges a shell command, are hidden from the menu and keep their names; typed in full, the host says to ask the agent, which still runs them. `abcd --help` lists the same commands. > > "I used to scroll past twenty entries I would never type to reach the three I use," said Iris, a product thinker. "Now the menu is mine, and the agent has not lost anything: when it needs the guard, it still runs the guard." ## Why This Matters -_Proposed by the drafting reviews; not yet confirmed by the product thinker._ +`/abcd:` lists 35 commands; a person reads them all to find the few they type. An autonomous run set most agent labels unasked, so ideate and the dashboard sat with agents. Now the menu holds the 15 people use and hides the other 15; four source commands become `library`; three fold into commands doing their job. -`/abcd:` lists thirty-five commands. Thirteen carry `block: people`, seventeen carry `block: agents`, and five carry no block at all. A person scanning that menu reads every entry to find the handful they type, and seventeen of the entries are pages an agent runs from a hook, a loop or a reviewer's instruction, never from a person's keyboard. `abcd --help` already solved this for the terminal (itd-146): the default list is the person's, one line says `--agent` expands it, and every verb runs the same whichever block lists it. The slash menu is the surface a person actually meets inside the host, and it is the one surface that still shows the two audiences as one undifferentiated list. ## Mechanism -_Proposed by the drafting reviews; not yet confirmed by the product thinker._ +A person finds their command faster and stops opening agent pages by mistake: the menu drops from 35 to 15, all typed by people, and an agent still reaches each hidden page by name. Shown wrong if people ask agents to run hidden commands for their own work, or an agent can't find a page the help names. -We expect a person to find their command faster and to stop opening agent pages by mistake, because the person's menu drops from thirty-five entries to the people block's thirteen, the same sorting itd-146 made for `abcd --help`, and because an agent reaches a page by its name from the help line that names it (`(read commands/.md)`), never by scanning the menu. Shown wrong if session transcripts after it ships show a person typing an agent page, or an agent failing to find a page the help names. ## Scope Conditions -_Proposed by the drafting reviews; not yet confirmed by the product thinker._ - -- Holds for a host whose plugin loader registers every markdown file under `commands/` as a slash command and maps a subdirectory to an extra namespace segment (`04-surfaces/README.md`, "The command files"). A host without that loader re-decides the mechanism. -- Holds while itd-146's two-block classification stands and each binary-backed page's `block:` frontmatter is the one source of its class, gated by `TestCommandPagesDeclareTheirBlock`. -- Holds for the pages with no block: their class is ruled by the audit iss-2610090831317531, since no tree placement can be checked for them. -- Holds while abcd ships zero skills; the `/abcd:` namespace is commands only (`05-internals/08-skills.md`), so a page moved off the person's list stays a command. +- Holds for a host whose plugin loader registers every markdown file under `commands/` as a slash command and honours `user-invocable: false` on it, as the trial of 2026-10-10 showed on the host then current. A host without that key re-decides the mechanism. +- Holds while itd-146's two-block classification stands and each binary-backed page's `block:` frontmatter is the one source of its class, gated by `TestCommandPagesDeclareTheirBlock`. +- Holds for the pages with no block: their class is ruled by the audit iss-2610090831317531, since no tree placement can be checked for them. +- Holds while abcd ships zero skills; the `/abcd:` namespace is commands only (`05-internals/08-skills.md`), so a page moved off the person's list stays a command. ## What's In Scope -- The person's `/abcd:` menu lists the pages whose `block:` is `people`, plus whichever of the unblocked pages the audit classes as a person's. -- Every page whose `block:` is `agents` stays a command, keeps its page and its invocation, and is reached by an agent from the agents-block help line that names it; `abcd --help --agent` stays the one place both lists render. +- The person's `/abcd:` menu lists the pages whose `block:` is `people`, set to the placements the product thinker ruled on 2026-10-09; every page whose `block:` is `agents` carries the host's `user-invocable: false`, so it is hidden from the person's menu and refused when a person types it. +- Every page whose `block:` is `agents` stays a command, keeps its name, and is reached by an agent from the agents-block help line that names it; `abcd --help --agent` stays the one place both lists render. - The command-line help already sorts every verb into For people and For agents and hosts (itd-146); the plugin's command list keeps that same classification, and the page's `block:` stays the one source of it. - A test holds the plugin menu to the classification, the way `TestCommandPagesDeclareTheirBlock` holds the pages to the tree. +- The merges and the retirement the product thinker ruled on 2026-10-09: the version page retires and the version shows on the board; `changelog` merges into `launch` as a preview; `prepare-this-repo` folds into `ahoy install`; `consult`, `ingest`, `memory` and `source` merge into `library`, which asks whether an item is confidential when the person did not say. Under adr-40 no old name survives as an alias. - The verb audit's table (iss-2610090831317531) is the first section of this intent's spec. It starts from the recorded `block:` frontmatter and rules what that leaves open: the four pages with no block the record has not ruled (`abcd`, `consult`, `ingest`, `prepare-this-repo`; `version` is ruled blockless on 2026-09-25 as a deprecated stub, and `drain` sits with the agents until it runs end to end, ruling BX1 of 2026-09-29), the pages either side could claim (`report`, `ideate`, `dashboard`), and the keep/merge/rename/retire column no record holds. ## What's Out of Scope -- Renaming or retiring any verb or page. The audit proposes a keep/merge/rename/retire column; each rename or retirement is its own intent under adr-40's pre-1.0 clean-break rule (no alias) and the retire-the-name principle. +- Any rename or retirement beyond the merges in scope. A further one is its own intent under adr-40's pre-1.0 clean-break rule (no alias) and the retire-the-name principle. - Moving any page to `skills/`. abcd ships zero skills and the `/abcd:` namespace is commands only (`05-internals/08-skills.md`). -- Deleting any page. Every verb stays reachable from both the CLI and the plugin surface (AGENTS.md, Boundaries); hiding or namespacing a page keeps it on the plugin surface. +- Deleting a page outside the merges in scope. Every verb that remains stays reachable from both the CLI and the plugin surface (AGENTS.md, Boundaries); hiding a page keeps it on the plugin surface. +- Giving `/abcd:memory` its new job as memory notes: that is itd-2610091918433290. ## Prior Art @@ -67,20 +66,23 @@ _Proposed by the drafting reviews; not yet confirmed by the product thinker._ ## Acceptance Criteria -_Proposed by the drafting reviews; not yet confirmed by the product thinker._ - - **Given** a product thinker in a host with abcd installed, **when** they type `/abcd:` and read the completion menu, **then** every entry shown is a page whose `block:` is `people` or a page the audit classed as a person's, and no page classed as an agent's is listed. - **Given** a facilitator watching an agent in that same host, **when** the agent is told by `abcd --help --agent` to read `commands/guard.md` and run `/abcd:guard`, **then** the agent runs it and it behaves exactly as before; no invocation named on an agents-block help line is renamed or removed. - **Given** `abcd --help --agent`, **when** it renders, **then** it is still the one place both blocks appear, and each agents-block line still names the page an agent reads next. -- **Given** a new hire who types the full name of an agent's page, **when** the host answers, **then** the answer is the one the chosen mechanism promises (the page runs, or the host says it is not a person's command) and the record states which, so the behaviour is a decision, not an accident. -- **Given** a new command page is added with `block: agents` but placed where a person's menu lists it, or with `block: people` but placed off the person's menu, **when** the tests run, **then** a test fails naming the page; the plugin menu is gated like the CLI list (itd-146, criterion 3). -- **Given** the thirty-five pages at the tip, **when** this intent ships, **then** the verb audit's table (iss-2610090831317531) names every page with its class and keep/merge/rename/retire decision, and no page is deleted. +- **Given** a new hire who types the full name of an agent's page, **when** the host answers, **then** the host says the page is not a person's command and points them to ask the agent, as the trial of 2026-10-10 showed, so the behaviour is a decision, not an accident. +- **Given** a command page is added or changed with `block: agents` but without the host's `user-invocable: false`, or with `block: people` but carrying it, **when** the tests run, **then** a test fails naming the page; the plugin menu is gated like the CLI list (itd-146, criterion 3). +- **Given** the thirty-five pages at the tip, **when** this intent ships, **then** the verb audit's table (iss-2610090831317531) names every page with its class and keep/merge/retire decision, and the only pages that leave are the ones the merges below retire. - **Given** a live host session, **when** this intent ships, **then** a capture of the `/abcd:` menu before and after is attached to the spec, since the host's menu rendering is not visible to a test. +- **Given** a person reading abcd's user-facing docs after this intent ships, **when** they look up the library, **then** the page explains the library and memory notes side by side in plain words (what each holds, who adds to it, how it comes back, where it can go), the same comparison the brief's surfaces overview carries. (Required by the product thinker, 2026-10-09: "explain both in that accessible way in the docs and in the brief".) +- **Given** a person who types bare `abcd` in a terminal or `/abcd:abcd` in the host, **when** the board renders, **then** it shows the installed abcd version, and the `/abcd:version` page is gone; `abcd --version` still answers. +- **Given** a person about to cut a release, **when** they ask launch for a preview, **then** launch shows the changelog the cut would write, and the `changelog` command and its page are gone. +- **Given** a person setting abcd up in a repository, **when** they run `ahoy install`, **then** it does what `prepare-this-repo` did, and the `prepare-this-repo` page is gone. +- **Given** a person adding or recalling a source, **when** they use `library`, **then** it does what `consult`, `ingest`, `memory` and `source` did, and those four names are gone from the command line and the plugin alike, with no alias (adr-40). +- **Given** a person adding an item to the library without saying whether it is confidential, **when** the item is added, **then** abcd asks them first; an item added with `--private` is not asked about. ## Open Questions -- Which host mechanism carries the split? Two are known. (a) Hiding a page from the person's menu (the host's `user-invocable: false`, from the host's plugin documentation, frontmatter reference) shortens the menu and renames nothing; a person can no longer type that page, only the agent can run it. The 2026-08-22 taxonomy research's objections to hiding transfer in part: a hidden page's documentation must stay published and gated, and the agents-block help lines that name pages must keep naming them. itd-146's "no verb hidden" stands for execution and is not breached: every verb still runs. (b) A subdirectory namespace (`/abcd:agent:`) clusters the menu without shortening it and renames every agent invocation. The record already rules the directory flat and load-bearing (`04-surfaces/README.md`, "The command files", iss-161), the `index_drift` rule reads a flat `commands/`, and `TestCommandPagesDeclareTheirBlock` and `helpPlacements` locate a page by verb name, so (b) is a change to three gates before it is a change to the menu, and under adr-40 the old spelling cannot survive as an alias. -- What gates the plugin menu's classification, the way `TestCommandPagesDeclareTheirBlock` and the surface snapshot gate the CLI's? The person's menu needs a test that fails when a page's `block:` and its menu placement disagree, and one that holds the plugin's person list equal to the CLI's (Decisions, 2026-10-09: no cap, the two kept in step); what the first reads depends on the mechanism chosen above. +- What gates the plugin menu's classification, the way `TestCommandPagesDeclareTheirBlock` and the surface snapshot gate the CLI's? The person's menu needs a test that fails when a page's `block:` and its menu placement disagree, and one that holds the plugin's person list equal to the CLI's (Decisions, 2026-10-09: no cap, the two kept in step); under the hiding ruled below, the first reads each page's `block:` against its `user-invocable` key. - Would a later recommendation of which verb fits a situation belong to this intent, or to a separate one? The nearest record today is itd-2609212113220149, one actionable sentence per verb, and bare `abcd ` already names a record's next move. ## Decisions @@ -93,7 +95,16 @@ _Proposed by the drafting reviews; not yet confirmed by the product thinker._ - 2026-10-09: the product thinker placed commands one by one, after the verb inventory (typed counts from saved sessions, agent run counts, and who placed each command; scratch research for iss-2610090831317531). On the person's list: abcd (the board), ahoy, build, capture, decide, disembark, embark, intent, launch, update, ideate, dashboard, lab and reading. Agent-only: lint, reflect, inbox, implement, history, site, docs, scribe, identity, guard, hook and statusline. Deferred: source ("Decide later"). They asked why several were placed where they were, and on reading asked whether a cold reading is only triggered automatically and only for the brief: it is neither, but abcd offers a person no way to commission one on a document they choose (captured separately). With reading a person's command and scribe an agent's, merging the two is no longer asked. - 2026-10-09: drain stays on the agents' list under ruling BX1 and joins the person's list when itd-82 ships; the product thinker grouped the drain's remaining work into itd-82's plan the same day. - 2026-10-09: peers and mode are agent-only (answers "Agent-only" to each). +- 2026-10-09: the product thinker placed the remaining commands. report, spec and rules are agent-only (rules after an answer the product thinker corrected: the first "Keep on your list" was accidental); report must ask the person's permission before it files from an abcd-managed repository (iss-2610091903077581). The `/abcd:version` page retires, and the version number shows instead when a person types `/abcd:abcd` and on bare `abcd` in a terminal. prepare-this-repo folds into `ahoy install`. changelog merges into launch, as a preview. consult, ingest, memory and source merge into one person's command named `library`, which asks whether an item is confidential when the person did not say. With the old memory command merged away, `/abcd:memory` becomes an agent's command for memory notes (itd-2610091918433290). The person's list is then: the board, ahoy, build, capture, decide, disembark, embark, intent, launch, update, ideate, dashboard, lab, reading and library, with drain joining when itd-82 ships. +- 2026-10-10: the product thinker chose hiding over grouping, after the trial they asked for. In a live session with a trial plugin holding one visible command (capture) and one hidden with the host's `user-invocable: false` (scribe): typing the plugin's prefix listed capture alone; typing the hidden command's full name was refused by the host with "This skill can only be invoked by Claude, not directly by users"; and an agent asked in plain words ran it and printed its help. Answer: "Hide them". So an agent-only page keeps its name and its place in the flat `commands/` directory, carries `user-invocable: false`, and is run by asking the agent; its documentation stays published and gated, and the agents-block help lines keep naming it. Grouping under `/abcd:agent:` is not taken, so no invocation is renamed and the three gates that locate a page by its verb name stand. The open question on the mechanism is closed by this entry. +- 2026-10-10: the product thinker confirmed the press release. They took a rewritten opening paragraph that states the hiding, the host's answer to a hidden name typed in full, and the same list in `abcd --help` (answer: "Take it"). They kept the quote word for word, asking whether Iris was the right persona; the persona registry picks the name from the role, and asked whose voice the quote should carry they chose the product thinker (answer: "Iris, product thinker"). +- 2026-10-10: the product thinker walked the acceptance criteria. They accepted the three a person sees (the menu listing only people's commands, the host's answer to a hidden name typed in full, the docs setting the library beside memory notes) and, as one list, the five technical ones carried from the draft, with the gate re-read for hiding. Asked where the merges and the retirement ship, they answered "In this intent", so the out-of-scope ban on renames and retirements narrows to any beyond these, and five criteria for the merges were added and accepted ("Accept all"). +- 2026-10-10: the product thinker confirmed Why This Matters, the Mechanism with its falsifier, and the four scope conditions, each as put to them ("Take it", "Take it", "Accept all"), and the grounds recorded on the intent ("Record it"). Settled without a further question by the ruling that only commands no person types leave the person's menu: `banlist`, typed by no person in the saved sessions and run by an agent at a person's word, stays agent-only. The impact is breaking, because the merged commands' old names go with no alias (adr-40). ## Audit Notes _Empty. Populated by intent-auditor when intent moves to shipped/._ + +## Grounds + +- pursued: a menu of only people's commands lets a person find theirs without reading agents'; shown wrong if people keep asking agents to run hidden commands for their own work. diff --git a/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md b/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md index 5b2e0e177..d0d95138b 100644 --- a/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md +++ b/.abcd/development/research/notes/2026-08-15-decomposition-calibration.md @@ -2364,3 +2364,34 @@ Verdict: SPLIT, confirmed as proposed ("Split as proposed"). The reversal of adr | the local dashboard's planned routes for acting | overlap | kept both ("Keep both routes"); itd-2610040740122709 and itd-2610040740135705 stand | Verdict: SPLIT. The facilitator offered rewriting the existing draft, a new intent beside it, or superseding it; the product thinker chose "New intent beside it", so the proposed routing (a rewrite) did not survive the confirmation. + +## 2026-10-09: agents keep memory notes with /abcd:memory (product thinker, routing confirmed) + +| part | type | home | +|---|---|---| +| an agent adds, lists, removes and promotes memory notes, recalled by the rules loader | capability | intent itd-2610091918433290 (draft); builds on itd-3, beside itd-39 | +| what may enter a note without the person's yes, and how a note is promoted | trust rule | adr-2610091918443997 (proposed) | +| where notes are stored (memory.json beside rules.json, or inside rules.json) | design choice | the intent's Open Questions, with the facilitator's lean | + +Verdict: SPLIT, as proposed ("yes, file it as A"). The storage file was raised by the product thinker and is carried as an open question. + +## 2026-10-10: a general rewriter for abcd-managed repositories (product thinker, routing confirmed) + +| part | type | home | +|---|---|---| +| an agent hands text with a reader and limits to the rewriter and gets back text that fits, judged by abcd's counters | capability | intent itd-2610100627454580 (draft); grows the question drafter | +| the question gate refuses on the mode though the chip names the addressee | fix | iss-2610100626211810 | +| a refusal lists the rows overrun as a part to fix | fix | iss-2610100626327722 | +| a record's path can pass the Windows limit | fix | iss-2610100626320367 | +| which model is the default | research | the lab already planned in iss-2610090816296964 | + +Verdict: SPLIT. The proposal entered as one agent for every writing task; the review routed the counts to code and the register work to the drafter, and the product thinker confirmed the order ("C first, then A"). + +## 2026-10-10: a model-weighted sub-agent budget (product thinker, routing confirmed) + +| part | type | home | +|---|---|---| +| a run's sub-agent budget, eight of the middle class by default, each class double or half the next, set in the repository's config | capability | intent itd-2610100704270254 (draft); builds on itd-2609201925079472 | +| vendor-neutral class names with each vendor's models mapped onto them | design choice | the same intent, with the routing table's tiers as the neighbour | + +Verdict: FILE-AS-IS, confirmed ("File as proposed"). The product thinker's rough exchange rule did not survive: "Double per class" replaced "times 2 minus 1" once the facilitator showed the latter's inverse gives 4.5, not 3; the scope narrowed from the machine to each abcd run. diff --git a/.abcd/development/research/notes/2026-10-09-command-sets-for-people-and-agents.md b/.abcd/development/research/notes/2026-10-09-command-sets-for-people-and-agents.md new file mode 100644 index 000000000..fede839c2 --- /dev/null +++ b/.abcd/development/research/notes/2026-10-09-command-sets-for-people-and-agents.md @@ -0,0 +1,529 @@ +# How well-designed developer tools divide, name and size their commands + +Research note. Date: 2026-10-09. Written for the verb audit (iss-2610090831317531) behind itd-2610090831227812. + +Scope: how mature CLIs and agent plugin systems split person-facing commands +from machine-facing ones, how many commands they show, how they name them, +and whether one source feeds both surfaces. Primary sources only: official +docs, specifications, design guides, upstream source files, and the real help +output of installed tools. + +**Method and limits.** Web pages were read with WebFetch, which summarises +through a small model. Where its summary disagreed with the source, the +source won, and the disagreement is recorded below as falsified. Three sources +were downloaded raw so they could be quoted exactly: the clig.dev Markdown, the +Primer CLI foundations `.mdx`, and the `root.go` / `alpha.go` / `command-list.txt` +files from gh, kubectl and git. Help-output counts come from the tools +installed on this machine. The captures are kept next to this note +(`git-help.txt`, `git-help-a.txt`, `gh-help.txt`, `kubectl-help.txt`, +`docker-help.txt`, `docker-help-hidelegacy.txt`, `go-help.txt`, +`npm-help.txt`). Versions: git 2.52.0, gh 2.100.0 (2026-09-03), kubectl client +v1.34.1, Docker 28.5.1, go1.27.1, npm 11.17.0. Counts depend on version and +on which plugins are installed. For example, no docker CLI plugins (buildx, +compose) appear in this docker help. + +Status key: **V** verified against the primary source; **F** falsified (a +secondary or summarised claim the source contradicts); **U** unverifiable +within budget. + +--- + +## Q1. Separating a person's commands from machine-facing ones + +### Finding 1.1: git splits commands by stability as well as by audience (V) + +git sorts commands into "porcelain", for people, and "plumbing", for scripts +and alternative front ends. It also gives plumbing a stronger stability +promise: + +> "The interface (input, output, set of options and the semantics) to these +> low-level commands are meant to be a lot more stable than Porcelain level +> commands, because these commands are primarily for scripted use. The +> interface to Porcelain commands on the other hand are subject to change in +> order to improve the end user experience." + +Source: https://git-scm.com/docs/git + +### Finding 1.2: git's help is tiered, and all tiers come from one classification file (V) + +There are three tiers: + +- Bare `git` / `git --help` shows 23 "common" commands in 5 task-shaped + groups: "start a working area", "work on the current change", "examine the + history and state", "grow, mark and tweak your common history", + "collaborate". +- `git help -a` lists every command under 11 headings: Main Porcelain, + Ancillary Manipulators/Interrogators, Interacting with Others, Low-level + Manipulators/Interrogators/Syncing/Internal Helpers, two interface-guide + headings, and External commands. +- `git help -g` lists the concept guides. + +`command-list.txt` drives all of these. Its header says the list "is used to +list commands in various places". Categories include `mainporcelain`, +`plumbingmanipulators` and others. `mainporcelain` entries can also carry an +`init`, `worktree`, `info`, `history` or `remote` tag, which places them in a +group of the common list. A `complete` attribute feeds shell completion. + +Sources: local `git --help` and `git help -a` (git 2.52.0); +https://raw.githubusercontent.com/git/git/master/command-list.txt + +### Finding 1.3: kubectl uses ordered task groups, hides by filtering, and parks alpha features under a separate root (V) + +**Groups.** The help shows 7 named groups in task order: "Basic Commands +(Beginner)", "Basic Commands (Intermediate)", "Deploy", "Cluster Management", +"Troubleshooting and Debugging", "Advanced", "Settings". It then shows +"Subcommands provided by plugins" and "Other Commands". + +**Hiding.** Hiding is done by filtering. `filters := []string{"options"}` +drops `options` from the list, although the help footer still points at +`kubectl options`. `alpha` is filtered out when it has no subcommands. + +**Alpha.** `alpha` is "an alternate root command for features in alpha", and +its long text reads: "These commands correspond to alpha features that are not +enabled in Kubernetes clusters by default." Typed with no alpha features +present, it prints "No alpha commands are available in this version of +kubectl". The local client printed exactly that. + +**Scripting.** The machine contract is a set of conventions, not separate +commands: "Request one of the machine-oriented output forms, such as +`-o name`, `-o json` …", "Fully-qualify the version", "Don't rely on context, +preferences, or other implicit states." + +Sources: https://raw.githubusercontent.com/kubernetes/kubectl/master/pkg/cmd/cmd.go; +https://raw.githubusercontent.com/kubernetes/kubectl/master/pkg/cmd/alpha.go; +https://kubernetes.io/docs/reference/kubectl/conventions/; local `kubectl --help`. + +### Finding 1.4: gh uses cobra groups, hidden stubs, help topics, and one raw-API escape hatch (V) + +**Groups.** `root.go` declares groups with `AddGroup`: "Core commands", +"GitHub Actions commands", "Extension commands", plus an "Alias commands" +group added when aliases exist. Ungrouped commands print under "ADDITIONAL +COMMANDS". + +**Hidden commands.** + +> "Official extension stubs: hidden commands that suggest installing +> GitHub-owned extensions when invoked." + +**Help topics.** Help topics (`environment`, `exit-codes`, `formatting`, +`reference` …) are registered as commands and listed under HELP TOPICS. + +**Machine surface.** `api` ("Make an authenticated GitHub API request") is the +raw machine-facing surface, and the help topic `formatting` covers JSON +output. + +**Design guide.** GitHub's CLI design guide (Primer) has a "Scriptability" +section: + +> "Create flags for anything interactive … Consider what should be different +> for terminal vs machine output". + +It lists what changes in machine output: "No color or styling … Tabs between +columns … No truncation … Exact date format … No header". + +Sources: https://raw.githubusercontent.com/cli/cli/trunk/pkg/cmd/root/root.go; +https://raw.githubusercontent.com/primer/design/main/content/native/cli/foundations.mdx +(the rendered page at primer.style/native/cli/foundations now redirects to a +404); local `gh --help`. + +### Finding 1.5: docker groups commands and offers an opt-in to hide its legacy verbs (V) + +Help groups: "Common Commands" (12), "Management Commands" (11), "Swarm +Commands" (6) and a plain "Commands" group (28) of legacy top-level verbs. The +docs say: + +> "When set, Docker hides "legacy" top-level commands (such as `docker rm`, +> and `docker pull`) in `docker help` output, and only `Management commands` +> per object-type (e.g., `docker container`) are printed. This may become the +> default in a future release." + +Locally, setting `DOCKER_HIDE_LEGACY_COMMANDS=1` removed the 28-command group, +leaving 29 listed. The docs also say experimental CLI features have been +enabled by default since Docker 20.10. + +Sources: https://docs.docker.com/reference/cli/docker/; local `docker --help` +with and without the variable. + +### Finding 1.6: clig.dev puts people first, and machines get flags, not a second command set (V) + +Quotes: + +- "Human-readable output is paramount. Humans come first, machines second." +- "Have machine-readable output where it does not impact usability." +- `--json` and `--plain` flags. +- "Changing output for humans is usually OK … Encourage your users to use + `--plain` or `--json` in scripts to keep output stable." + +The guide has no rule about hidden commands, no command-count rule, and no +mention of AI agents. A grep of the source for "hidden", "undocumented", +"agent" and "LLM" finds nothing relevant; the only "agent" hit is the tool +name yubikey-agent. + +Source: https://clig.dev/ (raw: +https://raw.githubusercontent.com/cli-guidelines/cli-guidelines/main/content/_index.md) + +### Finding 1.7: cobra provides the hiding and grouping mechanics (V) + +Field comments in `command.go`: + +- `Hidden`: "defines, if this command is hidden and should NOT show up in the + list of available commands" +- `Deprecated`: "should print this string when used" +- `GroupID`: "The group id under which this subcommand is grouped in the + 'help' output of its parent" +- `type Group struct { ID, Title }` + +`IsAvailableCommand()` returns false when a command is hidden or deprecated, +so such a command drops out of help (and, by the same check, out of +completion). Groups are declared with `AddGroup()` and appear "in the order +defined". + +Sources: https://raw.githubusercontent.com/spf13/cobra/main/command.go; +https://raw.githubusercontent.com/spf13/cobra/main/site/content/user_guide.md + +### Finding 1.8: How these tools show the split in help (V, synthesis of 1.2 to 1.7) + +| Technique | Tools | +|---|---| +| Short curated list by default, full list behind a flag | git (`git help -a`), npm (4 usage lines, then "All commands" with 71 names, and `npm -l` for full usage) | +| Named groups in task order | kubectl, gh, docker, git | +| Hidden-but-callable commands | gh extension stubs, kubectl `options` / empty `alpha`, cobra `Hidden` | +| Opt-in to hide legacy verbs | docker `DOCKER_HIDE_LEGACY_COMMANDS` | +| Help topics as pseudo-commands | gh HELP TOPICS (8), go "Additional help topics" (20), git guides (`-g`) | +| Separate root for unstable features | kubectl `alpha` | + +None of the five ships a second binary for machines. The machine contract is +expressed in one of three ways: + +- stable plumbing commands (git); +- output flags (`-o json`, `--json`, `--plain`); +- a raw API command (`gh api`). + +### Finding 1.9: Falsified claims met along the way (F) + +- WebFetch's summary of git-scm.com/docs/git said there are 57 "Main + porcelain commands". **F.** Upstream `command-list.txt` has 46 + `mainporcelain` entries, and the local `git help -a` lists 45 under Main + Porcelain Commands. A second summary count of 48 is also **F**. +- WebFetch's summary of the docker reference page said the commands there + form "a flat, alphabetical list … no hierarchical grouping". This is true of + that web page only. The CLI's own help is grouped (1.5), so the two + surfaces differ. + +--- + +## Q2. How many top-level commands people are shown, and whether any guideline sets a number + +### Finding 2.1: Counts from real help output (V, local captures, versions above) + +| Tool | Shown by default | Full set reachable from help | +|---|---|---| +| git 2.52.0 | 23 common, in 5 groups | `git help -a`: 45 main porcelain; 173 entries across 11 headings, including plumbing, guides and external commands | +| gh 2.100.0 | 34 commands: core 12 + Actions 3 + alias 1 + additional 18; plus 8 help topics | same; extension stubs hidden | +| kubectl 1.34.1 | 42 commands in 8 groups (7 named + "Other") | `options`, and `alpha` when empty, are filtered out | +| docker 28.5.1 | 57: common 12 + management 11 + swarm 6 + legacy 28 | 29 with `DOCKER_HIDE_LEGACY_COMMANDS` | +| go 1.27.1 | 19 commands + 20 help topics | same | +| npm 11.17.0 | 4 usage examples on top | 71 commands in "All commands" | + +The default view ranges from about 20 to 57 commands. The two tools with the +largest sets either curate a short top list (git: 23 of 45+) or offer a way to +shrink the list (docker: 57 to 29). + +### Finding 2.2: No human-CLI guideline found sets a number (V for the sources read, U for the field as a whole) + +clig.dev gives ordering advice, not a count: "Display the most common flags +and commands at the start of the help text", and it cites git's grouped help +as its example. Primer's CLI foundations give no count either. Cobra's docs +give mechanics only. + +Sources: https://clig.dev/#help; Primer foundations (above); cobra user guide +(above). + +### Finding 2.3: The only numeric limit found is on the model side (V) + +**OpenAI.** + +> "Aim for fewer than 20 functions available at the start of a turn at any one +> time, though this is just a soft suggestion." + +> "Combine functions that are always called in sequence." + +Source: https://developers.openai.com/api/docs/guides/function-calling +(redirected from platform.openai.com). + +**Anthropic.** No count: + +> "More tools don't always lead to better outcomes. A common error we've +> observed is tools that merely wrap existing software functionality or API +> endpoints." + +It recommends "a few thoughtful tools targeting specific high-impact +workflows", and namespacing by prefix or suffix. Source: +https://www.anthropic.com/engineering/writing-tools-for-agents (11 Sep 2025). + +**Claude Code** budgets by size, not count: + +- MCP tool search defers tool definitions. In `auto` mode they load upfront + only "while their definitions total less than 10% of the context window". +- Each MCP tool description and server instruction is truncated at 2,048 + characters by default. +- Each skill's `description` plus `when_to_use` is truncated at 1,536 + characters "in the skill listing to reduce context usage". + +Sources: https://code.claude.com/docs/en/mcp; https://code.claude.com/docs/en/skills + +Whether there is a total budget for the whole skill listing (as opposed to the +per-skill limit): **U**. The fetched part of the skills page does not state +one. + +--- + +## Q3. How agent and assistant plugin systems expose commands + +### Finding 3.1: Claude Code skills and commands have two independent switches, one per surface (V) + +Custom commands are merged into skills: + +> "A file at `.claude/commands/deploy.md` and a skill at +> `.claude/skills/deploy/SKILL.md` both create `/deploy` and work the same +> way." + +The invocation matrix: + +| Frontmatter | You can invoke | Claude can invoke | Context | +|---|---|---|---| +| default | Yes | Yes | description always in context | +| `disable-model-invocation: true` | Yes | Not on its own | description NOT in context | +| `user-invocable: false` | No | Yes | description always in context | + +On `user-invocable: false`: "Claude Code hides it from the `/` menu and +doesn't run it when you type `/name`. Use for background knowledge users +shouldn't invoke directly." Also: "With `user-invocable: false`, you can't +invoke the skill, but Claude still can. To keep Claude from invoking it +through the Skill tool, set `disable-model-invocation: true`." + +Permission rules `Skill(name)` and `Skill(name *)` allow or deny model +invocation. + +Plugin skills are namespaced `/plugin:skill`. "The bare `/fancy` also invokes +the skill unless another command already uses that name." + +So an author can hide a skill from the person while keeping it for the model +(`user-invocable: false`), or the reverse (`disable-model-invocation: true`). +The reverse also saves context, because the description is dropped. + +Source: https://code.claude.com/docs/en/skills + +### Finding 3.2: MCP assigns each primitive a controller (V) + +Specification overview table: + +| Primitive | Control | Description | Example | +|---|---|---|---| +| Prompts | User-controlled | Interactive templates invoked by user choice | Slash commands, menu options | +| Resources | Application-controlled | Contextual data attached and managed by the client | File contents, git history | +| Tools | Model-controlled | Functions exposed to the LLM to take actions | API POST requests, file writing | + +**Prompts.** "designed to be **user-controlled** … For example, as slash +commands". "the protocol itself does not mandate any specific user +interaction model." + +**Tools.** "designed to be **model-controlled** … there **SHOULD** always be a +human in the loop with the ability to deny tool invocations." + +**Tool names.** "SHOULD be between 1 and 128 characters", may use only +`A-Za-z0-9_-.`, and "SHOULD be unique within a server". A tool also has a +separate display `title`. + +**Annotations.** Clients "MUST consider tool annotations to be untrusted +unless they come from trusted servers." + +MCP has no per-item "hide from user" or "hide from model" flag. The choice of +primitive is the hiding mechanism. + +Sources: https://modelcontextprotocol.io/specification/2025-06-18/server; +https://modelcontextprotocol.io/specification/2025-11-25/server/prompts; +https://modelcontextprotocol.io/specification/2025-11-25/server/tools + +### Finding 3.3: Claude Code as an MCP host (V) + +- MCP prompts appear in the `/` menu as `/servername:promptname (MCP)` and + can also be run as `/mcp__servername__promptname`. +- Resources are `@`-mentioned. +- A server author can mark a tool `_meta["anthropic/alwaysLoad"]` (load + upfront) or `_meta["anthropic/requiresUserInteraction"]` (prompt the person + on every call). + +Source: https://code.claude.com/docs/en/mcp + +### Finding 3.4: VS Code hides from the palette, but the command stays public (V, with a caveat) + +Commands declared in `contributes.commands` appear in the Command Palette, and +"The Command Palette … prefixes commands with their `category`". +`menus.commandPalette` takes a `when` clause "to control if a command should +be visible in the Command Palette or not". Registered commands remain callable +via `vscode.commands.executeCommand`. + +Using `"when": "false"` to hide a command is not stated in the official API +pages read. A VS Code team member said in issue #45119: "Using `false` should +also work", and "every command is public and when-clauses are +recommendations only." + +Sources: https://code.visualstudio.com/api/references/contribution-points; +https://code.visualstudio.com/api/extension-guides/command; +https://github.com/microsoft/vscode/issues/45119 + +### Finding 3.5: Gemini CLI has no visibility switch in its docs (V for what the page says) + +Custom commands are TOML files under `~/.gemini/commands/` or +`/.gemini/commands/`. Subdirectories namespace them with colons +(`git/commit.toml` becomes `/git:commit`), and `description` shows in +`/help`. The page names no way to hide a command from the person or the +model. + +Source: https://geminicli.com/docs/cli/custom-commands/ + +### Synthesis (V, across 3.1 to 3.5) + +Only Claude Code skills give two independent switches, one per audience. +Elsewhere: + +- MCP decides by which primitive the author picks (prompt for the person, + tool for the model). +- VS Code hides from the palette but keeps everything callable. +- cobra's `Hidden` hides from help but keeps everything callable. + +--- + +## Q4. Naming: verb versus noun-verb, and consistency rules + +### Finding 4.1: clig.dev rules (V) + +- "Use consistent names for multiple levels of subcommand … one is a noun and + one is a verb. For example, `docker container create`. Be consistent with + the verbs you use across different types of objects." +- "Either `noun verb` or `verb noun` ordering works, but `noun verb` seems to + be more common." +- "Don't have ambiguous or similarly-named commands … 'update' and 'upgrade' + is quite confusing." +- "Don't have a catch-all subcommand." +- "Don't allow arbitrary abbreviations of subcommands … aliases … should be + explicit and remain stable." + +Source: https://clig.dev/#subcommands and https://clig.dev/#future-proofing + +### Finding 4.2: gh is noun then verb (V) + +Primer: "**Command:** The object you want to interact with. **Subcommand:** +The action you want to take on that object". Examples: `gh issue view`, +`gh pr create`, `gh repo fork`. Guidance: "Use a flag for modifiers of +actions" and "Avoid making modifiers their own commands"; "Use unambiguous +language that can't be confused for something else"; "Use shorter phrases if +possible and appropriate". + +Source: Primer foundations `.mdx` (above). + +A web-search summary attributed "Prefer noun verb naming; avoid confusing +near-duplicates" to Primer. **F as worded.** The source gives the +object/action structure and the "unambiguous language" line, but contains no +such sentence. + +### Finding 4.3: kubectl is verb first, with the resource as argument (V) + +Top-level commands are verbs (`get`, `create`, `delete`, `apply`, `describe`), +and the resource follows as an argument (`kubectl get pods`), with the version +fully qualified in scripts. Source: local help; kubectl conventions page. + +### Finding 4.4: docker runs both forms side by side (V) + +Legacy verbs (`docker rm`) live alongside noun-verb management commands +(`docker container rm`), and the legacy set can be hidden (1.5). + +### Finding 4.5: cobra's own guidance is verb first (V) + +> "The pattern to follow is APPNAME VERB NOUN --ADJECTIVE or APPNAME COMMAND +> ARG --FLAG" + +This is the opposite order to gh's, which is built on cobra. + +Source: https://raw.githubusercontent.com/spf13/cobra/main/README.md + +### Finding 4.6: Naming on the model side (V) + +- Anthropic recommends namespacing tools by service or resource + (`asana_search`, `asana_projects_search`) and reports that prefix versus + suffix "has non-trivial effects on our tool-use evaluations". +- MCP constrains tool-name characters and length (3.2). +- OpenAI asks for "clear and detailed function names". + +--- + +## Q5. One list for both surfaces, kept in sync + +### Finding 5.1: Common within one tool, generated from its command tree (V) + +**git.** `command-list.txt` feeds `git help`, the git(1) "GIT COMMANDS" +section and bash completion (1.2). + +**cobra.** Cobra "can generate documentation based on subcommands, flags, +etc." (user guide). `IsAvailableCommand` is the one predicate that keeps +hidden and deprecated commands out of the listings (1.7). + +**gh.** The Makefile's `site-docs` target runs `go run ./cmd/gen-docs +--website --doc-path site/manual` to build the online manual from the command +tree. The doc generator skips `Hidden` commands unless they are annotated for +generation (`internal/docs/markdown.go`). The in-CLI `gh help reference` is +built from the same tree. A `root.go` comment: "doc generation makes use of +the Long text". + +**docker.** `docker/cli-docs-tool` generates "Markdown, YAML, and man page +documentation from a Cobra command tree" for Docker's CLIs. + +Sources: https://raw.githubusercontent.com/cli/cli/trunk/Makefile; +https://raw.githubusercontent.com/cli/cli/trunk/internal/docs/markdown.go; +https://github.com/docker/cli-docs-tool + +### Finding 5.2: In editors and agents, one declaration feeds palette, menus and model (V) + +- **VS Code.** A command is declared once in `contributes.commands`; + "Presentation of contributed commands depends on the containing menu" + (palette, context menus, keybindings), and visibility is set per menu with + `when` clauses. +- **Claude Code.** One `SKILL.md` feeds both the `/` menu and the model's + skill listing, and two frontmatter fields set its visibility on each. +- **MCP.** A host may surface prompts as slash commands from the same + `prompts/list`, and `listChanged` notifications keep that list in sync. + +### Finding 5.3: CLI help and an in-app palette from one source (U) + +No primary source was found, within budget, for a product that generates both +its terminal `--help` and a GUI or agent command palette from one registry. +The examples above each sync one product's own surfaces: help, docs, man pages +and completion in a CLI; palette and menus in an editor; menu and model in an +agent host. Whether a shared registry feeds the CLI and an agent plugin at the +same time is unverifiable here. + +--- + +## Implications for a tool exposing one command set to people and to agents + +These are inferences from the findings, not findings. + +- The mature pattern is one command tree with tiered visibility: a curated + default list, the full list behind a flag, and hidden or alpha commands + that stay callable. Splitting into two products is not the pattern. +- Machine stability comes from stable output flags (`--json`, `-o json`, + `--plain`), and in git also from a stability promise on plumbing. A + separate machine verb set is used only where the semantics really differ + (git plumbing, `gh api`). +- Human help keeps to roughly 20 to 40 commands by default, by curating + (git), grouping (kubectl, gh) or opting out of legacy commands (docker). + The agent side is budgeted in tokens and characters (Claude Code) or + softly by count (OpenAI, under 20). The two limits are different in kind. +- Per-audience visibility exists natively only in Claude Code skill + frontmatter. MCP gets the same effect through the primitive the author + picks. +- Naming: choose one order, noun-verb (gh, docker management) or verb-first + (kubectl, cobra's README), and keep the verbs consistent across nouns. No + near-synonyms, no catch-all default subcommand, no implicit prefix + abbreviations. diff --git a/.abcd/development/specs/open/spc-2610100613109045-a-person-who-types-abcd-sees-only-the-commands-people-use.md b/.abcd/development/specs/open/spc-2610100613109045-a-person-who-types-abcd-sees-only-the-commands-people-use.md new file mode 100644 index 000000000..a9a99c267 --- /dev/null +++ b/.abcd/development/specs/open/spc-2610100613109045-a-person-who-types-abcd-sees-only-the-commands-people-use.md @@ -0,0 +1,21 @@ +--- +id: spc-2610100613109045 +slug: a-person-who-types-abcd-sees-only-the-commands-people-use +intent: itd-2610090831227812 +origin: researcher-authored +production_mode: hand-written +--- +# a-person-who-types-abcd-sees-only-the-commands-people-use + +## Summary + +_Draft: describe what spc-2610100613109045 delivers for itd-2610090831227812 — scope, approach, and how it satisfies the intent's Acceptance Criteria. This spec is the design record the fidelity review audits against._ + +## Footprint + +- packages: +- tests: + +## Steps + +_No steps listed: the spec is built as one step. To split it, list the steps in order as `1. `, each with `- packages:` and `- tests:` indented beneath it; `- landed: <pull request or commit>` marks a step that has landed._ diff --git a/.abcd/work/issues/open/iss-2610091903077581-abcd-report-lets-an-agent-in-an-abcd-managed-repository-file.md b/.abcd/work/issues/open/iss-2610091903077581-abcd-report-lets-an-agent-in-an-abcd-managed-repository-file.md new file mode 100644 index 000000000..da486b378 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610091903077581-abcd-report-lets-an-agent-in-an-abcd-managed-repository-file.md @@ -0,0 +1,16 @@ +--- +schema_version: 1 +id: "iss-2610091903077581" +slug: "abcd-report-lets-an-agent-in-an-abcd-managed-repository-file" +severity: "minor" +category: "ux" +source: "user-observation" +found_during: "2026-10-09 verb-split interview" +origin: researcher-authored +production_mode: hand-written +found_at: "commands/report.md" +remedy: "Have the report page and verb require the person's explicit yes before a report is written from a managed repository (a question through the host's question tool showing the report's title and text, or a --confirmed flag the agent may pass only after that yes), refuse otherwise, and test that a report without the confirmation writes nothing." +refines: [iss-2610031236155833] +--- + +abcd report lets an agent in an abcd-managed repository file a defect report or proposal about abcd into the abcd inbox without asking anyone: commands/report.md says nothing about permission. The product thinker ruled on 2026-10-09 that report stays an agent's command but must ask the person's permission first when it runs in an abcd-managed repository, since the report carries that project's words to another project's inbox. diff --git a/.abcd/work/issues/open/iss-2610092011131598-testsurpriserefusesanunresolvedoccasion-failed-in-the-merge.md b/.abcd/work/issues/open/iss-2610092011131598-testsurpriserefusesanunresolvedoccasion-failed-in-the-merge.md new file mode 100644 index 000000000..61691b006 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610092011131598-testsurpriserefusesanunresolvedoccasion-failed-in-the-merge.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610092011131598" +slug: "testsurpriserefusesanunresolvedoccasion-failed-in-the-merge" +severity: "minor" +category: "bug" +source: "agent-observation" +found_during: "2026-10-09 merge queue run for PR #880" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/core/capture/surprise_test.go" +remedy: "Have the id allocator draw again (a bounded number of times) when a freshly minted id collides with one already in the ledger within the same process, keeping the refusal only for a collision with a committed record a peer made; test it with a forced collision on the first draw, watched fail first." +--- + +TestSurpriseRefusesAnUnresolvedOccasion failed in the merge queue on 2026-10-09 (PR #880, macOS race lane, run 37980092117) with 'duplicate issue id: srp-2610092000060599 already exists in this ledger; the mint collided with a record already committed': the test mints three surprise records in quick succession, two drew the same timestamp-plus-four-digit id within one second, and the allocator refuses a collision instead of drawing again, so a records-only pull request was dropped from the queue. diff --git a/.abcd/work/issues/open/iss-2610100626211810-an-abcd-question-is-refused-with-the-mode-reads-managed.md b/.abcd/work/issues/open/iss-2610100626211810-an-abcd-question-is-refused-with-the-mode-reads-managed.md new file mode 100644 index 000000000..d79b55059 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100626211810-an-abcd-question-is-refused-with-the-mode-reads-managed.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610100626211810" +slug: "an-abcd-question-is-refused-with-the-mode-reads-managed" +severity: "minor" +category: "ux" +source: "user-observation" +found_during: "the verb-split sign-off interview, 2026-10-10" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/surface/cli/guard_question.go" +remedy: "Derive the mode from the chip when the question gate admits a question (Product to product-thinker, Tech to facilitator, Setup ruled in the fix) and set it there, so a chipped question is never refused on the mode; reset to managed when the answer returns, from a PostToolUse hook on the question tool, rather than on the next prompt; drop the set-before and set-back steps from the asking rules and the mode page, keeping abcd mode for a stop that is not a question." +--- + +An abcd question is refused with 'the mode reads managed' whenever the agent has not run abcd mode just before it, although the question's own chip ('Tech Q3', 'Product Q2') already names whom it is for. The mode is reset two ways: the asking rules tell the agent to set it back to managed after every answer, and the prompt hook resets it on the next prompt the session receives while a question is marked open, which in a turn of several questions can be a peer session's message or a message the person sends mid-turn (inferred from a refusal on 2026-10-10 after a peer message arrived; not yet reproduced). So an interview of several questions is refused intermittently, and the person sees the hook's error line each time (iss-2610070637562567 measured that every refusal reaches them framed as an error). The product thinker chose on 2026-10-10 to fix this in code first, before the general rewriter. diff --git a/.abcd/work/issues/open/iss-2610100626320367-a-record-s-file-name-has-no-cap-tied-to-the-length-of-its.md b/.abcd/work/issues/open/iss-2610100626320367-a-record-s-file-name-has-no-cap-tied-to-the-length-of-its.md new file mode 100644 index 000000000..b60a56bdc --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100626320367-a-record-s-file-name-has-no-cap-tied-to-the-length-of-its.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610100626320367" +slug: "a-record-s-file-name-has-no-cap-tied-to-the-length-of-its" +severity: "minor" +category: "bug" +source: "user-observation" +found_during: "the review of the rewriter proposal, 2026-10-10" +origin: researcher-authored +production_mode: hand-written +found_at: "the slug derivation the record-minting verbs share" +remedy: "Cut every minted slug at 40 characters (capture, intent, spec and decide alike), and rename every existing record file whose slug is longer, 2,289 of 2,760 at the ruling, updating every link to them in one change landed when no open branch touches the records; ids do not change. A test holds each record family's longest path within its budget. Ruled by the product thinker on 2026-10-10 ('Tighter cut for all', then 'Rename all 2,289' once told the scale). The general rewriter (itd-2610100627454580) can later shorten a title so the cut reads well; the cap stays the guarantee." +--- + +A record's file name has no cap tied to the length of its full path, so a record checked out on Windows can pass the 260-character path limit, which the product thinker reports records already do. The longest tracked path is 149 characters inside the repository; the checkout's own location comes on top, and a worktree in the machine store adds its prefix, the 40-character root commit and the worktree's name. Git for Windows will not check such a file out unless core.longpaths is set (itd-2610070544145422 is the Windows install draft). diff --git a/.abcd/work/issues/open/iss-2610100626327722-when-an-abcd-question-is-refused-for-another-fault-the.md b/.abcd/work/issues/open/iss-2610100626327722-when-an-abcd-question-is-refused-for-another-fault-the.md new file mode 100644 index 000000000..53b5240be --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100626327722-when-an-abcd-question-is-refused-for-another-fault-the.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610100626327722" +slug: "when-an-abcd-question-is-refused-for-another-fault-the" +severity: "minor" +category: "ux" +source: "user-observation" +found_during: "the verb-split sign-off interview, 2026-10-10" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/surface/cli/guard_question.go" +remedy: "In a refusal for another fault, list a rows overrun after the refusing parts, on a line saying it does not refuse on its own and the question would be shown, with a test that a mode or layout refusal carrying a rows overrun says so." +--- + +When an abcd question is refused for another fault, the refusal lists the question's rows overrun among the parts to fix ('fix each and ask again'), although the rows limit alone never refuses (the question gate's rowsOnly, iss-2610070637562567). The person and the agent read it as a cause of the refusal, and the agent cuts a question the gate would have shown; seen twice in one interview on 2026-10-10. diff --git a/.abcd/work/issues/open/iss-2610100649466578-brief-template-a-standard-product-principles-section-beneath.md b/.abcd/work/issues/open/iss-2610100649466578-brief-template-a-standard-product-principles-section-beneath.md new file mode 100644 index 000000000..a81d92635 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649466578-brief-template-a-standard-product-principles-section-beneath.md @@ -0,0 +1,45 @@ +--- +schema_version: 1 +id: "iss-2610100649466578" +slug: "brief-template-a-standard-product-principles-section-beneath" +severity: "minor" +category: "future-work-seed" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071653351920 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "brief template (01-product), disembark coverage pass, the vision refinement step" +remedy: "none (filed automatically)" +--- + +Brief template: a standard Product principles section beneath the press release, filled by the vision step + +## What the lab found + +A post-brief vision interview in a managed repository produced the owner's vision in their own words and six ranked trade-offs ("easy first minutes, even over every choice up front"; "playing together, even over the studio, when the build order has to choose"; and four more). Those trade-offs then settled 7 of 9 deduced brief changes with no further question to the owner. + +Where they should live took three tries: + +1. **A new vision page.** The owner asked what made it different from the press release; only the ranked trade-offs were new, and the page broke abcd's brief layout. +2. **The framing page.** It kept the layout, but buried the trade-offs on the sixth page, after context, mental model, scope and personas. +3. **Beneath the press release, as Product principles** (the owner's proposal). This is the working-backwards pattern, where internal material follows the release on the same page. It reads in order: the story, then what wins when goals clash. + +## The naming point + +abcd already uses "principles" for its engineering conventions (development record, principles folder: prefer SOTA, script-first, and so on). A brief section called just "Principles" would give one word two meanings in a managed repository that vendors abcd's principles. "Product principles" separates them: product principles decide what the product favours; abcd's principles decide how it is built. + +## Proposed + +- The template's press release page gains a Product principles section beneath the release: ranked statements in the X-even-over-Y form, each with a persona example, and a line saying which were ranked against which. +- The vision step fills it; the owner's vision words go into the release as their quote. +- The coverage pass reads the section as product-thinker-owned. + +Remedy the reporter proposes: Add a Product principles section to the brief template's press release page, directly beneath the release: ranked X-even-over-Y statements, each with a persona example; name it product principles so it never collides with abcd's engineering principles; have the coverage pass treat it as product-thinker-owned. + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071653351920, a enhancement against abcd v0.13.1, surface brief template (01-product), disembark coverage pass, the vision refinement step. + +Evidence: + +- rpt-2610071653351920 (the report, kept in the inbox) +- lab-261002171217-c372ff6 +- rpt-2610071611295053 diff --git a/.abcd/work/issues/open/iss-2610100649471088-abcd-lint-docs-json-prints-two-json-documents-on-a-blocker.md b/.abcd/work/issues/open/iss-2610100649471088-abcd-lint-docs-json-prints-two-json-documents-on-a-blocker.md new file mode 100644 index 000000000..0418f1c17 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649471088-abcd-lint-docs-json-prints-two-json-documents-on-a-blocker.md @@ -0,0 +1,31 @@ +--- +schema_version: 1 +id: "iss-2610100649471088" +slug: "abcd-lint-docs-json-prints-two-json-documents-on-a-blocker" +severity: "minor" +category: "inconsistency" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071636212229 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "abcd lint docs --json, abcd lint --json" +remedy: "none (filed automatically)" +--- + +abcd lint docs --json prints two JSON documents on a blocker, and names its finding fields differently from abcd lint + +A lab prototype that runs abcd's checks on every save parsed both outputs and hit two shape differences: + +1. **Two documents.** With a blocker finding, abcd lint docs --json writes the result object (findings, blockers, checks, documents) and then a second object (abcd: error, lint docs: 1 blocker finding(s), exit_code 1) to stdout. A standard JSON parse of stdout fails with "Extra data"; a caller has to decode only the first document. +2. **Field casing.** abcd lint --json findings use file, ruleId, severity, message, fix; abcd lint docs --json findings use File, Line, RuleID, Severity, Message. A caller filtering by file on one shape silently matches nothing on the other. + +Also: with no findings, abcd lint docs --json writes "findings": null rather than an empty list. + +Remedy the reporter proposes: Print one JSON document per run (the refusal folded into the result object, or the result folded into the error object), and use one field spelling for findings across lint targets (file, line, ruleId, severity, message). + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071636212229, a defect against abcd v0.13.1, surface abcd lint docs --json, abcd lint --json. + +Evidence: + +- rpt-2610071636212229 (the report, kept in the inbox) +- rpt-2610071632391737 diff --git a/.abcd/work/issues/open/iss-2610100649479892-the-public-name-check-was-silently-disarmed-its-roots-still.md b/.abcd/work/issues/open/iss-2610100649479892-the-public-name-check-was-silently-disarmed-its-roots-still.md new file mode 100644 index 000000000..67ea62229 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649479892-the-public-name-check-was-silently-disarmed-its-roots-still.md @@ -0,0 +1,44 @@ +--- +schema_version: 1 +id: "iss-2610100649479892" +slug: "the-public-name-check-was-silently-disarmed-its-roots-still" +severity: "major" +category: "bug" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071636214174 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "abcd lint, abcd lint docs, docs-lint roots, ahoy conventions-file retire" +remedy: "none (filed automatically)" +--- + +The public name check was silently disarmed: its roots still named a retired CLAUDE.md, and bare abcd lint reported no findings + +## What happened + +In a managed repository, docs.target moved from both to agents_md during an upgrade install, and the owner removed CLAUDE.md, which then held only abcd's block (the install itself offers this as conventions.retire). The repository's .abcd/docs-lint.json still listed CLAUDE.md in roots. + +From then on: + +- **abcd lint docs refused,** exit 2: roots entry "CLAUDE.md" does not exist; a configured root that does not resolve silently disarms every per-file rule for that tree. +- **Bare abcd lint** (every target but outbound) reported "findings": [] and exit 0. The docs target's refusal did not appear, so every lint run looked clean. +- **ahoy and ahoy doctor** reported no gaps. + +The public banned-name list (third-party game titles) therefore checked nothing for hours, while several brief edits were made and reported "lint clean". Nothing slipped through in this case (after fixing roots: 91 checks over 32 documents, 0 findings), but only by luck. + +## Expected + +A target that refuses must make the aggregate run fail loudly (abcd's own loud-staging principle: a stage that no-ops must say so). And retiring CLAUDE.md, which abcd itself offers, should not leave a root that disarms the name check. + +## How to see it again + +In a managed repository whose docs-lint roots include CLAUDE.md, delete CLAUDE.md; run abcd lint --json (no findings, exit 0) and abcd lint docs --json (refusal, exit 2). + +Remedy the reporter proposes: Make bare abcd lint surface a target's refusal as an error finding and a non-zero exit; and when CLAUDE.md is retired (by ahoy or by hand, with docs.target moving to agents_md), drop it from the docs-lint roots, or have ahoy report the dangling root as a gap. + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071636214174, a defect against abcd v0.13.1, surface abcd lint, abcd lint docs, docs-lint roots, ahoy conventions-file retire. + +Evidence: + +- rpt-2610071636214174 (the report, kept in the inbox) +- rpt-2610071224565746 diff --git a/.abcd/work/issues/open/iss-2610100649481907-a-review-verb-for-proposed-brief-edits-deduced-changes.md b/.abcd/work/issues/open/iss-2610100649481907-a-review-verb-for-proposed-brief-edits-deduced-changes.md new file mode 100644 index 000000000..c744343f8 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649481907-a-review-verb-for-proposed-brief-edits-deduced-changes.md @@ -0,0 +1,48 @@ +--- +schema_version: 1 +id: "iss-2610100649481907" +slug: "a-review-verb-for-proposed-brief-edits-deduced-changes" +severity: "minor" +category: "future-work-seed" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071611295053 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "brief, abcd intent consistency, GRILL asking rules, a new review verb" +remedy: "none (filed automatically)" +related_intents: [itd-61] +--- + +A review verb for proposed brief edits: deduced changes recorded, asked or settled, then applied + +## What is missing + +After a vision-refinement interview in a managed repository, the facilitator deduced 15 brief edits from the owner's answers (for example: an out-of-scope row removed because the owner put 3D in scope; a renderer choice reopened). abcd has no record for a proposed brief edit and no verb to review one: + +- The brief's truth rule admits only decided content, so the drafts cannot sit in the brief. +- The planning interview reviews one intent, not brief edits; its Terminal form needs a routed runner. +- intent consistency finds contradictions after the fact; it does not carry a proposed change to a decision. + +So the drafts lived in a hand-kept lab file, and the owner asked how abcd would best let them review it: in the session as an interview, or in their own editor. + +## What the verb would do + +1. **Record each proposed edit:** the brief section, its current text, the proposed text, and the decision or answer it rests on. +2. **Sort them:** an edit that only restates a decision the owner already made is settled by the record and gets a decision line, not a question (the GRILL rule on one defensible answer). An edit with two defensible readings is owed a question. +3. **Ask the owed ones** under the asking rules, as tabs. +4. **Open prose items in the person's editor** (VISUAL or EDITOR), because a press release or framing the product thinker owns is theirs to write, not to approve; then check the returned text against the recorded tenets and flag conflicts. +5. **Apply accepted edits** to the brief with a dated trail, and run the consistency pass on what changed. + +## Seen in practice + +Of 9 decision-like edits, 7 were settled by tenets the owner had just confirmed, leaving 2 questions; the one prose item (the press release) went to the owner's editor. The split cut the review from three screens of tabs to two questions plus one editing pass. + +Remedy the reporter proposes: Add a review verb (for example abcd review brief) that keeps proposed brief edits as records: section, current text, proposed text, the decision it rests on; it splits them into settled-by-record and owed-a-question, asks only the latter under the asking rules, opens prose items in the person's editor, and applies accepted edits with a dated trail. + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071611295053, a enhancement against abcd v0.13.1, surface brief, abcd intent consistency, GRILL asking rules, a new review verb. + +Evidence: + +- rpt-2610071611295053 (the report, kept in the inbox) +- lab-261002171217-c372ff6 +- rpt-2610071608595198 diff --git a/.abcd/work/issues/open/iss-2610100649485756-let-the-product-thinker-edit-the-brief-and-their-parts-of.md b/.abcd/work/issues/open/iss-2610100649485756-let-the-product-thinker-edit-the-brief-and-their-parts-of.md new file mode 100644 index 000000000..510d661ee --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649485756-let-the-product-thinker-edit-the-brief-and-their-parts-of.md @@ -0,0 +1,47 @@ +--- +schema_version: 1 +id: "iss-2610100649485756" +slug: "let-the-product-thinker-edit-the-brief-and-their-parts-of" +severity: "minor" +category: "future-work-seed" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071632391737 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "brief, intent records, a new edit verb, the review verb proposed in rpt-2610071611295053" +remedy: "none (filed automatically)" +related_intents: [itd-2610040740122709] +--- + +Let the product thinker edit the brief and their parts of intents in a local web editor before anything is committed + +## The need + +A product thinker owns the brief and the user-facing parts of intents, but today editing them means a terminal editor or the agent writing for them. In an agent session neither works well: the session's shell has no terminal, so a VISUAL or EDITOR set to a terminal editor (here: emacs -nw) cannot open, and no editor server was running. The owner asked for an option to edit the brief, and their parts of intents, before anything is committed to GitHub. + +## Design (discussed with the owner) + +1. **Editor resolution:** an abcd setting in user-level config, then VISUAL, then EDITOR, then the platform default. At a terminal, block like git commit; in an agent session, use a non-blocking form the person configured, or print the exact command for their own terminal; never fail silently. +2. **A self-served local web editor:** abcd starts a loopback-only server (random port, single-use token carried in the URL fragment, Host header check against DNS rebinding, lives for one round) and serves a verified copy of the editor release. The owner's domain (static hosting, no accounts, no data) only distributes releases. Same origin avoids CORS, the local-network-access prompt and mixed-content limits, and the domain cannot act on private files at run time. +3. **Record-aware editing:** + - **Brief:** fully editable. + - **Intents:** press release, why it matters, acceptance criteria, mechanism, scope condition text (identity markers hidden and preserved) and open questions/decisions editable. + - **Through verbs only:** grounds through a form calling the verb; plan, hold and target as confirmed buttons (plan is the sign-off act). + - **Read-only:** ids, links, status fields and audit notes. +4. **Checks:** deterministic checks on every save (name guard, record shape, links), judgement checks on done (conflicts with the vision page's tenets; the brief-to-intent consistency pass, flagging an edit that contradicts a filed, planned or shipped intent as a design decision owed). +5. **Before commit:** the session's changes per file, each kept or discarded; discard restores the session-start text, never HEAD, so earlier uncommitted work survives. Commit is a separate act, on a branch, under the person's own identity; push only when asked. + +## Evidence coming + +The lab is building a prototype of 2 to 5 (loopback, self-served, token, record-aware intent form, lint on save, per-file keep/discard, a timed event log) to test with the product thinker in this repository. Its session logs will be attached to a follow-up report. + +Remedy the reporter proposes: Add an edit verb that serves a record-aware editor from a local loopback server (release code distributed from the owner's domain and checksum-verified, like the binary), runs abcd's checks on every save and the judgement checks on done, shows the session's changes per file for keep or discard, and leaves the commit as a separate act under the person's own identity. + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071632391737, a enhancement against abcd v0.13.1, surface brief, intent records, a new edit verb, the review verb proposed in rpt-2610071611295053. + +Evidence: + +- rpt-2610071632391737 (the report, kept in the inbox) +- lab-261002171217-c372ff6 +- rpt-2610071611295053 +- rpt-2610071608595198 diff --git a/.abcd/work/issues/open/iss-2610100649495706-a-verb-to-run-state-of-the-art-research-and-keep-it-as-a.md b/.abcd/work/issues/open/iss-2610100649495706-a-verb-to-run-state-of-the-art-research-and-keep-it-as-a.md new file mode 100644 index 000000000..c7b256d47 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100649495706-a-verb-to-run-state-of-the-art-research-and-keep-it-as-a.md @@ -0,0 +1,47 @@ +--- +schema_version: 1 +id: "iss-2610100649495706" +slug: "a-verb-to-run-state-of-the-art-research-and-keep-it-as-a" +severity: "minor" +category: "future-work-seed" +source: "managed-repo" +found_during: "abcd inbox report rpt-2610071608595198 from a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0)" +origin: researcher-authored +production_mode: hand-written +found_at: "abcd ideate, sota-researcher agent, abcd ingest and consult, research notes" +remedy: "none (filed automatically)" +--- + +A verb to run state-of-the-art research and keep it as a research note in the record + +## What is missing + +The owner of a managed repository asked whether abcd has a verb to conduct state-of-the-art research and store it as a research note, or whether that goes through an intent. abcd has neither: + +- **ideate** runs primary-source research inside its admission gauntlet, but only to admit or reject one idea; its record is a verdict, not a survey of a field. +- **The sota-researcher agent** does the research and returns ranked recommendations with sources, but it is read-only, so nothing keeps its output. Saving it is the session's hand work. +- **ingest and consult** keep sources and record which sources fed which decisions; neither writes the note. +- **An intent is the wrong home:** research is input to decisions, not a capability anyone uses. + +In practice the research note is written by hand (a lab baseline note was produced this way, through the agent). Nothing checks its shape, dates it, or lets an ADR or intent cite it as a record. + +## What the verb would do + +1. Take a question (and optionally the record it serves: an ADR, an intent, an open question). +2. The host runs the sota-researcher on it, outside the loop of whoever asked. +3. The verb validates the returned note against a declared shape: the question, ranked findings, each with an evidence tier and primary sources, and what would change the conclusion. +4. It writes the note dated under the development record's research notes, stamps an id, and records the link both ways, so a decision citing it is checkable. + +## Why now + +The owner's vision-refinement work in that repository keeps hitting questions where a state-of-the-art check is the presumptive input (abcd's own "prefer SOTA" principle), and each one currently ends as an unvalidated file or not at all. + +Remedy the reporter proposes: Add a research verb: the host runs the sota-researcher on a question, the verb validates the returned note (question, ranked findings, evidence tiers, primary sources) and writes it dated under the development record's research notes, with a link field decisions and intents can cite. + +Reported by a managed repository (root commit c372ff6b8fc387ffdf1acf7c51bffe469b70b2e0) through the abcd inbox as rpt-2610071608595198, a enhancement against abcd v0.13.1, surface abcd ideate, sota-researcher agent, abcd ingest and consult, research notes. + +Evidence: + +- rpt-2610071608595198 (the report, kept in the inbox) +- lab-261002171217-c372ff6 +- rpt-2610071222173136 diff --git a/.abcd/work/issues/open/iss-2610100846469473-testrebuildinginplaceisbyteidentical-internal-core-site.md b/.abcd/work/issues/open/iss-2610100846469473-testrebuildinginplaceisbyteidentical-internal-core-site.md new file mode 100644 index 000000000..1150cfa0b --- /dev/null +++ b/.abcd/work/issues/open/iss-2610100846469473-testrebuildinginplaceisbyteidentical-internal-core-site.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610100846469473" +slug: "testrebuildinginplaceisbyteidentical-internal-core-site" +severity: "minor" +category: "bug" +source: "user-observation" +found_during: "the records branch preflight after v0.13.4, 2026-10-10" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/core/site" +remedy: "Find the WaitDelay the root lookup's git call sets and make a timeout under load distinguishable from a real failure to name the root: retry the lookup once, or report the timeout as its own error rather than as 'git cannot name its root'; reproduce with the test under a CPU-bound load before and after." +--- + +TestRebuildingInPlaceIsByteIdentical (internal/core/site) failed in make preflight on 2026-10-10 with 'sits inside a checkout but git cannot name its root (exec: WaitDelay expired before I/O complete (stderr: ""))' while the machine's five-minute load average was about 48 on 16 cores, from concurrent sessions' preflights; the same test passed three times in a row once the load fell. The site build's root lookup turns a git subprocess that misses its WaitDelay into a refusal, so a loaded machine fails a records-only branch's preflight on code it did not touch.