@open-agent-toolkit/cli 0.3.16 → 0.3.18

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 (124) hide show
  1. package/assets/agents/oat-phase-implementer.md +26 -6
  2. package/assets/agents/oat-reviewer.md +51 -1
  3. package/assets/bundle-metadata.json +1 -1
  4. package/assets/docs/contributing/documentation.md +4 -0
  5. package/assets/docs/contributing/skills.md +3 -1
  6. package/assets/docs/getting-started/bootstrap.md +1 -1
  7. package/assets/docs/getting-started/index.md +0 -4
  8. package/assets/docs/getting-started/tool-packs.md +0 -7
  9. package/assets/docs/reference/cli-reference.md +42 -1
  10. package/assets/docs/reference/config-and-local-state.md +11 -2
  11. package/assets/docs/reference/project-artifacts.md +43 -8
  12. package/assets/docs/skills/repo-improve.md +9 -7
  13. package/assets/docs/workflows/advanced/autonomy.md +40 -0
  14. package/assets/docs/workflows/backlog-and-planning/backlog-lifecycle.md +25 -24
  15. package/assets/docs/workflows/backlog-and-planning/remote-project-management.md +0 -7
  16. package/assets/docs/workflows/ideas/lifecycle.md +2 -7
  17. package/assets/docs/workflows/projects/execution/project-log.md +22 -0
  18. package/assets/docs/workflows/projects/reviews/review-flavors.md +8 -0
  19. package/assets/public-package-versions.json +4 -4
  20. package/assets/skills/oat-agent-instructions-apply/SKILL.md +14 -4
  21. package/assets/skills/oat-brainstorm/SKILL.md +17 -13
  22. package/assets/skills/oat-docs-apply/SKILL.md +13 -3
  23. package/assets/skills/oat-doctor/SKILL.md +11 -1
  24. package/assets/skills/oat-explainer-kit/SKILL.md +1 -1
  25. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +6 -3
  26. package/assets/skills/oat-pjm-review-backlog/SKILL.md +2 -2
  27. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +28 -3
  28. package/assets/skills/oat-project-autonomous/SKILL.md +60 -5
  29. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +44 -6
  30. package/assets/skills/oat-project-capture/SKILL.md +7 -3
  31. package/assets/skills/oat-project-complete/SKILL.md +39 -34
  32. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +106 -28
  33. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +30 -3
  34. package/assets/skills/oat-project-design/SKILL.md +12 -9
  35. package/assets/skills/oat-project-discover/SKILL.md +8 -4
  36. package/assets/skills/oat-project-document/SKILL.md +14 -5
  37. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +44 -6
  38. package/assets/skills/oat-project-implement/SKILL.md +1 -1
  39. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +6 -6
  40. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +44 -6
  41. package/assets/skills/oat-project-implement/references/phase-execution.md +20 -6
  42. package/assets/skills/oat-project-import-plan/SKILL.md +20 -6
  43. package/assets/skills/oat-project-lite/SKILL.md +7 -5
  44. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +44 -6
  45. package/assets/skills/oat-project-new/SKILL.md +6 -2
  46. package/assets/skills/oat-project-plan/SKILL.md +14 -6
  47. package/assets/skills/oat-project-pr-final/SKILL.md +1 -1
  48. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +44 -6
  49. package/assets/skills/oat-project-progress/SKILL.md +13 -1
  50. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +7 -3
  51. package/assets/skills/oat-project-quick-start/SKILL.md +17 -12
  52. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +44 -6
  53. package/assets/skills/oat-project-reconcile/SKILL.md +8 -4
  54. package/assets/skills/oat-project-retro/SKILL.md +1 -1
  55. package/assets/skills/oat-project-retro/references/apply-procedure.md +6 -6
  56. package/assets/skills/oat-project-retro-file/SKILL.md +7 -3
  57. package/assets/skills/oat-project-review-provide/SKILL.md +23 -4
  58. package/assets/skills/oat-project-review-provide-remote/SKILL.md +19 -1
  59. package/assets/skills/oat-project-review-receive/SKILL.md +37 -12
  60. package/assets/skills/oat-project-review-receive-remote/SKILL.md +7 -3
  61. package/assets/skills/oat-project-revise/SKILL.md +13 -5
  62. package/assets/skills/oat-project-spec/SKILL.md +8 -4
  63. package/assets/skills/oat-project-summary/SKILL.md +11 -7
  64. package/assets/skills/oat-repo-knowledge-index/SKILL.md +54 -20
  65. package/assets/skills/oat-repo-knowledge-index/scripts/refresh-owned.mjs +118 -0
  66. package/assets/skills/oat-review-provide/SKILL.md +7 -3
  67. package/assets/skills/oat-review-receive-remote/SKILL.md +14 -4
  68. package/assets/skills/oat-wave-execute/SKILL.md +24 -11
  69. package/assets/skills/oat-wave-execute/assets/wrapper-plan-template.md +16 -2
  70. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +45 -17
  71. package/assets/templates/pjm-agents.md +38 -8
  72. package/assets/templates/repo-agents.md +5 -0
  73. package/assets/templates/repo-readme.md +5 -0
  74. package/dist/commands/backlog/archive.d.ts +3 -0
  75. package/dist/commands/backlog/archive.d.ts.map +1 -1
  76. package/dist/commands/backlog/archive.js +63 -26
  77. package/dist/commands/backlog/index.d.ts.map +1 -1
  78. package/dist/commands/backlog/index.js +3 -0
  79. package/dist/commands/backlog/rewrite-references.d.ts +5 -0
  80. package/dist/commands/backlog/rewrite-references.d.ts.map +1 -1
  81. package/dist/commands/backlog/rewrite-references.js +39 -1
  82. package/dist/commands/init/index.d.ts.map +1 -1
  83. package/dist/commands/init/index.js +1 -0
  84. package/dist/commands/init/tools/shared/skill-script-references.d.ts.map +1 -1
  85. package/dist/commands/init/tools/shared/skill-script-references.js +8 -1
  86. package/dist/commands/internal/commit-paths.d.ts +3 -0
  87. package/dist/commands/internal/commit-paths.d.ts.map +1 -0
  88. package/dist/commands/internal/commit-paths.js +31 -0
  89. package/dist/commands/internal/index.d.ts.map +1 -1
  90. package/dist/commands/internal/index.js +2 -0
  91. package/dist/commands/pjm/init.d.ts.map +1 -1
  92. package/dist/commands/pjm/init.js +37 -8
  93. package/dist/commands/project/archive/archive-utils.d.ts +6 -3
  94. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  95. package/dist/commands/project/archive/archive-utils.js +510 -104
  96. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  97. package/dist/commands/project/archive/push-runner.js +1 -0
  98. package/dist/commands/project/log/append.d.ts +2 -3
  99. package/dist/commands/project/log/append.d.ts.map +1 -1
  100. package/dist/commands/project/log/append.js +125 -111
  101. package/dist/commands/project/migrate/index.d.ts +1 -2
  102. package/dist/commands/project/migrate/index.d.ts.map +1 -1
  103. package/dist/commands/project/migrate/index.js +8 -2
  104. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  105. package/dist/commands/project/new/scaffold.js +4 -4
  106. package/dist/commands/project/promote/promote.d.ts +8 -0
  107. package/dist/commands/project/promote/promote.d.ts.map +1 -1
  108. package/dist/commands/project/promote/promote.js +37 -6
  109. package/dist/commands/project/status.d.ts.map +1 -1
  110. package/dist/commands/project/status.js +3 -0
  111. package/dist/commands/project/sync/ref-sync.d.ts +12 -1
  112. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
  113. package/dist/commands/project/sync/ref-sync.js +347 -23
  114. package/dist/commands/shared/agents-md-lock.d.ts +3 -0
  115. package/dist/commands/shared/agents-md-lock.d.ts.map +1 -0
  116. package/dist/commands/shared/agents-md-lock.js +130 -0
  117. package/dist/commands/shared/agents-md.d.ts.map +1 -1
  118. package/dist/commands/shared/agents-md.js +26 -8
  119. package/dist/commands/shared/exact-path-commit.d.ts +32 -0
  120. package/dist/commands/shared/exact-path-commit.d.ts.map +1 -0
  121. package/dist/commands/shared/exact-path-commit.js +691 -0
  122. package/dist/validation/skills.d.ts.map +1 -1
  123. package/dist/validation/skills.js +138 -11
  124. package/package.json +3 -2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-phase-implementer
