From 9e5c42c25f1e9c3d6c662171770b775c8d07011b Mon Sep 17 00:00:00 2001 From: Keysat Date: Sun, 14 Jun 2026 10:36:36 -0500 Subject: [PATCH] Add capture/triage inbox loop; dogfood AGENTS.md/ROADMAP; document git-tracking standard Introduce the cross-project capture->triage->roadmap loop: /capture appends an idea or bug to INBOX.md from any repo (new-project ideas included), /triage drains a project's items into its AGENTS.md or ROADMAP.md. Give the standards repo its own AGENTS.md (+ CLAUDE.md symlink) and ROADMAP.md so it follows its own standard, and add a 'What git tracks' section to portability.md plus the canonical .gitignore block answering what is committed vs gitignored around .claude and symlinks. --- .gitignore | 10 +++ AGENTS.md | 96 ++++++++++++++++++++++ CLAUDE.md | 1 + INBOX.md | 33 ++++++++ README.md | 3 +- ROADMAP.md | 120 ++++++++++++++++++++++++++++ adapters/claude/commands/capture.md | 17 ++++ adapters/claude/commands/triage.md | 20 +++++ guides/capture.md | 56 +++++++++++++ guides/triage.md | 70 ++++++++++++++++ portability.md | 59 +++++++++++++- 11 files changed, 483 insertions(+), 2 deletions(-) create mode 100644 AGENTS.md create mode 120000 CLAUDE.md create mode 100644 INBOX.md create mode 100644 ROADMAP.md create mode 100644 adapters/claude/commands/capture.md create mode 100644 adapters/claude/commands/triage.md create mode 100644 guides/capture.md create mode 100644 guides/triage.md diff --git a/.gitignore b/.gitignore index e43b0f9..4a081f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,11 @@ +# Secrets & local env +.env +.env.* +!.env.example + +# Claude Code — commit shared config, ignore personal/local +.claude/settings.local.json +.claude/*.local.json + +# OS cruft .DS_Store diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9ad2ad7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,96 @@ +# Standards — AGENTS.md + +The home of my agent-operating standards **and** the live global fleet that serves them. +This repo is both the documentation of how any coding agent works in my repos and the +actual source of the global agents, commands, and `how-i-work.md` that every project +inherits. Edit here and every repo on this machine feels it. + +For a human-facing tour of the four standards documents, read `README.md` — this file is +the agent-facing orientation and does not restate it. + +> **Inbox check (this repo):** At session start, if `INBOX.md` has unchecked items tagged +> `(standards)`, surface them before proposing next steps; triage with `/triage`. + +## What this repo is the source of + +The global layer lives here and is wired into `~/.claude` by **directory symlinks**, so a +file added under `adapters/` is live immediately — no per-file linking: + +- `~/.claude/commands` → `adapters/claude/commands/` — global slash commands (`/retrofit`, + `/handoff`, `/full-eval`, `/capture`, `/triage`). +- `~/.claude/agents` → `adapters/claude/agents/` — global subagents (reviewer, evaluator, + security-auditor, doc-auditor, exerciser, researcher, janitor, portability-checker, + start9-spec-checker). +- `~/.claude/CLAUDE.md` → `how-i-work.md` — my universal preferences, loaded every session. + (Distinct from this repo's *root* `CLAUDE.md`, which → `AGENTS.md`: same filename, different + scopes — global preferences vs. this repo's orientation.) + +Because these are *global*, decisions here are never scoped to this repo alone. The test +for anything proposed ("should we adopt linters / hooks / CI?", "is this skill worth +building?") is **whether it's generally best-in-class across all the repos I build** — this +repo is just where that cross-repo standard is authored and stored. + +## Layout + +- `README.md` — human index of the four standards docs. +- `how-i-work.md` — universal preferences (served as `~/.claude/CLAUDE.md`). +- `portability.md` — the vendor-neutral / hot-swap protocol. +- `retrofit-playbook.md` — terminal runbook for moving a project's brain onto disk. +- `subagents-handbook.md` — designing and running delegated agents. +- `guides/` — **neutral substance**: the self-contained operating guide for each command + and agent, written as plain prose any vendor's harness could follow. +- `adapters/claude/{commands,agents}/` — **thin Claude wrappers**: frontmatter + a pointer + to the matching `guides/` file. Substance never lives in a wrapper. +- `INBOX.md` — cross-project capture buffer for untriaged ideas/bugs (see below). +- `ROADMAP.md` — longer-term backlog for this repo (future agents, commands, standards). + +## Conventions when editing + +- **Substance in `guides/`, machinery in `adapters/`.** To add or change what a + command/agent *does*, edit its `guides/.md`. The wrapper only carries frontmatter + and the "read your guide, then follow it exactly; if you can't read it, stop — don't + improvise" pointer. Match the existing wrappers exactly. +- **Portability first.** Knowledge lives in vendor-neutral files; vendor-named paths are + relative symlinks into them. Full protocol in `portability.md`; the `portability-checker` + agent verifies it. +- **Keep this file lean.** Whole-repo, every-session facts only. Subsystem detail goes in a + guide. Near-term status goes in `## Current state` below; longer-term backlog in + `ROADMAP.md`. +- Follow `how-i-work.md` for collaboration, git, and debugging defaults. + +## The capture → triage → roadmap loop + +A frictionless path from "random thought about some repo" to "on the right list," so ideas +stop scattering into phone notes: + +- **`/capture`** appends one structured line to `INBOX.md` from *any* repo (you need not be + in the target repo) and commits+pushes the standards repo so the note is durable. Capture + is deliberately dumb and uniform — no routing decision at capture time. +- **`/triage`**, run *inside* a project, drains that project's `INBOX.md` items and routes + each — `Current state`, the repo's `ROADMAP.md`, a guide, or discard — with your + approval, then clears them from the inbox. +- **Inbox is upstream of every repo's ROADMAP.** ROADMAP is triaged, owned backlog for one + repo; the inbox is the raw, cross-project buffer that feeds the ROADMAPs. + +**Inbox-check line (the portable surfacing mechanism).** Every project repo's `AGENTS.md` +should carry this so any vendor's agent surfaces pending items at session start: + +> **Inbox check:** At session start, if `~/Projects/standards/INBOX.md` exists, scan it for +> items tagged `(this-repo)` and surface them before proposing next steps; triage with +> `/triage`. + +## Current state + +- The capture→triage→roadmap loop is built and live: `AGENTS.md` (+ `CLAUDE.md` symlink), + `ROADMAP.md`, `INBOX.md`, and the `/capture` + `/triage` commands. The repo dogfoods its + own standard, including the active inbox-check line above. +- `/capture` also handles **new-project ideas** (`(new)` / `(new:name)`, type `project`); + these wait for the new-repo bootstrap and are never triaged into an existing repo. +- The git-tracking standard ("What git tracks") is now in `portability.md`, and this repo's + `.gitignore` follows it. +- Specced in `ROADMAP.md`, not built: `roundup` (next up), the `new-project` bootstrap, the + cross-repo quality-gate standard (linters/hooks/CI), and the optional SessionStart hook. +- The portable inbox-check line is still not in *other* repos' AGENTS.md nor the retrofit + playbook template — threading it (and the canonical `.gitignore`) into bootstrapping is a + ROADMAP item. +- Next: build `roundup`, then thread the standards into `retrofit-playbook.md`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/INBOX.md b/INBOX.md new file mode 100644 index 0000000..76751a2 --- /dev/null +++ b/INBOX.md @@ -0,0 +1,33 @@ +# Inbox — cross-project capture buffer + +Raw, untriaged ideas and bugs for **any** repo, captured from anywhere so they stop +scattering into phone notes. `/capture` appends here; `/triage`, run inside a project, +drains that project's items into its `AGENTS.md` (`## Current state`) or `ROADMAP.md`. This +buffer is upstream of every repo's ROADMAP — nothing here is owned or scheduled until +triaged. + +**Line format** — one item per line: + +``` +- [ ] (project) [type][Pn] note — optional context, YYYY-MM-DD +``` + +- `project` — the target repo's folder name (e.g. `relay`), or `standards` for this repo, + or `?` if unsure. For an idea that would be a **brand-new repo** (no folder exists yet), + use `new` — or `new:working-name` if you have a name in mind. +- `type` — `bug` | `feature` | `idea` | `skill` | `agent` | `project` | `chore` + (`project` = a potential new repo; handled by the new-repo bootstrap, not `/triage`). +- `Pn` — priority `P0` (drop-everything) … `P3` (someday). Default `P2` if unspecified. +- `[ ]` unchecked = untriaged; `/triage` removes items once they're routed. + +Example: + +``` +- [ ] (relay) [bug][P1] health-check probes the wrong port after the bind refactor — found while testing, 2026-06-14 +``` + +--- + +## Items + + diff --git a/README.md b/README.md index 199076d..6f57c94 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ My agent-operating standards: how context and knowledge are organized so any coding agent — Claude Code today, another tomorrow — is productive in my repos immediately, with everything it needs and nothing it doesn't. -This file is the index and the in-the-moment lookup. The depth lives in the four documents below; nothing here is restated there. +This file is the index and the in-the-moment lookup. The depth lives in the documents below; nothing here is restated there. (`AGENTS.md` is the agent-facing counterpart — loaded every session via the `CLAUDE.md` symlink — and orients an agent *working in* this repo rather than reading about the standards.) ## The documents @@ -11,6 +11,7 @@ This file is the index and the in-the-moment lookup. The depth lives in the four - **retrofit-playbook.md** — the one-time, terminal-by-terminal runbook for moving an existing project out of a single long chat onto disk. - **subagents-handbook.md** — designing and running delegated agents. - **guides/** — neutral substance (checklists, role knowledge). **adapters/** — vendor machinery (symlink targets for `~/.claude/commands` and `~/.claude/agents`). +- **INBOX.md** — cross-project capture buffer. `/capture` appends an idea or bug to it from any repo without acting on it; `/triage`, run inside a project, drains that project's items into its `AGENTS.md` Current state or `ROADMAP.md`. The inbox sits upstream of every repo's ROADMAP. ## Where does this instruction go? diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..94f4e73 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,120 @@ +# ROADMAP — Standards + +Longer-term backlog for the standards repo: future agents, commands, and cross-repo +standards to hash out and build later. Near-term status lives in `AGENTS.md` → +`## Current state`. Items here are parked, not committed — we iterate on them when we pick +one up. Newly captured cross-repo ideas land in `INBOX.md` first and graduate here on +triage. + +--- + +## 1. Cross-repo quality-gate standard (linters / pre-commit hooks / CI) + +**Why:** with agents writing the code, these stop being developer conveniences and become +the falsifiable rails that let an agent check its own work — write, get told exactly what's +wrong, iterate, verify. The *standard* is authored here; *application* is per-repo (in each +repo's AGENTS.md), because what's best-in-class differs by language/stack. + +**The principle to encode:** every code repo should give its agent a fast, deterministic, +agent-runnable feedback loop — the subset of checks that run without a human and can't be +skipped. Tier it: + +- **Linter/formatter** — per-stack (e.g. ruff/black, eslint/prettier, gofmt). Fast, runs on + every change; the agent fixes before moving on. +- **Pre-commit hook** — the unskippable gate: runs the linter + quick tests and blocks the + commit if they fail. This is the highest-ROI piece and the first to add. +- **CI on push** — the heavier rebuild + full test suite. Lower priority for solo repos on + Gitea (Gitea Actions exists); add when a repo has real collaborators or releases. + +**This repo's own first instance:** it's Markdown + symlinks, so its quality gate isn't a +code linter — it's a pre-commit hook that runs the **structural checks** this repo already +has an agent for: relative-symlink integrity (`AGENTS.md ← CLAUDE.md`, +`docs/guides/* ← .claude/rules/*`, the `adapters/` directory symlinks) and internal-link +validity. The `portability-checker` agent encodes the invariants; the hook makes the +deterministic subset unskippable. Build this as the worked example of the standard. Concrete +checks to start with: (a) the `type` enum is identical across `guides/capture.md`, +`INBOX.md`, and `AGENTS.md`; (b) `CLAUDE.md` is a relative symlink resolving to `AGENTS.md`; +(c) every `adapters/claude/{commands,agents}/*.md` wrapper has a matching `guides/.md` +substance file (no wrapper-without-guide drift). + +**Open questions:** one shared hook framework (pre-commit.com) vs. hand-rolled per repo; +how the standard gets *adopted* into a repo (a `/harden` command that installs the right +linter+hook for the detected stack?); whether to define a minimal "agentic-ops baseline" +checklist doc alongside the other four standards docs. + +## 2. `roundup` — cross-project status agent (the inverse of capture/triage) + +**Why:** a global "what should I do next / which project to focus on" view. Capture/triage +push items *down* into project repos; roundup reads back *up* across all of them. + +**Shape:** a command (`/roundup`, run from `~/Projects`) that fans out one read-only +subagent per repo to read that repo's `AGENTS.md` (`## Current state`) and `ROADMAP.md`, +plus reads the standards `INBOX.md` for not-yet-triaged items. It synthesizes **one +aggregated to-do list across all projects, grouped by priority**, including items that +haven't been pushed down to a repo yet. Mirror `full-eval`'s orchestrator pattern: fan out, +then synthesize into one report; the per-repo readers can be the generic `Explore` agent or +a small dedicated reader. + +**Division of labor (the user's explicit call):** the agent *reads and reports* — it +gathers and presents findings grouped by priority; it does **not** decide the best use of +time. Prioritizing across projects is a back-and-forth the user does on top of the report. +So the output is a clean, evidence-backed inventory, and the "what's actually worth doing +now" conversation happens after, in the main thread. + +**Open questions:** which folders count as "my projects" (scan `~/Projects`, skip non-repos +and the standards repo itself?); how to keep it cheap (cap readers, summarize hard); whether +roundup output is ephemeral or written to a `STATUS.md` in the standards repo for diffing +over time like `EVALUATION.md`. + +## 3. Deterministic inbox surfacing — SessionStart hook (optional upgrade over the portable line) + +**Why:** the portable mechanism (the inbox-check line in every repo's AGENTS.md) is +model-interpreted and therefore skippable. A Claude `SessionStart` hook that greps +`INBOX.md` for the current repo's tag and prints matching items is deterministic and +unskippable — the same quality-gate logic as item 1, applied to capture. + +**Tradeoff:** hooks are Claude-specific and per-repo, so they don't travel to other vendors. +Decision already made: keep the AGENTS.md line as the **belt-and-suspenders portable +default**, and offer the hook as an opt-in upgrade for repos where you want the guarantee. +Possible form: a snippet the quality-gate `/harden` flow (item 1) installs alongside the +linter hook. + +## 4. Thread the inbox-check line into bootstrapping + +**Why:** right now adding the portable inbox-check line to a repo is manual. It should be +automatic so every repo inherits it. + +- Add the line to the AGENTS.md template in `retrofit-playbook.md` (Step 1, prompt A) and + to the `/retrofit` guide's Phase 4. +- Thread the canonical `.gitignore` block (now in `portability.md` → "What git tracks") + into `retrofit-playbook.md` Step 0 and the new-repo bootstrap, so every repo's committed + `.gitignore` carries it rather than relying on a global excludesfile. +- Consider a one-time sweep command that adds it to every existing repo's AGENTS.md. +- Decide whether the canonical wording lives in `how-i-work.md` (so it's truly universal) + or stays a per-repo line. + +## 5. `new-project` — idea → scoped → scaffolded → Gitea repo + +**Why:** the inverse of `/retrofit`. Retrofit moves an *existing* project onto disk; this +takes a captured `(new)` inbox idea and turns it into a real, standards-compliant repo. It +closes the capture loop: `/capture (new) …` → bootstrap → a repo that already has AGENTS.md, +the CLAUDE.md symlink, ROADMAP.md, the canonical `.gitignore`, and the inbox-check line. + +**Shape:** a command (`/new-project`, run from `~/Projects`), main-thread and collaborative +— scoping is a conversation, not a delegated job. Phases: + +1. **Workshop the scope** — back-and-forth to sharpen objectives, non-goals, stack, and the + key early decisions. Pull the seed from the `(new)` inbox item if one exists. This is the + high-value step and stays interactive (like roundup, the reasoning is the user's). +2. **Seed prompt** — synthesize the workshop into a concrete project brief / initial build + prompt plus a scaffolding plan; get the user's sign-off. +3. **Scaffold** — create the new folder under `~/Projects`, write the initial AGENTS.md + (from the brief) + CLAUDE.md symlink, ROADMAP.md, README, the canonical `.gitignore`, + `.claude/` wiring, and the starting directory structure. Compliant from line one. +4. **Publish** — `git init` + initial commit, create the Gitea repo, add the remote, push + (reuse retrofit-playbook Part 4; if no Gitea API token is available, hand back the manual + "create empty repo, copy URL" step). Then remove the `(new)` item from the inbox. + +**Open questions:** Gitea repo creation — API token vs. manual UI step; how much scaffolding +is generic vs. stack-specific (does it call a `/harden` step from item 1 to install the +stack's linter+hook?); whether the workshop output also seeds the first `## Current state`. diff --git a/adapters/claude/commands/capture.md b/adapters/claude/commands/capture.md new file mode 100644 index 0000000..ebefd8d --- /dev/null +++ b/adapters/claude/commands/capture.md @@ -0,0 +1,17 @@ +--- +description: Log an idea or bug to the cross-project inbox (INBOX.md in the standards repo) from any repo, without acting on it +argument-hint: the idea or bug — optionally name the project, type, and priority +allowed-tools: Bash(git:*), Read, Edit, Write +--- + +Capture a quick note into the cross-project inbox. Do not act on it — just record it +durably and confirm. +What to capture (the note, optionally with project / type / priority): $ARGUMENTS + +Your complete guide — the fields to parse, the inbox line format, and the commit/push step +that makes the note durable — is at: + + ~/Projects/standards/guides/capture.md + +Read it in full first, then follow it exactly. If you cannot read that file, stop and +report precisely that — do not improvise the capture or drop the note. diff --git a/adapters/claude/commands/triage.md b/adapters/claude/commands/triage.md new file mode 100644 index 0000000..4cd0acf --- /dev/null +++ b/adapters/claude/commands/triage.md @@ -0,0 +1,20 @@ +--- +description: Drain this project's items from the cross-project inbox (INBOX.md) into its AGENTS.md Current state or ROADMAP.md, with your approval +argument-hint: [optional focus, e.g. "just the bugs"] +allowed-tools: Bash(git:*), Read, Edit, Write, Grep, Glob +--- + +Triage the cross-project inbox for the repository in the current working directory: route +this repo's captured items to where they belong, then clear them from the inbox. +Optional focus from me (may be empty): $ARGUMENTS + +Your complete guide — how to select this repo's items, the routing destinations, the +approval gate, and the two-repo commit — is at: + + ~/Projects/standards/guides/triage.md + +Read it in full first, then follow it exactly. If you cannot read that file, stop and +report precisely that — do not improvise the triage. + +Routing decisions are mine: propose a destination for each item and wait for my approval +before editing any project file or removing anything from the inbox. diff --git a/guides/capture.md b/guides/capture.md new file mode 100644 index 0000000..4ba6505 --- /dev/null +++ b/guides/capture.md @@ -0,0 +1,56 @@ +# Capture — append an idea or bug to the cross-project inbox + +The user has a thought about some project — a feature, an idea, a bug they just hit — and +wants it logged *now*, without acting on it and without stopping to decide where it +belongs. Your whole job is to record it durably and get out of the way. Capture is +deliberately dumb and uniform: no routing, no triage, no discussion of the merits. Routing +happens later, via `/triage`, inside the relevant project. + +The inbox is a single file: `~/Projects/standards/INBOX.md`. You append to it regardless of +which repo the user invoked you from. + +## Procedure + +1. **Parse the note** from the user's input (`$ARGUMENTS`). Extract or infer four fields — + keep it fast, ask only when a field is genuinely missing and can't be inferred: + - **project** — the target repo. If the user named one, use it. If not, infer from the + current working directory's folder name. If you truly can't tell, use `?` (triage will + sort it) rather than interrogating the user. If the idea is for a **brand-new repo that + doesn't exist yet** ("new project/app/idea for…"), use `new` — or `new:working-name` if + they gave a name — and set type `project`. These wait for the new-repo bootstrap flow + and are never triaged into an existing repo. + - **type** — one of `bug | feature | idea | skill | agent | project | chore` (`project` + = a potential new repo, used with a `new`/`new:name` project tag). Infer from wording + ("found a bug" → bug, "we should add" → feature, "what if" → idea). Default `idea`. + - **priority** — `P0`…`P3`. Use a priority only if the user signals one ("urgent", + "P1", "minor"). Default `P2`. + - **note** — the user's text, lightly cleaned up to stand on its own later. Preserve + their meaning; don't editorialize or expand. +2. **Append one line** to the `## Items` section of `~/Projects/standards/INBOX.md`, in the + exact format the file documents: + `- [ ] (project) [type][Pn] note — optional context, YYYY-MM-DD` + Use today's date. Don't reformat or reorder existing lines. +3. **Make it durable.** Commit and push *only the inbox line* so the note survives and is + visible from any session or machine — this is the point of the tool, so do it without + asking: + - `git -C ~/Projects/standards add INBOX.md` + - `git -C ~/Projects/standards commit -m "Capture: " -- INBOX.md` + (the `-- INBOX.md` pathspec commits only the inbox, even if other changes happen to be + staged in the standards repo — never sweep unrelated work into a capture commit). + - `git -C ~/Projects/standards push` (only if a remote is configured; if the push fails, + report it but don't treat the capture as lost — it's committed locally). + Do not touch or commit anything in the repo the user invoked you from. +4. **Confirm in one line** — echo back the exact line you wrote and where, e.g. + `Logged to inbox: (relay) [bug][P1] … — triage it next time you're in relay with /triage.` + Nothing more; the user is mid-thought on something else. + +## Rules + +- One invocation = one item, unless the user clearly lists several; then append one line + each. +- Never act on the captured item, open files in the target repo, or start discussing the + fix. Capture only. +- No secrets in the note — if the user's text contains a key/token/password, replace it + with a placeholder and say you did. +- If you cannot write to `~/Projects/standards/INBOX.md` (missing, unwritable), stop and + report precisely that — do not silently drop the note or stash it somewhere else. diff --git a/guides/triage.md b/guides/triage.md new file mode 100644 index 0000000..8f9559a --- /dev/null +++ b/guides/triage.md @@ -0,0 +1,70 @@ +# Triage — drain this project's inbox items into the right place + +You are running inside one project repo. Your job is to take the items in the cross-project +inbox that belong to *this* repo and route each one to where it actually lives — then clear +it from the inbox. This is the deliberate, with-context counterpart to `/capture`: capture +is dumb and uniform, triage is where the judgment happens. Routing decisions are the user's +call — propose, don't impose. + +The inbox is `~/Projects/standards/INBOX.md`. This repo is identified by its current working +directory's folder name (and `AGENTS.md`/`README.md` if you need to confirm the name). + +## Procedure + +1. **Gather.** Read `~/Projects/standards/INBOX.md`. Select the unchecked items whose + `(project)` tag matches this repo's folder name. Also surface any `(?)` items and ask the + user whether each belongs to this repo — don't assume. **Never select `(new)` or + `(new:…)` items** — those are proposed new repos, not work for this one; if any exist, + note them in your report as awaiting the new-repo bootstrap, but leave them in the inbox. + If there are no matching items, say so and stop. +2. **Orient.** Read this repo's `AGENTS.md` (especially `## Current state`) and `ROADMAP.md` + (if present) so your routing proposals fit what's already there and you can spot + duplicates of items already tracked. +3. **Propose a routing for each item.** Present them as a short list, each with a proposed + destination and a one-line reason. The destinations: + - **`## Current state` in AGENTS.md** — near-term, act-on-it-now items (high priority, + active work, a bug to fix this session). + - **`ROADMAP.md`** — longer-term backlog (features, ideas, deferred work). Create + `ROADMAP.md` if it doesn't exist and there's anything to put there. + - **A `docs/guides/.md`** (or this repo's equivalent guide location) — if the + item is durable subsystem guidance rather than a task. + - **Escalate to the standards repo** — if the item is really a cross-repo idea (a new + command/agent/standard), it belongs in the standards `ROADMAP.md` or stays in the + inbox tagged `(standards)`, not in this project. Flag these; don't force them into the + project. + - **Discard** — already done, duplicate, or no longer wanted. Say why. + Let the captured priority (`Pn`) inform the destination but use judgment — a `P1` bug + goes to Current state, a `P3` idea to ROADMAP. +4. **Get approval.** Wait for the user to confirm or adjust the routing. Do not edit any + file before they approve — these are their durable project files. +5. **Apply.** Make the approved edits to this repo's files (keep `## Current state` lean — + present tense, ~15 lines max per the close-out convention; if it overflows, push older + items to ROADMAP). Then remove the triaged items from `~/Projects/standards/INBOX.md` — delete the + lines outright (the git history is the record); leave untriaged and other-repo items + untouched. +6. **Commit.** Two repos changed — present the proposed commit message(s) for both and + **wait for the user to confirm before committing or pushing anything** (the same gate as + step 4): this project's AGENTS.md/ROADMAP changes, and the standards repo's INBOX.md + (`git -C ~/Projects/standards …`). Follow `how-i-work.md` for messages and the + no-AI-attribution rule. +7. **Report** what landed where, what was discarded, and any items escalated to the + standards repo that the user still needs to handle there. + +## The portable inbox-check line + +So pending items surface automatically at the *start* of a session (not only when the user +remembers to run `/triage`), every project repo's `AGENTS.md` should carry this line — it's +vendor-neutral, so any harness that reads AGENTS.md honors it: + +> **Inbox check:** At session start, if `~/Projects/standards/INBOX.md` exists, scan it for +> items tagged `(this-repo)` and surface them before proposing next steps; triage with +> `/triage`. + +If this repo's AGENTS.md lacks that line, offer to add it as part of the triage. + +## Rules + +- Never invent items or routings. If an item is ambiguous, ask. +- Never edit a project file before the user approves the routing. +- If you cannot read `~/Projects/standards/INBOX.md`, stop and report precisely that — do + not guess what was captured. diff --git a/portability.md b/portability.md index cf47a4c..33e090d 100644 --- a/portability.md +++ b/portability.md @@ -6,7 +6,10 @@ ``` ~/Projects/standards/ - how-i-work.md portability.md retrofit-playbook.md subagents-handbook.md + AGENTS.md ← CLAUDE.md (relative symlink) ← agent-facing orientation to this repo + README.md how-i-work.md portability.md retrofit-playbook.md subagents-handbook.md + ROADMAP.md ← this repo's backlog (future agents, commands, standards) + INBOX.md ← cross-project capture buffer (/capture → here, /triage drains it) guides/ ← neutral substance (vendor-agnostic): checklists, role knowledge adapters/ claude/ @@ -43,6 +46,60 @@ Corollaries: **Scope rule:** every artifact lives at the scope it describes — project-specific in that repo; universal in the standards repo. There, neutral substance goes in `guides/` and vendor machinery is quarantined under `adapters//` (so a second provider's wrappers never intermix with Claude's or with the shared guides). +## What git tracks + +Symlinks and `.claude/` raise a recurring question: what belongs in the repo, what stays +local, and how does the global `~/.claude` layer get backed up? One rule resolves all three +— **git tracks knowledge and the wiring that serves it; it ignores machine-local state and +secrets** — but it lands in three places. + +**1. Relative symlinks are committed and travel.** Git stores a symlink as its target path. +Because every vendor path in this standard is a *relative* symlink (`CLAUDE.md → AGENTS.md`, +`.claude/rules/x.md → ../../docs/guides/x.md`), it commits and clones correctly on any +machine. This is the concrete payoff of the relative-symlink mandate: an absolute symlink +would commit too, but break on every other clone. Never commit an absolute symlink. + +**2. Inside a project repo — commit shared, ignore local.** + +Committed (any agent or teammate needs them to work the repo correctly — corollary 1): +`AGENTS.md` and its `CLAUDE.md` symlink; `docs/guides/*.md` and their `.claude/rules/*.md` +symlinks; `ROADMAP.md`; `.claude/settings.json` (shared project settings and hooks — +deterministic behavior is part of the repo); `.claude/agents/*.md`, `.claude/commands/*.md`, +`.claude/skills/` (project-scoped wrappers). + +Gitignored (per-user, per-machine, or secret): `.claude/settings.local.json` and any +`*.local.*` (personal permissions/overrides); `.env` and secrets (corollary 5); OS cruft. + +Put these in the repo's **own committed `.gitignore`** — don't rely on a global +excludesfile, which a fresh clone or another machine won't have. Canonical block: + +``` +# Secrets & local env +.env +.env.* +!.env.example + +# Claude Code — commit shared config, ignore personal/local +.claude/settings.local.json +.claude/*.local.json + +# OS cruft +.DS_Store +``` + +**3. The global `~/.claude` layer is backed up *through the standards repo*, not on its +own.** `~/.claude` is not a git repo. Its durable, portable parts — `commands`, `agents`, +`CLAUDE.md` — are symlinks *into* this standards repo, so committing and pushing standards +backs them up. Everything else under `~/.claude` (the machine-local `settings.json`, +`projects/` session transcripts and auto-memory, history, todos, caches) is disposable +session state by design (corollary 4) and is neither committed nor backed up. What makes +this safe: promote anything durable out of auto-memory into a committed file (AGENTS.md or a +guide); audit with `/memory`. + +So the answer to "are we backing up all of `.claude`?" is **no, by design**: knowledge and +shared wiring are committed per-repo or symlinked into a backed-up repo; machine-local state +and secrets never are. + ## Swap protocol (between already-adopted tools) 1. Finish the task and run the close-out ritual; exit the session.