@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
@@ -5,7 +5,7 @@ disable-model-invocation: false
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Glob, Grep, Bash(git:*), Bash(oat:*), AskUserQuestion
7
7
  metadata:
8
- version: 1.4.3
8
+ version: 1.4.5
9
9
  ---
10
10
 
11
11
  # Progress Router
@@ -179,6 +179,20 @@ Read `{project}/state.md` frontmatter:
179
179
  - `oat_hill_completed` - Completed HiLL checkpoints
180
180
  - `oat_skill_gate_overrides` - Configured lifecycle gates this project
181
181
  deliberately disabled, keyed by gate-aware skill name
182
+ - `oat_implement_exit_gate` - The implementation exit gate record
183
+ - `oat_quick_start_gate` - The quick-start plan gate record
184
+
185
+ Blockers may be legacy reason strings or structured `{task_id, reason, since}`
186
+ records. Display strings as their reason; display records as
187
+ `{task_id}: {reason} (since {since})`, reading each field deliberately rather
188
+ than coercing the object to text. `oat project status --json` preserves those
189
+ three literal string fields; `--field project.blockers` and
190
+ `--shell BLOCKERS=project.blockers` serialize the list as JSON. Empty lists mean
191
+ no blockers; mixed lists retain entries in order. Records missing any nonempty
192
+ string field and other malformed entries become diagnostic legacy strings:
193
+ `Malformed blocker entry: <JSON>`. They remain visible to blocker checks and
194
+ human output. Legacy string normalization remains unchanged. Do not change
195
+ state or routing merely to render blockers.
182
196
 
183
197
  **Display format:**
184
198
 
@@ -191,6 +205,8 @@ Read `{project}/state.md` frontmatter:
191
205
  Completed: {oat_hill_completed as checkmarks}
192
206
  HiLL Pending: {yes/no for current phase}
193
207
  Gate Overrides: {gate-aware skill keys from oat_skill_gate_overrides, or "None"}
208
+ Quick-Start Gate: {status}/{disposition}, decided {decided_at}, fingerprint {config_fingerprint} (as recorded), or "None"
209
+ Exit Gate: {status}/{disposition} as recorded, or "None"
194
210
  Blockers: {oat_blockers or "None"}
195
211
  Next: {recommended_skill}