3
- version: 1.1.6
3
+ version: 1.1.7
4
4
  description: Implements one plan phase end-to-end, commits each task separately, self-checks between tasks, and handles bounded review fixes when resumed by oat-project-implement.
5
5
  tools: Read, Write, Edit, Bash, Grep, Glob, Task
6
6
  color: cyan
@@ -142,11 +142,23 @@ replaces every task and phase verification command below.
142
142
  Artifact and recovery-ledger bookkeeping commits must first resolve scope with
143
143
  `oat project scope "$PROJECT_PATH" --format value`. A `synced` project uses
144
144
  `oat project push` with the original bookkeeping message; other scopes keep the
145
- existing scoped `git add` and `git commit` commands. Scope resolution fails
145
+ shared `oat internal commit-paths --identity "$COMMIT_IDENTITY" --message "$BOOKKEEPING_MESSAGE" -- "${BOOKKEEPING_OWNED_FILES[@]}"` command with exact producer-owned files. Set a unique operation identity before the first attempt and retain it and the literal file list through retries. Scope resolution fails
146
146
  closed. A nonzero project-push exit stops bookkeeping until the reported
147
147
  recovery is resolved and the push is retried. Planned code task commits such as
148
148
  `feat(pNN-tNN)` are unchanged.
149
149
 
150
+ ## Recovery Capacity Disclosure
151
+
152
+ Report the supplied effective phase limit, prior durable usage, remaining
153
+ capacity and reconciled pending attempt in phase progress and boundary reports.
154
+ The root owns policy resolution and its source/override disclosure; use the
155
+ brief and authoritative `state.md` ledger, never a guessed local counter.
156
+ Capacity is not permission: failed-attempt terminality, eligibility/proof,
157
+ exact-target continuity and repository authority still apply when allowance
158
+ remains. Recovery events, warnings and route retries are distinct from reserved
159
+ attempt usage. Do not interpret remaining capacity as continue-after-failure
160
+ authority.
161
+
150
162
  ## Prevention and Post-Commit Recovery
151
163
 
152
164
  Prevention is the first recovery control. Before every planned task commit:
@@ -431,11 +443,19 @@ For every task:
431
443
  prevention does not consume a recovery attempt.
432
444
  6. Self-review requirements, behavioral tests, scope, and accidental changes.
433
445
  7. Fix any issue before committing.
434
- 8. Create exactly one task commit using `commit_convention`.
446
+ 8. Create exactly one task commit using `commit_convention` through the shared
447
+ `oat internal commit-paths --identity "${ORIGINAL_REQUEST_ID}:${TASK_ID}" --message "$TASK_COMMIT_MESSAGE" -- "${TASK_OWNED_FILES[@]}"` primitive.
448
+ Before task edits, initialize `TASK_OWNED_FILES=()` and append each exact
449
+ created, modified or removed file at its producer, including both rename
450
+ sides. Retain the list and request/task identity for retries; never discover
451
+ ownership from the staged index or pass directory pathspecs. Verify the
452
+ command's help first; if missing, stop and update the CLI with no alternate
453
+ Git commit route. A blocked/failed result stops with its receipt/diagnostic.
435
454
  In a smoke child, source preflight owns repository-wide hook validation and
436
- the child intentionally has no dependency install. Use
437
- `git -c core.hooksPath=/dev/null commit ...` for that task commit; do not
438
- mutate Git config or use `--no-verify`.
455
+ the child intentionally has no dependency install. Keep that launcher-owned
456
+ hook policy on the same primitive using per-process
457
+ `env GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=core.hooksPath GIT_CONFIG_VALUE_0=/dev/null oat internal commit-paths ...`;
458
+ do not mutate Git config or use `--no-verify`. Ordinary tasks keep hooks enabled.
439
459
  9. Verify:
440
460
  - HEAD is exactly one commit after `PRE_TASK_HEAD`;
441
461
  - the commit changes only files in the effective task boundary, which is
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-reviewer
3
- version: 1.2.10
3
+ version: 1.2.11
4
4
  description: Unified reviewer for OAT projects - mode-aware verification of requirements/design alignment and code quality. Writes a review artifact to disk by default, or returns structured findings in-memory when dispatched in structured-output mode.
5
5
  tools: Read, Bash, Grep, Glob, Write, Task
6
6
  color: yellow
