The orchestrator was running `git add ./TODO/` and `git commit -m
chore(todo): ...` itself in Phase 9, baking filesystem-tracker
specifics into commands/workflow.md. The point of @pm as an
abstraction is that it should be swappable — a Linear-backed @pm or a
Notion-backed @pm should drop in without touching the workflow
command. With API-backed trackers, "commit the TODO updates" is a
no-op and `git add ./TODO/` is wrong.
Push persistence shape behind the @pm boundary:
- New @pm capability `Commit pending changes` accepts a commit message
and returns {ok, sha, message}. Filesystem @pm runs `git add ./TODO/`
+ `git commit -m <msg>` and returns the SHA. Tracker-backed
implementations no-op and return sha: null.
- @pm gains tightly-scoped bash access: `git add ./TODO/*`,
`git commit -m *`, `git status --porcelain ./TODO/*` only. Push,
reset, rebase, checkout, branch, tag are explicit denies. Everything
else falls through to the default deny.
- Phase 9 "Commit TODO Changes" replaces orchestrator-side git with a
@pm dispatch; orchestrator constructs the message from run context
and captures the returned SHA for the summary.
- Failure Handler gains a step 5 (commit pending after the failure
comment add). Today the comment is left uncommitted in the working
tree and gets discarded with the throwaway worktree (ADR-14) —
forensic loss. With this change the failure note lands as its own
commit on the failed branch.
- Routing matrix Phase 9 rows updated; ADR-22's superseded wording
about orchestrator-side staging removed.
Stub-pass / body-pass / wip code commits remain orchestrator-owned —
those are code, not tracker-specific.
Refs: config/opencode/workflow-design.md ADR-23
In recent runs the orchestrator skipped @pm and edited TODO/ files
itself, despite the workflow.md anti-pattern warning. Root cause: the
workflow doc literally taught the orchestrator the path layout
(`./TODO/<ID>.md`), making self-help a discoverable shortcut.
Fix: remove the recipe. The orchestrator now never constructs or reads
any per-issue TODO path. All TODO operations go through @pm dispatches;
@pm returns the absolute file path of every issue it touches, and the
orchestrator captures and reuses those paths downstream.
- Phase 1 loses the TODO-existence and depends-on checks (former steps
3 and 9 of the recent edit) — Phase 1 is now git/worktree-only.
- Phase 2 expands @pm's existing dispatch into a `Validate run
prerequisites` operation that returns either {ok: true,
issue_file_path, issue: {...}} or {ok: false, error_code, message}
with error_code in {tracker_missing, issue_not_found,
dependency_unmet, dependency_missing}. depends-on enforcement moves
here.
- Phase 7 split_needed exit, Phase 9 TODO Update, Phase 9 Commit TODO
Changes, and Failure Handler all reference @pm-returned paths or use
`git add ./TODO/` blanketly (safe because Phase 1 verified clean tree
and only @pm writes there during a run).
- pm.md gains a path-return rule: every read returns issue_file_path,
every write returns the modified paths. Run-Prerequisite Output
format documented with all four error codes.
- ADR-22 captures the rationale; routing matrix updates Phase 1/2 rows;
pipeline diagram labels updated.
The fix is discoverability-only — no permission deny on TODO/, per
explicit user direction. The schema lives in agents/pm.md, which the
orchestrator does not load.
Refs: config/opencode/workflow-design.md ADR-22
@pm originally had two read modes — git-ref (via `git show <ref>:TODO.md`)
and filesystem. Git-ref existed because the workflow once ran in a bare
repo with no working tree. Once the workflow was simplified to assume
opencode is launched in the worktree, every dispatch (Phase 2 read,
Phase 9 update, Failure handler) uses filesystem mode. Git-ref mode
became dead weight: it added bash permissions, an allowlist, a "Bash
Discipline" section, and a dual-mode "How to Read" section, but the
workflow never invoked it. A reviewer correctly flagged the resulting
inconsistency between the two-mode docs and the single-mode usage.
@pm is now single-mode. Bash access is removed (bash: false, no
permission allowlist). The "How to Read" section collapses to "you
operate on TODO/ via the filesystem only" with one explicit pointer
that ad-hoc historical reads (`git show main:TODO/GAL-39.md`) are
out of scope — the user can run that themselves.
The workflow drops the now-redundant "(live filesystem mode)"
qualifier from Phase 2 / Phase 9 / Failure handler dispatches and
the Roles & Dispatch table updates @pm's constraint to "No bash."
The single TODO.md schema is replaced by a Linear-style folder layout
matching the user's existing setup at /home/harald/git/bglga/TODO:
TODO/
├── README.md # category-grouped index (top-level only)
├── GAL-1.md
├── GAL-2.md
└── …
Each issue file has YAML frontmatter (id, title, status, parent,
labels) and a body with optional sections (Sub-issues, Acceptance
criteria, Integration test hints, Comments). The status set shrinks
to Todo / In Progress / Done; Branch / PR / Priority / Assignee
fields are gone. Comments are date-only.
@pm gains directory-walking semantics (still scoped to TODO/), bash
allowlist additions for git ls-tree and ls, and a propagation rule:
status flips to/from Done update the dependent index — README.md for
top-level issues, or the parent file's Sub-issues line for sub-issues.
The workflow's Phase 1 sanity check now verifies TODO/, TODO/README.md,
and TODO/<ID>.md all exist. Phase 2 reads the issue file and flips Todo
to In Progress with index propagation. Phase 9 stages everything under
TODO/ as a separate atomic chore(todo) commit, sets the status to Done
(or leaves In Progress for incomplete runs), and adds a date + branch +
commit comment. Failure handler routes through the same directory.
Gives @pm narrowly-scoped bash access (git show *, git rev-parse *) so
it can read TODO.md directly from any git ref. The workflow no longer
needs to mktemp + redirect the file before invoking the agent; Phase 2
just tells @pm the bare repo path and default branch and lets it run
git show "$DEFAULT_BRANCH:TODO.md" itself. Cleanup steps for the temp
snapshot are removed from Phase 10 and the failure handler.
Drops all GitHub-specific tooling (gh CLI, draft PR creation) so the
workflow stops at git commit and leaves push/PR/MR to the user.
TODO.md is now expected to be a tracked file on the default branch.
Phase 1 verifies the repo is bare via `git rev-parse --is-bare-repository`,
resolves the default branch from HEAD / init.defaultBranch, and snapshots
TODO.md via `git show "$DEFAULT_BRANCH:TODO.md"` to a tempfile that @pm
reads in Phase 2. Phase 10 updates the live TODO.md inside the worktree
and commits the change separately. The /review command drops its PR
mode for the same reason; @pm documents the read-only-snapshot vs.
live-worktree path distinction.
Adds @check, @simplify, @test, @make, @pm subagents and the /workflow
and /review slash commands from the autonomous multi-agent workflow
gist by ppries.
@pm is rewritten to manage issues in a local ./TODO.md file instead of
Linear (file-only access, documented schema, structured JSON output).
/workflow is adapted: TODO.md-based issue context, generic worktree
paths (no hardcoded ~/repos/veo/sunstone), generic branch examples,
and a Phase 1 guard that verifies origin is on GitHub before any
work begins.