diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8b8dfd2..03de86e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,10 +9,10 @@ }, "plugins": [ { - "name": "workbench", + "name": "fathom", "source": "./", "description": "Two agent skills, scaffold and execute, that carry a tracker issue from requirements to an open code review, on GitHub or any other forge with an adapter. Works with Asana or Linear, runs on Claude Code and Kiro, tracks tasks in beads or a committed markdown checklist, and resumes from repository state.", - "version": "1.1.0", + "version": "2.0.0", "author": { "name": "crod951" }, diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 0cb8bdf..17a20fa 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { - "name": "workbench", - "version": "1.1.0", - "description": "Workbench provides the execute and scaffold skills for driving Asana or Linear tracker issues from requirements to an open code review, on GitHub or any other forge with an adapter. Agent-portable skills for Claude Code and Kiro with resumable, task-tracked implementation runs.", + "name": "fathom", + "version": "2.0.0", + "description": "Fathom provides the execute and scaffold skills for driving Asana or Linear tracker issues from requirements to an open code review, on GitHub or any other forge with an adapter. Agent-portable skills for Claude Code and Kiro with resumable, task-tracked implementation runs.", "author": { "name": "crod951", "email": "crod951@gmail.com" diff --git a/.skillspector-baseline.yaml b/.skillspector-baseline.yaml index 6e7bd8f..868116b 100644 --- a/.skillspector-baseline.yaml +++ b/.skillspector-baseline.yaml @@ -27,7 +27,7 @@ rules: adding that phrase to a skill, re-review whether the suppression still only hides benign uses. - # workbench-shared carries the contract files execute and scaffold read; + # fathom-shared carries the contract files execute and scaffold read; # its SKILL.md exists so directory-copying installers (npx skills) bring it # along. Scanning it flags documentation text, not executable skill behavior. diff --git a/README.md b/README.md index 4278bcc..8ecab6d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ All skills are scanned with [NVIDIA SkillSpector](https://github.com/NVIDIA/Skil ```text /plugin marketplace add crod951/skills -/plugin install workbench@crod951 +/plugin install fathom@crod951 ``` **Kiro, Codex, and other agents** - use [skills.sh](https://www.skills.sh) for an editable copy on any agent: @@ -20,27 +20,27 @@ All skills are scanned with [NVIDIA SkillSpector](https://github.com/NVIDIA/Skil npx skills@latest add crod951/skills ``` -When the installer asks which skills to take, take all of them; `workbench-shared` carries the contract files the other two read. +When the installer asks which skills to take, take all of them; `fathom-shared` carries the contract files the other two read. > Individual plugins may have additional prerequisites that run in your **terminal** (e.g., `brew install`). See each plugin's README for details. ## Available Plugins -### workbench (v1.1.0) +### fathom (v2.0.0) -Workbench provides two agent skills, execute and scaffold, that carry a tracker issue from requirements to an open code review, on GitHub or any other forge with an adapter. +Fathom provides two agent skills, execute and scaffold, that carry a tracker issue from requirements to an open code review, on GitHub or any other forge with an adapter. It works with Asana or Linear as your issue tracker, and both skills run unchanged on Claude Code and Kiro. #### Prerequisites - An Asana or Linear MCP plugin installed and authenticated - [Beads CLI](https://github.com/gastownhall/beads) installed (`bd` command available); optional, but recommended for the richest task memory -- A forge adapter for wherever your reviews live. Two ship built in: GitHub, which needs the [GitHub CLI](https://cli.github.com/) installed and authenticated (`gh` command available), and a generic-git fallback that pushes the branch and hands the review off to you. Write a `.workbench/forge.md` from the bundled template only for a forge workbench does not ship. +- A forge adapter for wherever your reviews live. Two ship built in: GitHub, which needs the [GitHub CLI](https://cli.github.com/) installed and authenticated (`gh` command available), and a generic-git fallback that pushes the branch and hands the review off to you. Write a `.fathom/forge.md` from the bundled template only for a forge Fathom does not ship. #### Install ```bash -/plugin install workbench@crod951 +/plugin install fathom@crod951 ``` #### Skills @@ -65,7 +65,7 @@ scaffold these requirements - **Task memory** - beads-backed when available, with a plain checklist file fallback - **Conventional Commits** - one commit per task, referencing the issue ref - **Tracker-only access** - tracker work only happens through the connected tracker MCP; when it is missing, the skill refuses and stops -- **Forge-portable** - reviews go through a five-operation forge contract; GitHub and a generic-git fallback ship built in, and any other forge is a `.workbench/forge.md` you write without forking +- **Forge-portable** - reviews go through a five-operation forge contract; GitHub and a generic-git fallback ship built in, and any other forge is a `.fathom/forge.md` you write without forking #### Tracker Status Lifecycle @@ -73,7 +73,7 @@ scaffold these requirements Todo → In Progress (execute starts) → In Review (review opened) → Done (review merged) ``` -See the [full guide](./docs/workbench.md) for setup, task memory, and the security boundary. +See the [full guide](./docs/fathom.md) for setup, task memory, and the security boundary. --- diff --git a/docs/workbench.md b/docs/fathom.md similarity index 71% rename from docs/workbench.md rename to docs/fathom.md index ee8b6a4..b79aa65 100644 --- a/docs/workbench.md +++ b/docs/fathom.md @@ -1,6 +1,6 @@ -# Workbench +# Fathom -Workbench is a pair of agent skills that carry a tracker issue from requirements to an open code review. +Fathom is a pair of agent skills that carry a tracker issue from requirements to an open code review. - **scaffold** turns requirements into a tracker issue plus linked sub-issues. - **execute** drives an existing issue through implementation to a code review, one task at a time. @@ -32,7 +32,7 @@ It works with **Asana** or **Linear**, and runs unchanged on **Claude Code** and ## What you get A run of the two skills back to back produces: a tracker issue with sub-issues, a feature branch, a plan document a reviewer can read before any code exists, one commit per unit of work, a code review whose body links the issue and lists what was verified, and the issue sitting in review. -On a forge without an adapter the last step is a handoff rather than an opened review: the branch is pushed and you get the base, title, and body to open it yourself — see [Forges](#forges) for the tiers. +On a forge without an adapter the last step is a handoff rather than an opened review: the branch is pushed and you get the base, title, and body to open it yourself - see [Forges](#forges) for the tiers. The design goal is that **nothing is remembered between invocations**. Every run reads state from your repository and your tracker, so an interrupted run resumes by being re-invoked, in either agent. @@ -41,7 +41,7 @@ Resuming on a *different* machine works for whatever was committed and pushed. The checklist backend travels with each task commit; beads keeps its database out of git by design and shares only its export, so a beads run commits that export alongside each task for the same reason. **Requirements:** an Asana or Linear MCP connected in your agent, and optionally the beads CLI (`bd`) for richer task memory. -On GitHub, the GitHub CLI (`gh`) authenticated. On another forge, an adapter you write — or nothing at all: the bundled generic-git fallback still pushes the branch and hands the review off to you. See [Forges](#forges). +On GitHub, the GitHub CLI (`gh`) authenticated. On another forge, an adapter you write - or nothing at all: the bundled generic-git fallback still pushes the branch and hands the review off to you. See [Forges](#forges). ## Install (30-second setup) @@ -59,11 +59,11 @@ Run these inside a Claude Code session: ```text /plugin marketplace add crod951/skills -/plugin install workbench@crod951 +/plugin install fathom@crod951 /reload-plugins ``` -Confirm both skills loaded by asking for the skill list; you should see `workbench:execute` and `workbench:scaffold`. +Confirm both skills loaded by asking for the skill list; you should see `fathom:execute` and `fathom:scaffold`. @@ -75,7 +75,7 @@ npx skills@latest add crod951/skills ``` Pick which coding agents to install onto - the installer auto-detects what you have. -**Take all three entries when it asks which skills you want: `workbench-shared` carries the contract files the other two read, and an install without it stops at the first step.** +**Take all three entries when it asks which skills you want: `fathom-shared` carries the contract files the other two read, and an install without it stops at the first step.** Kiro's default agent auto-loads everything under `~/.kiro/skills/`, so no further configuration is needed there. Other agents may need the skill added to their config after install; see that agent's page on [skills.sh](https://www.skills.sh). @@ -88,23 +88,23 @@ Other agents may need the skill added to their config after install; see that ag The same installer works on any agent - including Claude Code - and writes the skills as ordinary files you own and can edit. Nothing updates behind your back; pull the latest changes when you want them with `npx skills update`. -Installing fully by hand also works; keep `execute/`, `scaffold/`, and `workbench-shared/` as siblings at the destination's top level: +Installing fully by hand also works; keep `execute/`, `scaffold/`, and `fathom-shared/` as siblings at the destination's top level: ```bash # global install, available in every workspace cp -r skills/. ~/.kiro/skills/ # or symlink while iterating, so edits take effect immediately -ln -s "$PWD/skills/execute" ~/.kiro/skills/execute -ln -s "$PWD/skills/scaffold" ~/.kiro/skills/scaffold -ln -s "$PWD/skills/workbench-shared" ~/.kiro/skills/workbench-shared +ln -s "$PWD/skills/execute" ~/.kiro/skills/execute +ln -s "$PWD/skills/scaffold" ~/.kiro/skills/scaffold +ln -s "$PWD/skills/fathom-shared" ~/.kiro/skills/fathom-shared ``` ### 2. Run either skill once per repo -The first run asks the [setup questions](#setup-step-by-step) - tracker, destination, state mapping, base branch, approval mode - and commits the answers to `.workbench/config.md`, so teammates are never asked again. +The first run asks the [setup questions](#setup-step-by-step) - tracker, destination, state mapping, base branch, approval mode - and commits the answers to `.fathom/config.md`, so teammates are never asked again. ### 3. Bam - you're ready to go. @@ -131,7 +131,7 @@ gh auth login ``` Preflight verifies the forge on every run alongside the tracker MCP. -Unlike the tracker, an unverified forge does not stop the run — it selects a tier, and the run says which one it picked. See [Forges](#forges) for what each tier does and how to support a forge that is not GitHub. +Unlike the tracker, an unverified forge does not stop the run - it selects a tier, and the run says which one it picked. See [Forges](#forges) for what each tier does and how to support a forge that is not GitHub. ### 3. Optionally install beads @@ -145,7 +145,7 @@ bd version ### 4. Answer the first-run questions -The first time either skill runs in a repository it asks a short series of questions, one at a time, and writes the answers to `.workbench/config.md`. +The first time either skill runs in a repository it asks a short series of questions, one at a time, and writes the answers to `.fathom/config.md`. Because that file is committed, **teammates who clone the repo are never asked any of it**. | Question | Why it is asked | @@ -155,7 +155,7 @@ Because that file is committed, **teammates who clone the repo are never asked a | How do your states map? | Your real board sections or workflow states get mapped to three phases: in progress, in review, done. | | Which forge? | Where your reviews live. Seeded from your `origin` remote, then from CLIs on your `PATH`. See [Forges](#forges). | | How should the tracker learn a review merged? | Asana and Linear differ; skipped entirely when your forge has no CI hooks. See [How the tracker learns a review merged](#how-the-tracker-learns-a-review-merged). | -| Which base branch? | Feature branches start from it and reviews target it. Defaults to your current branch, unless that is itself a workbench branch. | +| Which base branch? | Feature branches start from it and reviews target it. Defaults to your current branch, unless that is itself a Fathom branch. | | Stop for approval, or run straight through? | Sets the default approval mode for future runs. See [Approval modes](#approval-modes). | If your tracker has no state for a phase, which is common for review states in a fresh Linear team, the skill says so and offers real choices rather than silently picking the nearest state. @@ -211,7 +211,7 @@ that PR got abandoned A run does this: verifies the tracker MCP, sweeps for merged work, resolves tracker and task memory, fetches the issue, reads relevant code, creates the branch from a freshly fetched base, builds the breakdown and plan document, moves the issue to in progress, then loops one task at a time. Each task gets claimed, implemented, tested, committed on its own, and closed in both task memory and the tracker. -At the end it pushes, opens the review — or, in the manual tier, hands you everything needed to open it — and moves the issue to in review. +At the end it pushes, opens the review - or, in the manual tier, hands you everything needed to open it - and moves the issue to in review. Re-invoking on the same issue resumes it. Guards see what already exists and skip it. @@ -241,7 +241,7 @@ Auto mode removes friction, not judgment. - An ambiguous setup answer still asks that one question, because a wrong destination misfiles every future issue in the repo. - A reply whose target is unclear, an issue ref that disagrees with the branch, an issue already done, and requirements too thin to break down all still stop and ask. -Set the default during first-run setup, or edit `approval` in `.workbench/config.md`. +Set the default during first-run setup, or edit `approval` in `.fathom/config.md`. Override it per run from the prompt, in either direction: ```text @@ -258,7 +258,7 @@ When auto mode accepts a setup answer rather than having you confirm it, the pro ``` Did the invocation name one? -> use it -Does .workbench/config.md name one? -> use it +Does .fathom/config.md name one? -> use it Is exactly one tracker MCP connected? -> use it Are both connected? -> ask once, save the answer Is neither connected? -> stop, name both, print setup steps @@ -284,7 +284,7 @@ Adding beads to a repository later only affects issues started afterwards, so a ``` Named in the invocation? -> use it, this run only Recorded as base-branch in the profile? -> use it -Current branch is itself a workbench branch? -> ask, never stack one issue on another +Current branch is itself a Fathom branch? -> ask, never stack one issue on another Otherwise -> the current branch, reported so you see it ``` @@ -295,7 +295,7 @@ Branching from a stale local copy is the usual cause of conflicts at merge time. ``` Does the prompt say auto approve, or ask me first? -> that, this run only -Does .workbench/config.md set approval? -> that +Does .fathom/config.md set approval? -> that Otherwise -> ask ``` @@ -317,12 +317,12 @@ In the manual tier the "review merged" line never fires, because nothing can obs | Path | What it is | | --- | --- | -| `.workbench/config.md` | The committed profile: tracker, forge, destination, state mapping, base branch, closer choice. | -| `.workbench/forge.md` | Only if you wrote an adapter for a forge workbench does not ship. See [Forges](#forges). | -| `.workbench/plans/.md` | The per-issue plan: issue link, codebase context, approach, tasks, testing strategy. Written for people, never carries status. | -| `.workbench/tasks/.md` | Task statuses as checkboxes. Only when the checklist backend is active. | +| `.fathom/config.md` | The committed profile: tracker, forge, destination, state mapping, base branch, closer choice. | +| `.fathom/forge.md` | Only if you wrote an adapter for a forge Fathom does not ship. See [Forges](#forges). | +| `.fathom/plans/.md` | The per-issue plan: issue link, codebase context, approach, tasks, testing strategy. Written for people, never carries status. | +| `.fathom/tasks/.md` | Task statuses as checkboxes. Only when the checklist backend is active. | | `.beads/` | Beads task database and its JSONL export, when beads is the backend. | -| `.github/workflows/workbench-close.yml` | Only if you accepted the optional merge-closer Action. GitHub only; never offered on a forge without CI hooks. | +| `.github/workflows/fathom-close.yml` | Only if you accepted the optional merge-closer Action. GitHub only; never offered on a forge without CI hooks. | Plans and task files stay after the review merges; they are the record of how the work was broken down. @@ -330,7 +330,7 @@ Plans and task files stay after the review merges; they are the record of how th The forge is where your reviews live: the system that receives the branch and holds the code review. It is resolved separately from the tracker, and GitHub is one option rather than an assumption. -Workbench drives the forge through five operations — verify, resolve base, open review, publish review, read review state — and each adapter declares what its forge can actually do. Capabilities differ in kind, not just in command names, so an adapter that declares no CI hooks simply never gets offered a workflow file. +Fathom drives the forge through five operations - verify, resolve base, open review, publish review, read review state - and each adapter declares what its forge can actually do. Capabilities differ in kind, not just in command names, so an adapter that declares no CI hooks simply never gets offered a workflow file. ### The three tiers @@ -344,11 +344,11 @@ Every run lands in one tier and says which: The manual tier has one consequence worth knowing up front: **nothing can observe the review, so no later run will move the issue to done.** Issues accumulate in review until you close them. The run says this at handoff rather than leaving you to discover it. -### Supporting a forge workbench does not ship +### Supporting a forge Fathom does not ship -Internal and self-hosted forges are the reason the contract exists. Workbench cannot ship an adapter for a forge whose name and CLI it has never seen — but you can write one. +Internal and self-hosted forges are the reason the contract exists. Fathom cannot ship an adapter for a forge whose name and CLI it has never seen - but you can write one. -Copy `skills/workbench-shared/forges/TEMPLATE.md` to `.workbench/forge.md` in your repository, fill in the five operations against your forge's CLI, declare the capability table, and commit it. A repo-local adapter beats every bundled one, so nothing else changes and this plugin never needs forking. Your teammates who clone the repo get it automatically. +Copy `skills/fathom-shared/forges/TEMPLATE.md` to `.fathom/forge.md` in your repository, fill in the five operations against your forge's CLI, declare the capability table, and commit it. A repo-local adapter beats every bundled one, so nothing else changes and this plugin never needs forking. Your teammates who clone the repo get it automatically. A partial adapter is fine and often correct. One that opens reviews but declares `reviewLookup: none` still does the useful part; it just leaves the sweep off. That is far better than an adapter that guesses at review state, because a wrong guess marks abandoned work as shipped. @@ -356,8 +356,8 @@ Two rules the skills hold to, no matter the tier: **anything executed against a ## How the tracker learns a review merged -Linear can close issues natively, Asana cannot, so workbench supports several arrangements. -It asks once which one you use and records the answer — unless your forge declares no CI hooks, in which case the question is skipped and the sweep is the only mechanism. +Linear can close issues natively, Asana cannot, so Fathom supports several arrangements. +It asks once which one you use and records the answer - unless your forge declares no CI hooks, in which case the question is skipped and the sweep is the only mechanism. 1. **The tracker's own forge integration.** On GitHub, Linear closes an issue when a review body contains `Closes TES-5`. Asana can do the equivalent with its free GitHub App plus a rule that completes a task when its linked pull request merges. @@ -372,7 +372,7 @@ It asks once which one you use and records the answer — unless your forge decl You can also just say so, and the skill confirms the real state through the forge before acting. A review **closed without merging** is never treated as done. -You get told which issue and review were abandoned and asked whether to resume or move the issue back. The observation is recorded as a comment on the tracker issue, so you are told once rather than on every run — and because it lives on the tracker, it works even when your base branch is protected. +You get told which issue and review were abandoned and asked whether to resume or move the issue back. The observation is recorded as a comment on the tracker issue, so you are told once rather than on every run - and because it lives on the tracker, it works even when your base branch is protected. ## Working conventions @@ -441,15 +441,15 @@ See [Developing this plugin](#developing-this-plugin). ## Known limitations -- **Kiro has not been re-verified since the most recent changes.** The skills ran successfully on Kiro earlier in development, and the wiring is unchanged, but the rename, base-branch resolution, and commit-verification work have only been exercised on Claude Code. +- **Kiro has not been re-verified since the most recent changes.** The skills ran successfully on Kiro earlier in development, and the wiring is unchanged, but the workbench-to-Fathom rename, base-branch resolution, and commit-verification work have only been exercised on Claude Code. Smoke-test one run before relying on it there. - **The Linear merge-closer Action template has never been run end to end.** The Asana one has, three times. Verify your first merge rather than assuming. - **The issue type passed to `createIssue` is not stored as a tracker field.** It survives in the issue description and drives the branch prefix, but Linear labels and Asana custom fields are not set from it. -- **Linear suggests its own branch names**, such as `chris/tes-5-slug`, while workbench generates `feat/tes-5-slug`. +- **Linear suggests its own branch names**, such as `chris/tes-5-slug`, while Fathom generates `feat/tes-5-slug`. Using Linear's copy-branch-name button will not match. - **No CI awareness.** Once the review is open, a failing CI run is not noticed or reported. -- **Forges other than GitHub need an adapter you write.** Workbench ships GitHub and a generic-git fallback; anything else is a `.workbench/forge.md` you author. See [Forges](#forges). +- **Forges other than GitHub need an adapter you write.** Fathom ships GitHub and a generic-git fallback; anything else is a `.fathom/forge.md` you author. See [Forges](#forges). - **Jira is not supported.** Only Asana and Linear. ## Developing this plugin @@ -461,33 +461,84 @@ This is easy to miss and will make you think a fix did not work. Either reinstall after each change: ``` -/plugin uninstall workbench -/plugin install workbench@crod951 +/plugin uninstall fathom +/plugin install fathom@crod951 /reload-plugins ``` -Or point the agent at your working tree with the symlinks shown under [Install](#install), which Kiro picks up live. +Or point the agent at your working tree with the symlinks shown under [Install](#install-30-second-setup), which Kiro picks up live. Before trusting a test run, confirm which copy is live by comparing line counts: ```bash -wc -l ~/.claude/plugins/cache//workbench/*/skills/execute/SKILL.md \ +wc -l ~/.claude/plugins/cache//fathom/*/skills/execute/SKILL.md \ skills/execute/SKILL.md ``` ## Upgrading +Two things hold for every legacy repository once you have done the rename for your version below. + +Repos set up before forge support need no extra work for the forge field itself. +The next run asks which forge you use and adds `forge` to the profile, exactly as it repairs any other missing field. +Existing `.fathom/` records that carry a branch and no review id keep working, since the sweep falls back to matching by branch and rewrites the record with an id when it finds one. + +If the repo used beads, confirm `.beads/.gitignore` and `.gitattributes` exist, since the beads tooling writes both, and untrack any beads runtime files an earlier version committed. + +### From workbench 1.x to Fathom 2.0.0 + +The plugin name and the state directory both moved, and nothing migrates automatically. + +1. `/plugin uninstall workbench`, refresh the marketplace listing so it carries the new plugin name, then `/plugin install fathom@crod951` and `/reload-plugins`. + A cached listing still names the plugin `workbench`, so the install may fail until it refreshes; `/plugin marketplace update crod951` does it, and removing and re-adding the marketplace works too. +2. `git mv .workbench .fathom`. +3. `git mv .github/workflows/workbench-close.yml .github/workflows/fathom-close.yml`, then change its `name:` to `fathom-close` and every `.workbench/` path inside it to `.fathom/`. +4. Change the first line of `.fathom/config.md` to `# fathom tracker profile`. +5. Commit all of it together and push to your base branch, so teammates are not re-prompted and the merge-closer keeps working. +6. Repeat steps 2 and 4 on every unmerged feature branch, before you resume it and before you merge the base into it. + +```bash +git switch +git mv .workbench .fathom +# repeat step 4 here too, so this branch's config.md matches the base's +git commit -m "chore: move .workbench to .fathom" +git merge +``` + +Do the rename **before** merging the base, and do not reorder those two commands. +Once the base has been merged in, `.fathom/` already exists on the branch, so `git mv .workbench .fathom` stops meaning "rename" and starts meaning "move inside". +How that shows up depends on whether git's rename detection fires for your repository, which is why the order is worth following rather than reasoning about: at best the merge stops on a file-location conflict and the `git mv` then fails loudly, and at worst it quietly produces `.fathom/.workbench/tasks/.md` and exits 0. +Repeating step 4 keeps the merge clean for the same reason. +Both sides otherwise create `.fathom/config.md` independently, which git resolves by content when it detects the rename and stops on as an add/add conflict when it does not. + +Step 6 is not optional for work already in flight, and merging the base does not cover it. +The base's rename only moves files the base already had, and a feature branch's own `.workbench/plans/.md` and `.workbench/tasks/.md` were never on the base, so they stay behind and become invisible to Fathom 2.0.0. +On a checklist-backed branch the issue then looks as though it was never broken down: `execute` re-adopts the tracker's existing sub-issues and reopens tasks that are already finished, and in a repository that also has `.beads/` it silently moves that issue onto the beads backend, which `memory.md` otherwise forbids. +A beads-backed branch keeps its task state, since `.beads/` is never renamed, but its per-issue record is the plan document, left behind at `.workbench/plans/`, so the branch goes invisible to the done-on-merge sweep instead. +Either way the merge-closer finds no record for the branch and takes the same green-but-closed-nothing exit described next. + +Step 3 matters more than it looks. +A merge-closer left pointing at `.workbench/` finds no file, takes its zero-match branch, and exits successfully, so every merge shows a green check that closed nothing. + +On a skills.sh install, re-run `npx skills@latest add crod951/skills` and take all three entries. +`fathom-shared` is a new skill name at the destination, so nothing installs it in place of the old one, and without it both skills stop at the first step. +Then delete the stale `workbench-shared/` directory from your skills root, since `execute/` and `scaffold/` are overwritten in place but the old shared directory is not removed. + +Abandoned reviews you already triaged stay triaged. +The sweep reads the legacy `workbench: review-closed-unmerged` sentinel alongside the current one, so it does not re-report them. + +### From issue-lifecycle + Repos set up by an earlier version need four things renamed or added: -1. Rename `.issue-lifecycle/` to `.workbench/`. -2. Rename `.github/workflows/issue-lifecycle-close.yml` to `.github/workflows/workbench-close.yml`, and update the path it greps to `.workbench/`. -3. Change the profile's first line to `# workbench tracker profile`. +1. Rename `.issue-lifecycle/` to `.fathom/`. +2. Rename `.github/workflows/issue-lifecycle-close.yml` to `.github/workflows/fathom-close.yml`, then change its `name:` to `fathom-close` and update the path it greps to `.fathom/`. +3. Change the profile's first line to `# fathom tracker profile`. 4. Add `base-branch` to the profile, or let the next run ask. -Repos set up before forge support need nothing. The next run asks which forge you use and adds `forge` to the profile, exactly as it repairs any other missing field. Existing `.workbench/` records that carry a branch and no review id keep working — the sweep falls back to matching by branch and rewrites the record with an id when it finds one. - -If the repo used beads, confirm `.beads/.gitignore` and `.gitattributes` exist, since the beads tooling writes both, and untrack any beads runtime files an earlier version committed. +The in-flight branch caveat above applies here too, with `.issue-lifecycle/` in place of `.workbench/`. +Rename it on every unmerged feature branch as well, not just on the base, and there too do the rename and the profile edit on the branch before merging the base into it, for the same reason. Version 3 of the predecessor plugin removed its slash commands (`/issue-start`, `/issue-task`, `/commit`, `/issue-finish`). The `execute` skill covers the issue flow they formed: "execute TES-5" does what the whole sequence used to. -The one gap is `/commit` as a standalone conventional-commit helper outside an issue run; workbench applies its commit conventions only inside execute runs, so for non-issue commits use your agent's normal commit flow, borrowing the rules in `skills/workbench-shared/conventions.md` if you want the same style. +The one gap is `/commit` as a standalone conventional-commit helper outside an issue run; Fathom applies its commit conventions only inside execute runs, so for non-issue commits use your agent's normal commit flow, borrowing the rules in `skills/fathom-shared/conventions.md` if you want the same style. diff --git a/skills/execute/SKILL.md b/skills/execute/SKILL.md index 2ea032f..fc9ac4b 100644 --- a/skills/execute/SKILL.md +++ b/skills/execute/SKILL.md @@ -35,25 +35,25 @@ Every run begins by reading durable state from the repository and the tracker, n Before doing any tracker or memory work, read: These paths are relative to the directory containing this SKILL.md file, not the current workspace. -In a global Kiro install they resolve under `~/.kiro/skills/` (for example `~/.kiro/skills/workbench-shared/trackers.md`); in a Claude Code plugin install they resolve inside the plugin's `skills/` directory. +In a global Kiro install they resolve under `~/.kiro/skills/` (for example `~/.kiro/skills/fathom-shared/trackers.md`); in a Claude Code plugin install they resolve inside the plugin's `skills/` directory. -- `../workbench-shared/trackers.md` for the tracker contract, phase names, and first-run profile setup. -- `../workbench-shared/forges.md` for the forge contract, adapter resolution, the capability tiers, and base-branch resolution. -- `../workbench-shared/memory.md` for the memory contract and backend resolution rules. -- `../workbench-shared/agents.md` for the per-agent notes that apply to whichever agent is running this skill. -- `../workbench-shared/conventions.md` for staging safety, commit messages, the plan document, and progress reporting. -- `../workbench-shared/approval.md` for the two approval modes, and for the stops that hold in both. +- `../fathom-shared/trackers.md` for the tracker contract, phase names, and first-run profile setup. +- `../fathom-shared/forges.md` for the forge contract, adapter resolution, the capability tiers, and base-branch resolution. +- `../fathom-shared/memory.md` for the memory contract and backend resolution rules. +- `../fathom-shared/agents.md` for the per-agent notes that apply to whichever agent is running this skill. +- `../fathom-shared/conventions.md` for staging safety, commit messages, the plan document, and progress reporting. +- `../fathom-shared/approval.md` for the two approval modes, and for the stops that hold in both. If any of these files cannot be found and read, stop immediately and report which paths were tried - never improvise their contracts from memory or proceed without them. ## Procedure -1. Resolve the approval mode per `../workbench-shared/approval.md` and state it, then run preflight verification as described in `../workbench-shared/trackers.md` before any other tracker step. +1. Resolve the approval mode per `../fathom-shared/approval.md` and state it, then run preflight verification as described in `../fathom-shared/trackers.md` before any other tracker step. Infer the preflight target from the invocation before verifying anything: an explicitly named tracker, or the shape of the issue ref from the invocation argument, a pasted URL, or the current branch name, in the same order of preference step 4 uses; only when none of those settles it fall back to the profile, then to the single connected MCP, per the shared precedence in `trackers.md`. This keeps preflight, the sweep, and the run itself on one tracker; verifying whatever the profile names while the invocation clearly targets the other tracker would sweep and verify the wrong one. Stop here, following that section's instructions, when the tracker's MCP does not verify. - A forge that does not verify is not a stop: it selects a capability tier per `../workbench-shared/forges.md`. State the resolved tier before continuing, so the user knows up front whether this run will end in an opened review or a manual handoff. -2. Run the done-on-merge sweep for the resolved tracker; the mechanics are described in `../workbench-shared/trackers.md` and are tracker-agnostic, with each adapter file defining only its own closure action for the merged path. + A forge that does not verify is not a stop: it selects a capability tier per `../fathom-shared/forges.md`. State the resolved tier before continuing, so the user knows up front whether this run will end in an opened review or a manual handoff. +2. Run the done-on-merge sweep for the resolved tracker; the mechanics are described in `../fathom-shared/trackers.md` and are tracker-agnostic, with each adapter file defining only its own closure action for the merged path. This sweep is itself tracker work, so it only runs once preflight has verified the MCP. When the invocation itself was a cleanup phrase, run only this sweep, report what it found, then stop; do not continue into the rest of this procedure. Treat any claim about a review's fate as a cleanup phrase, whether it says merged, closed, abandoned, landed, or shipped, and whether it names an issue or asks to clean up whatever is outstanding. @@ -61,13 +61,13 @@ If any of these files cannot be found and read, stop immediately and report whic When the resolved forge declares `reviewLookup: none`, the claim cannot be confirmed at all. Say that plainly and act on nothing; do not close an issue on the strength of an unverifiable claim, since a wrong close is exactly what the confirmation step exists to prevent. 3. Resolve which tracker owns this issue and which memory backend owns its task state, following `trackers.md` and `memory.md`. When the repo already contains beads state but the beads tooling is unavailable on this machine, stop and say so as memory.md directs; never substitute a different backend for a repo whose state lives in another one. - Load the existing `.workbench/config.md` tracker profile, or run first-run setup when none exists; either way, run the tracker adapter's profile-load checks and honor any one-time offers they define. + Load the existing `.fathom/config.md` tracker profile, or run first-run setup when none exists; either way, run the tracker adapter's profile-load checks and honor any one-time offers they define. 4. Determine the issue ref from the invocation argument, a pasted issue URL, or the current branch name, in that order of preference; when the argument and the branch name refer to different issues, stop and ask the user which one to use. 5. Call `getIssue` for that ref and save its title, description, type, URL, and existing children for the rest of this run. When the issue is already in the `done` phase or marked complete, do not start work: say so, report what the sweep found for it, and ask whether to reopen it or pick a different issue. 6. Search the codebase and read the files that look relevant to this issue, noting existing patterns to follow during implementation. 7. Ensure a feature branch exists for this issue; when one must be created, prefix its name from the issue type (`feat/` for a feature, `fix/` for a bug, `chore/` for a chore, `docs/` for docs, `feat/` by default) followed by the issue ref and a short title slug; skip creation when a matching branch already exists. - Resolve the base branch per the base-branch rules in `../workbench-shared/forges.md`, then fetch it and create the new branch from the fetched remote copy rather than from a local copy that may be behind, since branching from a stale local copy is the usual cause of conflicts at merge time. + Resolve the base branch per the base-branch rules in `../fathom-shared/forges.md`, then fetch it and create the new branch from the fetched remote copy rather than from a local copy that may be behind, since branching from a stale local copy is the usual cause of conflicts at merge time. When the branch already exists and the base branch has moved on since, bring it up to date before implementing, and report that you did. When that update conflicts, stop and hold exactly as an unfixable test failure would: keep the work, leave the task in progress, report which files conflict, and let the user decide how to resolve them; never resolve a conflict by discarding either side's changes. 8. Ensure the breakdown exists. @@ -77,7 +77,7 @@ If any of these files cannot be found and read, stop immediately and report whic - When the issue already has children, call `listSubIssues` to adopt them instead of inventing a new breakdown; for each adopted sub-issue, still call `createTask`, passing that sub-issue's existing ref as `subIssueRef` and skipping `createSubIssue` since the sub-issue already exists, then write the returned task id back onto that sub-issue the same way, and setting `deps` the same way. - After every child task exists, add the parent's dependency edge on each child, so the parent cannot close before its children and "no open children" becomes a real signal rather than an assumption. - Either way, write the plan document described in `conventions.md` and commit it with the breakdown. - - Write `.workbench/tasks/.md` only when the resolved backend is the checklist adapter, since that file holds checkbox statuses; with beads active the statuses live in beads and no file belongs there, as `memory.md` states. + - Write `.fathom/tasks/.md` only when the resolved backend is the checklist adapter, since that file holds checkbox statuses; with beads active the statuses live in beads and no file belongs there, as `memory.md` states. 9. Call `updateState` to move the issue to the `inProgress` phase. 10. Run the implementation loop until `claimNext` reports nothing claimable. Each pass through the loop does the following, in order. @@ -101,19 +101,19 @@ If any of these files cannot be found and read, stop immediately and report whic Commit any leftover uncommitted change that belongs to this issue's tasks, leaving unrelated working-tree edits alone rather than sweeping them into the review. Close the parent task in the memory backend (a no-op for the checklist adapter, whose file is the parent record). - Then open the review through the forge contract in `../workbench-shared/forges.md`, never by invoking a forge CLI directly from this procedure. + Then open the review through the forge contract in `../fathom-shared/forges.md`, never by invoking a forge CLI directly from this procedure. - Confirm the resolved base with `resolveBase` first, as the contract requires, before anything is created against it. - Push the branch, unless the resolved adapter declares `pushesForYou`; when it does, `openReview` owns the push and pushing here would produce a wrong branch state. - Call `openReview` with the branch, the resolved base, a title, and a body containing `Closes ` for a Linear issue or the task's URL for an Asana task, plus a summary, the list of completed tasks, and a test plan. - Skip this when a review already exists for the branch, and reuse that one; resuming an issue must never open a second review. - Call `publishReview` with the returned id. - - Record `- Review: ` in this issue's file under `.workbench/`, alongside the existing `- PR:` line, since the sweep looks issues up by id. + - Record `- Review: ` in this issue's file under `.fathom/`, alongside the existing `- PR:` line, since the sweep looks issues up by id. - Call `updateState` to move the issue to the `inReview` phase. When `openReview` returns the manual-handoff result instead of an id, there is no review object: skip `publishReview`, record no review id, print the handoff. Still apply `inReview`, and say plainly that no later run will move this issue to `done` on its own because the forge cannot be observed, so closing it is now a manual step. - Finally, post a completion comment on the issue, including the done-on-merge note from `asana.md` when the tracker is Asana, and commit and push the task-state files this run changed as a final closing commit so the branch carries the completed state, staging them by explicit path per the staging rules in `conventions.md`: the beads JSONL export and `metadata.json` when beads is the backend, and this issue's files under `.workbench/`; never sweep `.beads/` or `.workbench/` as directories, since the beads database and runtime files are intentionally ignored and must not ride into the review. + Finally, post a completion comment on the issue, including the done-on-merge note from `asana.md` when the tracker is Asana, and commit and push the task-state files this run changed as a final closing commit so the branch carries the completed state, staging them by explicit path per the staging rules in `conventions.md`: the beads JSONL export and `metadata.json` when beads is the backend, and this issue's files under `.fathom/`; never sweep `.beads/` or `.fathom/` as directories, since the beads database and runtime files are intentionally ignored and must not ride into the review. 12. Report a final summary: the issue, the review URL when one was opened or the resolved tier when one was not, the tracker's current phase, and the task counts from `status()`. ## Display overlay diff --git a/skills/workbench-shared/SKILL.md b/skills/fathom-shared/SKILL.md similarity index 50% rename from skills/workbench-shared/SKILL.md rename to skills/fathom-shared/SKILL.md index 80ef53c..f3e91e9 100644 --- a/skills/workbench-shared/SKILL.md +++ b/skills/fathom-shared/SKILL.md @@ -1,12 +1,12 @@ --- -name: workbench-shared -description: Internal shared contracts for the workbench execute and scaffold skills. Never invoke this directly; it holds the tracker, memory, approval, and convention reference files those skills read at runtime. It exists as a skill only so installers that copy skill directories carry these files alongside execute and scaffold. +name: fathom-shared +description: Internal shared contracts for the Fathom execute and scaffold skills. Never invoke this directly; it holds the tracker, memory, approval, and convention reference files those skills read at runtime. It exists as a skill only so installers that copy skill directories carry these files alongside execute and scaffold. version: 1.0.0 --- -# Workbench shared contracts +# Fathom shared contracts This directory is not an invocable skill. It holds the contract files the `execute` and `scaffold` skills read before doing any tracker or memory work: `trackers.md`, `memory.md`, `agents.md`, `conventions.md`, `approval.md`, and the per-tracker and per-backend adapter files under `trackers/` and `memory/`. -If an agent invoked this by mistake, stop here and do nothing; the real entry points are the `execute` and `scaffold` skills, which reference these files as `../workbench-shared/.md`. +If an agent invoked this by mistake, stop here and do nothing; the real entry points are the `execute` and `scaffold` skills, which reference these files as `../fathom-shared/.md`. diff --git a/skills/workbench-shared/agents.md b/skills/fathom-shared/agents.md similarity index 82% rename from skills/workbench-shared/agents.md rename to skills/fathom-shared/agents.md index 6dfd9b8..a7a22bc 100644 --- a/skills/workbench-shared/agents.md +++ b/skills/fathom-shared/agents.md @@ -7,7 +7,7 @@ Read the rest of this plugin's skills as agent-neutral; when you need an agent-s ## Install Claude Code: install this plugin from its marketplace repo. -Kiro: install with the skills CLI, `npx skills add crod951/skills -a kiro-cli`, which places `execute/`, `scaffold/`, and `workbench-shared/` as siblings under `~/.kiro/skills/`; or copy or symlink the contents of this plugin's `skills/` directory there by hand so the three sit as siblings directly under the destination. Copying the `skills/` directory itself would nest them one level too deep and break every `../workbench-shared/` reference. +Kiro: install with the skills CLI, `npx skills add crod951/skills -a kiro-cli`, which places `execute/`, `scaffold/`, and `fathom-shared/` as siblings under `~/.kiro/skills/`; or copy or symlink the contents of this plugin's `skills/` directory there by hand so the three sit as siblings directly under the destination. Copying the `skills/` directory itself would nest them one level too deep and break every `../fathom-shared/` reference. ## Task display overlay @@ -40,7 +40,7 @@ Kiro: use an equivalent structured prompt when the workspace exposes one; otherw ## Permissions -For smooth autonomous runs, pre-approve these command families ahead of time: `git`, `bd`, the CLI named by the resolved forge adapter (`gh` for GitHub, and whatever a repo-local `.workbench/forge.md` names), and whichever tool names the runtime discovery step in the previous section resolves for the connected tracker MCP server. +For smooth autonomous runs, pre-approve these command families ahead of time: `git`, `bd`, the CLI named by the resolved forge adapter (`gh` for GitHub, and whatever a repo-local `.fathom/forge.md` names), and whichever tool names the runtime discovery step in the previous section resolves for the connected tracker MCP server. Claude Code: add these to the permissions allowlist in settings (project or user settings.json). Kiro: add these to its trusted/allowed command configuration. diff --git a/skills/workbench-shared/approval.md b/skills/fathom-shared/approval.md similarity index 97% rename from skills/workbench-shared/approval.md rename to skills/fathom-shared/approval.md index 3cf2784..b2329fe 100644 --- a/skills/workbench-shared/approval.md +++ b/skills/fathom-shared/approval.md @@ -6,7 +6,7 @@ The mode changes which questions get asked; it never changes which conditions st ## Resolving the mode Resolve it once at the start of a run, first match winning. -The profile may not be loaded yet at that point, so read only the `approval` field from `.workbench/config.md` if the file exists, and treat a missing file as no answer. +The profile may not be loaded yet at that point, so read only the `approval` field from `.fathom/config.md` if the file exists, and treat a missing file as no answer. When first-run setup then establishes a mode later in the same run, that answer governs the rest of that run. The invocation overrides everything, in either direction. @@ -70,7 +70,7 @@ When a new stop is added to either skill, decide explicitly whether it belongs t ## Recording it -First-run setup asks for the mode as its own question, after the tracker questions, and records it as `approval: auto` or `approval: ask` in `.workbench/config.md`. +First-run setup asks for the mode as its own question, after the tracker questions, and records it as `approval: auto` or `approval: ask` in `.fathom/config.md`. Because the profile is committed, teammates inherit the choice. Editing that field changes it permanently; an invocation phrase changes it for one run. When one skill hands off to the other, carry the resolved mode across so a per-run override is not lost at the boundary; say which mode the handed-off run is using. diff --git a/skills/workbench-shared/conventions.md b/skills/fathom-shared/conventions.md similarity index 98% rename from skills/workbench-shared/conventions.md rename to skills/fathom-shared/conventions.md index 41b88c5..e87ec98 100644 --- a/skills/workbench-shared/conventions.md +++ b/skills/fathom-shared/conventions.md @@ -43,7 +43,7 @@ Name the task in the body so the commit ties back to task memory. ## The plan document -During breakdown, write a human-readable plan for the issue at `.workbench/plans/.md`, and commit it with the breakdown. +During breakdown, write a human-readable plan for the issue at `.fathom/plans/.md`, and commit it with the breakdown. This document is a reference artifact for people, never resume state; task status always lives in the resolved memory backend. Include these sections: diff --git a/skills/workbench-shared/forges.md b/skills/fathom-shared/forges.md similarity index 95% rename from skills/workbench-shared/forges.md rename to skills/fathom-shared/forges.md index ffc45db..8f339ee 100644 --- a/skills/workbench-shared/forges.md +++ b/skills/fathom-shared/forges.md @@ -61,7 +61,7 @@ An internal forge on an unrecognized host matches no bundled adapter, so remote- Resolve in this order, first match winning. -Use `.workbench/forge.md` when the repository contains one; a repo-local adapter wins over everything. +Use `.fathom/forge.md` when the repository contains one; a repo-local adapter wins over everything. Otherwise use the bundled adapter named by the profile's `forge` field, for example `forges/github.md` for `forge: github`. Otherwise, when the profile records `forge: none`, run in the manual tier described below and make no offers. Otherwise the repository has no forge answer yet, so run the first-run forge question. @@ -71,7 +71,7 @@ A wrong inference here pushes code to the wrong place. ### The repo-local adapter -`.workbench/forge.md` is how a team supports a forge this plugin has never heard of. +`.fathom/forge.md` is how a team supports a forge this plugin has never heard of. They write one file describing the five operations and the capability table against their own forge's CLI, commit it to their own repository, and every later run resolves it. No fork of this plugin, and no change to any shared contract, is required. @@ -80,7 +80,7 @@ A partial adapter is legitimate and useful: an adapter that implements `verifyFo ### First-run forge question -Ask once per repository, and record the answer as `forge` in `.workbench/config.md`. +Ask once per repository, and record the answer as `forge` in `.fathom/config.md`. Use the agent's structured question mechanism named in `agents.md`, as every other first-run question does. Seed the question with whatever detection can offer, in this order. @@ -106,7 +106,7 @@ Do not drop to tier 2 instead; the tier-2 offers presume no adapter exists, and **Tier 2, assisted.** No adapter resolved, but a candidate forge CLI was found on `PATH`. -Push the branch, then offer three choices: use the candidate for this run only, write `.workbench/forge.md` now so later runs are tier 1, or fall through to the manual tier. +Push the branch, then offer three choices: use the candidate for this run only, write `.fathom/forge.md` now so later runs are tier 1, or fall through to the manual tier. The best outcome is the committed adapter, because it is reviewable by the team and durable across runs. **Tier 3, manual.** @@ -155,7 +155,7 @@ Use the base branch named in the invocation when the request specifies one, and Otherwise use the profile's `base-branch` when it records one. Otherwise use the repository's current branch, and say which branch you resolved so the choice is visible. -Guard against one trap: when the current branch is itself a workbench feature branch, meaning its name carries an issue ref and one of the branch prefixes, do not silently use it as a base. +Guard against one trap: when the current branch is itself a Fathom feature branch, meaning its name carries an issue ref and one of the branch prefixes, do not silently use it as a base. Building one issue's work on top of another's unmerged branch entangles two reviews, so ask which base to use instead. Fetch the resolved base branch before creating anything from it, and create the new branch from the fetched remote copy rather than from a local copy that may be behind. diff --git a/skills/workbench-shared/forges/TEMPLATE.md b/skills/fathom-shared/forges/TEMPLATE.md similarity index 94% rename from skills/workbench-shared/forges/TEMPLATE.md rename to skills/fathom-shared/forges/TEMPLATE.md index 789db1f..feccb44 100644 --- a/skills/workbench-shared/forges/TEMPLATE.md +++ b/skills/fathom-shared/forges/TEMPLATE.md @@ -1,11 +1,11 @@ # Forge adapter template -Copy this file to `.workbench/forge.md` in your repository, fill it in for your forge, and commit it. +Copy this file to `.fathom/forge.md` in your repository, fill it in for your forge, and commit it. A repo-local adapter wins over every bundled one, so nothing else needs to change and this plugin does not need to be forked. Read `../forges.md` for the contract these operations implement. Read `github.md` for a complete worked example, and `generic-git.md` for the minimum viable one. -Those three references resolve inside the plugin's `skills/workbench-shared/forges/` directory, so read them before copying this file; from the copy at `.workbench/forge.md` they will not resolve, which is fine because the finished adapter needs none of them at runtime. +Those three references resolve inside the plugin's `skills/fathom-shared/forges/` directory, so read them before copying this file; from the copy at `.fathom/forge.md` they will not resolve, which is fine because the finished adapter needs none of them at runtime. Guidance is in `>` blockquotes throughout. Delete the blockquotes as you fill each section in. diff --git a/skills/workbench-shared/forges/generic-git.md b/skills/fathom-shared/forges/generic-git.md similarity index 100% rename from skills/workbench-shared/forges/generic-git.md rename to skills/fathom-shared/forges/generic-git.md diff --git a/skills/workbench-shared/forges/github.md b/skills/fathom-shared/forges/github.md similarity index 100% rename from skills/workbench-shared/forges/github.md rename to skills/fathom-shared/forges/github.md diff --git a/skills/workbench-shared/memory.md b/skills/fathom-shared/memory.md similarity index 86% rename from skills/workbench-shared/memory.md rename to skills/fathom-shared/memory.md index 14d3dc6..5363e47 100644 --- a/skills/workbench-shared/memory.md +++ b/skills/fathom-shared/memory.md @@ -26,7 +26,7 @@ Follow this order: Check the issue's own state before the repository's state, because the per-issue signal decides that issue's backend. -When `.workbench/tasks/.md` exists, use the checklist adapter for this issue. +When `.fathom/tasks/.md` exists, use the checklist adapter for this issue. The file's existence is the signal, not its contents: `init` creates it before any task lines are added, so requiring checkboxes would send a run that died between `init` and the first task into a different backend and fork that issue's status across both. Do this even when `.beads/` exists and even when `bd` is installed. An issue whose statuses already live in checkboxes keeps that backend for its whole life; adding beads to a repository later must never move an in-flight issue, which would orphan the statuses already recorded in its checklist file. @@ -59,7 +59,7 @@ Skip the overlay silently when the agent exposes no such tools. ## No dual truth Task status never lives in two places. -The human-readable plan always lives in the plan document at `.workbench/plans/.md` described in `conventions.md`, and that document never carries status. -When the beads adapter is active, statuses live in beads and no file is written under `.workbench/tasks/` for that issue. -When the checklist adapter is active, `.workbench/tasks/.md` holds the checkbox statuses for that issue, and the plan still lives in the plan document. -Whichever backend is active, at least one file under `.workbench/` must record the issue's branch, its review id once one exists, and its tracker URL, because the merge sweep finds an issue by searching that directory, and a merge-closer running on the forge's own CI finds one the same way. +The human-readable plan always lives in the plan document at `.fathom/plans/.md` described in `conventions.md`, and that document never carries status. +When the beads adapter is active, statuses live in beads and no file is written under `.fathom/tasks/` for that issue. +When the checklist adapter is active, `.fathom/tasks/.md` holds the checkbox statuses for that issue, and the plan still lives in the plan document. +Whichever backend is active, at least one file under `.fathom/` must record the issue's branch, its review id once one exists, and its tracker URL, because the merge sweep finds an issue by searching that directory, and a merge-closer running on the forge's own CI finds one the same way. diff --git a/skills/workbench-shared/memory/beads.md b/skills/fathom-shared/memory/beads.md similarity index 100% rename from skills/workbench-shared/memory/beads.md rename to skills/fathom-shared/memory/beads.md diff --git a/skills/workbench-shared/memory/checklist.md b/skills/fathom-shared/memory/checklist.md similarity index 93% rename from skills/workbench-shared/memory/checklist.md rename to skills/fathom-shared/memory/checklist.md index 906d3cb..ebec2eb 100644 --- a/skills/workbench-shared/memory/checklist.md +++ b/skills/fathom-shared/memory/checklist.md @@ -1,6 +1,6 @@ # checklist adapter -This adapter is backed by a single markdown file, `.workbench/tasks/.md`, committed inside the consumer's repo on the feature branch. +This adapter is backed by a single markdown file, `.fathom/tasks/.md`, committed inside the consumer's repo on the feature branch. Only use this adapter once `memory.md`'s resolution procedure has already chosen the checklist for this run. Commit the file with every change this adapter makes, except the in-progress marker and the deferred hash append described under `close`, which stay uncommitted until they ride a later commit. The file is the parent record for the issue and the durable store for every task under it; there is no second location for status. @@ -41,7 +41,7 @@ Never renumber existing tasks when adding a new one; numbers are permanent once | Contract operation | Checklist file mapping | | --- | --- | -| `init(issueRef)` | Check whether `.workbench/tasks/.md` exists. When it does not, create it with the header line, the `Issue`, `Branch`, and `Review` lines, an empty `## Plan` section, and an empty `## Tasks` section, then commit it. When it already exists, do nothing; never overwrite an existing file. | +| `init(issueRef)` | Check whether `.fathom/tasks/.md` exists. When it does not, create it with the header line, the `Issue`, `Branch`, and `Review` lines, an empty `## Plan` section, and an empty `## Tasks` section, then commit it. When it already exists, do nothing; never overwrite an existing file. | | `createTask(title, description, subIssueRef, deps)` | Append a line to the `## Tasks` section: `- [ ] N. (deps: <dep-ids>) -> sub-issue: <subIssueRef>`, where `N` is the next unused task number. Omit the `(deps: ...)` segment when `deps` is empty. Fold any free-text `description` into the task title or leave it out of the line entirely; the checklist format has no separate description field. Commit this line together with the scaffold commit that creates the corresponding sub-issue; when the sub-issue already existed and was adopted rather than created, there is no scaffold commit, so commit the line with the breakdown commit instead. Return `N` as the task id. | | `claimNext()` | Read the file from the working tree and take the first `- [ ]` line whose listed deps are all `- [x]`, then rewrite that line's marker to `- [>]`. Leave the rewrite uncommitted: it rides the task's implementation commit later, so it never becomes a commit of its own. An uncommitted `- [>]` marker in the working tree is the resume signal, which is why resume reads the tree rather than the last commit. When a `- [>]` line already exists, return that task to be resumed instead of claiming a new one. This adapter assumes exactly one active runner per issue branch; it has no lock, so two concurrent runners could both claim or both resume the same task. When the file changes underfoot between reading and rewriting it, or the working tree shows commits this runner did not make, treat that as evidence of a second runner: stop and report rather than claim, since the resumable-single-pass contract makes concurrent runners out of scope by design. | | `close(taskId)` | Rewrite that task's `- [>]` marker to `- [x]` and append the ISO done date. Commit the implementation together with this rewrite as one commit. Then read that commit's short hash, state it in the progress line immediately, and append it to the closed task's line in the working tree, leaving that hash edit uncommitted so it rides the next commit that touches this file, which is the next task's close or the run's final closing commit. Never amend the closing commit to add its own hash: a file staged into a commit cannot contain that commit's final hash, and amending changes the hash again, so the recorded value would name a commit that no longer exists. Never create a separate commit just to carry the hash. | diff --git a/skills/workbench-shared/trackers.md b/skills/fathom-shared/trackers.md similarity index 93% rename from skills/workbench-shared/trackers.md rename to skills/fathom-shared/trackers.md index d804ac4..121072e 100644 --- a/skills/workbench-shared/trackers.md +++ b/skills/fathom-shared/trackers.md @@ -29,7 +29,7 @@ It may bundle more than one native id when the tracker needs that; Linear's carr Resolve a destination for a new top-level issue from only two sources: the caller-supplied hint for this invocation, or the tracker profile's configured default when no hint is given. When neither a hint nor a profile default exists, the agent must call `listDestinations`, list the destinations to the user, and ask once which one to use. Do not substitute any other source of truth for that question. -In particular, never infer a destination from tracker URLs found inside existing `.workbench/tasks/*.md` files, from prior issues in the repository, or from any other guess; a wrong inference silently files work in the wrong place, and even a right one takes the choice away from a user who may have several valid destinations. +In particular, never infer a destination from tracker URLs found inside existing `.fathom/tasks/*.md` files, from prior issues in the repository, or from any other guess; a wrong inference silently files work in the wrong place, and even a right one takes the choice away from a user who may have several valid destinations. The agent may inspect existing task files or prior issues to offer a suggested default inside that same question, for example "previous issues in this repo used X, use that again?". Offering a suggestion does not replace asking; still ask the question and wait for the user's answer before creating anything. One exception, defined in `approval.md`: in auto mode, when `listDestinations` returns exactly one destination the answer is determinate, so record it and report it instead of asking. @@ -84,7 +84,7 @@ The sweep is tracker-agnostic: it finds issues from repository state, and only i The sweep runs only when the resolved forge declares `reviewLookup: by-id`. When it declares `none`, there is no way to observe what happened to a review, so skip the sweep and say once that it was skipped and why; never report a clean sweep that did not run. -Find the outstanding issues by searching `.workbench/` for recorded reviews. +Find the outstanding issues by searching `.fathom/` for recorded reviews. Search the whole directory rather than only `tasks/`: depending on the resolved memory backend the per-issue record may be a plan document under `plans/` with no checklist file at all, and narrowing the search to `tasks/` silently skips those issues. For each issue the search finds, call `getReviewState` once with that issue's recorded review id and act on what it returns. @@ -118,17 +118,18 @@ Unlike the merged path, this one has no tracker state to key on: the issue sits Record the observation as a comment on the issue through `comment`, carrying a sentinel line such as: ``` -workbench: review-closed-unmerged <review url> <date> +fathom: review-closed-unmerged <review url> <date> ``` Before reporting, call `listComments` and skip any issue whose comments already contain the sentinel for that review. Match the sentinel as a substring anywhere in the comment stream, not by inspecting only the newest comment; users reply in comment threads, and a later reply must not hide the marker. +Treat the legacy sentinel `workbench: review-closed-unmerged` as valid for the same purpose when matching, since sentinels written before the rename live on the tracker rather than in the repository and no file rename reaches them; only ever write the current one. The tracker holds this marker rather than a file for one reason: the marker has to survive to other clones and later runs, and a file-based marker only does that when it is pushed to the base branch. Most shared repositories protect that branch, so the push fails, the marker never lands, and the report repeats forever as a stop that fires in both approval modes. A comment needs no branch write access and is visible from every clone. -When the resolved tracker cannot list comments, fall back to recording `- Review closed unmerged: <date> <review url>` in that issue's file under `.workbench/`, committed and pushed to the base branch. +When the resolved tracker cannot list comments, fall back to recording `- Review closed unmerged: <date> <review url>` in that issue's file under `.fathom/`, committed and pushed to the base branch. Say plainly, when taking that fallback, that the marker depends on write access to the base branch and that the review will be re-reported on every run if the push fails. Keep reading legacy `- PR closed unmerged:` lines as valid markers, so records written before this change are not re-reported. @@ -160,8 +161,8 @@ The connected tracker MCP is the only permitted channel for tracker operations a Run this setup procedure once per repository, then reuse its output on every later run. -Trigger setup when the repository has no `.workbench/config.md`. -Before prompting the user, check other local branches for a newer `.workbench/config.md` and offer to reuse it instead of starting over. +Trigger setup when the repository has no `.fathom/config.md`. +Before prompting the user, check other local branches for a newer `.fathom/config.md` and offer to reuse it instead of starting over. When no existing profile is found anywhere, the agent must run these six steps in order and must not skip any of them. Each step must get the user's answer before the next step starts, and the profile must not be written until every step has an answer. @@ -195,7 +196,7 @@ When a user's reply could answer more than one pending question, or its target i Run this check whenever the profile is loaded, not only during first-run setup, so a profile written before this question existed gets repaired rather than staying silent. 5. Confirm the base branch that feature branches should start from and merge into. Offer the repository's current branch as the default, since that is usually the integration branch the user is working from, and offer the repository's default branch as the alternative. - Do not offer the current branch when it is itself a workbench feature branch, meaning its name carries an issue ref and one of the branch prefixes. + Do not offer the current branch when it is itself a Fathom feature branch, meaning its name carries an issue ref and one of the branch prefixes. Recording that as the profile's base would make every future issue in the repository, and every teammate who clones it, branch from and target one issue's unmerged work, and the resolution-time guard would never fire because the profile now holds an explicit answer. Offer the default branch in that case, and say why the current branch was excluded. Record the answer as `base-branch` in the profile. @@ -203,7 +204,7 @@ When a user's reply could answer more than one pending question, or its target i Ask whether future runs should stop for approval at the usual points, or run straight through without asking. Record the answer as `approval: ask` or `approval: auto` per `approval.md`, and say that the safety stops listed there fire either way, so choosing auto does not mean unattended risk. -Save the confirmed profile to `.workbench/config.md` and commit that file only once all six steps above have an answer; include the confirmed default destination. +Save the confirmed profile to `.fathom/config.md` and commit that file only once all six steps above have an answer; include the confirmed default destination. Never announce that setup will happen and then write a profile without having asked each of these questions. A profile written without confirmed answers for every step is a defect, not a shortcut. A per-invocation destination hint applies only to that invocation; change the profile's `default-destination` only when it is absent or when the user explicitly asks to change it. @@ -211,9 +212,9 @@ A per-invocation destination hint applies only to that invocation; change the pr Use this format for the profile: ```markdown -# workbench tracker profile +# fathom tracker profile tracker: asana -forge: github # a bundled adapter name, "local" for .workbench/forge.md, or "none" +forge: github # a bundled adapter name, "local" for .fathom/forge.md, or "none" default-destination: Prototypes (1209000000000001) # add "# auto-accepted" when auto mode chose it base-branch: main approval: ask @@ -226,4 +227,4 @@ state-mapping: On every subsequent run, read the existing profile silently and use it without re-prompting. Re-run setup when a mapped state no longer exists in the tracker, or when the user explicitly asks to redo it. -Re-run setup to resolve merge conflicts in `.workbench/config.md`; do not attempt to hand-merge the conflicting mapping. +Re-run setup to resolve merge conflicts in `.fathom/config.md`; do not attempt to hand-merge the conflicting mapping. diff --git a/skills/workbench-shared/trackers/asana.md b/skills/fathom-shared/trackers/asana.md similarity index 96% rename from skills/workbench-shared/trackers/asana.md rename to skills/fathom-shared/trackers/asana.md index 55b236a..b34f676 100644 --- a/skills/workbench-shared/trackers/asana.md +++ b/skills/fathom-shared/trackers/asana.md @@ -59,7 +59,7 @@ When the resolved forge declares `reviewLookup: none`, no later run can detect t The done-on-merge sweep itself, including its handling of reviews closed without merging, is tracker-agnostic and defined in `../trackers.md`; run it exactly as written there. This adapter's closure action for the sweep's merged path: apply the mapped `done` state and set the task's completed flag. -## Closing on merge without any workbench machinery +## Closing on merge without any Fathom machinery Everything in this section and the next assumes the resolved forge is GitHub. Both arrangements below are GitHub-specific: one is a GitHub App, the other is a GitHub Actions workflow. @@ -87,7 +87,7 @@ Asking anyway is worse than skipping, because a yes writes a workflow file that When that line is absent and the forge declares `ciHooks`, ask the user once whether to install the merge-closer GitHub Action for instant Asana closure on review merge, then record the answer in the profile right away. Ask whenever no `merge-closer:` line is on record; once one is recorded, never ask again for this repository. -When the answer is yes, write `.github/workflows/workbench-close.yml` from the template below, record `merge-closer: installed` in the tracker profile, and commit both together. +When the answer is yes, write `.github/workflows/fathom-close.yml` from the template below, record `merge-closer: installed` in the tracker profile, and commit both together. Tell the user to add an `ASANA_TOKEN` repository secret, an Asana personal access token, since the workflow cannot post to the Asana API without it. When the answer is no, record `merge-closer: declined` in the tracker profile. The passive sweep and the on-demand cleanup trigger described in the execute skill keep working either way; this Action is an additive fast path, not a replacement. @@ -97,7 +97,7 @@ The agent must never borrow the `ASANA_TOKEN` secret or any other token from dis The file-discovery and ref-extraction block in this template is intentionally identical to the one in `linear.md`'s template; a change to either copy must be applied to both. ```yaml -name: workbench-close +name: fathom-close on: pull_request: @@ -124,15 +124,15 @@ jobs: # A branch must map to exactly one record; closing a task picked # arbitrarily from several matches could complete the wrong issue. - MATCHES=$(grep -rlF "$BRANCH" .workbench/ 2>/dev/null | sort) + MATCHES=$(grep -rlF "$BRANCH" .fathom/ 2>/dev/null | sort) MATCH_COUNT=$(printf '%s' "$MATCHES" | grep -c . || true) if [ "$MATCH_COUNT" -eq 0 ]; then - echo "No file under .workbench/ references branch $BRANCH, skipping." + echo "No file under .fathom/ references branch $BRANCH, skipping." exit 0 fi if [ "$MATCH_COUNT" -gt 1 ]; then - echo "Multiple files under .workbench/ reference branch $BRANCH; refusing to guess:" + echo "Multiple files under .fathom/ reference branch $BRANCH; refusing to guess:" echo "$MATCHES" exit 1 fi diff --git a/skills/workbench-shared/trackers/linear.md b/skills/fathom-shared/trackers/linear.md similarity index 96% rename from skills/workbench-shared/trackers/linear.md rename to skills/fathom-shared/trackers/linear.md index 529e5ba..28494bf 100644 --- a/skills/workbench-shared/trackers/linear.md +++ b/skills/fathom-shared/trackers/linear.md @@ -75,11 +75,11 @@ When the user accepts, record `installed`; when they decline, record `declined` It needs a `LINEAR_API_KEY` repository secret, a personal API key from Linear's settings, and the workflow state id that the profile maps to the `done` phase. Read that state id from the same list-issue-statuses call used during first-run setup, and substitute it into the template before writing the file. -Write it to `.github/workflows/workbench-close.yml`, commit it with the profile, and record `merge-closer: installed` so the sweep knows the Action owns the closure and only backstops it. +Write it to `.github/workflows/fathom-close.yml`, commit it with the profile, and record `merge-closer: installed` so the sweep knows the Action owns the closure and only backstops it. The file-discovery and ref-extraction block in this template is intentionally identical to the one in `asana.md`'s template; a change to either copy must be applied to both. ```yaml -name: workbench-close +name: fathom-close on: pull_request: @@ -112,15 +112,15 @@ jobs: # A branch must map to exactly one record; closing an issue picked # arbitrarily from several matches could complete the wrong one. - MATCHES=$(grep -rlF "$BRANCH" .workbench/ 2>/dev/null | sort) + MATCHES=$(grep -rlF "$BRANCH" .fathom/ 2>/dev/null | sort) MATCH_COUNT=$(printf '%s' "$MATCHES" | grep -c . || true) if [ "$MATCH_COUNT" -eq 0 ]; then - echo "No file under .workbench/ references branch $BRANCH, skipping." + echo "No file under .fathom/ references branch $BRANCH, skipping." exit 0 fi if [ "$MATCH_COUNT" -gt 1 ]; then - echo "Multiple files under .workbench/ reference branch $BRANCH; refusing to guess:" + echo "Multiple files under .fathom/ reference branch $BRANCH; refusing to guess:" echo "$MATCHES" exit 1 fi diff --git a/skills/scaffold/SKILL.md b/skills/scaffold/SKILL.md index 0f6fbd3..707b939 100644 --- a/skills/scaffold/SKILL.md +++ b/skills/scaffold/SKILL.md @@ -18,7 +18,7 @@ Do not edit MCP or agent configuration. Treat a disabled server as a deliberate user decision, a stop condition, never an obstacle to route around. This skill turns requirements into a scaffolded tracker issue plus its linked sub-issues. -In ask mode nothing is created in the tracker before the user approves the draft; in auto mode the scaffold is created without that approval, per `../workbench-shared/approval.md`. +In ask mode nothing is created in the tracker before the user approves the draft; in auto mode the scaffold is created without that approval, per `../fathom-shared/approval.md`. Tracker access goes only through the connected tracker MCP; when it is missing, stop and say so; never hunt for credentials on disk or call tracker APIs directly. This skill never writes task-memory or checklist files; the execute skill creates task memory when it runs its breakdown. @@ -27,22 +27,22 @@ This skill never writes task-memory or checklist files; the execute skill create Before doing any tracker work, read: These paths are relative to the directory containing this SKILL.md file, not the current workspace. -In a global Kiro install they resolve under `~/.kiro/skills/` (for example `~/.kiro/skills/workbench-shared/trackers.md`); in a Claude Code plugin install they resolve inside the plugin's `skills/` directory. +In a global Kiro install they resolve under `~/.kiro/skills/` (for example `~/.kiro/skills/fathom-shared/trackers.md`); in a Claude Code plugin install they resolve inside the plugin's `skills/` directory. -- `../workbench-shared/trackers.md` for the tracker contract and the tracker profile default destination. -- `../workbench-shared/agents.md` for the per-agent notes, including the structured question mechanism to prefer whenever this procedure asks the user anything. -- `../workbench-shared/approval.md` for the two approval modes, and for the stops that hold in both. +- `../fathom-shared/trackers.md` for the tracker contract and the tracker profile default destination. +- `../fathom-shared/agents.md` for the per-agent notes, including the structured question mechanism to prefer whenever this procedure asks the user anything. +- `../fathom-shared/approval.md` for the two approval modes, and for the stops that hold in both. If any of these files cannot be found and read, stop immediately and report which paths were tried - never improvise their contracts from memory or proceed without them. ## Procedure -1. Resolve the approval mode per `../workbench-shared/approval.md` and state it. - Then determine whether the tracker is already settled, in the shared precedence order from `../workbench-shared/trackers.md`: the invocation names one, a profile records one, or exactly one tracker MCP is connected; an invocation-named tracker wins over the profile. - When it is settled, run preflight verification against that tracker as described in `../workbench-shared/trackers.md`; stop there when the tracker's MCP does not verify. +1. Resolve the approval mode per `../fathom-shared/approval.md` and state it. + Then determine whether the tracker is already settled, in the shared precedence order from `../fathom-shared/trackers.md`: the invocation names one, a profile records one, or exactly one tracker MCP is connected; an invocation-named tracker wins over the profile. + When it is settled, run preflight verification against that tracker as described in `../fathom-shared/trackers.md`; stop there when the tracker's MCP does not verify. This skill creates tracker issues and never opens a review, so the forge's state does not gate it; a repository with no usable forge can still be scaffolded. When it is not settled, because no profile exists and both tracker MCPs are connected, do not guess which MCP to verify: defer preflight to step 3, which asks the tie-break question first and then runs preflight against the answer. -2. Run the done-on-merge sweep for the resolved tracker, whose tracker-agnostic mechanics are in `../workbench-shared/trackers.md`; it is tracker work, so it only runs once preflight has verified the MCP. +2. Run the done-on-merge sweep for the resolved tracker, whose tracker-agnostic mechanics are in `../fathom-shared/trackers.md`; it is tracker work, so it only runs once preflight has verified the MCP. When preflight was deferred in step 1, defer this sweep with it; step 3 runs both once the tracker is chosen. 3. Resolve the tracker, then the destination. - There is no existing issue ref to infer the tracker from, so this step settles the tracker explicitly. @@ -54,7 +54,7 @@ If any of these files cannot be found and read, stop immediately and report whic - Otherwise resolve the tracker profile's configured default destination. - When there is no hint and no configured default, call `listDestinations`, list them to the user, and ask once which one to use; do not infer a destination from any other source. - A suggestion drawn from prior issues in the repo may accompany that question, but the question must still be asked and answered before anything is created. - - When the repository has no tracker profile at all, run first-run setup from `../workbench-shared/trackers.md` to completion before showing the issue draft: all six of its steps in order, confirming the destination, the state mapping, the forge, the adapter's profile-load offers such as the merge-closer question, the base branch, and the approval mode. + - When the repository has no tracker profile at all, run first-run setup from `../fathom-shared/trackers.md` to completion before showing the issue draft: all six of its steps in order, confirming the destination, the state mapping, the forge, the adapter's profile-load offers such as the merge-closer question, the base branch, and the approval mode. Ask each setup question on its own and get its answer before asking the next; never show the issue draft while a setup question is still unanswered. 4. Gather the requirements before drafting. - Take them from the invocation itself when the text is there.