@open-agent-toolkit/cli 0.3.15 → 0.3.17

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 (189) hide show
  1. package/assets/NOTICES.md +48 -0
  2. package/assets/agents/oat-phase-implementer.md +26 -6
  3. package/assets/agents/oat-reviewer.md +51 -1
  4. package/assets/bundle-metadata.json +1 -1
  5. package/assets/docs/contributing/documentation.md +4 -0
  6. package/assets/docs/contributing/skills.md +3 -1
  7. package/assets/docs/getting-started/bootstrap.md +1 -1
  8. package/assets/docs/getting-started/index.md +0 -4
  9. package/assets/docs/getting-started/tool-packs.md +0 -7
  10. package/assets/docs/provider-sync/commands.md +21 -0
  11. package/assets/docs/reference/cli-reference.md +44 -2
  12. package/assets/docs/reference/config-and-local-state.md +11 -2
  13. package/assets/docs/reference/configuration.md +10 -2
  14. package/assets/docs/reference/project-artifacts.md +43 -8
  15. package/assets/docs/skills/index.md +1 -0
  16. package/assets/docs/skills/recon.md +8 -5
  17. package/assets/docs/skills/repo-improve.md +9 -7
  18. package/assets/docs/workflows/advanced/autonomy.md +50 -0
  19. package/assets/docs/workflows/advanced/workflow-gates.md +109 -10
  20. package/assets/docs/workflows/approvals-and-automation.md +3 -1
  21. package/assets/docs/workflows/backlog-and-planning/backlog-lifecycle.md +25 -24
  22. package/assets/docs/workflows/backlog-and-planning/remote-project-management.md +0 -7
  23. package/assets/docs/workflows/ideas/lifecycle.md +2 -7
  24. package/assets/docs/workflows/projects/closeout/closeout-skills.md +62 -1
  25. package/assets/docs/workflows/projects/execution/implementation-execution.md +23 -3
  26. package/assets/docs/workflows/projects/execution/project-log.md +6 -0
  27. package/assets/docs/workflows/projects/lifecycle.md +7 -0
  28. package/assets/docs/workflows/projects/reviews/index.md +63 -1
  29. package/assets/docs/workflows/projects/reviews/review-flavors.md +8 -0
  30. package/assets/docs/workflows/waves/wave-workflows.md +11 -3
  31. package/assets/public-package-versions.json +4 -4
  32. package/assets/skills/oat-agent-instructions-apply/SKILL.md +14 -4
  33. package/assets/skills/oat-brainstorm/SKILL.md +17 -13
  34. package/assets/skills/oat-docs-apply/SKILL.md +13 -3
  35. package/assets/skills/oat-doctor/SKILL.md +11 -1
  36. package/assets/skills/oat-explainer-kit/SKILL.md +1 -1
  37. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +6 -3
  38. package/assets/skills/oat-pjm-review-backlog/SKILL.md +2 -2
  39. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +28 -3
  40. package/assets/skills/oat-project-autonomous/SKILL.md +60 -5
  41. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +210 -165
  42. package/assets/skills/oat-project-capture/SKILL.md +7 -3
  43. package/assets/skills/oat-project-complete/SKILL.md +39 -34
  44. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +106 -28
  45. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +30 -3
  46. package/assets/skills/oat-project-complete-auto/SKILL.md +388 -0
  47. package/assets/skills/oat-project-design/SKILL.md +12 -9
  48. package/assets/skills/oat-project-discover/SKILL.md +8 -4
  49. package/assets/skills/oat-project-document/SKILL.md +14 -5
  50. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +210 -165
  51. package/assets/skills/oat-project-implement/SKILL.md +6 -1
  52. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +34 -7
  53. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +210 -165
  54. package/assets/skills/oat-project-implement/references/docs/complexity-review-fallback.md +262 -0
  55. package/assets/skills/oat-project-implement/references/docs/gate-approval-record.md +80 -0
  56. package/assets/skills/oat-project-implement/references/phase-execution.md +38 -6
  57. package/assets/skills/oat-project-import-plan/SKILL.md +20 -6
  58. package/assets/skills/oat-project-lite/SKILL.md +7 -5
  59. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +210 -165
  60. package/assets/skills/oat-project-new/SKILL.md +6 -2
  61. package/assets/skills/oat-project-next/SKILL.md +19 -2
  62. package/assets/skills/oat-project-next/references/docs/gate-approval-record.md +80 -0
  63. package/assets/skills/oat-project-plan/SKILL.md +14 -6
  64. package/assets/skills/oat-project-pr-final/SKILL.md +4 -3
  65. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +210 -165
  66. package/assets/skills/oat-project-progress/SKILL.md +27 -1
  67. package/assets/skills/oat-project-progress/references/docs/gate-approval-record.md +80 -0
  68. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +7 -3
  69. package/assets/skills/oat-project-quick-start/SKILL.md +47 -14
  70. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +210 -165
  71. package/assets/skills/oat-project-quick-start/references/docs/complexity-review-fallback.md +262 -0
  72. package/assets/skills/oat-project-quick-start/references/docs/gate-approval-record.md +80 -0
  73. package/assets/skills/oat-project-reconcile/SKILL.md +8 -4
  74. package/assets/skills/oat-project-retro/SKILL.md +1 -1
  75. package/assets/skills/oat-project-retro/references/apply-procedure.md +6 -6
  76. package/assets/skills/oat-project-retro-file/SKILL.md +7 -3
  77. package/assets/skills/oat-project-review-provide/SKILL.md +23 -4
  78. package/assets/skills/oat-project-review-provide-remote/SKILL.md +19 -1
  79. package/assets/skills/oat-project-review-receive/SKILL.md +57 -14
  80. package/assets/skills/oat-project-review-receive/references/docs/complexity-review-fallback.md +262 -0
  81. package/assets/skills/oat-project-review-receive-remote/SKILL.md +7 -3
  82. package/assets/skills/oat-project-revise/SKILL.md +13 -5
  83. package/assets/skills/oat-project-spec/SKILL.md +8 -4
  84. package/assets/skills/oat-project-summary/SKILL.md +11 -7
  85. package/assets/skills/oat-repo-knowledge-index/SKILL.md +54 -20
  86. package/assets/skills/oat-repo-knowledge-index/scripts/refresh-owned.mjs +118 -0
  87. package/assets/skills/oat-review-provide/SKILL.md +7 -3
  88. package/assets/skills/oat-review-receive-remote/SKILL.md +14 -4
  89. package/assets/skills/oat-wave-execute/SKILL.md +72 -38
  90. package/assets/skills/oat-wave-execute/assets/wrapper-plan-template.md +16 -2
  91. package/assets/skills/oat-wave-program/SKILL.md +15 -6
  92. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +45 -17
  93. package/assets/skills/oat-wrap-up/SKILL.md +9 -3
  94. package/assets/skills/oat-wrap-up/references/report-template.md +1 -1
  95. package/assets/skills/recon/SKILL.md +1 -1
  96. package/assets/skills/recon/references/packet-contract.md +18 -3
  97. package/assets/skills/recon/scripts/lib/contracts.mjs +16 -2
  98. package/assets/skills/recon/scripts/reconcile-ledger.mjs +20 -10
  99. package/assets/skills/recon/scripts/render-packet.mjs +31 -3
  100. package/assets/skills/recon/scripts/validate-packet.mjs +5 -5
  101. package/assets/templates/pjm-agents.md +38 -8
  102. package/assets/templates/repo-agents.md +5 -0
  103. package/assets/templates/repo-readme.md +5 -0
  104. package/assets/templates/state.md +7 -0
  105. package/dist/commands/backlog/archive.d.ts +3 -0
  106. package/dist/commands/backlog/archive.d.ts.map +1 -1
  107. package/dist/commands/backlog/archive.js +63 -26
  108. package/dist/commands/backlog/index.d.ts.map +1 -1
  109. package/dist/commands/backlog/index.js +3 -0
  110. package/dist/commands/backlog/rewrite-references.d.ts +5 -0
  111. package/dist/commands/backlog/rewrite-references.d.ts.map +1 -1
  112. package/dist/commands/backlog/rewrite-references.js +39 -1
  113. package/dist/commands/config/index.d.ts.map +1 -1
  114. package/dist/commands/config/index.js +13 -0
  115. package/dist/commands/gate/index.d.ts +5 -0
  116. package/dist/commands/gate/index.d.ts.map +1 -1
  117. package/dist/commands/gate/index.js +270 -9
  118. package/dist/commands/init/index.d.ts.map +1 -1
  119. package/dist/commands/init/index.js +1 -0
  120. package/dist/commands/internal/commit-paths.d.ts +3 -0
  121. package/dist/commands/internal/commit-paths.d.ts.map +1 -0
  122. package/dist/commands/internal/commit-paths.js +31 -0
  123. package/dist/commands/internal/index.d.ts.map +1 -1
  124. package/dist/commands/internal/index.js +2 -0
  125. package/dist/commands/pjm/init.d.ts.map +1 -1
  126. package/dist/commands/pjm/init.js +37 -8
  127. package/dist/commands/project/archive/archive-utils.d.ts +6 -3
  128. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  129. package/dist/commands/project/archive/archive-utils.js +510 -104
  130. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  131. package/dist/commands/project/archive/push-runner.js +1 -0
  132. package/dist/commands/project/log/append.d.ts +2 -3
  133. package/dist/commands/project/log/append.d.ts.map +1 -1
  134. package/dist/commands/project/log/append.js +55 -101
  135. package/dist/commands/project/migrate/index.d.ts +1 -2
  136. package/dist/commands/project/migrate/index.d.ts.map +1 -1
  137. package/dist/commands/project/migrate/index.js +8 -2
  138. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  139. package/dist/commands/project/new/scaffold.js +4 -4
  140. package/dist/commands/project/promote/promote.d.ts +8 -0
  141. package/dist/commands/project/promote/promote.d.ts.map +1 -1
  142. package/dist/commands/project/promote/promote.js +37 -6
  143. package/dist/commands/project/status.d.ts.map +1 -1
  144. package/dist/commands/project/status.js +3 -0
  145. package/dist/commands/project/sync/ref-sync.d.ts +12 -1
  146. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
  147. package/dist/commands/project/sync/ref-sync.js +347 -23
  148. package/dist/commands/shared/exact-path-commit.d.ts +32 -0
  149. package/dist/commands/shared/exact-path-commit.d.ts.map +1 -0
  150. package/dist/commands/shared/exact-path-commit.js +691 -0
  151. package/dist/commands/shared/frontmatter.d.ts +1 -1
  152. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  153. package/dist/commands/shared/frontmatter.js +1 -0
  154. package/dist/commands/state/generate.d.ts +1 -1
  155. package/dist/commands/state/generate.d.ts.map +1 -1
  156. package/dist/commands/state/generate.js +87 -8
  157. package/dist/commands/sync/apply.d.ts.map +1 -1
  158. package/dist/commands/sync/apply.js +31 -5
  159. package/dist/commands/sync/dry-run.d.ts.map +1 -1
  160. package/dist/commands/sync/dry-run.js +28 -11
  161. package/dist/commands/sync/sync.utils.d.ts +13 -0
  162. package/dist/commands/sync/sync.utils.d.ts.map +1 -1
  163. package/dist/commands/sync/sync.utils.js +21 -1
  164. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -1
  165. package/dist/commands/tools/shared/pack-manifest.js +1 -0
  166. package/dist/config/oat-config.d.ts +1 -0
  167. package/dist/config/oat-config.d.ts.map +1 -1
  168. package/dist/config/oat-config.js +3 -0
  169. package/dist/config/resolve.d.ts.map +1 -1
  170. package/dist/config/resolve.js +1 -0
  171. package/dist/drift/detector.js +6 -6
  172. package/dist/engine/compute-plan.d.ts.map +1 -1
  173. package/dist/engine/compute-plan.js +87 -2
  174. package/dist/engine/engine.types.d.ts +10 -1
  175. package/dist/engine/engine.types.d.ts.map +1 -1
  176. package/dist/engine/engine.types.js +4 -0
  177. package/dist/engine/execute-plan.d.ts.map +1 -1
  178. package/dist/engine/execute-plan.js +42 -5
  179. package/dist/engine/managed-copy-hash.d.ts +4 -3
  180. package/dist/engine/managed-copy-hash.d.ts.map +1 -1
  181. package/dist/engine/managed-copy-hash.js +4 -3
  182. package/dist/fs/assets.d.ts.map +1 -1
  183. package/dist/fs/assets.js +7 -1
  184. package/dist/manifest/hash.d.ts +8 -10
  185. package/dist/manifest/hash.d.ts.map +1 -1
  186. package/dist/ui/output.js +1 -1
  187. package/dist/validation/skills.d.ts.map +1 -1
  188. package/dist/validation/skills.js +151 -11
  189. package/package.json +3 -2
