@open-agent-toolkit/cli 0.1.39 → 0.1.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/assets/docs/cli-utilities/backlog-lifecycle.md +61 -0
  2. package/assets/docs/cli-utilities/config-and-local-state.md +47 -0
  3. package/assets/docs/cli-utilities/configuration.md +2 -0
  4. package/assets/docs/cli-utilities/index.md +1 -0
  5. package/assets/docs/provider-sync/instruction-sync.md +1 -0
  6. package/assets/docs/workflows/projects/dispatch-ceiling.md +14 -3
  7. package/assets/docs/workflows/projects/implementation-execution.md +16 -2
  8. package/assets/public-package-versions.json +4 -4
  9. package/assets/skills/oat-pjm-review-backlog/SKILL.md +29 -7
  10. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +25 -5
  11. package/assets/skills/oat-project-implement/SKILL.md +41 -10
  12. package/assets/templates/pjm-agents.md +80 -1
  13. package/assets/templates/pjm-handoffs-readme.md +21 -0
  14. package/assets/templates/reference-agents.md +13 -0
  15. package/assets/templates/repo-agents.md +4 -0
  16. package/assets/templates/repo-readme.md +35 -0
  17. package/dist/commands/backlog/archive.d.ts +33 -0
  18. package/dist/commands/backlog/archive.d.ts.map +1 -0
  19. package/dist/commands/backlog/archive.js +229 -0
  20. package/dist/commands/backlog/index.d.ts +2 -0
  21. package/dist/commands/backlog/index.d.ts.map +1 -1
  22. package/dist/commands/backlog/index.js +56 -2
  23. package/dist/commands/backlog/regenerate-index.d.ts +5 -1
  24. package/dist/commands/backlog/regenerate-index.d.ts.map +1 -1
  25. package/dist/commands/backlog/regenerate-index.js +7 -1
  26. package/dist/commands/backlog/shared/item-status.d.ts +13 -0
  27. package/dist/commands/backlog/shared/item-status.d.ts.map +1 -0
  28. package/dist/commands/backlog/shared/item-status.js +34 -0
  29. package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
  30. package/dist/commands/instructions/instructions.utils.js +24 -0
  31. package/dist/commands/pjm/doctor.d.ts.map +1 -1
  32. package/dist/commands/pjm/doctor.js +161 -0
  33. package/dist/commands/pjm/index.d.ts.map +1 -1
  34. package/dist/commands/pjm/index.js +2 -1
  35. package/dist/commands/pjm/init.d.ts +2 -1
  36. package/dist/commands/pjm/init.d.ts.map +1 -1
  37. package/dist/commands/pjm/init.js +7 -0
  38. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  39. package/dist/commands/project/dispatch-ceiling/index.js +80 -4
  40. package/package.json +2 -2
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Backlog Lifecycle
3
+ description: The states a file-backed backlog item moves through, how oat backlog archive closes it out atomically, and how oat pjm doctor catches lifecycle drift.
4
+ ---
5
+
6
+ # Backlog Lifecycle
7
+
8
+ The file-backed backlog under `.oat/repo/pjm/backlog/` tracks work as one Markdown file per item. This page describes the lifecycle those items move through, the atomic close-out command that keeps the pieces in sync, and the diagnostics that flag drift when a close-out is done by hand and something is missed.
9
+
10
+ For the flag-by-flag command reference, see [`oat backlog archive`](config-and-local-state.md#oat-backlog-archive). For the two-layer PJM surface that hosts the backlog, see [Tool Packs](tool-packs.md#install-vs-initialize).
11
+
12
+ ## Where a backlog item lives
13
+
14
+ - **`items/<id>.md`** - active, file-backed records. Each carries frontmatter with a `status` and an `updated` timestamp.
15
+ - **`archived/<id>.md`** - the resting place for closed-out items, preserving the full item file as history.
16
+ - **`completed.md`** - a newest-first summary log of completed work, one line per entry (`YYYY-MM-DD — BL-YYMMDD-slug — Title — one-line outcome`).
17
+ - **`index.md`** - the human-facing curated overview plus a managed, generated index table rebuilt from item frontmatter.
18
+
19
+ ## Item statuses
20
+
21
+ An item's `status` frontmatter field is one of exactly four values:
22
+
23
+ - `open` - captured, not yet started.
24
+ - `in_progress` - actively being worked.
25
+ - `closed` - completed.
26
+ - `wont_do` - abandoned or intentionally declined.
27
+
28
+ `closed` and `wont_do` are the two **terminal** statuses. These are the only valid values — never invent variants like `done`. A terminal item belongs in `archived/`, not `items/`.
29
+
30
+ ## Closing out an item
31
+
32
+ When an item reaches a terminal state, close it out with the atomic command rather than editing files by hand:
33
+
34
+ ```bash
35
+ # completed work
36
+ oat backlog archive BL-260705-example --summary "shipped the thing"
37
+
38
+ # abandoned work
39
+ oat backlog archive BL-260705-example --wont-do --summary "superseded by BL-260706-other"
40
+ ```
41
+
42
+ A single `oat backlog archive` run performs the whole close-out so its parts cannot drift apart:
43
+
44
+ 1. Sets the terminal `status` (`closed` by default, `wont_do` with `--wont-do`) and stamps `updated`.
45
+ 2. Appends a canonical newest-first entry to `completed.md`. `closed` items always get an entry (with a visible `TODO: summarize outcome` placeholder when `--summary` is omitted, so the gap stays visible); `wont_do` items get one only when you pass `--summary`.
46
+ 3. Moves `items/<id>.md` into `archived/` — with `git mv` inside a work tree, or a plain rename outside git.
47
+ 4. Regenerates the managed backlog index.
48
+
49
+ The command is safe to re-run: an item already in `archived/` produces a no-op warning with no writes. An out-of-enum current status (for example a hand-set `done`) is a hard error that names the file, lists the valid statuses, and tells you how to recover. See the [command reference](config-and-local-state.md#oat-backlog-archive) for exit codes and the `--json` payload.
50
+
51
+ ## Catching lifecycle drift
52
+
53
+ The manual close-out this command replaces is exactly where the two motivating repos drifted — an item was marked closed in frontmatter and summarized in `completed.md` but never moved to `archived/`, and one shipped with the invalid status `done`. `oat pjm doctor` (and therefore `oat doctor`, which aggregates the `pjm:*` checks) now surfaces that drift:
54
+
55
+ - **`pjm:backlog_terminal_in_items`** (fail) - a `closed` or `wont_do` item is still sitting in `items/`. Fix: run `oat backlog archive <id>` to finish the move.
56
+ - **`pjm:backlog_invalid_status`** (fail) - an item carries an out-of-enum or missing `status`. The message lists the offending file paths and the valid statuses.
57
+ - **`pjm:backlog_archived_open`** (warn) - an `open` or `in_progress` item is in `archived/`, which usually means it was archived prematurely.
58
+ - **`pjm:backlog_completed_unarchived`** (warn) - `completed.md` references an item whose file still lives in `items/`.
59
+ - **`pjm:backlog_duplicate_id`** (fail) - the same `<id>.md` exists in both `items/` and `archived/`. `oat backlog archive` refuses to auto-resolve this (it would clobber the archived record), so the duplicate must be reconciled by hand.
60
+
61
+ Doctor reports drift; it never auto-fixes. A human or agent runs `oat backlog archive` (or corrects the status) and re-runs doctor to confirm the backlog is clean again.
@@ -16,12 +16,59 @@ Use the `oat backlog` group when you want direct CLI support for the file-backed
16
16
  - `oat backlog init` - scaffold `.oat/repo/pjm/backlog/` with starter files and directories for a fresh repo
17
17
  - `oat backlog generate-id <title>` - generate a deterministic `BL-YYMMDD-slug` backlog ID from a title
18
18
  - `oat backlog generate-id <title> --created-at <timestamp>` - generate a reproducible ID for a known creation timestamp
19
+ - `oat backlog archive <id>` - atomic close-out: set a terminal status, record the completion in `completed.md`, move the item into `archived/`, and regenerate the index in one step
19
20
  - `oat backlog regenerate-index` - rebuild the managed backlog index table from item frontmatter
20
21
 
21
22
  Backlog IDs are deterministic date+slug identifiers (`BL-YYMMDD-slug`) derived from the creation date and title, so two machines or worktrees produce the same ID for the same record without scanning the local checkout. The slug is capped at 30 characters at the last whole-word boundary (with trailing stop-words trimmed), so prefer concise, meaningful titles. Index regeneration is deterministic and safe to re-run when resolving an index merge conflict.
22
23
 
23
24
  Run `oat backlog init` first when the local backlog scaffold does not exist yet in a fresh repo. This command group is primarily used by the `oat-pjm-*` project-management skills, but it is also available directly when you need to inspect or repair backlog metadata by hand.
24
25
 
26
+ For the end-to-end states an item moves through — and how `oat backlog archive` and `oat pjm doctor` keep the backlog honest — see [Backlog Lifecycle](backlog-lifecycle.md).
27
+
28
+ ### `oat backlog archive`
29
+
30
+ `oat backlog archive <id> [--wont-do] [--summary <text>] [--json] [--backlog-root <path>]` performs the full close-out for a backlog item so status flip, completed-log entry, file move, and index regeneration never drift apart.
31
+
32
+ **Arguments and flags:**
33
+
34
+ - `<id>` (required) - the backlog item id (`BL-YYMMDD-slug`); the item file must live under `items/`.
35
+ - `--wont-do` - close the item as `wont_do` instead of the default terminal status `closed`.
36
+ - `--summary <text>` - one-line outcome summary recorded in `completed.md`.
37
+ - `--backlog-root <path>` - override the backlog root (defaults to `.oat/repo/pjm/backlog`).
38
+ - `--json` - emit the machine-readable result payload instead of human log lines.
39
+
40
+ **Behavior:**
41
+
42
+ - Validates the item's current `status` against the enum (`open | in_progress | closed | wont_do`); an out-of-enum value such as `done` is a hard error with a fix hint. Archiving is legal from any valid status — a `closed` item still in `items/` just gets its move finished.
43
+ - Rewrites only the `status:` and `updated:` frontmatter lines (preserving any inline enum comment), then moves the item from `items/` to `archived/` with `git mv` inside a work tree, falling back to a plain rename (with a warning) outside git or if `git mv` fails.
44
+ - `closed` archives always append a canonical newest-first `completed.md` entry (`YYYY-MM-DD — <id> — Title — summary`); when `--summary` is omitted the entry carries a visible `TODO: summarize outcome` placeholder. `wont_do` archives append an entry only when `--summary` is provided. A missing `completed.md` is scaffolded from the starter template; a missing `## Completed Items` heading is scaffolded with a warning.
45
+ - Regenerates the managed backlog index after the move.
46
+ - Idempotent: re-running on an item already in `archived/` is a no-op warning with no writes.
47
+
48
+ **Exit codes:**
49
+
50
+ - `0` - item archived, or already-archived no-op.
51
+ - `1` - actionable error: unknown id (no file under `items/`) or an out-of-enum current status. The message names the file path, the valid statuses, and the fix.
52
+ - `2` - reserved for unexpected system/runtime failures.
53
+
54
+ **JSON payload (`--json`):**
55
+
56
+ On success the payload is the archive result object:
57
+
58
+ ```json
59
+ {
60
+ "id": "BL-260705-example",
61
+ "result": "archived",
62
+ "status": "closed",
63
+ "completedEntry": "written",
64
+ "movedTo": ".oat/repo/pjm/backlog/archived/BL-260705-example.md",
65
+ "indexRegenerated": true,
66
+ "warnings": []
67
+ }
68
+ ```
69
+
70
+ `result` is `archived` or `noop` (already archived); `completedEntry` is `written`, `scaffolded`, or `skipped` (e.g. a `wont_do` archive without `--summary`); `movedTo` is the destination path or `null`. On an actionable failure the payload is `{ "result": "error", "id": "<id>", "message": "<why + fix>" }`.
71
+
25
72
  For full project-management repo-reference setup, use [`oat pjm init`](tool-packs.md#install-vs-initialize). It scaffolds the two-layer PJM surface (`pjm/current-state.md`, `pjm/roadmap.md`, `reference/decisions/`, and AGENTS guides) and delegates the backlog sub-surface to `oat backlog init`.
26
73
 
27
74
  ## `oat decision ...`
@@ -232,6 +232,8 @@ reading config keys directly:
232
232
 
233
233
  ```bash
234
234
  oat project dispatch-ceiling resolve --provider codex --json
235
+ oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
236
+ oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --orchestrator-tier sonnet --json
235
237
  oat project dispatch-ceiling resolve --provider claude --orchestrator-tier sonnet --json
236
238
  ```
237
239
 
@@ -15,6 +15,7 @@ Use this section when you want bootstrap guidance, tool-pack lifecycle details,
15
15
  - [Tool Packs and Installed Assets](tool-packs.md) - Bundled packs and `oat tools` lifecycle commands.
16
16
  - [Configuration](configuration.md) - OAT configuration guidance across shared, local, user, and provider-sync surfaces.
17
17
  - [Config and Local State](config-and-local-state.md) - Utility command groups for config, local state, diagnostics, and related inspection flows.
18
+ - [Backlog Lifecycle](backlog-lifecycle.md) - Backlog item states, atomic close-out with `oat backlog archive`, and lifecycle drift detection in `oat pjm doctor`.
18
19
  - [Workflow Gates](workflow-gates.md) - Per-skill final commands and cross-runtime review dispatch with `oat gate`.
19
20
 
20
21
  ## What Lives Here
@@ -22,6 +22,7 @@ Instruction sync is currently project-only.
22
22
  - It scans the current repository recursively.
23
23
  - It supports nested directories all the way down the tree.
24
24
  - It skips provider-irrelevant or local-only roots such as `.git`, `.oat`, `.worktrees`, and `node_modules`.
25
+ - Exception: `.oat/repo/**` is scanned even though the rest of `.oat/` is skipped, so the curated `AGENTS.md` files there (repo root guidance, `pjm/`, `reference/`) get their sibling `CLAUDE.md` shims managed and validated like any other directory. The rest of `.oat/` (`templates/`, `projects/`, `sync/`) stays excluded.
25
26
  - It does not scan user-level provider roots such as `~/.claude` in this release.
26
27
 
27
28
  ## Canonical Model
@@ -61,11 +61,20 @@ Before dispatching a subagent, the orchestrator calls:
61
61
  oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --preflight --json
62
62
  ```
63
63
 
64
+ For implementer or fix dispatch, pass the runtime classification too. In Codex
65
+ this is the preferred effort; in Claude it is the preferred model tier:
66
+
67
+ ```bash
68
+ oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
69
+ oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --json
70
+ ```
71
+
64
72
  The resolver:
65
73
 
66
74
  1. reads the concrete `providers.<provider>` value (config precedence, then project state) — **never the preset label**;
67
75
  2. looks up that provider's **adapter** in the provider ceiling registry;
68
- 3. returns a per-provider result: `{ value, mode, mechanism, dispatchArgs }`.
76
+ 3. applies `--preferred` for implementer/fix dispatch, capping it against the ceiling;
77
+ 4. returns a per-provider result: `{ value, mode, mechanism, dispatchArgs, selection }`.
69
78
 
70
79
  `mode` is the honest enforcement status, computed right there and never persisted:
71
80
 
@@ -89,8 +98,8 @@ The same ceiling intent produces different — but honest — behavior per provi
89
98
 
90
99
  ### Why the mechanisms differ
91
100
 
92
- - **Codex** dispatches through **pinned, sync-time role variants**. Per-call reasoning-effort proved unreliable in practice, so OAT generates committed `oat-phase-implementer-{low..xhigh}` / `oat-reviewer-{low..xhigh}` role files and dispatches the variant matching the resolved effort.
93
- - **Claude** uses the **per-call Task `model` parameter**, which is reliable and bidirectional (a Sonnet orchestrator can dispatch an Opus subagent and vice-versa) and overrides agent frontmatter so OAT simply passes `model` at dispatch and needs no variant files.
101
+ - **Codex** dispatches through **pinned, sync-time role variants**. Per-call reasoning-effort proved unreliable in practice, so OAT generates committed `oat-phase-implementer-{low..xhigh}` / `oat-reviewer-{low..xhigh}` role files. Implementer/fix dispatch passes `--preferred` so `dispatchArgs.variant` matches the selected capped effort; reviewer dispatch uses the variant matching the resolved ceiling.
102
+ - **Claude** uses the **per-call Task `model` parameter**, which is reliable and bidirectional (a Sonnet orchestrator can dispatch an Opus subagent and vice-versa) and overrides agent frontmatter. Implementer/fix dispatch passes `--preferred` as the preferred model tier and receives the capped selected `model`; reviewer dispatch uses the ceiling model. OAT needs no variant files.
94
103
  - **Unsupported providers** (any without a registered adapter) resolve to `unsupported` with `dispatchArgs: null`. The resolve command **returns cleanly and never blocks** — the ceiling is recorded as intent and applied if/when an adapter ships, while the provider runs at its own capabilities.
95
104
 
96
105
  A **provider adapter registry** is what lets these genuinely different mechanisms sit behind one resolver, so the lifecycle skills consume `dispatchArgs` without ever branching on provider.
@@ -104,6 +113,8 @@ The ceiling means slightly different things for the two dispatch roles:
104
113
 
105
114
  Both providers honor this distinction (Codex selects the matching variant; Claude passes the matching model).
106
115
 
116
+ Generic sidecars such as built-in `explorer` are outside this implementer/reviewer/fix contract. They may run at provider default when they are read-only advisory helpers. In that case, dispatch logs should say `Preferred effort: provider-default`, `Selected effort: provider-default`, and `Effort axis: provider-default`; only log a concrete selected effort when the actual sidecar payload pins a reliable provider control.
117
+
107
118
  ## Verify-on-upgrade
108
119
 
109
120
  Only a request for a tier **above** the orchestrator's current tier risks a silent plan/entitlement fallback. So the adapter verifies the actually-dispatched model **only** on that upgrade path; capping down or staying lateral needs no check. OAT never logs `enforced` unless the requested control was actually honored.
@@ -108,9 +108,9 @@ Model and effort are separate axes. Each axis logs one of these states:
108
108
  - `not-applicable` — this host/API has no meaningful per-dispatch concept for that axis.
109
109
  - `host-auto` — exceptional; the host uses that axis internally but the orchestrator cannot read or pin it.
110
110
 
111
- In Codex, implementation and fix dispatch classify a preferred effort (`low`, `medium`, `high`, or `xhigh`) and select `min(preferred, resolved_ceiling)`. The selected effort maps to the matching pinned role: `oat-phase-implementer-low`, `oat-phase-implementer-medium`, `oat-phase-implementer-high`, or `oat-phase-implementer-xhigh`. Reviewer dispatch uses the reviewer variant matching the resolved ceiling (`oat-reviewer-low|medium|high|xhigh`) for deterministic quality gates. Base/unpinned Codex roles are provider-default fallbacks; they should be logged as `provider-default`, not as inherited parent-session ceiling.
111
+ In Codex, implementation and fix dispatch classify a preferred effort (`low`, `medium`, `high`, or `xhigh`) and pass it to `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <effort>`. The resolver selects `min(preferred, resolved_ceiling)` and returns the matching pinned role: `oat-phase-implementer-low`, `oat-phase-implementer-medium`, `oat-phase-implementer-high`, or `oat-phase-implementer-xhigh`. Reviewer dispatch uses the reviewer variant matching the resolved ceiling (`oat-reviewer-low|medium|high|xhigh`) for deterministic quality gates. Base/unpinned Codex roles are provider-default fallbacks; they should be logged as `provider-default`, not as inherited parent-session ceiling.
112
112
 
113
- In Claude Code, subagent model selection is a model axis when available and is capped by `workflow.dispatchCeiling.providers.claude` (or the compiled concrete value from a preset) or project `oat_dispatch_ceiling`. The separate effort axis is `not-applicable`.
113
+ In Claude Code, implementation and fix dispatch classify a preferred model tier (`haiku`, `sonnet`, or `opus`) and pass it to `oat project dispatch-ceiling resolve --provider claude --role implementer --preferred <model> --orchestrator-tier <current-orchestrator-tier>`. The resolver selects `min(preferred, resolved_ceiling)` and returns the `model` argument to pass at dispatch. Reviewer dispatch targets the resolved Claude ceiling directly. The separate effort axis is `not-applicable`.
114
114
 
115
115
  Dispatch logs use a consistent structured block so provider behavior is comparable without flattening the model and effort axes:
116
116
 
@@ -151,10 +151,24 @@ Model axis: host-auto
151
151
  Effort axis: host-auto
152
152
  Dispatch target: host default
153
153
  Rationale: host does not expose readable or pinnable dispatch controls; rationale maps to standard effort.
154
+
155
+ OAT Dispatch: p02-t10 sidecar exploration
156
+ Host: Codex
157
+ Preferred effort: provider-default
158
+ Dispatch ceiling: xhigh
159
+ Selected effort: provider-default
160
+ Ceiling source: project state
161
+ Provider default effort: xhigh
162
+ Model axis: inherited
163
+ Effort axis: provider-default
164
+ Dispatch target: explorer
165
+ Rationale: read-only sidecar exploration; generic explorer payload does not pin an OAT-managed effort variant.
154
166
  ```
155
167
 
156
168
  Phase and review scope packets include dispatch context when the orchestrator has resolved it: `model_axis`, `effort_axis`, `dispatch_ceiling`, `ceiling_source`, `provider_default_effort`, and `dispatch_rationale`.
157
169
 
170
+ Generic sidecars such as built-in `explorer` are not OAT-managed implementer, reviewer, or fix roles. If a sidecar payload does not pin a reliable effort/model control, log it as provider-default rather than classifying the task complexity as a selected effort. Sidecar results are advisory context; implementation and review/fix gates still follow the OAT-managed dispatch rules above.
171
+
158
172
  ### Dispatch Profile overrides
159
173
 
160
174
  `plan.md` should omit `## Dispatch Profile` by default. Missing dispatch rows are normal, because runtime selection has fresher phase context and host capability information at execution time.
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.1.39",
3
- "docs-config": "0.1.39",
4
- "docs-theme": "0.1.39",
5
- "docs-transforms": "0.1.39"
2
+ "cli": "0.1.41",
3
+ "docs-config": "0.1.41",
4
+ "docs-theme": "0.1.41",
5
+ "docs-transforms": "0.1.41"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-pjm-review-backlog
3
- version: 1.3.0
3
+ version: 1.4.0
4
4
  description: Use when prioritizing the file-backed repo backlog or evaluating roadmap alignment. Produces value-effort ratings, dependency mapping, and execution recommendations.
5
5
  argument-hint: '[backlog-root] [--roadmap=<path>] [--output=<path>]'
6
6
  disable-model-invocation: true
@@ -48,12 +48,13 @@ When executing this skill, provide lightweight progress feedback so the user can
48
48
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
49
49
 
50
50
  - Before multi-step work, print short step indicators, e.g.:
51
- - `[1/6] Resolving backlog inputs…`
52
- - `[2/6] Cataloging backlog items…`
53
- - `[3/6] Reading codebase context…`
54
- - `[4/6] Writing review document…`
55
- - `[5/6] Summarizing recommendations…`
56
- - `[6/6] (Optional) Priority-alignment walkthrough…` — only print after the operator accepts the offer in Step 9
51
+ - `[1/7] Resolving backlog inputs…`
52
+ - `[2/7] Cataloging backlog items…`
53
+ - `[3/7] Reading codebase context…`
54
+ - `[4/7] Writing review document…`
55
+ - `[5/7] Summarizing recommendations…`
56
+ - `[6/7] (Optional) Priority-alignment walkthrough…` — only print after the operator accepts the offer in Step 9
57
+ - `[7/7] (Optional) Refreshing project kickoff handoffs…` — only print after the operator agrees a kickoff stack in Step 10
57
58
 
58
59
  ## Arguments
59
60
 
@@ -225,6 +226,26 @@ If the operator declines, stop after the summary. Do not silently write or modif
225
226
 
226
227
  When referencing backlog items inside the priority-alignment doc, the **Reference Format Convention** still applies — link to the item file and pair the ID with a human-readable title.
227
228
 
229
+ ### Step 10: Refresh Project Kickoff Handoffs (Optional)
230
+
231
+ When a priority-alignment pass concludes (Step 9), generate or refresh one **kickoff handoff** per item in the agreed kickoff stack. A handoff is a one-shot kickoff prompt — consumable context for turning a backlog item into a project, not durable documentation. The item file and `reference/` remain the source of truth. Handoffs live under `.oat/repo/pjm/handoffs/`; see that directory's `README.md` for the convention (generated by `oat pjm init`).
232
+
233
+ This step mirrors the **Project Kickoff Handoffs** section of the pjm instruction template (`pjm/AGENTS.md`) — follow that section's semantics; do not invent divergent wording. It is **collaborative and human-gated**: kickoff-stack membership, lane count, and ordering are the operator's decisions from Step 9. Present them; do not choose them. Do not generate handoffs for parked or queued items until they are actually next.
234
+
235
+ **When to run:** only after the operator has agreed a kickoff stack in the Step 9 walkthrough. If Step 9 was declined or produced no kickoff stack, skip this step.
236
+
237
+ **For each item in the agreed kickoff stack**, write or refresh `.oat/repo/pjm/handoffs/<BL-id>.md` with:
238
+
239
+ - the backlog item reference — its ID **and** human-readable title **and** path (never a bare ID);
240
+ - the recommended project mode (`oat-project-quick-start` vs `oat-project-new`), including which artifacts (spec/design/plan) to pre-populate from existing research when it exists;
241
+ - authoritative input pointers (research directories, decision records, code paths);
242
+ - repo conventions and verification gates the item file does not restate;
243
+ - a close-out section requiring (a) the **Backlog Lifecycle** — `oat backlog archive <id>` — executed in the same PR that ships the item, and (b) deletion of the handoff file (`git rm`) in that same PR.
244
+
245
+ **Staleness:** if this alignment pass drops an item from the kickoff stack, delete its handoff (`git rm .oat/repo/pjm/handoffs/<BL-id>.md`) in the same pass rather than letting it drift.
246
+
247
+ Every backlog item reference in a handoff — like every reference in review output and alignment docs — pairs the ID with its human-readable title per the **Reference Format Convention**. No bare IDs.
248
+
228
249
  ## Success Criteria
229
250
 
230
251
  - Every active backlog item file has a value-effort rating with rationale
@@ -234,4 +255,5 @@ When referencing backlog items inside the priority-alignment doc, the **Referenc
234
255
  - Output document follows the review template structure
235
256
  - Living review is written to `.oat/repo/pjm/backlog/reviews/backlog-and-roadmap-review.md` (unless `--output` is explicitly overridden); dated snapshots, when emitted, live in the same `backlog/reviews/` directory and never under `.oat/repo/reviews/`
236
257
  - The operator is offered (but never forced into) a collaborative walkthrough that produces or updates `backlog/reviews/priority-alignment.md`; if the operator accepts, the file is written using the priority-alignment template and includes a Changelog entry for this pass; if the operator declines, no file is created or modified
258
+ - When a priority-alignment pass produces an agreed kickoff stack, one handoff per kickoff-stack item is written or refreshed under `.oat/repo/pjm/handoffs/` (with item reference, recommended mode, input pointers, repo conventions/gates, and a close-out requiring the Backlog Lifecycle executed and the handoff deleted in the same shipping PR); handoffs for reprioritized-out items are deleted in the same pass; kickoff-stack membership, lane count, and ordering remain human decisions the skill presents rather than chooses
237
259
  - Every user-facing reference to a backlog item pairs the ID with a human-readable title (per the Reference Format Convention)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-pjm-update-repo-reference
3
- version: 1.2.0
3
+ version: 1.3.0
4
4
  description: Use when repo reference artifacts need updating — roadmap, decision records, backlog status, or completed history. Frequently invoked at project completion, often chained from `oat-project-document`, to ensure active `.oat/repo/pjm/` state and durable `.oat/repo/reference/` records reflect what shipped.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -69,7 +69,11 @@ For recently completed or in-progress projects, read `discovery.md`, `spec.md`,
69
69
  Promote notable findings into one of:
70
70
 
71
71
  - Backlog item files under `.oat/repo/pjm/backlog/items/`
72
- - Completed summaries in `.oat/repo/pjm/backlog/completed.md`
72
+ - Completed close-outs via `oat backlog archive <id>` (see Step 4) — the atomic
73
+ command flips the item's `status`, appends the canonical
74
+ `.oat/repo/pjm/backlog/completed.md` entry, moves the item file into
75
+ `archived/`, and regenerates the index in one step. Reserve hand-editing
76
+ `completed.md` for narrative touch-ups the command does not own.
73
77
  - Decision records under `.oat/repo/reference/decisions/`, created with
74
78
  `oat decision new "<title>"` (delegate to `oat-pjm-decision` for a guided
75
79
  capture). Do not hand-author decision files or write into a legacy
@@ -89,16 +93,32 @@ Update these files as applicable:
89
93
  4. `.oat/repo/pjm/backlog/items/*.md`
90
94
  - Add or update active backlog items as file-backed records.
91
95
  5. `.oat/repo/pjm/backlog/completed.md`
92
- - Keep newest completed summaries first.
96
+ - Keep newest completed summaries first. Prefer letting `oat backlog archive <id>`
97
+ append the canonical entry (see below) over hand-editing.
93
98
  6. `.oat/repo/pjm/backlog/archived/*.md`
94
- - Add rich historical item files only when a completed item needs preserved detail.
99
+ - Item files land here automatically when you run `oat backlog archive <id>`.
100
+ Only hand-add or enrich a file here when a completed item needs preserved
101
+ detail the command did not capture.
95
102
  7. `.oat/repo/reference/decisions/`
96
103
  - Create new decisions with `oat decision new` (see `oat-pjm-decision`); the
97
104
  command writes one `DR-YYMMDD-slug` record and regenerates the managed
98
105
  decision index. Do not hand-edit `reference/decisions/index.md` inside its
99
106
  managed markers.
100
107
 
101
- If you modify backlog item files or the completed archive structure, run:
108
+ To close out a completed backlog item, run the atomic close-out command rather
109
+ than moving files by hand:
110
+
111
+ ```bash
112
+ oat backlog archive <id> --summary "one-line outcome"
113
+ # abandoned work: oat backlog archive <id> --wont-do --summary "why"
114
+ ```
115
+
116
+ This flips the item's `status` to a terminal value (`closed`/`wont_do` — never
117
+ invent variants like `done`), stamps `updated`, appends the canonical
118
+ newest-first `completed.md` entry, moves the item file from `items/` into
119
+ `archived/`, and regenerates the managed index in one step. Only when you edit
120
+ backlog files by hand outside this command (curated overview text, an enriched
121
+ `archived/` record) re-run the index regeneration:
102
122
 
103
123
  ```bash
104
124
  oat backlog regenerate-index
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-implement
3
- version: 2.0.23
3
+ version: 2.0.24
4
4
  description: Use when plan.md is ready for execution. Dispatches phase-level subagents with bounded fix loops; supports plan-declared parallel phase groups with worktree-isolated execution and ordered fan-in.
5
5
  oat_gateable: true
6
6
  argument-hint: '[--retry-limit <N>] [--dry-run]'
@@ -204,7 +204,13 @@ Resolution order:
204
204
  "mode": "enforced",
205
205
  "mechanism": "pinned-variant",
206
206
  "dispatchArgs": { "variant": "oat-phase-implementer-high" },
207
- "verifyOnDispatch": false
207
+ "verifyOnDispatch": false,
208
+ "selection": {
209
+ "role": "implementer",
210
+ "preferredValue": null,
211
+ "selectedValue": "high",
212
+ "capped": false
213
+ }
208
214
  }
209
215
  }
210
216
  }
@@ -212,8 +218,10 @@ Resolution order:
212
218
 
213
219
  Read `providers.<active-provider>` for the concrete dispatch controls. The
214
220
  `dispatchArgs` field carries the provider-specific argument to pass through
215
- (Codex: `variant` name; Claude: `model` string). Never re-derive these from the
216
- preset label the resolver is the single compilation/join point.
221
+ (Codex: `variant` name; Claude: `model` string). For implementer/fix dispatch,
222
+ pass `--preferred <preferred-effort>` and use `selection.selectedValue` as the
223
+ selected axis value. Never re-derive these from the preset label or a ceiling-only
224
+ variant — the resolver is the single compilation/join point.
217
225
 
218
226
  Print before phase work:
219
227
 
@@ -311,7 +319,7 @@ Codex rules:
311
319
  - `high`: broad architecture, security/auth/redaction boundaries, subtle state behavior, or repeated substantive review failures
312
320
  - `xhigh`: highest-risk work that requires the configured ceiling to allow xhigh
313
321
  3. Selected effort is `min(preferred, resolved_ceiling)` for implementer/fix work.
314
- 4. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer`; read `providers.codex.dispatchArgs.variant` for the role name (e.g., `oat-phase-implementer-high`). Pass that variant name directly do not re-derive it from the ceiling value.
322
+ 4. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`; read `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` for the selected role name (e.g., `oat-phase-implementer-medium`). The resolver caps the preferred effort against the ceiling; never pass a ceiling-only implementer variant when `selection.selectedValue` is lower.
315
323
  5. For review dispatch: call `oat project dispatch-ceiling resolve --provider codex --role reviewer`; read `providers.codex.dispatchArgs.variant` for the reviewer role name (e.g., `oat-reviewer-high`). Reviewer always targets the ceiling for deterministic quality gate behavior.
316
324
  6. Use base/unpinned Codex roles only as a fallback or explicit provider-default choice. Log `Selected effort: provider-default`, display provider default effort when known, and do not describe this as parent-ceiling inheritance.
317
325
  7. Do not use top-level per-call `reasoning_effort` as the standard OAT selected-effort path; dogfooding showed that path can be inconsistent.
@@ -319,9 +327,9 @@ Codex rules:
319
327
  Claude rules:
320
328
 
321
329
  - Claude ceiling is model-based: `haiku < sonnet < opus`.
322
- - Implementer dispatch: select the lowest sufficient model capped by the resolved Claude ceiling (`min(preferred, ceiling)`).
330
+ - Implementer/fix dispatch: classify the preferred model (`haiku`, `sonnet`, or `opus`) and pass it to the resolver as `--preferred <preferred-model>`. The resolver selects the lowest sufficient model capped by the resolved Claude ceiling (`min(preferred, ceiling)`).
323
331
  - Review dispatch: target the resolved Claude ceiling directly.
324
- - Call `oat project dispatch-ceiling resolve --provider claude --role implementer --orchestrator-tier <current-orchestrator-tier>` (or `--role reviewer`); read `providers.claude.dispatchArgs.model` for the model string to pass. Pass `--orchestrator-tier` so the resolver can flag above-orchestrator upgrade requests and set `verifyOnDispatch` correctly.
332
+ - For implementer/fix dispatch, call `oat project dispatch-ceiling resolve --provider claude --role implementer --preferred <preferred-model> --orchestrator-tier <current-orchestrator-tier>`; for review dispatch, call the same resolver with `--role reviewer` and no `--preferred`. Read `providers.claude.selection.selectedValue` and `providers.claude.dispatchArgs.model` for the selected model string to pass. Pass `--orchestrator-tier` so the resolver can flag above-orchestrator upgrade requests and set `verifyOnDispatch` correctly.
325
333
  - Pass `model: "<value>"` when `model_axis=selected:<value>` on the Task tool call.
326
334
  - Keep `effort_axis=not-applicable`; Claude Code has no separate per-dispatch effort axis.
327
335
 
@@ -336,7 +344,7 @@ Structured dispatch log:
336
344
  ```text
337
345
  OAT Dispatch: Phase {phase_id} {implementation | fix | review}
338
346
  Host: {Claude Code | Codex | Cursor | other host}
339
- Preferred effort: {low | medium | high | xhigh | not-applicable}
347
+ Preferred effort: {low | medium | high | xhigh | provider-default | not-applicable}
340
348
  Dispatch ceiling: {resolved ceiling value}
341
349
  Selected effort: {low | medium | high | xhigh | provider-default | not-applicable}
342
350
  Ceiling source: {repo config | project state | preflight prompt}
@@ -395,6 +403,29 @@ Dispatch target: oat-reviewer
395
403
  Rationale: base unpinned role fallback; effective effort follows Codex provider default.
396
404
  ```
397
405
 
406
+ Generic sidecar/explorer dispatch:
407
+
408
+ - Built-in or generic sidecars such as `explorer` are not OAT-managed implementer, reviewer, or fix roles.
409
+ - If a sidecar spawn payload does not explicitly pin a reliable effort/model control, log `Preferred effort: provider-default`, `Selected effort: provider-default`, and `Effort axis: provider-default`.
410
+ - Do not classify a generic sidecar as `Preferred effort: low|medium|high|xhigh` unless the actual host invocation contains the corresponding reliable selection. If the host has no reliable effort control for that sidecar, use provider-default wording instead.
411
+ - Sidecar outputs are advisory context only. Implementation work and review/fix gates still follow the OAT-managed dispatch rules above.
412
+
413
+ Codex generic explorer example:
414
+
415
+ ```text
416
+ OAT Dispatch: p02-t10 sidecar exploration
417
+ Host: Codex
418
+ Preferred effort: provider-default
419
+ Dispatch ceiling: xhigh
420
+ Selected effort: provider-default
421
+ Ceiling source: project state
422
+ Provider default effort: xhigh
423
+ Model axis: inherited
424
+ Effort axis: provider-default
425
+ Dispatch target: explorer
426
+ Rationale: read-only sidecar exploration; generic explorer payload does not pin an OAT-managed effort variant.
427
+ ```
428
+
398
429
  Include resolved dispatch context in scope packets when known:
399
430
 
400
431
  ```yaml
@@ -740,8 +771,8 @@ For each phase `pNN` in the plan (or each phase in the current parallel group),
740
771
 
741
772
  2. Perform a pre-dispatch assertion against the host invocation parameters. The Phase Scope fields are audit/context fields; selected axes must also be represented in the actual host dispatch call.
742
773
  - Codex implementer/fix dispatch:
743
- - Before building the `spawn_agent` argument map, classify the phase complexity and choose preferred effort (`low`, `medium`, `high`, or `xhigh`), then cap it to the resolved Codex dispatch ceiling.
744
- - Build the `spawn_agent` argument map before logging the dispatch. If `effort_axis=selected:low|medium|high|xhigh`, the argument map MUST use the matching `agent_type`: `"oat-phase-implementer-low"`, `"oat-phase-implementer-medium"`, `"oat-phase-implementer-high"`, or `"oat-phase-implementer-xhigh"`. Then derive the `OAT Dispatch:` block `Effort axis:` field from that same argument map.
774
+ - Before building the `spawn_agent` argument map, classify the phase complexity and choose preferred effort (`low`, `medium`, `high`, or `xhigh`), then call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`.
775
+ - Build the `spawn_agent` argument map from `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` before logging the dispatch. If `effort_axis=selected:low|medium|high|xhigh`, the argument map MUST use the matching `agent_type`: `"oat-phase-implementer-low"`, `"oat-phase-implementer-medium"`, `"oat-phase-implementer-high"`, or `"oat-phase-implementer-xhigh"`. Then derive the `OAT Dispatch:` block `Effort axis:` field from that same argument map.
745
776
  - Example selected low payload shape: `agent_type: "oat-phase-implementer-low"` and a Phase Scope message containing `effort_axis: selected:low`.
746
777
  - Immediately after spawning, compare the returned Codex status line with the selected effort before waiting on the agent. If the spawned status reports a different effort than the selected value (for example, the log says `effort_axis=selected:medium` but the spawn result reports `gpt-5.5 high`), treat this as an orchestration deviation. Stop, record the deviation in `implementation.md`, and redispatch with corrected parameters before continuing. Do not use work from the mismatched dispatch.
747
778
  - If `effort_axis=provider-default`, use base `agent_type: "oat-phase-implementer"` and omit `reasoning_effort`. The dispatch rationale MUST say this is a base/unpinned fallback and include provider default effort when known.
@@ -10,4 +10,83 @@ This directory owns active project-management state.
10
10
  - `current-state.md` records the present operating picture.
11
11
  - `roadmap.md` records prioritized direction and sequencing.
12
12
  - `backlog/` stores file-per-record backlog items and generated indexes.
13
- - Do not store durable research, brainstorms, imported plans, or decision history here.
13
+ - `handoffs/` stores one-shot project-kickoff prompts for backlog items
14
+ (see `handoffs/README.md`); each is deleted in the PR that ships its item.
15
+ - Do not store durable research, brainstorms, imported plans, or decision
16
+ history here.
17
+
18
+ ## Backlog Lifecycle
19
+
20
+ Invariant: `backlog/items/` holds only active work (`status: open` or
21
+ `in_progress`). Completed and abandoned records live in `backlog/archived/`.
22
+ `backlog/completed.md` is the newest-first summary of what shipped.
23
+
24
+ **Trigger.** Close an item out when either is true:
25
+
26
+ - an item's `status` changes to `closed` or `wont_do` (these are the only
27
+ terminal values — never invent variants like `done`), or
28
+ - a commit or PR satisfies an item's acceptance criteria — **even when the work
29
+ happened outside an OAT project lifecycle** (small doc commits included).
30
+
31
+ The agent or person shipping the work owns the close-out, in the same
32
+ commit/PR as the work whenever practical.
33
+
34
+ **Close-out (primary path).** Run `oat backlog archive <id>` — add `--wont-do`
35
+ for abandoned work and `--summary "<text>"` to record the outcome. The command
36
+ performs the whole close-out atomically: it flips `status` to the terminal
37
+ value and bumps `updated`, appends the canonical `backlog/completed.md` entry
38
+ (always for `closed`; for `wont_do` only when `--summary` is given), moves the
39
+ item file from `backlog/items/` to `backlog/archived/`, and regenerates
40
+ `backlog/index.md`. Stage the resulting changes with the shipping commit/PR.
41
+
42
+ **Manual fallback.** These are the steps the command automates — follow them, in
43
+ order, only when closing out by hand:
44
+
45
+ 1. In the item file, set `status: closed` (or `wont_do`) and bump `updated`.
46
+ 2. Append a summary entry to `backlog/completed.md` (newest first; entry format
47
+ is documented at the top of that file). Add the entry for a `wont_do` item
48
+ only when the abandonment itself is worth recording (an explicit summary).
49
+ 3. `git mv` the item file from `backlog/items/` to `backlog/archived/`.
50
+ 4. Run `oat backlog regenerate-index` and stage the regenerated
51
+ `backlog/index.md`.
52
+ 5. If the completion changes the operating picture, refresh
53
+ `current-state.md` and the curated overview section of `backlog/index.md`.
54
+
55
+ A partial close-out (status flipped or `completed.md` updated, but the file
56
+ left in `items/`) is how drift starts — finish all steps or none. `oat pjm
57
+ doctor` surfaces this drift.
58
+
59
+ **When reviewing backlog state** (e.g. `oat-pjm-review-backlog`), cross-check
60
+ recent commits against open items: work that shipped without a close-out
61
+ should be closed retroactively with a note.
62
+
63
+ ## Project Kickoff Handoffs
64
+
65
+ `handoffs/` holds one-shot kickoff prompts — consumable context for turning a
66
+ backlog item into a project, not documentation. The item file and `reference/`
67
+ remain the source of truth. See `handoffs/README.md` for the directory
68
+ convention.
69
+
70
+ - **When to generate:** when a priority-alignment pass concludes (e.g. the
71
+ walkthrough at the end of `oat-pjm-review-backlog`), write or refresh one
72
+ handoff per item in the agreed kickoff stack. Kickoff-stack membership, lane
73
+ count, and ordering are the human's call — present them, do not choose them.
74
+ Do not generate handoffs for parked or queued items until they are actually
75
+ next.
76
+ - **Naming:** one file per backlog item, `handoffs/<BL-id>.md`.
77
+ - **Required content:**
78
+ - the backlog item reference — its ID **and** human-readable title **and**
79
+ path (never a bare ID);
80
+ - the recommended project mode (`oat-project-quick-start` vs
81
+ `oat-project-new`), including which artifacts (spec/design/plan) to
82
+ pre-populate from existing research when it exists;
83
+ - authoritative input pointers (research directories, decision records, code
84
+ paths);
85
+ - repo conventions and verification gates the item file does not restate;
86
+ - a close-out section requiring (a) the **Backlog Lifecycle** above executed
87
+ in the same PR that ships the item and (b) deletion of the handoff file
88
+ (`git rm`) in that same PR.
89
+ - **Staleness:** if a later alignment pass drops an item from the kickoff
90
+ stack, delete its handoff in that pass rather than letting it drift.
91
+ - Every backlog item reference — in review output, alignment docs, and
92
+ handoffs — pairs the ID with its human-readable title. No bare IDs.
@@ -0,0 +1,21 @@
1
+ ---
2
+ oat_template: true
3
+ oat_template_name: pjm-handoffs-readme
4
+ ---
5
+
6
+ # PJM Handoffs
7
+
8
+ One-shot kickoff context for backlog items about to become OAT projects. Each
9
+ file stitches the backlog item, existing research, code pointers, and mode
10
+ guidance into a single prompt an operator passes as context when starting a
11
+ project (`oat-project-quick-start` or `oat-project-new`).
12
+
13
+ Conventions:
14
+
15
+ - One file per backlog item, named `<BL-id>.md`.
16
+ - Handoffs are **consumable, not durable**: once the project is created and the
17
+ content is absorbed into project artifacts, delete the handoff (`git rm`) in
18
+ the same PR that ships the work. Durable knowledge belongs in the item file,
19
+ `reference/`, or project artifacts — never here.
20
+ - Each handoff carries its own deletion instruction so the consuming agent
21
+ needs no outside context.
@@ -12,3 +12,16 @@ This directory owns append-mostly reference material.
12
12
  - `external-plans/` stores imported provider or external plans.
13
13
  - Create research, brainstorm, and deck folders on demand when a workflow needs them.
14
14
  - Do not put active roadmap, current-state, or backlog records directly under `reference/`.
15
+
16
+ ## Source of Truth
17
+
18
+ | Topic | Canonical location |
19
+ | -------------------------------------- | --------------------------------------------------------------------------- |
20
+ | Backlog close-out / lifecycle workflow | `../pjm/AGENTS.md` (Backlog Lifecycle) |
21
+ | Project kickoff handoffs | `../pjm/AGENTS.md` (Project Kickoff Handoffs) + `../pjm/handoffs/README.md` |
22
+ | Durable decisions | `decisions/` |
23
+ | Active operating picture / roadmap | `../pjm/current-state.md`, `../pjm/roadmap.md` |
24
+
25
+ **Update rule.** Do not restate the backlog close-out workflow here. When it
26
+ changes, edit `../pjm/AGENTS.md` and link to it — this directory defers to that
27
+ section rather than duplicating it.
@@ -11,3 +11,7 @@ Use this directory as the canonical OAT repo-reference root.
11
11
  - Durable append-mostly references live in `reference/`.
12
12
  - Keep generated indexes inside their managed marker pairs.
13
13
  - When an index conflicts, regenerate it with the owning OAT command and stage the result.
14
+ - Backlog close-out follows the **Backlog Lifecycle** in `pjm/AGENTS.md` — run
15
+ `oat backlog archive <id>` in the same PR that ships the work.
16
+ - `README.md` is the human-facing orientation for this directory; agent-facing
17
+ rules live in the `AGENTS.md` files alongside each subdirectory.