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
Forgejo's Mermaid parser is stricter than GitHub's and rejected two
diagrams in workflow-design.md:
1. Flowchart 3.1 — `@check`, `@test`, `@make` in pipe-delimited edge
labels were tokenised as LINK_ID (newer Mermaid uses `@{...}` for
edge IDs), e.g. `P7E -->|@check → @test → @make| P7` failed at
the first @.
2. State diagram 3.2 — the second colon inside transition labels
(`escalate: test_design`) collided with the `:` field separator
that splits transition from label.
Drops the @-prefix from labels in all three diagrams (`@check` → `check`
in prose-of-the-label only; ADRs and prose elsewhere keep `@check`
backticked, which is just markdown). Replaces second colons with
descriptive text. Drops parentheses from state-diagram transition
labels. Drops the Unicode arrow `→` in favour of plain words.
Quotes the flowchart node-label strings to keep `<br/>` safe.
The ADR text and prose continue to use `@<name>` references — those
live in markdown, not Mermaid, and render the same.
Operational rules in commands/workflow.md and the agent files have
been accreting through repeated patches, with the rationale scattered
across commit messages and conversations. New gaps kept surfacing
after the fact (Phase 7 mid-impl escalation, Phase 8 routing for
test-design findings, Phase 5.5 entirely missing) because there was
no single place to audit the flow.
Adds config/opencode/workflow-design.md as a sibling to commands/
and agents/. It is the design rationale and decision log; operational
rules stay in the command and agent files. The intended flow is:
discuss new ideas / failure modes here → reach a decision → update
the operational files → record the decision in the ADR log.
Pre-populated with: cast & responsibilities table; three Mermaid
diagrams (phase pipeline, Phase 7 escalation state machine, issue
lifecycle); a routing matrix that lists every observed (phase,
signal) → action pair so gaps are visible at a glance; 12 ADRs
covering decisions made over the past several days (forge-agnostic,
TODO/ folder, worktree-only, polyglot agents, absolute-path dispatch,
run artifacts on disk, stub-first Rust TDD, @test inside cfg(test)
mod, Phase 5.5, single-mode @pm, file follow-ups, Phase 7 mid-impl
escalation); and 5 open questions teed up for future discussion.