@@ -0,0 +1,388 @@
1
+ ---
2
+ name: oat-project-complete-auto
3
+ description: Use when a workflow step names this skill (oat-wave-execute closeout step 8 or the oat-wave-program completion checkpoint) to complete one or more OAT projects without prompts. Non-interactive companion to oat-project-complete; requires workflow.autonomousComplete.
4
+ argument-hint: '--requested-by <requesting-step> [--completion-before-merge --reason <text>] [--batch --program-checkpoint <ledger-ref>] [<project-path>...]'
5
+ disable-model-invocation: false
6
+ user-invocable: false
7
+ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
8
+ metadata:
9
+ version: 1.0.0
10
+ ---
11
+
12
+ # Autonomous Project Completion
13
+
14
+ Non-interactive project completion for workflow steps that name this skill.
15
+ It decides every answer the interactive completion flow would ask for
16
+ from config and recorded project state, refuses whenever an answer would need a
17
+ human, and then runs the interactive completion steps unchanged.
18
+
19
+ This skill is **model-invocable** (`disable-model-invocation: false`) so that
20
+ orchestrators such as `oat-wave-execute` can run it as a named step. It is
21
+ **not** user-invocable (`user-invocable: false`): it has no interactive surface
22
+ and is never offered as a slash command. A person completing a project uses
23
+ `oat-project-complete`.
24
+
25
+ ## Relationship to oat-project-complete
26
+
27
+ This skill is the **autonomous companion** to `oat-project-complete`, which
28
+ stays user-invocable and model-invisible so its human gate is preserved where
29
+ it is wanted. The companion does not copy the completion process: after its
30
+ guards pass it loads the interactive skill's current `SKILL.md` and follows its
31
+ steps, supplying the answers resolved below.
32
+
33
+ | Concern | oat-project-complete (interactive) | oat-project-complete-auto (autonomous) |
34
+ | ------------- | -------------------------------------- | --------------------------------------------------------------------- |
35
+ | Invocation | User-invocable, model-invisible | Model-invocable, never user-invocable |
36
+ | Authorization | The user's confirmation | `workflow.autonomousComplete: true` plus a recognized requesting step |
37
+ | Prompts | One batched prompt, gate confirmations | None; any answer that needs a human refuses the project |
38
+ | Scope | The active project | One project, or a batch of wave-wrapper projects at program close |
39
+ | Provenance | The user | The requesting step, in the run report and the completion commit body |
40
+
41
+ ## Progress Indicators (User-Facing)
42
+
43
+ When this skill is executed, provide concise status updates:
44
+
45
+ - Print a phase banner once at start:
46
+
47
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
48
+ OAT ▸ COMPLETE PROJECT AUTO
49
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
50
+
51
+ - Before major phases, print compact indicators, for example:
52
+ - `[1/5] Checking the autonomous completion opt-in…`
53
+ - `[2/5] Checking the activation contract…`
54
+ - `[3/5] Preflighting {project}…`
55
+ - `[4/5] Completing {project}…`
56
+ - `[5/5] Returning the run report…`
57
+
58
+ ## Inputs
59
+
60
+ | Input | Required | Meaning |
61
+ | ----------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
62
+ | `--requested-by <requesting-step>` | Always | The step that names this skill (see Recognized requesting steps). Recorded as provenance. |
63
+ | `--completion-before-merge` | Only from such a step | The requesting step completes the project before its PR merges. Permits an open, tracked PR through a recorded exception. |
64
+ | `--reason <text>` | With the flag above | Why completion runs before the merge; written into the exception. |
65
+ | `--batch` | Program close only | Complete several wave-wrapper projects in one invocation. |
66
+ | `--program-checkpoint <ledger-ref>` | With `--batch` | The program ledger entry recording the operator's yes at the program-end checkpoint. |
67
+ | `<project-path>...` | Batch: one or more paths | Projects to complete. A single run without a path uses `oat config get activeProject`. |
68
+
69
+ ### Recognized requesting steps
70
+
71
+ | `--requested-by` value | Requesting step | Completion before merge |
72
+ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | ----------------------- |
73
+ | `oat-wave-execute:closeout-step-8` | `oat-wave-execute` closeout step 8, completing a wave before its merge handoff | yes |
74
+ | `oat-wave-program:program-completion-checkpoint` | `oat-wave-program` `wave-close` step 6, after the operator's yes, with `--batch` | no |
75
+ | `oat-autonomous-lifecycle:<skill-name>` | A lifecycle skill under `OAT_AUTONOMOUS=1` whose `SKILL.md` names this skill as a step (verified in Step 2) | no |
76
+
77
+ `--completion-before-merge` is accepted only with a value whose "Completion
78
+ before merge" column is `yes`.
79
+
80
+ ## Process
81
+
82
+ Set `SKILL_DIR` to the absolute physical (`cd -P`) directory containing this
83
+ loaded `SKILL.md` before Step 1; Step 2 resolves sibling skills relative to it.
84
+
85
+ Steps 1 through 3 are read-only with respect to lifecycle decisions and
86
+ mutations. Step 3 may refresh a synced checkout with `oat project pull`, which
87
+ must succeed before any authoritative project artifact is read. No exception
88
+ record, active-project pointer, summary, retro, project-log entry, review move,
89
+ or lifecycle state is written until every guard for that project has passed.
90
+
91
+ ### Step 1: Opt-in Guard
92
+
93
+ ```bash
94
+ AUTONOMOUS_COMPLETE=$(oat config get workflow.autonomousComplete 2>/dev/null || true)
95
+ if [[ "$AUTONOMOUS_COMPLETE" != "true" ]]; then
96
+ echo "interactive completion required: workflow.autonomousComplete is not true; run oat-project-complete." >&2
97
+ exit 1
98
+ fi
99
+ ```
100
+
101
+ The opt-in is standing authorization set in config, never inferred from the
102
+ request. Without it, stop with `interactive completion required`, report the
103
+ projects as not started, and write nothing.
104
+
105
+ ### Step 2: Activation Contract
106
+
107
+ Run only when the invocation carries a recognized `--requested-by` value:
108
+
109
+ - `oat-wave-execute:closeout-step-8` and
110
+ `oat-wave-program:program-completion-checkpoint` are steps that name this
111
+ skill.
112
+ - `oat-autonomous-lifecycle:<skill-name>` additionally requires
113
+ `OAT_AUTONOMOUS=1` in the environment of this run and a lifecycle skill that
114
+ names this skill as a step. `<skill-name>` must match `oat-[a-z0-9-]+`;
115
+ resolve its `SKILL.md` through the same sibling, user, then repository probe
116
+ as the interactive skill below, and refuse unless that skill's current
117
+ `SKILL.md` contains the exact invocation
118
+ `--requested-by oat-autonomous-lifecycle:<skill-name>`. Running under
119
+ `OAT_AUTONOMOUS=1` is not itself a request: until a lifecycle skill carries
120
+ that invocation, this route refuses every claim. No lifecycle skill carries
121
+ it today, so the two workflow steps above are the only working routes.
122
+
123
+ Refuse, writing nothing, when `--requested-by` is missing or unrecognized, when
124
+ `--completion-before-merge` comes from a step whose column above is `no`, or
125
+ when `--batch` arrives without `--program-checkpoint` or from any step other
126
+ than the program completion checkpoint. Never invoke this skill on your own
127
+ initiative: noticing a finished, unarchived, or lingering project is not a
128
+ request, and self-initiated cleanup is refused. The requesting step is the
129
+ provenance recorded in the run report (Step 6) and in the completion commit
130
+ body (Step 5).
131
+
132
+ Before any project is preflighted, resolve the interactive skill this run will
133
+ follow. A candidate must carry both `SKILL.md` and the `scripts/` directory its
134
+ steps call, so a partial install stops here instead of after the Step 4
135
+ exception write:
136
+
137
+ ```bash
138
+ COMPLETE_SKILL_DIR=""
139
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true)
140
+ for CANDIDATE in \
141
+ "$(dirname "$SKILL_DIR")/oat-project-complete" \
142
+ "${HOME}/.agents/skills/oat-project-complete" \
143
+ "${REPO_ROOT:+$REPO_ROOT/.agents/skills/oat-project-complete}"; do
144
+ [ -n "$CANDIDATE" ] || continue
145
+ if [ -f "$CANDIDATE/SKILL.md" ] && [ -d "$CANDIDATE/scripts" ]; then
146
+ COMPLETE_SKILL_DIR=$(cd -P "$CANDIDATE" && pwd -P)
147
+ break
148
+ fi
149
+ done
150
+ if [ -z "$COMPLETE_SKILL_DIR" ]; then
151
+ echo "oat-project-complete unavailable: no installed copy with SKILL.md and scripts/" >&2
152
+ exit 1
153
+ fi
154
+ ```
155
+
156
+ An unavailable interactive skill stops the run as an `activation` refusal,
157
+ writing nothing.
158
+
159
+ ### Step 3: Objective Preflight (Per Project)
160
+
161
+ Preflight each project on its own. Any failed check refuses that project with
162
+ the failing check named; never assume an answer, and never repair the state
163
+ to make a check pass.
164
+
165
+ Resolve scope first and accept only `shared`, `local`, or `synced`. For a
166
+ synced project, pull before `closeout-check`, status, log, review-ledger reads,
167
+ or any other authoritative artifact read or answer resolution. A failed scope
168
+ lookup, an unknown scope, or a failed pull refuses the project as
169
+ `preflight:1`; never continue from stale local state. If the pull fails and
170
+ the project directory is absent, report the archive-resume reason below and
171
+ leave recovery to `oat-project-complete`.
172
+
173
+ ```bash
174
+ PROJECT_PATH="<project path>"
175
+ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || {
176
+ echo "preflight:1: cannot resolve project scope for $PROJECT_PATH; refusing completion" >&2
177
+ exit 1
178
+ }
179
+ case "$PROJECT_SCOPE" in
180
+ shared|local|synced) ;;
181
+ *)
182
+ echo "preflight:1: unknown project scope '$PROJECT_SCOPE' for $PROJECT_PATH; refusing completion" >&2
183
+ exit 1
184
+ ;;
185
+ esac
186
+ if [[ "$PROJECT_SCOPE" == "synced" ]]; then
187
+ oat project pull "$PROJECT_PATH" || {
188
+ echo "preflight:1: project pull failed for $PROJECT_PATH; refusing completion" >&2
189
+ if [[ ! -d "$PROJECT_PATH" ]]; then
190
+ echo "project directory absent (archived?); resume with oat-project-complete" >&2
191
+ fi
192
+ exit 1
193
+ }
194
+ fi
195
+ CLOSEOUT_CHECK_EXIT=0
196
+ CLOSEOUT_CHECK_JSON=$(oat project closeout-check "$PROJECT_PATH" --json --autonomous) || CLOSEOUT_CHECK_EXIT=$?
197
+ PROJECT_STATUS_JSON=$(oat project status --project-path "$PROJECT_PATH" --json)
198
+ PROJECT_LOG_CHECK=$(oat project log check --project "$PROJECT_PATH" --json)
199
+ ```
200
+
201
+ Hard-fail the project when any of these holds:
202
+
203
+ 1. **Post-implement sequence incomplete:** `closeout-check` exits non-zero or
204
+ reports a `status` other than `complete` or `not_required`. Report its
205
+ `invariant` and `nextOwner`. When it reports `status: error` with
206
+ `Project not found` (the project directory is gone, typically archived by
207
+ an earlier run whose later step failed), report instead the reason
208
+ `project directory absent (archived?); resume with oat-project-complete`:
209
+ recovery belongs to the interactive skill, not to another companion run.
210
+ 2. **Incomplete tasks:** `project.progress.total` is zero or
211
+ `project.progress.completed` is less than `project.progress.total`.
212
+ 3. **Final review not passed:** the latest appended review event whose Scope is
213
+ `final` and Type is `code` in the plan's `## Reviews` ledger (the
214
+ `oat-project-complete` Step 3.1 read) is missing or not `passed`.
215
+ 4. **PR precondition unmet:** see the PR-merge precondition below.
216
+ 5. **Unresolved blockers:** `project.blockers` is non-empty.
217
+ 6. **Project-log gate unsatisfied:** `oat project log check` reports
218
+ `status: "ambiguous"` or fails. An `absent` log, a sealed log, and a log
219
+ whose roll-up the completion steps will perform are satisfied.
220
+ 7. **A completion question has no recorded answer:** see the answer table
221
+ below. For example, a durable (`shared` or `synced`) project with
222
+ `workflow.archiveOnComplete` unset, deferred Medium findings that the
223
+ interactive gate confirmation would ask about, or a documentation gate that
224
+ `documentation.requireForProjectCompletion: true` makes blocking.
225
+
226
+ #### PR-merge precondition
227
+
228
+ OAT supports completing a project before its PR merges
229
+ (`oat-project-complete`; `oat-wave-execute` closeout step 8 completes each wave
230
+ before its merge handoff). This skill composes with that ordering through one
231
+ recorded exception and no other.
232
+
233
+ Read the tracked PR from `project.prStatus` and `project.prUrl`, then read its
234
+ state from GitHub:
235
+
236
+ ```bash
237
+ PR_STATE=$(gh pr view "$PR_URL" --json state --jq .state)
238
+ ```
239
+
240
+ | Requested by | Completion before merge | GitHub PR state | `oat_pr_status` | `oat_pr_url` | Final review | Result |
241
+ | ------------------- | ----------------------- | --------------- | --------------- | ------------ | ------------ | ------------------------ |
242
+ | a recognized step | any | `MERGED` | any | set | `passed` | pass, no exception |
243
+ | a before-merge step | yes | `OPEN` | `open` | set | `passed` | pass, exception recorded |
244
+
245
+ Every other combination is refused: an open PR invoked without a
246
+ completion-before-merge step, an open PR the project does not track, a closed
247
+ or absent PR, a PR state `gh` cannot read, and any final review row that is not
248
+ `passed`. A merged program-end batch passes with no exception.
249
+
250
+ When the exception applies, write it into the project's `implementation.md`
251
+ before any completion write (Step 4), and repeat it in the run report.
252
+
253
+ #### Answer table
254
+
255
+ Every question or confirmation in `oat-project-complete` resolves as follows.
256
+ A row marked "refuse" is checked during this preflight, so the completion
257
+ steps never reach it.
258
+
259
+ | `oat-project-complete` question or gate | Resolution |
260
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
261
+ | Confirm completion (Step 2) | Yes, from the opt-in plus the recognized requesting step (and the program checkpoint in batch mode). |
262
+ | Archive (Step 2) | `workflow.archiveOnComplete` when set; local projects never archive; unset on a durable project: refuse. |
263
+ | Generate or refresh summary (Step 2) | Yes when `summary.md` is missing or stale. |
264
+ | Generate project retro (Step 2) | Never offered: this run is non-interactive. |
265
+ | Final project recap (Step 2) | The persisted decision, else the lifecycle intent resolver in autonomous mode; a result that still needs a prompt: refuse. |
266
+ | Open PR (Step 2) | No, forced by Step 5 even where the interactive Step 2 would not ask. The precondition requires an existing merged or tracked open PR; `workflow.createPrOnComplete` is read and reported, never acted on. |
267
+ | Final review not passed (Step 3.1) | Refuse (preflight check 3). |
268
+ | Deferred Medium findings (Step 3.2) | Unresolved items: refuse. |
269
+ | Documentation sync (Step 3.3) | Blocking gate: refuse. Soft suggestion: continue without writing `oat_docs_updated`. |
270
+ | Recap generation failure (Step 3.6) | The interactive autonomy rule: retry once, then persist `skip/failed_attempt`. |
271
+ | Retirement sweep findings (Step 3.7) | The interactive autonomy rule: record `deferred advisory`. |
272
+ | Project-log synthesis pending (Step 3.7) | Warn and continue, as the interactive step does. |
273
+
274
+ ### Step 4: Record a Completion-Before-Merge Exception
275
+
276
+ Only when the PR-merge precondition passed through the exception row, append
277
+ this block to the project's `implementation.md` before any other write. Place
278
+ it at the end of the `## Implementation Log` section, or at the end of the file
279
+ when that section is absent, and do not append a second block for the same PR
280
+ and requesting step:
281
+
282
+ ```markdown
283
+ ### Completion-before-merge exception ({UTC timestamp})
284
+
285
+ - Requesting workflow: {--requested-by value}
286
+ - PR: {oat_pr_url} (open)
287
+ - Reason: {--reason value}
288
+ - Recorded by: oat-project-complete-auto
289
+ ```
290
+
291
+ For `PROJECT_SCOPE="synced"`, publish the exception before Step 5 or any
292
+ further completion step: the delegated interactive skill's arrival pull must
293
+ not overwrite an unpublished exception. Run this even when the matching
294
+ exception already exists, so a retry publishes an earlier failed push without
295
+ duplicating the block:
296
+
297
+ ```bash
298
+ if [[ "$PROJECT_SCOPE" == "synced" ]]; then
299
+ oat project push "$PROJECT_PATH" \
300
+ --message "chore(oat): record completion-before-merge exception" --json || {
301
+ echo "completion-before-merge exception push failed for $PROJECT_PATH; stopping before completion" >&2
302
+ exit 1
303
+ }
304
+ fi
305
+ ```
306
+
307
+ A push failure stops the whole run. Report Step 4 as failed and the exception
308
+ left in the local checkout; do not point the active project, delegate completion,
309
+ or start further projects. For shared and local projects, the completion
310
+ bookkeeping commit carries this file with the rest of the completion changes.
311
+
312
+ ### Step 5: Complete the Project
313
+
314
+ For each project that passed Steps 3 and 4, in the order given:
315
+
316
+ 1. Point the active project at it: `oat config set activeProject "$PROJECT_PATH"`.
317
+ 2. Export `OAT_AUTONOMOUS=1` and `OAT_NON_INTERACTIVE=1` for the completion
318
+ steps so their autonomous branches apply (`closeout-check --autonomous`,
319
+ `complete-state --autonomous`, the recap retry, and the retirement sweep).
320
+ 3. Bind `SKILL_DIR="$COMPLETE_SKILL_DIR"` (resolved in Step 2) only while
321
+ following the interactive steps, so their `$SKILL_DIR/scripts/*.mjs`
322
+ references resolve, and restore this skill's own directory afterwards.
323
+ 4. Load the current `oat-project-complete/SKILL.md` and follow its Steps 1
324
+ through 12, supplying the answer table above wherever it would ask. Never
325
+ complete from a remembered version of that skill. Its own guards still run,
326
+ including the Step 1.5 closeout gate and the Step 5 closeout re-check.
327
+ 5. Override the PR decision. Supplying answers only where the interactive
328
+ flow asks is not enough: its Step 2 sets `SHOULD_OPEN_PR="true"` without
329
+ asking when `workflow.createPrOnComplete` is `true` and no tracked PR is
330
+ open, which includes a merged PR. Once its Step 2 has resolved its answers,
331
+ and again before its Step 11, set `SHOULD_OPEN_PR="false"`, whatever
332
+ `workflow.createPrOnComplete` or `oat_pr_status` says. This skill never runs
333
+ `gh pr create`. Updates to an existing tracked PR proceed as the interactive
334
+ steps require, including the Step 11.5 description sync when
335
+ `WAS_PR_OPEN_AT_START="true"`.
336
+ 6. Add the provenance to the completion bookkeeping commit body that Step 10
337
+ creates: a `Requested-by: {--requested-by value}` line and, when an exception
338
+ was recorded, a `Completion-before-merge exception: {oat_pr_url}` line. When
339
+ the archive owns the lifecycle commit (a synced archive), the run report
340
+ alone carries the provenance and says so.
341
+
342
+ If a completion step fails after it has written anything, stop the whole run,
343
+ report the step and the state left behind, and do not start further projects.
344
+ A later companion run refuses at preflight once the project directory has been
345
+ archived; resume with `oat-project-complete`, whose archive-resume branches
346
+ finish the tail. Never improvise a partial completion.
347
+
348
+ ### Batch Mode
349
+
350
+ At program close, `oat-wave-program` asks the operator one program completion
351
+ question; that answer is the human gate for the batch. On yes it invokes this
352
+ skill once with
353
+ `--requested-by oat-wave-program:program-completion-checkpoint --batch --program-checkpoint <ledger-ref>`
354
+ and every deferred wave-wrapper project path.
355
+
356
+ Batch mode does not lower any guard. The opt-in is checked once; each project
357
+ is preflighted individually (Step 3) and a failed preflight refuses only that
358
+ project, which stays deferred while the others complete. Program close follows
359
+ every wave merge, so each project needs a merged PR; the completion-before-merge
360
+ exception is not available in batch mode. A completion-step failure after a
361
+ write stops the batch, as in Step 5.
362
+
363
+ ### Step 6: Run Report
364
+
365
+ Return a structured report, one entry per project:
366
+
367
+ ```yaml
368
+ oat_project_complete_auto:
369
+ requested_by: '{--requested-by value}'
370
+ mode: single | batch
371
+ program_checkpoint: '{ledger ref or -}'
372
+ opt_in: workflow.autonomousComplete=true
373
+ projects:
374
+ - path: '{project path}'
375
+ status: completed | refused | failed
376
+ refused_check: '{opt-in | activation | preflight:<n> | -}'
377
+ reason: '{failing check, or -}'
378
+ pr: '{oat_pr_url} ({GitHub state})'
379
+ exception: '{requesting workflow; PR URL; reason} | none'
380
+ archive: '{true|false} (from workflow.archiveOnComplete | local default)'
381
+ completion_commit: '{sha or -}'
382
+ ```
383
+
384
+ A refused or failed project lists the check that stopped it. `refused_check`
385
+ names the guard: `opt-in` (Step 1), `activation` (Step 2, including an
386
+ unavailable interactive skill), or `preflight:<n>` for check `<n>` of Step 3,
387
+ so a caller can tell a deferrable stop from an objective failure. The caller records
388
+ the outcome in its own ledger; a refused wave wrapper stays deferred.
@@ -5,13 +5,17 @@ disable-model-invocation: true
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Bash(git:*), Bash(oat template:*), Glob, Grep, AskUserQuestion
7
7
  metadata:
8
- version: 2.3.7
8
+ version: 2.3.8
9
9
  ---
10
10
 
11
11
  # Design Phase
12
12
 
13
13
  Transform specification requirements into a detailed technical design with architecture, components, and implementation strategy.
14
14
 
15
+ ## Hook-safe exact-path commits
16
+
17
+ Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
18
+
15
19
  ## Prerequisites
16
20
 
17
21
  **Required:** Completed discovery (`discovery.md` with `oat_status: complete`). Specification is optional — this skill folds requirements confirmation into its flow and produces `spec.md` as a byproduct (see Step 2). If the user already ran `oat-project-spec` standalone, that spec is reused.
@@ -328,8 +332,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
328
332
  if [ "$PROJECT_SCOPE" = "synced" ]; then
329
333
  oat project push "$PROJECT_PATH" --message "docs: confirm requirements for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
330
334
  else
331
- git add "$PROJECT_PATH/spec.md"
332
- git commit -m "docs: confirm requirements for {project-name}"
335
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/spec.md")
336
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:1" --message "docs: confirm requirements for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
333
337
  fi
334
338
  ```
335
339
 
@@ -603,8 +607,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
603
607
  if [ "$PROJECT_SCOPE" = "synced" ]; then
604
608
  oat project push "$PROJECT_PATH" --message "docs: draft design for {project-name} (awaiting review)" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
605
609
  else
606
- git add "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md"
607
- git diff --cached --quiet || git commit -m "docs: draft design for {project-name} (awaiting review)"
610
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
611
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:2" --message "docs: draft design for {project-name} (awaiting review)" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
608
612
  fi
609
613
  ```
