diff --git a/tasks/backlog/13-agents-md-as-the-canonical-brief.md b/tasks/backlog/13-agents-md-as-the-canonical-brief.md new file mode 100644 index 0000000..339374a --- /dev/null +++ b/tasks/backlog/13-agents-md-as-the-canonical-brief.md @@ -0,0 +1,98 @@ +# 13 — AGENTS.md as the canonical brief; CLAUDE.md becomes a pointer + +**Status:** Backlog +**Priority:** Medium — correctness gap for the opencode adapter today, naming debt everywhere else +**Type:** Refactor + +The workflow brief lives in `CLAUDE.md` — one vendor's filename for a +document every vendor's agents need. `AGENTS.md` is the cross-tool +convention (opencode, Codex, Gemini CLI and others read it natively), +and bench just shipped a second adapter whose agents don't read +`CLAUDE.md` at all: an opencode work agent today launches with no +project brief. Rename the content to `AGENTS.md`; keep `CLAUDE.md` as a +one-line pointer for compatibility. + +## Context + +Everywhere the name is load-bearing (grepped, current as of writing): + +- `update.sh:40` — the core-owned top-level file list copies `CLAUDE.md` + by name; the rename must ship there or updates resurrect the old file. +- `manager/core/prompts/work.md:7,27`, `review.md:17`, + `review-pr.md:17`, `act-pr.md:17` — every prompt says "read CLAUDE.md + at the repo root"; these instructions go to *all* vendors' agents, so + they must name the vendor-neutral file. +- `CLAUDE.md:8,28,262`, `README.md:38`, `board.py:9`, `taskfiles.py:3` — + self-references and doc pointers. +- `manager/local/CLAUDE.md` — the project-notes half; same rename logic + applies (`local/AGENTS.md`), and root AGENTS.md's "read it too" line + follows. +- Claude Code reads `CLAUDE.md` natively and supports `@path` imports; + recent versions also read `AGENTS.md` directly — verify the installed + CLI's behaviour at build time, but keep the pointer file regardless: + it costs one line and covers older CLIs and muscle memory. +**Affected areas:** root docs, `update.sh`, all four core prompts, +`manager/local/`, two module docstrings. No board logic reads the brief +— core never parses it, it only tells agents to. + +## What to build + +- `git mv CLAUDE.md AGENTS.md`, then a new `CLAUDE.md` containing only + the `@AGENTS.md` import (plus one comment line saying why it exists). +- Same split in `manager/local/`: content to `local/AGENTS.md`, pointer + `local/CLAUDE.md` kept. +- Update every reference found above — prompts say "read AGENTS.md"; + `update.sh`'s file list carries both names (AGENTS.md as content, + CLAUDE.md as pointer, both core-owned). +- README's install section gains one line: the brief is `AGENTS.md`, + `CLAUDE.md` is a compatibility pointer — so adopters with their own + root AGENTS.md know what lands in `.task-manager/`. +- Check the opencode adapter's behaviour: opencode reads AGENTS.md from + the working directory's tree natively, so a worktree containing it is + covered with no adapter change — confirm, and note it in + `adapters/README.md`'s wire/run guidance. + +**Out of scope** — the tempting neighbours this rename does not touch: + +- Changing what the brief *says* (cards 03/07 territory) — this task + moves the document, verbatim. +- Per-vendor brief variants — one AGENTS.md serves everyone, that being + the entire point. + +## Acceptance + +- [ ] Repo root: `AGENTS.md` holds the full workflow doc; `CLAUDE.md` + is a pointer (import + comment) and nothing else. Same pair in + `manager/local/`. +- [ ] `grep -rn "CLAUDE.md"` across core, prompts, scripts and README + returns only the pointer files themselves and deliberate + compatibility mentions. +- [ ] A Claude Code session in this repo still loads the full brief + (via native AGENTS.md support or the import — verified live). +- [ ] An opencode launch's working tree presents the brief under the + name opencode reads natively. +- [ ] Edge case — `update.sh` round-trip: given an installed project on + the old layout, when core updates to this version, then AGENTS.md + arrives, the pointer CLAUDE.md replaces the old full copy, and no + resurrected vendor-named brief shadows the real one. + +## Open questions + +- None. + +## Notes + +Prompted by the owner (2026-07-30): "AGENTS.md is the more standard +approach that works across coding agents." The rename is also a small +test of bench's own three-layer law: the brief was the last place where +a vendor's name was baked into core-owned, cross-vendor machinery. + +**Risks** + +- Older Claude Code CLIs without native AGENTS.md support depend + entirely on the pointer file's `@AGENTS.md` import line — if a future + edit trims the "redundant" pointer, those sessions silently lose the + whole brief. The pointer must be treated as load-bearing, not cruft. +- Host projects may have their own root AGENTS.md; bench's lives inside + `.task-manager/`, so no collision — but verify nested-file pickup for + both vendors rather than assuming it. diff --git a/tasks/review/08-focus-report-well-expands.md b/tasks/done/08-focus-report-well-expands.md similarity index 99% rename from tasks/review/08-focus-report-well-expands.md rename to tasks/done/08-focus-report-well-expands.md index 84295b5..50478e5 100644 --- a/tasks/review/08-focus-report-well-expands.md +++ b/tasks/done/08-focus-report-well-expands.md @@ -1,6 +1,6 @@ # 08 — Let the agent's report open from the Focus view -**Status:** Review +**Status:** Done **PR:** https://github.com/12vectors/bench/pull/4 **Priority:** Medium — the report is the payoff of a whole agent run, and Focus dead-ends exactly there **Type:** Bug diff --git a/tasks/backlog/03-focus-checks-come-from-the-project.md b/tasks/in-progress/03-focus-checks-come-from-the-project.md similarity index 99% rename from tasks/backlog/03-focus-checks-come-from-the-project.md rename to tasks/in-progress/03-focus-checks-come-from-the-project.md index 299aaeb..a6671a3 100644 --- a/tasks/backlog/03-focus-checks-come-from-the-project.md +++ b/tasks/in-progress/03-focus-checks-come-from-the-project.md @@ -1,6 +1,6 @@ # 03 — Focus checks come from the project, not from core -**Status:** Backlog +**Status:** In Progress **Priority:** Medium — cosmetic on bench's own board, but every adopting project sees a stranger's definition of done **Type:** Feature diff --git a/tasks/to-do/09-fit-the-board-on-small-laptops.md b/tasks/in-progress/09-fit-the-board-on-small-laptops.md similarity index 99% rename from tasks/to-do/09-fit-the-board-on-small-laptops.md rename to tasks/in-progress/09-fit-the-board-on-small-laptops.md index 7942aed..2c8d596 100644 --- a/tasks/to-do/09-fit-the-board-on-small-laptops.md +++ b/tasks/in-progress/09-fit-the-board-on-small-laptops.md @@ -1,6 +1,6 @@ # 09 — Fit all five columns on small laptop screens -**Status:** To Do +**Status:** In Progress **Priority:** Medium — daily-driver hardware; the Done column is cut off on a 13" MacBook **Type:** Bug diff --git a/tasks/backlog/12-choose-agent-models-per-intent.md b/tasks/in-progress/12-choose-agent-models-per-intent.md similarity index 99% rename from tasks/backlog/12-choose-agent-models-per-intent.md rename to tasks/in-progress/12-choose-agent-models-per-intent.md index 1aeb09f..5243c54 100644 --- a/tasks/backlog/12-choose-agent-models-per-intent.md +++ b/tasks/in-progress/12-choose-agent-models-per-intent.md @@ -1,6 +1,6 @@ # 12 — Let the board choose agent models, per launch intent -**Status:** Backlog +**Status:** In Progress **Priority:** Medium — works today by inheritance, but invisibly and uncontrollably **Type:** Feature diff --git a/tasks/backlog/01-install-ships-pristine-board.md b/tasks/review/01-install-ships-pristine-board.md similarity index 52% rename from tasks/backlog/01-install-ships-pristine-board.md rename to tasks/review/01-install-ships-pristine-board.md index af7a3d7..ed9c597 100644 --- a/tasks/backlog/01-install-ships-pristine-board.md +++ b/tasks/review/01-install-ships-pristine-board.md @@ -1,6 +1,7 @@ # 01 — Ship a pristine board on install, not bench's own cards -**Status:** Backlog +**Status:** Review +**PR:** https://github.com/12vectors/bench/pull/5 **Priority:** High — every install made after we start dogfooding inherits our cards **Type:** Bug @@ -66,3 +67,28 @@ root `tasks/` — the decision that made this bug real. The alternative (self-installing a `.task-manager/` inside bench) was rejected: it doubles the manager code, runs the board from a stale vendored copy, and would nest an installation inside every future clone. + + +--- + +## Work report — 2026-07-30 07:10 (Cleo) + +The work is complete — committed on this branch and fully tested. Closing report: + +--- + +The fix is implemented, committed (`44537ae`), and verified: the full test suite (54 tests, including 5 new ones) passes, and a fresh vendored install now boots with an empty board while bench's own repo keeps its task history untouched. + +**What changed** + +- `install.py` gained first-boot detection that runs before delegating to the adapter's `wire`. It fires only when the install is vendored (project root differs from the manager's root) **and** `manager/local/` has never been populated (no `.env`, no `state/`). In that state it removes everything in the five stage directories, `tasks/archive/`, `plans/` and `reference/`, keeps `task-template.md` and every `.gitkeep`, and prints each removal (`removed `, or `would remove ` under `--dry-run`). After a real (non-dry-run) clean it creates `manager/local/state/`, so the guard is permanently false from then on — even if the adapter wire fails, which matters because `start.sh` serves the board to hosts without `.claude/` and their cards must never be eaten on a later run. +- `README.md` notes under "Install into a repo" that the first `start.sh` clears the distribution's own cards. +- `tests/test_install_first_boot.py` exercises `install.py` end-to-end as a subprocess against scratch host layouts: first run cleans and prints; second run removes nothing and a host-created card survives; `--dry-run` lists without removing and without stamping; a pre-existing `local/.env` disarms the guard; a self-hosted repo is never cleaned. + +**One decision to know about, beyond the task's letter:** the task defined first boot purely by the absence of `local/.env` and `local/state/`, but that alone would also match a fresh development clone of bench itself and delete its git-tracked cards. I added a second condition — cleaning only happens when the install is vendored (project root ≠ manager root, the same resolution `config._repo_root` uses) — so self-hosted checkouts are structurally exempt. This is what makes acceptance point three hold even for an unwired bench clone. + +**For the reviewer** + +- Start with `first_boot_leftovers` and `first_boot_clean` in `install.py` — the guard logic and the stamp ordering are the whole risk surface. +- Run `python3 -m unittest discover -s tests` to reproduce the green run. +- One acceptance step I could not run literally: the sandbox denies executing `install.py` directly in this checkout, so "bench itself is untouched" is proven by `test_self_hosted_repo_is_never_cleaned` (which builds a git-initialised self-hosted layout) rather than by a live run here. The scratch-host tests cover the clone → first-run → second-run sequence the other acceptance points describe. diff --git a/tasks/backlog/04-activity-log-resize-grip-does-nothing.md b/tasks/to-do/04-activity-log-resize-grip-does-nothing.md similarity index 99% rename from tasks/backlog/04-activity-log-resize-grip-does-nothing.md rename to tasks/to-do/04-activity-log-resize-grip-does-nothing.md index aace7c4..1db5a77 100644 --- a/tasks/backlog/04-activity-log-resize-grip-does-nothing.md +++ b/tasks/to-do/04-activity-log-resize-grip-does-nothing.md @@ -1,6 +1,6 @@ # 04 — Make the activity log's resize grip actually resize -**Status:** Backlog +**Status:** To Do **Priority:** Medium — a visible, advertised control ("drag to resize") that silently does nothing **Type:** Bug diff --git a/tasks/backlog/10-review-launches-die-on-multiedit-deny-rule.md b/tasks/to-do/10-review-launches-die-on-multiedit-deny-rule.md similarity index 99% rename from tasks/backlog/10-review-launches-die-on-multiedit-deny-rule.md rename to tasks/to-do/10-review-launches-die-on-multiedit-deny-rule.md index 0b69e7d..a8ecc4e 100644 --- a/tasks/backlog/10-review-launches-die-on-multiedit-deny-rule.md +++ b/tasks/to-do/10-review-launches-die-on-multiedit-deny-rule.md @@ -1,6 +1,6 @@ # 10 — Review launches die at startup: MultiEdit deny rule names a tool that no longer exists -**Status:** Backlog +**Status:** To Do **Priority:** High — every ◔ review PR / ◔ still true? launch fails before the agent starts **Type:** Bug diff --git a/tasks/backlog/11-failed-agent-runs-must-be-visible.md b/tasks/to-do/11-failed-agent-runs-must-be-visible.md similarity index 99% rename from tasks/backlog/11-failed-agent-runs-must-be-visible.md rename to tasks/to-do/11-failed-agent-runs-must-be-visible.md index 57b3425..406ac79 100644 --- a/tasks/backlog/11-failed-agent-runs-must-be-visible.md +++ b/tasks/to-do/11-failed-agent-runs-must-be-visible.md @@ -1,6 +1,6 @@ # 11 — A failed agent run must leave a visible trace on the card -**Status:** Backlog +**Status:** To Do **Priority:** High — three agents died today and the board showed nothing a human would notice **Type:** Feature