196
212
  ```
@@ -203,6 +219,16 @@ even when no gate is currently configured for that skill, and never infer a
203
219
  configured gate from an override alone. This is read-only reporting: never add,
204
220
  remove, or repair the map here.
205
221
 
222
+ Both gate records share the core defined in
223
+ `references/docs/gate-approval-record.md`. Report a quick-start record as that
224
+ doc describes: its stored fields as recorded, with `config_fingerprint` shown as
225
+ provenance and never recomputed, or `malformed` when its fields do not form a
226
+ valid record. Report the exit-gate
227
+ record's `status` and `disposition` as recorded; its freshness belongs to the
228
+ implementation workflow and is not re-derived here. Either record adds no route
229
+ and no warning: quick plan readiness stays the single routing rule for quick
230
+ plans. Show "None" for an absent record, and never write or repair one here.
231
+
206
232
  ### Step 5: Determine Next Skill
207
233
 
208
234
  Based on project state, recommend next action.
@@ -0,0 +1,80 @@
1
+ # Lifecycle Gate Approval Record
2
+
3
+ A configured lifecycle gate ends in an outcome the operator or a later session
4
+ needs to see again: it passed, it warned, the operator explicitly continued
5
+ past a failure, the project disabled it, or it blocked. Chat output does not
6
+ survive the session, so the skill that runs the gate persists the outcome in
7
+ project `state.md`. This document defines the record's shared core once; each
8
+ carrier names where it lives and what it adds.
9
+
10
+ ## Core record
11
+
12
+ ```yaml
13
+ <carrier>:
14
+ status: allowed # allowed | blocked
15
+ disposition: passed # passed | warned | prompt_approved | project_disabled; null when blocked
16
+ config_fingerprint: '<stable hash of the resolved gate declaration>'
17
+ reviewed_head: '<full SHA of the commit the gate reviewed>'
18
+ decided_at: '2026-10-02T15:20:00Z'
19
+ ```
20
+
21
+ - `status`: `allowed` | `blocked`.
22
+ - `disposition`: `passed`, `warned`, `prompt_approved`, or `project_disabled`
23
+ when `status` is `allowed`; `null` when `status` is `blocked`.
24
+ - `config_fingerprint`: the writer's stable hash of the resolved gate
25
+ declaration it ran (command, description, `onFailure`, `maxAttempts`, and the
26
+ project override state), recorded as provenance. Implement recomputes its own
27
+ carrier's fingerprint under its Step 14 rules; quick-start readers do not.
28
+ - `reviewed_head`: the full 40-character SHA of the commit the gate reviewed,
29
+ recorded as provenance. `null` when no gate ran.
30
+ - `decided_at`: the ISO 8601 UTC time the outcome was decided. A record written
31
+ before `decided_at` existed is not malformed for that reason alone.
32
+
33
+ ## Write rules
34
+
35
+ | Gate outcome | Record |
36
+ | --------------------------------------------------------------- | ----------------------------------------------------------- |
37
+ | Passed its threshold | `allowed` / `passed` |
38
+ | Failed under `onFailure: warn` | `allowed` / `warned` |
39
+ | Failed under `onFailure: prompt`, operator explicitly continued | `allowed` / `prompt_approved` |
40
+ | Failed under `onFailure: prompt`, operator declined or deferred | `blocked` / `null` |
41
+ | `block` still failing after `maxAttempts` | `blocked` / `null` |
42
+ | Configured but disabled by project override (no launch) | `allowed` / `project_disabled` |
43
+ | Launch, transport, validation, or receive failure | `blocked` / `null` |
44
+ | Not configured | no record (quick-start); implement writes `allowed/no_gate` |
45
+
46
+ Only an explicit operator continuation writes `prompt_approved`. Declining,
47
+ deferring, giving no response, or running under `OAT_AUTONOMOUS=1` writes
48
+ `blocked`, never anything that reads as approval. A rerun of the same gate
49
+ replaces the record.
50
+
51
+ ## Carriers
52
+
53
+ - **`oat_implement_exit_gate`** (`oat-project-implement`,
54
+ `references/completion-and-closeout.md` Step 14) uses this core and keeps its
55
+ additional values and fields there: the `pending` and `stale` statuses, the
56
+ `no_gate` disposition, and the resolution, attempt, launch, receive, waiver,
57
+ and freshness fields. Its own effective-delta freshness rule decides whether a
58
+ record is current.
59
+ - **`oat_quick_start_gate`** (`oat-project-quick-start`, Gate Execution) carries
60
+ exactly the core.
61
+
62
+ ## Reading a quick-start record
63
+
64
+ Readers report a quick-start record as recorded and do not recompute
65
+ `config_fingerprint`: no CLI emits a canonical fingerprint for the quick-start
66
+ gate, so a recomputation could not be reproduced across sessions. They do not
67
+ route on the record either.
68
+
69
+ - Report `status`, `disposition`, `decided_at`, and `config_fingerprint` (as
70
+ provenance) exactly as stored.
71
+ - Report the record as malformed when `status` and `disposition` do not form
72
+ one of the combinations in the write rules, or when a present `decided_at` is
73
+ not a valid ISO 8601 UTC time.
74
+ - `reviewed_head` is provenance only and is not compared with `HEAD`, because
75
+ the quick-start completion step commits after the gate.
76
+ - An absent record means none was written: no gate was configured, the gate
77
+ has not reached an outcome, or the plan predates the record. Readers do not
78
+ infer which.
79
+
80
+ Readers never write, repair, or infer a record.
@@ -6,7 +6,7 @@ disable-model-invocation: true
6
6
  user-invocable: true
7
7
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
8
8
  metadata:
9
- version: 1.2.4
9
+ version: 1.2.5
10
10
  ---
11
11
 
12
12
  # Promote Project To Spec-Driven Lifecycle
@@ -15,6 +15,10 @@ Convert a quick/import workflow project into a Spec-Driven OAT lifecycle project
15
15
 
16
16
  Lite projects promote through quick first: run `oat project promote <path> --to quick`, then use this skill. This skill's direct eligibility remains quick/import only.
17
17
 
18
+ ## Hook-safe exact-path commits
19
+
20
+ 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`.
21
+
18
22
  ## Prerequisites