610
614
 
@@ -646,8 +650,7 @@ Wait for user response:
646
650
  if [ "$PROJECT_SCOPE" = "synced" ]; then
647
651
  oat project push "$PROJECT_PATH" --message "docs: revise design after user review feedback" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
648
652
  else
649
- git add "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md"
650
- git commit -m "docs: revise design after user review feedback"
653
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:3" --message "docs: revise design after user review feedback" -- "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" || exit 1
651
654
  fi
652
655
  Re-present this prompt.
653
656
  - If user does not approve yet (wants to pause without explicit change
@@ -813,8 +816,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
813
816
  if [ "$PROJECT_SCOPE" = "synced" ]; then
814
817
  oat project push "$PROJECT_PATH" --message "chore(oat): mark design complete for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
815
818
  else
816
- git add "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md"
817
- git diff --cached --quiet || git commit -m "chore(oat): mark design complete for {project-name}"
819
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
820
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:4" --message "chore(oat): mark design complete for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
818
821
  fi
819
822
  ```
820
823
 
@@ -5,13 +5,17 @@ disable-model-invocation: false
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Bash(git:*), Bash(oat:*), Bash(pnpm:*), Glob, Grep, AskUserQuestion
7
7
  metadata:
8
- version: 2.2.8
8
+ version: 2.2.9
9
9
  ---
10
10
 
11
11
  # Discovery Phase
12
12
 
13
13
  Gather requirements and understand the problem space through natural collaborative dialogue.
14
14
 
15
+ ## Hook-safe exact-path commits
16
+
17
+ Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
18
+
15
19
  ## Prerequisites
16
20
 
17
21
  **Required:** Knowledge base must exist. If missing, run the `oat-repo-knowledge-index` skill first.
@@ -575,14 +579,14 @@ Key decisions:
575
579
  Ready for design phase" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
576
580
  else
577
581
  PROJECT_OUTPUT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md")
578
- git add -- "${PROJECT_OUTPUT_PATHS[@]}"
579
- git commit -m "docs: complete discovery for {project-name}
582
+ OWNED_COMMIT_PATHS=("${PROJECT_OUTPUT_PATHS[@]}")
583
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-discover:1" --message "docs: complete discovery for {project-name}
580
584
 
581
585
  Key decisions:
582
586
  - {Decision 1}
583
587
  - {Decision 2}
584
588
 
585
- Ready for design phase"
589
+ Ready for design phase" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
586
590
  fi
587
591
  ```
588
592
 
@@ -6,13 +6,17 @@ disable-model-invocation: false
6
6
  user-invocable: true
7
7
  allowed-tools: Read, Write, Edit, Bash(git:*), Bash(jq:*), Bash(oat pjm:*), Bash(oat project push:*), Bash(oat project scope:*), Bash(oat tools:*), Glob, Grep, AskUserQuestion, Skill
8
8
  metadata:
9
- version: 1.8.6
9
+ version: 1.8.8
10
10
  ---
11
11
 
12
12
  # Project Documentation Sync
13
13
 
14
14
  Read project artifacts and implementation code to identify documentation surfaces that need updating, present a delta plan for approval, and apply changes — all in a single invocation.
15
15
 
16
+ ## Hook-safe exact-path commits
17
+
18
+ Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
19
+
16
20
  ## Prerequisites
17
21
 
18
22
  **Required:**
@@ -490,6 +494,11 @@ Track which recommendations were approved for Step 7.
490
494
 
491
495
  ### Step 7: Apply Approved Changes
492
496
 
497
+ Initialize `OWNED_OUTPUT_FILES=()` before documentation writes. Append each
498
+ exact successfully written or removed documentation path, including both
499
+ rename sides and generated index/navigation files actually changed. Retain this
500
+ producer list for the Step 8a helper commit and retries.
501
+
493
502
  Execute the approved documentation updates.
494
503
 
495
504
  **For each approved recommendation:**
@@ -540,8 +549,8 @@ If `$DOCS_CONFIG` exists and new files were created in the docs directory:
540
549
  **8a. Stage and commit documentation changes:**
541
550
 
542
551
  ```bash
543
- git add {list of changed/created documentation files}
544
- git diff --cached --quiet || git commit -m "docs({project-name}): update documentation from project artifacts"
552
+ OWNED_COMMIT_PATHS=("${OWNED_OUTPUT_FILES[@]}")
553
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-document:1" --message "docs({project-name}): update documentation from project artifacts" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
545
554
  ```
546
555
 
547
556
  Only stage files that were actually changed or created in Step 7. Do not use `git add -A`.
@@ -559,8 +568,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
559
568
  if [ "$PROJECT_SCOPE" = "synced" ]; then
560
569
  oat project push "$PROJECT_PATH" --message "chore({project-name}): mark docs updated" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
561
570
  else
562
- git add "$PROJECT_PATH/state.md"
563
- git diff --cached --quiet || git commit -m "chore({project-name}): mark docs updated"
571
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/state.md")
572
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-document:2" --message "chore({project-name}): mark docs updated" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
564
573
  fi
565
574
  ```
566
575