@@ -201,6 +201,49 @@ Strategy`, check whether the evidence matches the declared strategy, covers
201
201
  - Code that doesn't map to any requirement
202
202
  - If significant: add to High findings (potential scope creep)
203
203
 
204
+ ### Step 3.5: Probe Changed Consequential Boundaries
205
+
206
+ For code reviews, inventory the changed trust, input, size and limit boundaries
207
+ within the resolved review scope. For each boundary, name a credible failure
208
+ and a focused probe with an independent expected outcome. Include assurance
209
+ contracts expressed in executable guidance when that guidance is the changed
210
+ public boundary. Do not manufacture a probe for unchanged behavior or a
211
+ merely cosmetic edit.
212
+
213
+ Run applicable focused probes within existing containment and write authority;
214
+ preserve review independence and never mutate product files to repair a
215
+ finding. Record the exact command, input or fixture/artifact provenance,
216
+ expected categorical result, observed categorical result and any concrete
217
+ execution limitation. A passing suite alone cannot substantiate a changed
218
+ consequential guarantee. Inspect a failing control that exercises the claimed
219
+ bad state and an accepted control that shows the valid state still works.
220
+
221
+ When execution is unavailable, independently read and inspect implementer
222
+ probe artifacts, exact commands, the recorded failing and accepted controls,
223
+ and their correspondence to the reviewed code and immutable revision. Exact
224
+ commands, artifact provenance and the limitation must be recorded. This may
225
+ satisfy the evidence obligation when the controls credibly substantiate the
226
+ guarantee; an unsupported implementer assertion is insufficient. A limitation
227
+ by itself is not evidence of correctness.
228
+
229
+ Missing consequential evidence requires a blocking finding under the existing
230
+ severity model. Use the
231
+ existing Critical/High severity model for the guarantee's risk, name the
232
+ unresolved claim and smallest missing proof, and do not report that guarantee
233
+ as accepted. Do not add a new severity, gate status or acceptance exception.
234
+
235
+ | Evidence case | Review disposition |
236
+ | -------------------------------------------------------------- | -------------------------------------------------------------------------- |
237
+ | Consequential guarantee, absent evidence | Blocking finding; guarantee unresolved |
238
+ | Inspected failing + accepted controls, reviewer cannot execute | Eligible evidence when independently verified; record execution limitation |
239
+ | Unsupported implementer assertion | Blocking finding; assertion cannot substantiate the guarantee |
240
+ | Docs-only, no credible changed boundary | No manufactured probe obligation; use conservation review |
241
+
242
+ Keep scope proportional: no new harness, broad testing campaign or
243
+ model-efficacy claim. Docs-only changes with no credible changed boundary have
244
+ no manufactured probe obligation. Preserve containment, independence,
245
+ dispatch controls and the existing output schemas.
246
+
204
247
  ### Step 4: Verify Artifact Quality
205
248
 
206
249
  This step applies to **artifact reviews** only.
@@ -487,6 +530,10 @@ worker claims, and root-inline coverage}
487
530
 
488
531
  ## Verification Commands
489
532
 
533
+ {Changed-boundary probes: exact commands, input/artifact provenance,
534
+ expected/observed categorical outcomes and limitations; distinguish executed
535
+ commands, suggested reruns and independently inspected evidence.}
536
+
490
537
  Run these to verify the implementation:
491
538
 
492
539
  ```bash
@@ -559,6 +606,9 @@ interface StructuredFindings {
559
606
  - `severity` MUST be one of the four enum values, mapped from the same Critical/High/Medium/Low buckets as Step 7.
560
607
  - `file` and `line` MUST both be set or both be `null`. A finding with a concrete location sets both; a reviewer-level finding without a specific location sets both to `null` and is conveyed via the `summary` / its own `body`, not as an inline location.
561
608
  - `id` prefixes follow the existing convention (`C`/`H`/`M`/`L`) and are stable within a single dispatch — no renumbering.
609
+ - Use existing `summary` and finding bodies for compact probe results and limitations,
610
+ including independently inspected control provenance. Keep exact repeatable
611
+ commands in `verification_commands`; add no fields to `StructuredFindings`.
562
612
  - `verification_commands` carries what Step 8's "Verification Commands" section would have carried, as an array of command strings.
563
613
 
564
614
  Default behavior is unaffected: when `oat_output_mode` is absent or set to anything other than `structured`, follow Steps 8-9 and write the artifact exactly as before. Analysis reviews MUST honor `oat_output_mode: structured` whenever supplied by an auto-review loop: return the `StructuredFindings` object and write no artifact.
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.3.16"
3
+ "oatVersion": "0.3.18"
4
4
  }
@@ -52,6 +52,10 @@ Documentation should ship with the code it explains. This page covers the core d
52
52
  ## Authoring Expectations
53
53
 
54
54
  - Keep docs aligned with the current repo behavior and current command surface.
55
+ - Give each Markdown or MDX page exactly one document H1. `pnpm docs:validate`
56
+ reports the file and count when a page has zero or multiple H1s. ATX and
57
+ Setext headings count, including headings inside blockquotes or lists;
58
+ frontmatter and fenced code do not.
55
59
  - Prefer cross-links over duplicated conceptual content.
56
60
  - Use `oat-docs-authoring` for targeted OAT/Fumadocs docs edits; it delegates
57
61
  universal page-quality guidance to `authoring-docs` and keeps local
@@ -238,7 +238,9 @@ the bundle strips — requires bumping that skill's `metadata.version` in the
238
238
  same PR, one bump per changed skill in the final PR diff, even if the skill was
239
239
  edited multiple times on the branch. A change to a skill's `scripts/` or
240
240
  `references/` therefore needs the bump just as an edit to `SKILL.md` does: both
241
- ship to every `oat tools install` consumer. Changing a canonical agent role
241
+ ship to every `oat tools install` consumer. Changes under `.agents/docs/`
242
+ also require a bump for every skill that vendors the changed document through
243
+ a file or directory symlink, because bundling follows those links. Changing a canonical agent role
242
244
  under `.agents/agents/*.md` requires bumping that file's top-level `version:`;
243
245
  agent roles deliberately keep the top-level field, so the gate accepts either
244
246
  declaration shape and never demands `metadata.version` of them. The gate reads
@@ -50,7 +50,7 @@ After core initialization completes, `oat init` can enter an interactive guided
50
50
  - after placement is chosen, repository `AGENTS.md` guidance is a separate opt-in. Accepting creates the root file with the managed `OAT tools` section when it is absent, and appends that section to an existing file or contained symlink target that lacks it, with one append-only write. An existing file is never replaced: when the section exists but differs, OAT prints a repository-relative, copy-pasteable managed-block patch instead. Declining leaves `AGENTS.md` unchanged