19
23
 
20
24
  - Active project exists.
@@ -153,8 +157,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || {
153
157
  if [ "$PROJECT_SCOPE" = "synced" ]; then
154
158
  oat project push "$PROJECT_PATH" --message "chore(oat): promote {project-name} to spec-driven" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
155
159
  else
156
- git add "$PROJECT_PATH/discovery.md" "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md"
157
- git diff --cached --quiet || git commit -m "chore(oat): promote {project-name} to spec-driven"
160
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
161
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-promote-spec-driven:1" --message "chore(oat): promote {project-name} to spec-driven" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
158
162
  fi
159
163
  ```
160
164
 
@@ -5,15 +5,19 @@ argument-hint: '<project-name> ["project description"]'
5
5
  oat_gateable: true
6
6
  disable-model-invocation: true
7
7
  user-invocable: true
8
- allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
8
+ allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, Task
9
9
  metadata:
10
- version: 2.3.17
10
+ version: 2.3.19
11
11
  ---
12
12
 
13
13
  # Quick Start Project
14
14
 
15
15
  Create or resume a project in **quick mode** and produce a runnable `plan.md` with minimal ceremony.
16
16
 
17
+ ## Hook-safe exact-path commits
18
+
19
+ 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`.
20
+
17
21
  ## Prerequisites
18
22
 
19
23
  - A repository initialized for OAT (`.oat/` and `.agents/` exist).
@@ -98,7 +102,7 @@ writing lifecycle artifacts does not imply unrelated full test suites.
98
102
  Before scaffolding, surface the working tree state so unrelated changes don't get carried into the project workflow's bookkeeping commits.
99
103
 
100
104
  1. Run `git status --porcelain`. If empty, continue silently to the next step.
101
- 2. If `.oat/sync/manifest.json` is the only entry **and** its two-character status code is either `??` or made up solely of the letter `M` and blanks — a plain modification, staged, unstaged, or both — commit it without asking: `git add -- .oat/sync/manifest.json` then `git commit -m "chore: run sync"`. Report the commit in one line and continue to the next step. That file is `oat sync` output and carries no user content, so the prompt below was always answered "commit now" for it. Every other code falls through to the prompt below, including any code that pairs `M` with something else: `MD` (deleted in the worktree), `MT` (type change), `AM`, `RM`, `CM`, and every unmerged state. Auto-staging one of those would commit a deletion, a retyped file, or a half-resolved merge. Any other dirty path, in any combination, also falls through.
105
+ 2. If `.oat/sync/manifest.json` is the only entry **and** its two-character status code is either `??` or made up solely of the letter `M` and blanks — a plain modification, staged, unstaged, or both — commit it without asking: `oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:1" --message "chore: run sync" -- .oat/sync/manifest.json`. Report the commit in one line and continue to the next step. That file is `oat sync` output and carries no user content, so the prompt below was always answered "commit now" for it. Every other code falls through to the prompt below, including any code that pairs `M` with something else: `MD` (deleted in the worktree), `MT` (type change), `AM`, `RM`, `CM`, and every unmerged state. Auto-staging one of those would commit a deletion, a retyped file, or a half-resolved merge. Any other dirty path, in any combination, also falls through.
102
106
  3. Otherwise, present the dirty list to the user.
103
107
  4. If `.oat/sync/manifest.json` or paths under `.claude/`, `.cursor/`, `.codex/` appear in the list, note: "These are generated by `oat sync` (often by `pnpm run worktree:init` or `oat-worktree-bootstrap-auto`) and are typically safe to commit as `chore: run sync`."
104
108
  5. Offer three choices via `AskUserQuestion`:
@@ -290,8 +294,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
290
294
  if [ "$PROJECT_SCOPE" = "synced" ]; then
291
295
  oat project push "$PROJECT_PATH" --message "chore(oat): capture quick-start discovery for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
292
296
  else
293
- git add "$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md"
294
- git diff --cached --quiet || git commit -m "chore(oat): capture quick-start discovery for {project-name}"
297
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md")
298
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:2" --message "chore(oat): capture quick-start discovery for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
295
299
  fi
296
300
  ```
297
301
 
@@ -348,8 +352,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
348
352
  if [ "$PROJECT_SCOPE" = "synced" ]; then
349
353
  oat project push "$PROJECT_PATH" --message "chore(oat): promote quick-start discovery for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
350
354
  else
351
- git add "$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md"
352
- git diff --cached --quiet || git commit -m "chore(oat): promote quick-start discovery for {project-name}"
355
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md")
356
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:3" --message "chore(oat): promote quick-start discovery for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
353
357
  fi
354
358
  ```
355
359
 
@@ -555,8 +559,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
555
559
  if [ "$PROJECT_SCOPE" = "synced" ]; then
556
560
  oat project push "$PROJECT_PATH" --message "chore(oat): capture quick-start design for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
557
561
  else
558
- git add "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md"
559
- git diff --cached --quiet || git commit -m "chore(oat): capture quick-start design for {project-name}"
562
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
563
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:4" --message "chore(oat): capture quick-start design for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
560
564
  fi
561
565
  ```
562
566
 
@@ -569,8 +573,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
569
573
  if [ "$PROJECT_SCOPE" = "synced" ]; then
570
574
  oat project push "$PROJECT_PATH" --message "chore(oat): complete quick-start discovery for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
571
575
  else
572
- git add "$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md"
573
- git diff --cached --quiet || git commit -m "chore(oat): complete quick-start discovery for {project-name}"
576
+ OWNED_COMMIT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md")
577
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:5" --message "chore(oat): complete quick-start discovery for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
574
578
  fi
575
579
  ```
576
580
 
@@ -846,7 +850,7 @@ as the last check before plan and project completion:
846
850
 
847
851
  Handle all three `resolution` values explicitly:
848
852
  - `not_configured`: no gate is configured; proceed directly to the completion steps in Step 3.7 below.
849
- - `configured_disabled_by_project`: the operator disabled this configured gate for this project. Do not launch any process. Emit `configured but disabled by project override`, including the project path and the `projectOverride` source from the envelope, then proceed directly to the completion steps in Step 3.7 below. A project-disabled gate never enters the passed, missing, or failed branches, and its `configuredGate` is evidence only, never executed.
853
+ - `configured_disabled_by_project`: the operator disabled this configured gate for this project. Do not launch any process. Emit `configured but disabled by project override`, including the project path and the `projectOverride` source from the envelope, write `oat_quick_start_gate` as `allowed/project_disabled` with `reviewed_head: null` per **Persist the gate outcome** below, then proceed directly to the completion steps in Step 3.7 below. A project-disabled gate never enters the passed, missing, or failed branches, and its `configuredGate` is evidence only, never executed.
850
854
  - `configured`: continue with the steps below, executing `effectiveGate` exactly as configured.
851
855
 
852
856
  A null, missing, malformed, or unrecognized result is an operational failure
@@ -891,6 +895,17 @@ as the last check before plan and project completion:
891
895
  - `prompt`: surface the gate failure and ask the human how to proceed.
892
896
  - `warn`: record the gate failure and continue.
893
897
 
898
+ **Complexity review at `maxAttempts`.** When `block` attempts are exhausted,
899
+ dispatch the complexity review that
900
+ `references/docs/complexity-review-fallback.md` defines for the plan bundle
901
+ before escalating, then show its decision message with the accumulated
902
+ feedback; under `OAT_AUTONOMOUS=1`, put the same content in the boundary
903
+ report instead. Record the operator's choice with the report path in
904
+ `implementation.md`. Agents never select the disposition. Only exhausted
905
+ `block` attempts trigger the review. To launch it, load the current
906
+ `oat-project-dispatch-subagents/SKILL.md` and follow it, resolving the route
907
+ as that doc's "Routing outside implement" section describes.
908
+
894
909
  7. Runtime selection note: the review-only declaration carries producer
895
910
  identity, not reviewer runtime identity. By default, `oat gate review` and
896
911
  `oat gate cross-provider-exec` resolve the current host from built-in
@@ -905,6 +920,23 @@ A gate that ends in `block` after attempts are exhausted, or at an unresolved
905
920
  `prompt` boundary, means the completion steps below MUST NOT run; the phase
906
921
  stays `in_progress` and resumable.
907
922
 
923
+ **Persist the gate outcome.** For a configured gate, including one disabled by
924
+ project override, write `oat_quick_start_gate` to `$PROJECT_PATH/state.md` with
925
+ the core fields defined in `references/docs/gate-approval-record.md` once the
926
+ gate reaches its outcome, and commit it with the next quick-start bookkeeping
927
+ commit or before stopping:
928
+
929
+ - passed: `allowed/passed`;
930
+ - `warn` failure: `allowed/warned`;
931
+ - a `prompt` failure the operator explicitly continues past: `allowed/prompt_approved`;
932
+ - a `prompt` failure declined or deferred (every `prompt` failure under
933
+ `OAT_AUTONOMOUS=1`), `block` exhausted after `maxAttempts`, or a launch,
934
+ validation, or receive failure: `blocked` with `disposition: null`;
935
+ - `configured_disabled_by_project`: `allowed/project_disabled` with `reviewed_head: null` and no launch.
936
+
937
+ `not_configured` writes no record. `reviewed_head` is the plan commit the gate
938
+ reviewed and `decided_at` the decision time. A rerun replaces the record. Step 3.7 stays gated by the control flow above and does not read this record back.
939
+
908
940
  ### Step 3.7: Record Review Disposition and Mark Plan Complete
909
941
 
910
942
  Reach this completion boundary only after the configured gate passes or resolves
@@ -1153,15 +1185,16 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
1153
1185
  if [ "$PROJECT_SCOPE" = "synced" ]; then
1154
1186
  oat project push "$PROJECT_PATH" --message "chore(oat): update quick-start artifacts for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
1155
1187
  else
1188
+ OWNED_COMMIT_PATHS=()
1156
1189
  for path in \
1157
1190
  "$PROJECT_PATH/discovery.md" \
1158
1191
  "$PROJECT_PATH/design.md" \
1159
1192
  "$PROJECT_PATH/plan.md" \
1160
1193
  "$PROJECT_PATH/implementation.md" \
1161
1194
  "$PROJECT_PATH/state.md"; do
1162
- [ -e "$path" ] && git add "$path"
1195
+ [ -e "$path" ] && OWNED_COMMIT_PATHS+=("$path")
1163
1196
  done
1164
- git diff --cached --quiet || git commit -m "chore(oat): update quick-start artifacts for {project-name}"
1197
+ oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-quick-start:6" --message "chore(oat): update quick-start artifacts for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
1165
1198
  fi
1166
1199
  ```
1167
1200