51
51
  - installing `project-management` installs the capability only. Adopting it for this repository is a third, separate choice made with `oat pjm init` — see [Install vs. initialize](tool-packs.md#install-vs-initialize)
52
52
  2. **Local paths** — multi-select from default gitignored artifact paths (analysis, PR, reviews, ideas). Pre-existing paths are pre-checked; only new paths are added.
53
- 3. **Documentation** — detect or enter docs metadata for the repo when documentation exists.
53
+ 3. **Documentation** — detect or enter docs metadata for the repo when documentation exists. For existing plain documentation, choose **Plain Markdown** in the manual tooling menu and enter its docs root. Guided setup saves `documentation.tooling: "markdown"` and the normalized `documentation.root` while preserving the other documentation/config settings. Fumadocs remains the manual menu default; MkDocs, Docusaurus, VitePress and Nextra remain available. This choice does not add automatic Markdown detection or scaffold a framework.
54
54
  4. **Provider sync** — sync provider project views via `oat sync --scope project`.
55
55
  5. **Summary** — reports what was configured: active providers, tool packs status, local paths added/existing, and provider sync status. Includes suggested next steps.
56
56
 
@@ -55,10 +55,6 @@ view is the file or link that tool reads.
55
55
  available it falls back to the best available reviewer, which can be from the
56
56
  same family, and only records a warning. See
57
57
  [How independent the reviewer must be](../workflows/advanced/workflow-gates.md#how-independent-the-reviewer-must-be).
58
- - **Re-running `oat pjm init` removes remote settings.** It replaces the `pjm`
59
- section of `.oat/config.json` and deletes any `pjm.remote` settings, so back
60
- the file up first. See
61
- [Remote Project Management](../workflows/backlog-and-planning/remote-project-management.md#prerequisite).
62
58
  - **Ad-hoc reviews run in the agent you invoke them in.** `oat-review-provide`
63
59
  cannot send a review to a different model; to get another model's review,
64
60
  run the skill in that model's coding tool. See
@@ -1294,10 +1294,3 @@ that: later pack updates and `oat tools remove` leave them alone.
1294
1294
  loads; OAT does not resolve that for you.
1295
1295
 
1296
1296
  Installing any pack never gives OAT permission to publish to an issue tracker.
1297
-
1298
- > [!WARNING]
1299
- > Rerunning `oat pjm init` or `oat pjm migrate --apply` deletes the `pjm.remote`
1300
- > settings from `.oat/config.json`, so every remote setting silently returns to
1301
- > its default. Afterwards, check `git diff .oat/config.json` and restore the
1302
- > settings you need with `oat config set` (shared remote storage is restored
1303
- > with `oat pjm remote storage shared`) before doing more remote work.
@@ -37,6 +37,47 @@ Each full command reference should include:
37
37
 
38
38
  The first practical expansion path is to keep improving the existing owners: [Docs App Commands](../docs-tooling/commands.md), [Provider Interop Commands](../provider-sync/commands.md), [Config and Local State](config-and-local-state.md), [Tool Packs](../getting-started/tool-packs.md), [Workflow & Projects](../workflows/projects/index.md), and [Repository PR Comment Analysis](repository-pr-comments.md).
39
39
 
40
+ ## Exact-path maintenance commits
41
+
42
+ `oat internal commit-paths --identity <operation> --message <message> -- <files...>`
43
+ commits an explicit list of owned files with enabled Git hooks. Include tracked
44
+ removals and both names of a rename. Directories, untracked missing paths,
45
+ unmerged entries and paths outside the repository are rejected; the command
46
+ does not discover ownership or expand directory/glob pathspecs. Unrelated staged
47
+ entries and worktree bytes remain preserved, including partially staged files.
48
+ On success, owned index/worktree bytes match the hook-final commit.
49
+
50
+ Choose a unique identity before the first attempt and retain the identity,
51
+ message and literal path list for retries. With global `--json`, outcomes are
52
+ `committed`, `already-matching`, `nothing`, `blocked` or `failed`.
53
+ Success exits 0, `blocked` exits 1 and `failed` exits 2. A blocked result can
54
+ name a verified commit whose owned-index publication still needs repair; do not
55
+ claim settlement until a matching retry succeeds. Ignored receipts under the
56
+ Git directory verify the exact identity, commit, tree and paths before reuse.
57
+ Lock inspection/retry is bounded and never deletes another writer's lock.
58
+
59
+ If the command is unavailable, stop and update the CLI; there is no broad Git
60
+ commit fallback. Synced project artifacts still use `oat project push` after
61
+ successful scope resolution. During development, run the current source entry:
62
+
63
+ ```bash
64
+ pnpm --silent run cli -- internal commit-paths --identity "$COMMIT_IDENTITY" --message "$COMMIT_MESSAGE" -- "${OWNED_FILES[@]}"
65
+ ```
66
+
67
+ A `dist` invocation requires a fresh build after the latest CLI source changes.
68
+
69
+ For `oat backlog archive --json`, use the complete returned `affectedPaths`
70
+ array as the archive-owned list, converting absolute paths to literal
71
+ repository-relative files against the same repository root. Union per-item
72
+ results, append an owned
73
+ handoff's filesystem deletion, and format only existing supported text with
74
+ the repository command before the helper commit. Include both old/new item
75
+ paths and every ledger/index/reference output; never stage only the old
76
+ missing name. A settled noop may return no paths and needs no commit. Pending
77
+ Git retries include prior outputs only with HEAD ownership evidence, while
78
+ no-Git retries report current-pass mutations. See [Backlog
79
+ Lifecycle](../workflows/backlog-and-planning/backlog-lifecycle.md).
80
+
40
81
  ## Command Groups
41
82
 
42
83
  | Command group | What it covers | Go deeper |
@@ -155,7 +196,7 @@ Notable commands introduced in the current CLI surface:
155
196
  - `oat project list --json` - summary state for tracked projects under the configured projects root
156
197
  - `oat project closeout-check <project-path> [--autonomous] [--json]` - read-only check of the closeout invariant: a closeout that must snapshot its post-implementation sequence cannot reach terminal completion until its `oat_post_implement_sequence` snapshot exists, every stored step is recorded complete, approval is recorded, and the snapshot reached `status: complete`. A snapshot is required when the effective layered `workflow.postImplementSequence` is configured, when the closeout is autonomous (`--autonomous`, or `OAT_AUTONOMOUS=1` in the environment even without the flag), or when `oat_workflow_mode` is `lite`. Once a snapshot exists its recorded state is authoritative and current configuration is not consulted. JSON output reports `status` (`complete`, `not_required`, or `incomplete`), the missing `invariant` (`snapshot_missing`, `snapshot_malformed`, `sequence_failed`, `pre_approval_step_pending`, `approval_pending`, `post_approval_step_pending`, or `sequence_not_complete`), `route` (`oat-project-implement` when incomplete), `nextOwner` (the next stored step and its skill, or the approval), and the evaluated `inputs`. An incomplete or malformed result exits 1.
157
198
  - `oat project complete-state <project-path> [--archived] [--autonomous]` - apply the canonical completed-state mutation to a project's `state.md`; used by `oat-project-complete` during lifecycle closeout. It first evaluates the same closeout invariant as `oat project closeout-check` and refuses, with the same message and without writing, a configured, autonomous, or lite closeout whose snapshot is absent, malformed, or incomplete. A project whose implementation finished before closeout snapshots existed recovers by running `oat-project-implement`, which persists the snapshot (`completion-and-closeout.md` Step 15) and completes its stored steps; there is no override flag. An unconfigured, interactive, non-lite closeout without a snapshot completes as before.
158
- - `oat project archive [project-path] [--project-recap-run <project-relative-path>] [--no-commit]` - archive a tracked project through the same local move, summary export, and configured S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive stages the selected complete package into `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies every manifest-declared file byte, then atomically installs the export before deleting the active project. Existing destinations, incomplete inventory coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project. For synced projects, a configured S3 upload must succeed before terminal cleanup. Successful closeout makes `refs/oat/completed/<project>` authoritative, deletes the tracked JSON record and nested checkout, and leaves archive metadata sufficient for an idempotent recordless retry. With `--json`, the terminal receipt reports `completedRef`, `verifiedSourceSha`, whether `activeAliasDisposition` was `retained` or `removed`, whether `recordRetired` completed, and the parent `lifecycleCommit`. `--no-commit` is a manual/library-only option: for a synced project it still removes the checkout but deliberately leaves `lifecycleCommit` null. Never pass it through `oat-project-complete`, which requires that receipt.
199
+ - `oat project archive [project-path] [--project-recap-run <project-relative-path>] [--no-commit]` - archive a tracked project through the same local move, summary export, and configured S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive verifies the complete selected package and every immutable file byte, then atomically exports one self-contained `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>.html` page before deleting the active project. The full original package remains in the archived project. JSON `projectRecapExport` identifies `runId`, `page.sourceRelativePath`, `page.originalSha256`, `page.exportedSha256`, `verifiedArtifactCount`, and the flat `exportRoot`. No tracked sidecar is created. Matching dated pages are adopted on retry; conflicting destinations, incomplete inventory coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project. Summary and PR links point to the tracked page. For synced projects, a configured S3 upload must succeed before terminal cleanup. Successful closeout makes `refs/oat/completed/<project>` authoritative, deletes the tracked JSON record and nested checkout, and leaves archive metadata sufficient for an idempotent recordless retry. With `--json`, the terminal receipt reports `completedRef`, `verifiedSourceSha`, whether `activeAliasDisposition` was `retained` or `removed`, whether `recordRetired` completed, and the parent `lifecycleCommit`. `--no-commit` is a manual/library-only option: for a synced project it still removes the checkout but deliberately leaves `lifecycleCommit` null. Never pass it through `oat-project-complete`, which requires that receipt.
159
200
  - `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. The old `oat project archive sync` path remains as a deprecated shim.
160
201
  - `oat project dispatch record --event-file <json-file-or-dash>` - validate one generic dispatch record plus its namespaced OAT evidence event and print the result with `status: validated-only`. The command writes nothing; launches are recorded in the calling workflow's run record. Managed, effort-pinned Claude launches run it before launch: the input carries `claudeLaunch` with the real resolver result, generated definition, and proposed payload, plus `recordBase` and `event`. The command validates their agreement and derives the configured invocation fields; callers cannot copy those fields into `recordBase`. One validation run reports every violation across `claudeLaunch`, `recordBase`, and `event` in a single error message, one `stage path: message` line each; the `recordBase` cross-field rules run even when a required field is missing, checks that need a value that failed to parse are skipped and named on a final line, secret-shaped values and absolute paths are scrubbed from the message, and the exit code stays 1. A validated input per role is published at `.agents/skills/oat-dispatch-subagents/references/managed-claude-example.json`. The command validates evidence only — it never launches a provider. A `runtime-observation` event may carry either a finished `observation` or the provider `metadata` envelope (`provider`, `observedAt`, `entries`) to normalize, but not both. `entries` may be raw provider output: they are projected through the owning parser's allowlist, are never echoed in the output, and both forms have their `match` derived from the record's configured invocation rather than trusted from the caller, with the observation's `provider` bound to the record's. With `--json`, the result adds `runtimeIdentity` with separate `configured` and `observed` objects plus a `match` of `matching`, `mismatching`, `not-comparable`, or `null`; observation is corroboration only and never overrides configured invocation. Error output is redacted on a best-effort basis; absolute paths in identity fields are rejected outright, while some prose forms (colon-prefixed, URL routes) can survive. See [Evidence Layers](../workflows/advanced/evidence-layers.md).
161
202
  - `oat project dispatch canonical-role --role <name> --request-id <id> --skill-dir <dir> [--json]` - resolve a canonical role through the loaded, user (`$HOME/.agents`), and project (`<repo>/.agents`) tiers and print the `canonical-role-resolution` event that `oat project dispatch record` accepts unchanged: redacted `canonicalPath` and `selectedPath` in the form `<loaded|user|project>/agents/<name>.md`, the role's `contentDigest`, and `candidateMisses`. `--skill-dir` is required because the loaded tier is derived from the loaded skill's directory; a missing or invalid directory exits 1 with a redacted error. An unknown role prints `missing` evidence with its recovery commands. Read-only; the dependency is the `workflows` pack.
@@ -50,7 +50,7 @@ The command validates all inputs before creating the scaffold or writing an item
50
50
 
51
51
  - 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.
52
52
  - For the default `closed` path, validates and trims a nonblank `--summary` before any file or index mutation. The `wont_do` path may omit the summary and completion-ledger entry.
53
- - 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.
53
+ - Rewrites only the `status:` and `updated:` frontmatter lines (preserving any inline enum comment), then moves the item from `items/` to `archived/` with a filesystem rename. Archive leaves the Git index unchanged on initial archive and retry; callers own formatting, staging and committing the complete operation.
54
54
  - `closed` archives append a canonical newest-first `completed.md` entry (`YYYY-MM-DD — <id> — Title — summary`). `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.
55
55
  - Rewrites inbound references to the moved file across Markdown under `.oat/repo/**` — tracked and untracked files that Git does not ignore, or every `.md` file outside a Git work tree — (external plans, decision records, other backlog items): relative links, `.oat/repo`-relative and repository-root path strings (including `oat_external_plan_sources` frontmatter) that resolve to `items/<id>.md` now point at `archived/<id>.md`, and the moved item's own relative links (inline links with any title form, and reference-style definitions; never footnotes or prose) are rebased when their target exists, so they keep resolving. An inline code span whose whole content is a path to the item (optionally with an `#anchor`), such as an external plan's `Source artifact or scope` citation, is rewritten; any other code span or fenced code block that mentions `items/<id>.md` is left as written with a warning, so recorded commands keep their meaning. Only references that resolve to the item's former `items/<id>.md` path change, and a link that already resolves to a different existing file is never repointed; URLs are never touched, and symlinked Markdown files are skipped so nothing outside `.oat/repo` is read or written. Each rewritten file is reported; a reference that names `items/<id>.md` but cannot be resolved is left untouched with a warning.
56
56
  - Regenerates the managed backlog index after the move.
@@ -77,11 +77,18 @@ On success the payload is the archive result object:
77
77
  "rewrittenReferences": [
78
78
  ".oat/repo/reference/external-plans/2026-07-05-example-plan.md"
79
79
  ],
80
+ "affectedPaths": [
81
+ "/repo/.oat/repo/pjm/backlog/items/BL-260705-example.md",
82
+ "/repo/.oat/repo/pjm/backlog/archived/BL-260705-example.md",
83
+ "/repo/.oat/repo/pjm/backlog/completed.md",
84
+ "/repo/.oat/repo/pjm/backlog/index.md",
85
+ "/repo/.oat/repo/reference/external-plans/2026-07-05-example-plan.md"
86
+ ],
80
87
  "warnings": []
81
88
  }
82
89
  ```
83
90
 
84
- `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`; `rewrittenReferences` lists the repository-relative Markdown files whose references to the moved item were rewritten (on a no-op this lists anything the retried rewrite changed, and the human output prints each file on both paths). On an actionable failure the payload is `{ "result": "error", "id": "<id>", "message": "<why + fix>" }`.
91
+ `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`; `rewrittenReferences` lists the repository-relative Markdown files whose references to the moved item were rewritten (on a no-op this lists anything the retried rewrite changed, and the human output prints each file on both paths). `affectedPaths` is the deduplicated, normalized absolute operation path list: old item path (a tracked deletion), archived destination, index, completed ledger when written, and rewritten references. Retries report actual current-pass changes. In Git, a retry also reports prior uncommitted outputs only when HEAD still contains the old item and lacks the destination: the item move, a newly inserted ledger entry, a removed index entry, and references whose HEAD bytes still resolve to the old item. Existing archived links and unrelated edits in already-settled files are not claimed. Without Git history, retries report current-pass mutations only. A `wont_do` archive without an entry does not claim unrelated ledger changes. Capture each successful JSON result, deduplicate the union of `affectedPaths`, add any owned handoff filesystem deletion, and format existing affected text using the repository command. Pass that complete literal list to `oat internal commit-paths` with enabled hooks and a unique retained operation identity; stop on unavailable or blocked/failed helper, preserve unrelated staged/unstaged work, and never stage only the missing old path. An empty settled-noop list requires no commit. On an actionable failure the payload is `{ "result": "error", "id": "<id>", "message": "<why + fix>" }`.
85
92
 
86
93
  For full project-management repo-reference setup, use [`oat pjm init`](../getting-started/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`.
87
94
 
@@ -209,6 +216,8 @@ with `oat pjm init` as the recovery instead of treating absent
209
216
  `.oat/repo/pjm/` files as drift. See
210
217
  [Install vs. initialize](../getting-started/tool-packs.md#install-vs-initialize).
211
218
 
219
+ `oat pjm init` and `oat pjm migrate` update only their adoption markers; they preserve `pjm.remote` and other existing, unowned configuration fields.
220
+
212
221
  Workflow automation preferences are also visible through `oat config` and can be set at local, shared, or user scope. Notable review-loop keys:
213
222
 
214
223
  - `workflow.autoArtifactReview.plan` - default-on bounded artifact review for generated `plan.md` files before implementation handoff
@@ -75,6 +75,34 @@ implementation-then-regression, static/build, or manual/visual. Static or build
75
75
  checks alone fit only changes that cannot affect runtime behavior; every
76
76
  behavioral change needs evidence that fails without the change.
77
77
 
78
+ ## Blockers in state.md
79
+
80
+ `oat_blockers` accepts legacy reason strings and structured workflow records:
81
+
82
+ ```yaml
83
+ oat_blockers:
84
+ - task_id: p01-t03
85
+ reason: Waiting on API contract
86
+ since: '2026-10-03'
87
+ - waiting on review
88
+ ```
89
+
90
+ The control plane exposes `ProjectBlocker` as
91
+ `string | { task_id: string; reason: string; since: string }`.
92
+ `oat project status --json` preserves the three literal fields. Human status
93
+ shows the task, reason and date for records, and the reason for legacy strings.
94
+ `--field project.blockers` emits JSON; `--shell BLOCKERS=project.blockers`
95
+ emits a shell-quoted JSON assignment. Select a single field such as
96
+ `--field project.blockers.0.reason` to read a structured reason alone.
97
+
98
+ Empty lists remain empty. Mixed lists retain entries in order, with
99
+ legacy string normalization unchanged. Records missing any nonempty string
100
+ field, nested lists and non-string scalars become diagnostic legacy strings:
101
+ `Malformed blocker entry: <JSON>`. They remain visible to blocker checks and
102
+ human output without `[object Object]` coercion. The parser also accepts
103
+ JSON-encoded blocker lists for compatibility. These representations do not change workflow recommendations
104
+ or the state refresh command's existing raw-frontmatter handling.
105
+
78
106
  ## Supporting artifacts
79
107
 
80
108
  - `summary.md`: generated by `oat-project-summary` — re-runnable, tracks its own state via frontmatter for incremental updates after revisions
@@ -99,9 +127,12 @@ different retention contracts:
99
127
  the tracked branch with the active project tree. It remains only in the local
100
128
  archived project.
101
129
  - A selected final `project-recap` is a durable completion record. Before a
102
- shared project is removed, archive copies the complete selected run to
103
- `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies its
104
- package inventory and hashes, and reports that tracked export path. Summary
130
+ shared project is removed, archive verifies the complete selected run and
131
+ exports one self-contained HTML page to
132
+ `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>.html`. The
133
+ report identifies the run, original page/hash, exported hash, and verified
134
+ artifact count. The full original run, manifest, source, and QA evidence
135
+ remain in the archived project. Summary
105
136
  and PR links use this export, never the gitignored local archive. Lifecycle
106
137
  callers identify the selected project-relative run with:
107
138
 
@@ -110,12 +141,16 @@ different retention contracts:
110
141
  --project-recap-run explainers/<recap-slug>
111
142
  ```
112
143
 
113
- The archive exports at most one selected recap package. It rejects an existing
114
- dated destination and requires the selected path to stay under the project's
144
+ The archive exports at most one selected recap page, with local assets embedded
145
+ and unavailable project-source links removed. It adopts a byte-identical dated
146
+ page on retry and refuses a differing existing destination without overwriting
147
+ it. It creates no tracked manifest, fact-base, QA, or hash sidecar and requires the selected path to stay under the project's
115
148
  `explainers/` directory with a `project-recap` manifest. Verification checks
116
- the manifest's exact inventory, every declared file byte, the fact base and
117
- ledger, resolved theme, authored page, and QA result before deleting the active
118
- project.
149
+ the manifest version's exact inventory and raw immutable file-byte hashes before
150
+ deleting the active project. Direct CLI archive also accepts legacy v1 recaps:
151
+ the v1 contract verifies canonical fact-base and resolved-theme JSON identities
152
+ and build-record run/outcome agreement. The v2 contract additionally requires
153
+ ledger and QA evidence coverage. Project completion selects v2 recap runs.
119
154
 
120
155
  Both `built` and `built-needs-review` are complete, archivable outcomes.
121
156
  `built-needs-review` means the browser rung was unavailable or found an issue;
@@ -213,9 +213,11 @@ does not require a project name or an active-project pointer.
213
213
  the `oat-codebase-mapper` subagent. A preflight checks whether background
214
214
  agents can write files and switches to a read-only fallback if they cannot.
215
215
  Needs an active OAT project: no. If a knowledge directory already exists,
216
- choose whether to refresh it or skip the run. Refresh first deletes every
217
- `.md` file in `.oat/repo/knowledge/`, hand-written files included, and then
218
- regenerates the set. Move any notes you want to keep before you choose it.
216
+ choose whether to refresh it or skip the run. Refresh removes only regular
217
+ Markdown files marked `oat_generated: true` and regenerates the eight named
218
+ outputs. Hand-written notes survive; an unmarked expected-output collision
219
+ stops the run before deletion so you can decide how to preserve it. Symlinked
220
+ knowledge directories and output collisions are refused.
219
221
 
220
222
  **Example scenario:** A new teammate needs to understand which packages own
221
223
  the CLI, how shared configuration reaches applications, and which test
@@ -234,8 +236,9 @@ answered.
234
236
  knowledge files already exist. Otherwise it creates `.oat/repo/knowledge/`,
235
237
  starts a test subagent and then four `oat-codebase-mapper` subagents in the
236
238
  background, and writes the knowledge files. It then runs
237
- `git add .oat/repo/knowledge/` and `git commit` on your current branch with
238
- no further prompt; that commit also includes anything you had already staged.
239
+ `oat internal commit-paths` on your current branch with the exact generated
240
+ output/deletion paths and enabled hooks. Unrelated staged and unstaged work
241
+ remains intact.
239
242
  Afterwards it records the run in `.oat/tracking.json` and regenerates the
240
243
  `.oat/state.md` dashboard with `oat state refresh`; those two files are not
241
244
  part of the commit. It does not push.
@@ -244,8 +247,7 @@ part of the commit. It does not push.
244
247
  `project-index.md`, `stack.md`, `architecture.md`, `structure.md`,
245
248
  `conventions.md`, `testing.md`, `integrations.md`, and `concerns.md`. The
246
249
  workflow also updates its tracking/dashboard surface and commits the
247
- knowledge output on the current branch (unstage unrelated changes first; the
248
- commit includes anything already staged). Despite its name, `project-index.md` describes the
250
+ knowledge output on the current branch with exact path ownership. Despite its name, `project-index.md` describes the
249
251
  repository; it does not require a pre-existing OAT lifecycle project.
250
252
 
251
253
  **Next step:** Read the index and the concern or testing documents relevant
@@ -51,6 +51,46 @@ repository config, user config, or any other durable artifact. A later
51
51
  interactive session therefore needs no autonomy cleanup and behaves
52
52
  interactively around the state the autonomous run left behind.
53
53
 
54
+ ## Kickoff limits and hard stops
55
+
56
+ Kickoff reads the owning recovery, gate and dispatch contracts and reports the
57
+ effective project default and each known phase limit, source/override, prior
58
+ durable usage, remaining capacity and pending-attempt status. For a new project,
59
+ phase values remain unresolved until planning supplies them; the report is
60
+ refreshed before implementation and on resume.
61
+
62
+ Phase recovery uses `oat_phase_recovery_policy` in `state.md`: a
63
+ `phase_attempt_limits.<pNN>` override wins over `default_attempt_limit`, whose
64
+ owning default is `10`. Limits are integers from `0` through `20`. Usage comes
65
+ from the monotonic `phase_attempt_usage.<pNN>.used_attempts` ledger; remaining
66
+ capacity is `max(0, effective limit - used_attempts)`. A reconciled pending
67
+ reservation finishes that same attempt without another increment, even at the
68
+ limit.
69
+
70
+ These dry kickoff controls illustrate the unchanged policy, without launching
71
+ a provider:
72
+
73
+ - Default control: limit 10, used 3, remaining 7; source is the owning default
74
+ when the project has no override.
75
+ - Phase override control: limit 2, used 1, remaining 1; source is
76
+ `phase_attempt_limits.p01: 2`, even when the project default is 10.
77
+ - Zero limit: no new automatic attempt; a direction-required stop consumes no
78
+ attempt.
79
+
80
+ Capacity is not permission. A failed attempt is terminal even with remaining capacity.
81
+ A continue-after-failure policy remains a separate future choice. Route retries,
82
+ review-fix rounds, gate `maxAttempts`, recovery events and reserved recovery
83
+ attempts are separate counters. An elevated warning at three recovery events
84
+ changes no limit and grants no permission.
85
+
86
+ Kickoff also names the applicable owning hard stops: recovery eligibility or
87
+ proof failure, new-attempt budget exhaustion, malformed ledger or unresolved
88
+ pending attempt, exact-target/accepted-launch failure, blocking review policy,
89
+ missing credentials, repository authority, unresolved product judgment,
90
+ unauthorized destructive risk and inventory gaps. Each stop retains its owning
91
+ contract and configured gate semantics; the report names evidence and the
92
+ operator action needed to resume.
93
+
54
94
  ## Gate outcomes
55
95
 
56
96
  Every interactive lifecycle gate has one of two autonomous outcomes:
@@ -21,15 +21,6 @@ mutations write nothing and return an error naming the repository path and
21
21
  `oat pjm init` as the recovery. Check the current state with
22
22
  `oat pjm doctor --json` and read its `adoption.state` field.
23
23
 
24
- > [!WARNING]
25
- > Running `oat pjm init` again, or running `oat pjm migrate --apply`,
26
- > currently replaces the `pjm` section of `.oat/config.json` and deletes any
27
- > `pjm.remote` settings (your remote project management policy). Several
28
- > skills below tell you to rerun `oat pjm init` to repair a partial setup or
29
- > missing index markers. Before you do, back up `.oat/config.json`;
30
- > afterwards, check `git diff .oat/config.json` and restore `pjm.remote` if
31
- > it was removed.
32
-
33
24
  ## Where a backlog item lives
34
25
 
35
26
  - **`items/<id>.md`** - active, file-backed records. Each carries frontmatter with a `status` and an `updated` timestamp.
@@ -64,12 +55,24 @@ A single `oat backlog archive` run performs the whole close-out so its parts can
64
55
 
65
56
  1. Sets the terminal `status` (`closed` by default, `wont_do` with `--wont-do`) and stamps `updated`.
66
57
  2. Validates and trims a nonblank `--summary` before mutating a `closed` item, then appends its canonical (standard OAT format) newest-first `completed.md` entry. `wont_do` items may omit the summary and get an entry only when one is provided.
67
- 3. Moves `items/<id>.md` into `archived/` — with `git mv` inside a work tree, or a plain rename outside git.
58
+ 3. Moves `items/<id>.md` into `archived/` with a filesystem rename, leaving Git staging to the caller.
68
59
  4. Rewrites inbound references to the moved file across Markdown under `.oat/repo/**` (tracked and untracked files that Git does not ignore; a code span whose whole content is the item's path, such as an external plan's source citation, is rewritten, while other code spans and fenced code are left as written with a warning) — external plans, decision records, and other backlog items — so no link dangles at `items/<id>.md`, and reports each rewritten file. A reference it cannot resolve is left alone with a warning.
69
60
  5. Regenerates the managed backlog index.
70
61
 
71
62
  The command is safe to re-run: an item already in `archived/` produces a no-op warning and only retries the reference rewrite and index regeneration, so an interrupted close-out finishes on the next run. A missing closed-item summary or an out-of-enum current status (for example a hand-set `done`) is a hard error before mutation and includes recovery guidance. See the [command reference](../../reference/config-and-local-state.md#oat-backlog-archive) for exit codes and the `--json` payload.
72
63
 
64
+ The archive result includes normalized absolute `affectedPaths` for the whole
65
+ operation. Capture `--json` for each item, union the lists, and include owned
66
+ handoff deletions. Format existing affected text with the repository's
67
+ formatter, then use `oat internal commit-paths` with a unique retained identity
68
+ and the exact list. Include the old tracked item deletion and new destination
69
+ as well as ledger/index/references; staging only the old missing path fails.
70
+ Hooks remain enabled, and unrelated staged/unstaged work stays intact. Verify
71
+ helper availability first, stop on failure, and follow its retry diagnostics.
72
+ Settled noops claim only actual repairs; pending Git retries recover earlier
73
+ operation outputs from HEAD evidence. See [exact-path maintenance
74
+ commits](../../reference/cli-reference.md#exact-path-maintenance-commits).
75
+
73
76
  ## Catching lifecycle drift
74
77
 
75
78
  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:
@@ -101,8 +104,7 @@ work. Like every PJM skill that writes files on this page, it refuses to
101
104
  write until the repository has adopted PJM with `oat pjm init`. The skill
102
105
  first runs `oat pjm doctor --json` and inspects `adoption.state`; only
103
106
  `declared` or `inferred-legacy` permits writes. For `none` or
104
- `partial-initialization` it stops and tells you to run `oat pjm init` (read
105
- the [warning about rerunning it](#adoption-comes-first) first). Installed
107
+ `partial-initialization` it stops and tells you to run `oat pjm init`. Installed
106
108
  tools alone do not establish adoption. No active OAT project is required.
107
109
 
108
110
  **Example scenario:** A support incident exposed uncertainty about duplicate
@@ -145,7 +147,7 @@ the living review.
145
147
  `oat pjm doctor --json` before writes, and accessible backlog items. A
146
148
  roadmap is optional alignment evidence; an active OAT project is not
147
149
  required. The skill stops and tells you to run `oat pjm init` if adoption
148
- is absent or partial (see the [warning about rerunning it](#adoption-comes-first)).
150
+ is absent or partial.
149
151
 
150
152
  **Example scenario:** Your team has time for one maintenance initiative, but
151
153
  the backlog mixes isolated fixes with work blocked on shared infrastructure.
@@ -211,8 +213,7 @@ Context, Decision, and Consequences sections and reruns
211
213
  `oat decision regenerate-index` if it changed the status or title. Its
212
214
  workflow has no commit or push step. If the decision index markers are
213
215
  missing, it stops and tells you to repair the repository with
214
- `oat pjm init`; that is a rerun, so read the
215
- [warning about rerunning it](#adoption-comes-first) first.
216
+ `oat pjm init`.
216
217
 
217
218
  **Next step:** Review the record and link relevant work to it. If later
218
219
  evidence changes the choice, preserve history through the appropriate
@@ -249,9 +250,7 @@ sanitized description of which connector or provider CLI it can use for
249
250
  that tracker. The skill gathers that evidence for you.
250
251
 
251
252
  **Prerequisites:** PJM adoption verified by `oat pjm doctor --json` (the
252
- skill stops and points you to `oat pjm init` otherwise; rerunning init
253
- deletes `pjm.remote`, as the [warning above](#adoption-comes-first)
254
- explains), applicable local
253
+ skill stops and points you to `oat pjm init` otherwise), applicable local
255
254
  policy, and an available host capability matching the provider, operation,
256
255
  and exact account, workspace, site, or repository. No active OAT project is
257
256
  required. Remote mutation authority defaults to `read-only`, so `publish`
@@ -336,12 +335,14 @@ sanity check distinguishes valid active paths from retired references.
336
335
  the curated overview, and backlog item files under `.oat/repo/pjm/` as it
337
336
  judges applicable, with no separate approval step. It runs
338
337
  `oat backlog archive` for completed items, which moves each item file into
339
- `archived/` (with `git mv` inside a Git work tree), and it creates decision
340
- records with `oat decision new`. Its workflow has no commit or push step,
341
- so review the working-tree diff afterwards. If the backlog index markers
342
- are missing, it stops and tells you to repair the repository with
343
- `oat pjm init`; that is a rerun, so read the
344
- [warning about rerunning it](#adoption-comes-first) first.
338
+ `archived/` with a filesystem rename, and it creates decision
339
+ records with `oat decision new`. It automatically commits the exact archive
340
+ close-out paths and any owned kickoff handoff deletion with hooks enabled.
341
+ Other reference edits remain uncommitted, and the workflow has no push step,
342
+ so review the close-out commit and remaining working-tree diff afterwards.
343
+ If the backlog index markers are missing, it stops and tells you to repair
344
+ the repository with
345
+ `oat pjm init`.
345
346
 
346
347
  **Next step:** Review the changes against the implementation evidence and
347
348
  rerun diagnostics for lifecycle consistency. Start deferred work separately;
@@ -26,13 +26,6 @@ oat pjm doctor --json
26
26
  Continue only when `adoption.state` is `declared` or `inferred-legacy`. Run
27
27
  `oat pjm init` first when adoption is absent or only partially initialized.
28
28
 
29
- > [!WARNING]
30
- > Running `oat pjm init` again, or running `oat pjm migrate --apply`,
31
- > currently replaces the `pjm` section of `.oat/config.json` and deletes any
32
- > `pjm.remote` settings, which hold the remote policy described below. Before
33
- > you rerun either command, back up `.oat/config.json`. Afterwards, run
34
- > `git diff .oat/config.json` and restore `pjm.remote` if it was removed.
35
-
36
29
  ## Lifecycle operations
37
30
 
38
31
  The command family is `oat pjm remote`:
@@ -90,13 +90,8 @@ Good to know:
90
90
  (shared scope), pushed to a project ref (synced scope, the default on a
91
91
  fresh install), or kept on your machine (local scope).
92
92
 
93
- > [!WARNING]
94
- > Backlog items need project management (PJM, OAT's file-backed backlog,
95
- > roadmap, and decision records) adopted with `oat pjm init`. Run it once.
96
- > Running `oat pjm init` again, or running `oat pjm migrate --apply`,
97
- > currently deletes any `pjm.remote` settings from `.oat/config.json`. If
98
- > you rerun either command, check `git diff .oat/config.json` afterwards and
99
- > restore `pjm.remote` if it was removed.
93
+ Backlog items need project management (PJM, OAT's file-backed backlog,
94
+ roadmap, and decision records) adopted with `oat pjm init`. Run it once.
100
95
 
101
96
  1. Quick capture: `oat-idea-scratchpad` to review or capture idea seeds
102
97
  2. Start brainstorming: `oat-idea-new` (scaffolds directory, then invokes `oat-idea-ideate`)