@open-agent-toolkit/cli 0.2.41 → 0.2.45

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 (204) hide show
  1. package/assets/agents/oat-phase-implementer.md +11 -1
  2. package/assets/bundle-metadata.json +1 -1
  3. package/assets/docs/cli-utilities/configuration.md +11 -1
  4. package/assets/docs/quickstart.md +9 -0
  5. package/assets/docs/reference/cli-reference.md +56 -1
  6. package/assets/docs/reference/file-locations.md +18 -1
  7. package/assets/docs/reference/oat-directory-structure.md +20 -4
  8. package/assets/docs/workflows/projects/artifacts.md +27 -1
  9. package/assets/docs/workflows/projects/implementation-execution.md +22 -0
  10. package/assets/docs/workflows/projects/index.md +6 -0
  11. package/assets/docs/workflows/projects/lifecycle.md +19 -5
  12. package/assets/docs/workflows/projects/picking-up-projects.md +75 -0
  13. package/assets/docs/workflows/projects/pr-flow.md +22 -1
  14. package/assets/docs/workflows/projects/reviewing-oat-prs.md +60 -0
  15. package/assets/public-package-versions.json +4 -4
  16. package/assets/skills/oat-brainstorm/SKILL.md +135 -32
  17. package/assets/skills/oat-brainstorm/references/destinations.md +9 -6
  18. package/assets/skills/oat-cursor-cloud-projects/SKILL.md +11 -1
  19. package/assets/skills/oat-doctor/SKILL.md +8 -1
  20. package/assets/skills/oat-project-autonomous/SKILL.md +45 -1
  21. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +8 -8
  22. package/assets/skills/oat-project-capture/SKILL.md +29 -9
  23. package/assets/skills/oat-project-complete/SKILL.md +610 -38
  24. package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +265 -0
  25. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +764 -0
  26. package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +134 -0
  27. package/assets/skills/oat-project-complete/scripts/validate-nonarchive-lifecycle-receipt.mjs +160 -0
  28. package/assets/skills/oat-project-design/SKILL.md +33 -9
  29. package/assets/skills/oat-project-discover/SKILL.md +16 -3
  30. package/assets/skills/oat-project-document/SKILL.md +10 -4
  31. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +8 -8
  32. package/assets/skills/oat-project-implement/SKILL.md +14 -3
  33. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +18 -6
  34. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +8 -8
  35. package/assets/skills/oat-project-implement/references/phase-execution.md +9 -3
  36. package/assets/skills/oat-project-implement/references/plan-and-resume.md +3 -0
  37. package/assets/skills/oat-project-import-plan/SKILL.md +15 -9
  38. package/assets/skills/oat-project-new/SKILL.md +7 -5
  39. package/assets/skills/oat-project-next/SKILL.md +32 -10
  40. package/assets/skills/oat-project-plan/SKILL.md +18 -3
  41. package/assets/skills/oat-project-pr-final/SKILL.md +23 -2
  42. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +8 -8
  43. package/assets/skills/oat-project-pr-progress/SKILL.md +23 -2
  44. package/assets/skills/oat-project-progress/SKILL.md +23 -9
  45. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +20 -2
  46. package/assets/skills/oat-project-quick-start/SKILL.md +48 -18
  47. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +8 -8
  48. package/assets/skills/oat-project-reconcile/SKILL.md +14 -10
  49. package/assets/skills/oat-project-retro/SKILL.md +3 -3
  50. package/assets/skills/oat-project-retro/references/apply-procedure.md +102 -6
  51. package/assets/skills/oat-project-retro-file/SKILL.md +57 -6
  52. package/assets/skills/oat-project-review-provide/SKILL.md +45 -4
  53. package/assets/skills/oat-project-review-receive/SKILL.md +16 -7
  54. package/assets/skills/oat-project-review-receive-remote/SKILL.md +9 -3
  55. package/assets/skills/oat-project-revise/SKILL.md +12 -3
  56. package/assets/skills/oat-project-spec/SKILL.md +16 -3
  57. package/assets/skills/oat-project-summary/SKILL.md +113 -13
  58. package/assets/skills/oat-wave-execute/SKILL.md +34 -2
  59. package/assets/skills/oat-worktree-bootstrap/SKILL.md +13 -1
  60. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +13 -1
  61. package/dist/commands/config/index.d.ts +1 -0
  62. package/dist/commands/config/index.d.ts.map +1 -1
  63. package/dist/commands/config/index.js +30 -2
  64. package/dist/commands/doctor/index.d.ts +2 -0
  65. package/dist/commands/doctor/index.d.ts.map +1 -1
  66. package/dist/commands/doctor/index.js +27 -3
  67. package/dist/commands/doctor/synced-projects.d.ts +12 -0
  68. package/dist/commands/doctor/synced-projects.d.ts.map +1 -0
  69. package/dist/commands/doctor/synced-projects.js +208 -0
  70. package/dist/commands/init/gitattributes.d.ts +4 -0
  71. package/dist/commands/init/gitattributes.d.ts.map +1 -0
  72. package/dist/commands/init/gitattributes.js +12 -0
  73. package/dist/commands/init/gitignore.d.ts +8 -1
  74. package/dist/commands/init/gitignore.d.ts.map +1 -1
  75. package/dist/commands/init/gitignore.js +146 -41
  76. package/dist/commands/init/index.d.ts +2 -0
  77. package/dist/commands/init/index.d.ts.map +1 -1
  78. package/dist/commands/init/index.js +3 -0
  79. package/dist/commands/init/managed-block.d.ts +10 -0
  80. package/dist/commands/init/managed-block.d.ts.map +1 -0
  81. package/dist/commands/init/managed-block.js +40 -0
  82. package/dist/commands/init/tools/workflows/install-workflows.js +1 -1
  83. package/dist/commands/local/index.d.ts.map +1 -1
  84. package/dist/commands/local/index.js +5 -1
  85. package/dist/commands/local/sync.d.ts +4 -0
  86. package/dist/commands/local/sync.d.ts.map +1 -1
  87. package/dist/commands/local/sync.js +123 -2
  88. package/dist/commands/pjm/adoption.d.ts +2 -0
  89. package/dist/commands/pjm/adoption.d.ts.map +1 -1
  90. package/dist/commands/pjm/adoption.js +1 -1
  91. package/dist/commands/project/archive/archive-utils.d.ts +24 -0
  92. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  93. package/dist/commands/project/archive/archive-utils.js +349 -22
  94. package/dist/commands/project/archive/index.d.ts.map +1 -1
  95. package/dist/commands/project/archive/index.js +1 -0
  96. package/dist/commands/project/archive/push-runner.d.ts +5 -1
  97. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  98. package/dist/commands/project/archive/push-runner.js +33 -4
  99. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  100. package/dist/commands/project/complete-state/index.js +3 -1
  101. package/dist/commands/project/index.d.ts.map +1 -1
  102. package/dist/commands/project/index.js +12 -0
  103. package/dist/commands/project/links/compute.d.ts +9 -0
  104. package/dist/commands/project/links/compute.d.ts.map +1 -0
  105. package/dist/commands/project/links/compute.js +27 -0
  106. package/dist/commands/project/links/index.d.ts +17 -0
  107. package/dist/commands/project/links/index.d.ts.map +1 -0
  108. package/dist/commands/project/links/index.js +72 -0
  109. package/dist/commands/project/links/refresh.d.ts +26 -0
  110. package/dist/commands/project/links/refresh.d.ts.map +1 -0
  111. package/dist/commands/project/links/refresh.js +92 -0
  112. package/dist/commands/project/links/render.d.ts +24 -0
  113. package/dist/commands/project/links/render.d.ts.map +1 -0
  114. package/dist/commands/project/links/render.js +68 -0
  115. package/dist/commands/project/list.d.ts +5 -0
  116. package/dist/commands/project/list.d.ts.map +1 -1
  117. package/dist/commands/project/list.js +182 -9
  118. package/dist/commands/project/migrate/index.d.ts +22 -0
  119. package/dist/commands/project/migrate/index.d.ts.map +1 -0
  120. package/dist/commands/project/migrate/index.js +79 -0
  121. package/dist/commands/project/new/index.d.ts +2 -0
  122. package/dist/commands/project/new/index.d.ts.map +1 -1
  123. package/dist/commands/project/new/index.js +14 -2
  124. package/dist/commands/project/new/scaffold.d.ts +22 -1
  125. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  126. package/dist/commands/project/new/scaffold.js +287 -69
  127. package/dist/commands/project/open/index.d.ts +16 -0
  128. package/dist/commands/project/open/index.d.ts.map +1 -1
  129. package/dist/commands/project/open/index.js +151 -19
  130. package/dist/commands/project/pause/index.d.ts +8 -0
  131. package/dist/commands/project/pause/index.d.ts.map +1 -1
  132. package/dist/commands/project/pause/index.js +129 -19
  133. package/dist/commands/project/prune/index.d.ts +21 -0
  134. package/dist/commands/project/prune/index.d.ts.map +1 -0
  135. package/dist/commands/project/prune/index.js +95 -0
  136. package/dist/commands/project/pull/index.d.ts +28 -0
  137. package/dist/commands/project/pull/index.d.ts.map +1 -0
  138. package/dist/commands/project/pull/index.js +157 -0
  139. package/dist/commands/project/push/index.d.ts +22 -0
  140. package/dist/commands/project/push/index.d.ts.map +1 -0
  141. package/dist/commands/project/push/index.js +100 -0
  142. package/dist/commands/project/scope/index.d.ts +17 -0
  143. package/dist/commands/project/scope/index.d.ts.map +1 -0
  144. package/dist/commands/project/scope/index.js +107 -0
  145. package/dist/commands/project/split/run.d.ts +4 -0
  146. package/dist/commands/project/split/run.d.ts.map +1 -1
  147. package/dist/commands/project/split/run.js +48 -10
  148. package/dist/commands/project/sync/git.d.ts +18 -0
  149. package/dist/commands/project/sync/git.d.ts.map +1 -0
  150. package/dist/commands/project/sync/git.js +60 -0
  151. package/dist/commands/project/sync/record.d.ts +22 -0
  152. package/dist/commands/project/sync/record.d.ts.map +1 -0
  153. package/dist/commands/project/sync/record.js +133 -0
  154. package/dist/commands/project/sync/ref-sync.d.ts +120 -0
  155. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -0
  156. package/dist/commands/project/sync/ref-sync.js +962 -0
  157. package/dist/commands/project/sync/resolve-target.d.ts +27 -0
  158. package/dist/commands/project/sync/resolve-target.d.ts.map +1 -0
  159. package/dist/commands/project/sync/resolve-target.js +159 -0
  160. package/dist/commands/shared/oat-paths.d.ts +4 -1
  161. package/dist/commands/shared/oat-paths.d.ts.map +1 -1
  162. package/dist/commands/shared/oat-paths.js +2 -2
  163. package/dist/commands/shared/project-scope.d.ts +23 -0
  164. package/dist/commands/shared/project-scope.d.ts.map +1 -0
  165. package/dist/commands/shared/project-scope.js +106 -0
  166. package/dist/commands/tools/migrate/index.js +1 -1
  167. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
  168. package/dist/commands/tools/shared/pack-inventory.js +11 -0
  169. package/dist/commands/tools/shared/pack-lifecycle.js +1 -1
  170. package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -1
  171. package/dist/commands/tools/shared/pack-reconcile.js +4 -1
  172. package/dist/commands/tools/update/index.d.ts.map +1 -1
  173. package/dist/commands/tools/update/index.js +20 -10
  174. package/dist/commands/tools/update/update-tools.d.ts +2 -0
  175. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  176. package/dist/config/oat-config.d.ts +6 -3
  177. package/dist/config/oat-config.d.ts.map +1 -1
  178. package/dist/config/oat-config.js +41 -7
  179. package/dist/config/resolve.d.ts.map +1 -1
  180. package/dist/config/resolve.js +2 -1
  181. package/dist/fs/io.d.ts +2 -1
  182. package/dist/fs/io.d.ts.map +1 -1
  183. package/dist/fs/io.js +5 -2
  184. package/dist/projects/split/finalize.d.ts.map +1 -1
  185. package/dist/projects/split/finalize.js +55 -2
  186. package/dist/projects/split/resume.d.ts +3 -0
  187. package/dist/projects/split/resume.d.ts.map +1 -1
  188. package/dist/projects/split/resume.js +34 -7
  189. package/dist/projects/split/seed-children.d.ts.map +1 -1
  190. package/dist/projects/split/seed-children.js +6 -0
  191. package/dist/projects/split/write-parent.d.ts +7 -0
  192. package/dist/projects/split/write-parent.d.ts.map +1 -1
  193. package/dist/projects/split/write-parent.js +7 -4
  194. package/dist/release/public-package-contract.d.ts.map +1 -1
  195. package/dist/release/public-package-contract.js +1 -0
  196. package/dist/validation/skills.d.ts.map +1 -1
  197. package/dist/validation/skills.js +434 -0
  198. package/package.json +4 -4
  199. package/dist/__tests__/skills/split-flow-fixtures.d.ts +0 -50
  200. package/dist/__tests__/skills/split-flow-fixtures.d.ts.map +0 -1
  201. package/dist/__tests__/skills/split-flow-fixtures.js +0 -161
  202. package/dist/commands/__tests__/helpers.d.ts +0 -12
  203. package/dist/commands/__tests__/helpers.d.ts.map +0 -1
  204. package/dist/commands/__tests__/helpers.js +0 -36
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-brainstorm
3
- version: 1.3.1
3
+ version: 1.3.4
4
4
  description: Use when the user explicitly invokes the `brainstorm` verb, including `/oat-brainstorm`, "let's brainstorm", "brainstorm this", "can we brainstorm X", or "help me brainstorm X". For ambiguous exploratory phrasing ("I've been thinking", "what if", "help me think through"), do NOT auto-enter; respond conversationally and offer mode only after ≥2 sustained exploratory turns. Do NOT use for review, debug, PR, status, implementation, or active-workflow questions.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -89,9 +89,9 @@ These messages get a direct response, not a workflow takeover. If the model has
89
89
  - No formal requirements / specs / architectural designs (the design phase belongs to `oat-project-design`, not here).
90
90
  - No auto-routing to a destination before convergence — the destination is identified at the end of the conversation, not the beginning. Opportunistic surfacing on a clear trigger phrase is allowed; pre-emptively forcing a destination is not.
91
91
  - Visual-companion offer must run only when the topic is visual-likely OR the user has explicitly asked for it. Never offer when the topic is text-likely; never skip when the topic is visual-likely.
92
- - No fold-back commit on a dirty working tree without running the preflight `git status` check first (see Process step 9 active-project branches).
93
- - No `git add -A` and no directory globs for the fold-back commit. Staging is always scoped: `git add -- "$ARTIFACT_PATH"`.
94
- - No printing the fold-back handoff prompt before `git commit` actually succeeds. The prompt references a hash; a missing commit makes the prompt misleading.
92
+ - No fold-back persistence on a dirty artifact, or from a synced checkout with any dirty project file, without running the preflight `git status` check first (see Process step 9 active-project branches).
93
+ - For shared/local fold-back, no `git add -A` or directory globs: stage only `git add -- "$ARTIFACT_PATH"`. For synced fold-back, never stage on the parent branch; use the validated `oat project push --json` receipt.
94
+ - No printing the fold-back handoff prompt before the scope-appropriate branch commit or synced push succeeds. The prompt references a hash; a missing persistence receipt makes it misleading.
95
95
 
96
96
  **ALLOWED Activities:**
97
97
 
@@ -100,7 +100,7 @@ These messages get a direct response, not a workflow takeover. If the model has
100
100
  - Pack and active-project detection at convergence time (`oat tools has <pack>` / `oat config get activeProject`).
101
101
  - Reading downstream skill files (`oat-idea-*`, `oat-pjm-add-backlog-item`, `oat-project-*`) and following their process inline using the synthesized payload as pre-filled answers.
102
102
  - Rendering the doc-to-path artifact from `templates/brainstorm-doc.md`.
103
- - Active-project fold-back: appending synthesis to the chosen upstream artifact and committing — only after the safety contract (preflight, scoped staging, conditional handoff print) is satisfied.
103
+ - Active-project fold-back: appending synthesis to the chosen upstream artifact and persisting by scope — exact-path branch commit for shared/local, validated project-ref push for synced — only after the safety contract is satisfied.
104
104
 
105
105
  **Self-Correction Protocol:**
106
106
  If you catch yourself:
@@ -110,9 +110,9 @@ If you catch yourself:
110
110
  - Forcing a destination before convergence → STOP. Return to free brainstorming and let convergence happen via trigger phrase or natural soft cue.
111
111
  - Skipping the visual-companion offer when visual content is coming → STOP. Print the offer as its own message before continuing.
112
112
  - Offering the visual companion before a text-likely brainstorm has any visual need → STOP. Set `VISUAL_COMPANION = "deferred"` and continue text-only.
113
- - Running the fold-back commit on a dirty working tree without preflight → STOP. Re-route through the dirty-tree handler (three-option picker) before any artifact mutation.
114
- - Staging with `-A` or a directory glob during fold-back → STOP. The fold-back commit must be `git add -- "$ARTIFACT_PATH"` only.
115
- - Printing the fold-back handoff prompt before the commit succeeds → STOP. Surface the commit error and let the user resolve it before the prompt is emitted.
113
+ - Running fold-back persistence on a dirty artifact without preflight → STOP. Re-route through the dirty-tree handler (three-option picker) before any artifact mutation.
114
+ - For shared/local scope, staging with `-A` or a directory glob during fold-back → STOP; use `git add -- "$ARTIFACT_PATH"` only. For synced scope, any parent-branch staging → STOP; use `oat project push`.
115
+ - Printing the fold-back handoff prompt before the branch commit or synced push succeeds → STOP. Surface the persistence error and let the user resolve it before the prompt is emitted.
116
116
 
117
117
  **Recovery:**
118
118
 
@@ -302,7 +302,21 @@ If "keep going", return to step 5. If "wrap up", surface the **pack-filtered ter
302
302
  - Gated by `WORKFLOWS_INSTALLED == "true"` AND `ACTIVE_PROJECT_VALID == "true"`: `Active project: fold-back` and `Active project: brainstorming reference file`. When this branch fires, present the **3-way active-project router first** (see step 9 active-project branches) — its outcome controls whether the rest of the picker is even surfaced.
303
303
  3. Evaluate whether the accumulated brainstorm scope is large enough to offer a split destination. Track the same four split signals used by discovery and evaluate them through the installed CLI:
304
304
 
305
+ Define this fail-closed parser once before any synced persistence below. If
306
+ it rejects a receipt, print the complete CLI JSON, run
307
+ `oat project pull "$ACTIVE_PROJECT"`, resolve any reported conflict, and
308
+ retry the original push; never infer a commit from local Git state.
309
+
305
310
  ```bash
311
+ parse_synced_push_receipt() {
312
+ node -e '
313
+ let value;
314
+ try { value = JSON.parse(process.argv[1]); } catch { process.exit(1); }
315
+ if (!["pushed", "up-to-date"].includes(value.status) || !/^[0-9a-f]{40}$/.test(value.sha)) process.exit(1);
316
+ process.stdout.write(value.sha);
317
+ ' "$1"
318
+ }
319
+
306
320
  oat project split evaluate-signals --fired "<comma-list>"
307
321
  ```
308
322
 
@@ -392,7 +406,7 @@ After confirmation succeeds, proceed to step 9 (handoff).
392
406
 
393
407
  ### Step 9: Handoff
394
408
 
395
- Branch on the destination. Each branch executes its handoff inline using the confirmed payload. The non-fold-back destinations are listed first; the active-project router and fold-back commit safety contract are detailed at the end of this step.
409
+ Branch on the destination. Each branch executes its handoff inline using the confirmed payload. The non-fold-back destinations are listed first; the active-project router and scope-aware fold-back persistence contract are detailed at the end of this step.
396
410
 
397
411
  **Resolving `${SKILLS_ROOT}` for chained skills.** The `ideas` and
398
412
  `project-management` packs default to user scope just as `brainstorm` does, so a
@@ -552,15 +566,35 @@ Uniform across spec-driven and quick modes. Differs only in which plan-authoring
552
566
 
553
567
  Confirm the chosen artifact with the user (minimal confirmation per `references/destinations.md`). Set `ARTIFACT_PATH` to the absolute path.
554
568
 
555
- **Step 2 — Preflight `git status` check.** Run **before** any artifact mutation, scoped to the chosen artifact only:
569
+ **Persistence invariant:** shared and local project artifacts remain ordinary
570
+ parent-checkout files and use exact-path branch commits. Synced project
571
+ artifacts live only in the nested project checkout and become durable only
572
+ through a validated `oat project push --json` receipt on
573
+ `refs/oat/projects/<slug>`; never stage a synced artifact on the parent branch.
574
+ This invariant applies equally to clean fold-back, both dirty fold-back choices,
575
+ and the brainstorming reference-file route.
576
+
577
+ **Step 2 — Preflight `git status` check.** Run **before** any artifact mutation.
578
+ For shared/local projects, scope the check to the chosen artifact. For synced
579
+ projects, inspect the full nested checkout because `oat project push` persists
580
+ every pending project file:
556
581
 
557
582
  ```bash
558
- git status --porcelain -- "$ARTIFACT_PATH"
583
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
584
+ # fail closed: never fall back to branch bookkeeping when scope resolution fails
585
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
586
+ git -C "$ACTIVE_PROJECT" status --porcelain
587
+ else
588
+ git status --porcelain -- "$ARTIFACT_PATH"
589
+ fi
559
590
  ```
560
591
 
561
592
  The check happens before any append, so the skill can route around the dirty case without having half-written the synthesis.
562
593
 
563
- **Step 3 — If the artifact is clean** (no entry in the porcelain output): this is the happy path.
594
+ **Step 3 — If the artifact is clean** (no entry in the porcelain output): this
595
+ is the happy path. For synced projects, "artifact is clean" additionally
596
+ requires the entire project checkout to be clean; a clean chosen artifact
597
+ beside another dirty project file must take Step 4.
564
598
 
565
599
  1. Append the synthesis as a clearly-marked section to `ARTIFACT_PATH`:
566
600
 
@@ -570,33 +604,90 @@ The check happens before any append, so the skill can route around the dirty cas
570
604
 
571
605
  Section body contains: `chosenDirection` (with rationale), key decisions (extracted from the conversation), and a transcript appendix (`transcriptSessionNote`). Optionally include `openQuestions` and `nextSteps` if surfaced.
572
606
 
573
- 2. Stage **only** the artifact:
607
+ 2. Persist **only** the artifact under the scope guard:
574
608
 
575
609
  ```bash
576
- git add -- "$ARTIFACT_PATH"
610
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
611
+ # fail closed: never fall back to branch bookkeeping when scope resolution fails
612
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
613
+ FOLD_BACK_PUSH=$(oat project push "$ACTIVE_PROJECT" --message "chore(oat): integrate brainstorm into <artifact-basename> for <project-name>" --json) || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
614
+ FOLD_BACK_COMMIT_SHA=$(parse_synced_push_receipt "$FOLD_BACK_PUSH") || { printf '%s\n' "$FOLD_BACK_PUSH" >&2; echo "Recovery: run oat project pull \"$ACTIVE_PROJECT\", resolve conflicts, then retry this push." >&2; exit 1; }
615
+ else
616
+ git add -- "$ARTIFACT_PATH"
617
+ git commit -m "chore(oat): integrate brainstorm into <artifact-basename> for <project-name>"
618
+ FOLD_BACK_COMMIT_SHA=$(git rev-parse HEAD)
619
+ fi
577
620
  ```
578
621
 
579
- Use the explicit `--` filename form. **Never `git add -A`. Never directory globs.** Other working-tree paths are not touched by this commit.
622
+ For non-synced projects, use the explicit `--` filename form. **Never `git add -A`. Never directory globs.** Other working-tree paths are not touched by this commit. For synced projects, `FOLD_BACK_COMMIT_SHA` comes from the push JSON rather than the parent branch.
580
623
 
581
- 3. Commit with the canonical message:
624
+ 3. `<artifact-basename>` is `design.md` or `discovery.md` depending on which was chosen. `<project-name>` is the active project's slug.
582
625
 
583
- ```bash
584
- git commit -m "chore(oat): integrate brainstorm into <artifact-basename> for <project-name>"
585
- ```
626
+ 4. If the guarded persistence succeeded → proceed to step 5 (handoff prompt).
627
+
628
+ **Step 4 — If the artifact is dirty** (any entry in the porcelain output):
629
+ pause the fold-back, present the user with three options before any artifact
630
+ mutation occurs. For synced projects, any dirty project file makes this branch
631
+ apply; name other dirty project files in the warning so the user knows
632
+ `oat project push` would include them. Carry the scope resolved by the preflight
633
+ into the selected branch and resolve it again inside every persistence block so
634
+ failures remain fail-closed.
586
635
 
587
- `<artifact-basename>` is `design.md` or `discovery.md` depending on which was chosen. `<project-name>` is the active project's slug.
636
+ - **Option A — Commit current artifact changes first** (recommended when prior changes are unrelated to the brainstorm). Ask the user for a one-line subject and persist the existing artifact state before appending the synthesis:
588
637
 
589
- 4. If `git commit` succeeded → proceed to step 5 (handoff prompt).
638
+ ```bash
639
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
640
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
641
+ CURRENT_ARTIFACT_PUSH=$(oat project push "$ACTIVE_PROJECT" --message "$CURRENT_ARTIFACT_SUBJECT" --json) || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
642
+ CURRENT_ARTIFACT_COMMIT_SHA=$(parse_synced_push_receipt "$CURRENT_ARTIFACT_PUSH") || { printf '%s\n' "$CURRENT_ARTIFACT_PUSH" >&2; echo "Recovery: run oat project pull \"$ACTIVE_PROJECT\", resolve conflicts, then retry this push." >&2; exit 1; }
643
+ else
644
+ git add -- "$ARTIFACT_PATH"
645
+ git commit --only -m "$CURRENT_ARTIFACT_SUBJECT" -- "$ARTIFACT_PATH"
646
+ CURRENT_ARTIFACT_COMMIT_SHA=$(git rev-parse HEAD)
647
+ fi
648
+ ```
649
+
650
+ Only after that succeeds, append the synthesis. Persist the fold-back as a
651
+ second commit on the same scope:
652
+
653
+ ```bash
654
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
655
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
656
+ FOLD_BACK_PUSH=$(oat project push "$ACTIVE_PROJECT" --message "chore(oat): integrate brainstorm into <artifact-basename> for <project-name>" --json) || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
657
+ FOLD_BACK_COMMIT_SHA=$(parse_synced_push_receipt "$FOLD_BACK_PUSH") || { printf '%s\n' "$FOLD_BACK_PUSH" >&2; echo "Recovery: run oat project pull \"$ACTIVE_PROJECT\", resolve conflicts, then retry this push." >&2; exit 1; }
658
+ else
659
+ git add -- "$ARTIFACT_PATH"
660
+ git commit --only -m "chore(oat): integrate brainstorm into <artifact-basename> for <project-name>" -- "$ARTIFACT_PATH"
661
+ FOLD_BACK_COMMIT_SHA=$(git rev-parse HEAD)
662
+ fi
663
+ ```
590
664
 
591
- **Step 4 — If the artifact is dirty** (any entry in the porcelain output): pause the fold-back, present the user with three options before any artifact mutation occurs:
665
+ For synced projects, the two returned project-ref SHAs prove that the prior
666
+ dirty state was pushed before the fold-back.
667
+
668
+ - **Option B — Include current changes in the fold-back persistence.** Warn explicitly: "The persisted fold-back will mix prior unrelated edits with the brainstorm synthesis. The handoff prompt's receipt SHA will reference both. Confirm?" If the user accepts, append the synthesis and persist the combined state once:
669
+
670
+ ```bash
671
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
672
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
673
+ MIXED_FOLD_BACK_PUSH=$(oat project push "$ACTIVE_PROJECT" --message "chore(oat): integrate brainstorm + prior edits into <artifact-basename> for <project-name>" --json) || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
674
+ FOLD_BACK_COMMIT_SHA=$(parse_synced_push_receipt "$MIXED_FOLD_BACK_PUSH") || { printf '%s\n' "$MIXED_FOLD_BACK_PUSH" >&2; echo "Recovery: run oat project pull \"$ACTIVE_PROJECT\", resolve conflicts, then retry this push." >&2; exit 1; }
675
+ else
676
+ git add -- "$ARTIFACT_PATH"
677
+ git commit --only -m "chore(oat): integrate brainstorm + prior edits into <artifact-basename> for <project-name>" -- "$ARTIFACT_PATH"
678
+ FOLD_BACK_COMMIT_SHA=$(git rev-parse HEAD)
679
+ fi
680
+ ```
681
+
682
+ The `--only` path commit retains the existing non-synced Git route while
683
+ preserving unrelated staged state. A synced dirty branch never runs parent
684
+ `git add` for the project artifact.
592
685
 
593
- - **Option A — Commit current artifact changes first** (recommended when prior changes are unrelated to the brainstorm). Skill commits the existing artifact state with a separate, user-described commit message (ask the user for a one-line subject), then proceeds with fold-back as a new scoped commit on top.
594
- - **Option B — Include current changes in the fold-back commit.** Skill warns explicitly: "The fold-back commit will mix prior unrelated edits with the brainstorm synthesis. The handoff prompt's commit hash will reference both. Confirm?" If user accepts, append synthesis, then `git add -- "$ARTIFACT_PATH"`, then commit with an adjusted message acknowledging the mix (e.g., `chore(oat): integrate brainstorm + prior edits into <artifact> for <project-name>`).
595
686
  - **Option C — Abort fold-back; capture as reference file instead.** Switch the destination to **branch 9j** (active-project brainstorming reference file). Upstream artifact is left untouched.
596
687
 
597
- After the user picks A or B and the resulting commit succeeds, proceed to step 5. After option C, jump to branch 9j.
688
+ After the user picks A or B and the resulting branch commit or synced push succeeds, proceed to step 5. After option C, jump to branch 9j.
598
689
 
599
- **Step 5 — Handoff prompt.** Print **only after the scoped commit succeeds.** If `git commit` failed (pre-commit hooks rejected, signing failed, anything else), surface the error verbatim and **do NOT print the handoff prompt** — the prompt references a commit hash, and a missing commit makes the prompt actively misleading. The user resolves the failure (or re-routes via option C above) before fold-back can complete.
690
+ **Step 5 — Handoff prompt.** Print **only after the scoped commit or synced push succeeds.** If persistence failed (pre-commit hooks rejected, signing failed, push failed, anything else), surface the error verbatim and **do NOT print the handoff prompt** — the prompt references a commit hash, and a missing commit makes the prompt actively misleading. The user resolves the failure (or re-routes via option C above) before fold-back can complete.
600
691
 
601
692
  Resolve the handoff target by `ACTIVE_PROJECT_MODE` and `ACTIVE_PROJECT_PR_STATUS`:
602
693
 
@@ -606,7 +697,7 @@ Resolve the handoff target by `ACTIVE_PROJECT_MODE` and `ACTIVE_PROJECT_PR_STATU
606
697
  | quick | none / closed | `oat-project-quick-start` |
607
698
  | either | open (`oat_pr_status: open`) | `oat-project-revise` |
608
699
 
609
- Print the handoff prompt template, substituting `<skill-name>`, `<artifact>`, `<hash>`, and `<subject>` from the actual commit:
700
+ Print the handoff prompt template, substituting `<skill-name>`, `<artifact>`, `<hash>`, and `<subject>` from the actual branch commit or synced push receipt:
610
701
 
611
702
  ```
612
703
  Run `<skill-name>` with this context:
@@ -634,14 +725,26 @@ If `<ACTIVE_PROJECT>/brainstorming/` does not exist, create it (`mkdir -p`). The
634
725
 
635
726
  Render `${SKILL_DIR}/templates/brainstorm-doc.md` (resolve `${SKILL_DIR}` per the rule in step 3) with the synthesized payload (same shape as the doc-to-path destination) and write to the resolved path.
636
727
 
637
- After writing, commit the file with scoped staging (mirror the discipline of the active-project fold-back commit safety contract):
728
+ After writing, persist the file with the same fail-closed scope guard:
638
729
 
639
730
  ```bash
640
- git add -- "<active-project-relative-path>"
641
- git commit -m "chore(oat): capture brainstorming reference for <project-name>"
731
+ PROJECT_SCOPE=$(oat project scope "$ACTIVE_PROJECT" --format value) || { echo "oat: cannot resolve project scope for $ACTIVE_PROJECT; refusing to commit artifacts" >&2; exit 1; }
732
+ # fail closed: never fall back to branch bookkeeping when scope resolution fails
733
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
734
+ REFERENCE_PUSH=$(oat project push "$ACTIVE_PROJECT" --message "chore(oat): capture brainstorming reference for <project-name>" --json) || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
735
+ REFERENCE_COMMIT_SHA=$(parse_synced_push_receipt "$REFERENCE_PUSH") || { printf '%s\n' "$REFERENCE_PUSH" >&2; echo "Recovery: run oat project pull \"$ACTIVE_PROJECT\", resolve conflicts, then retry this push." >&2; exit 1; }
736
+ else
737
+ git add -- "<active-project-relative-path>"
738
+ git commit -m "chore(oat): capture brainstorming reference for <project-name>"
739
+ REFERENCE_COMMIT_SHA=$(git rev-parse HEAD)
740
+ fi
642
741
  ```
643
742
 
644
- Use only `git add -- <path>` so unrelated working-tree changes are not swept into the commit. After the commit succeeds, capture the short hash via `git rev-parse --short HEAD` and report it alongside the absolute path written (for example: "Wrote `<absolute-path>` and committed as `<hash>`."). End mode assertion.
743
+ For shared/local scope, use only `git add -- <path>` so unrelated working-tree changes are not swept into the commit, then capture `git rev-parse --short HEAD`. For synced scope, use the validated push receipt SHA and never stage the artifact on the parent branch. Report the resulting SHA alongside the absolute path written, then end mode assertion.
744
+
745
+ For synced projects, the preceding short-hash sentence is superseded by the
746
+ full `REFERENCE_COMMIT_SHA` returned from `oat project push --json`; no parent
747
+ branch artifact commit occurs.
645
748
 
646
749
  #### 9k — Promote to N projects
647
750
 
@@ -667,7 +770,7 @@ End mode assertion when the split handoff completes or reports its own blocker.
667
770
  - ✅ Confirmation pattern matches `references/destinations.md`: `full` for scoped backlog item (field-by-field with example wording), `minimal` for slug/path/artifact destinations, `none` for inline-only and summarize-idea-directly.
668
771
  - ✅ Each handoff branch (9a-9k) reads the correct downstream `SKILL.md` path and enters at the documented step. Project promotion writes `discovery.md` only — never `design.md` — and does not auto-chain into the next phase.
669
772
  - ✅ Doc-to-path validation handles all four cases: path-is-directory, parent-missing (with explicit out-of-repo confirmation), file-already-exists (overwrite or rename), unwritable (surface OS error).
670
- - ✅ Fold-back commit safety contract honored: preflight `git status --porcelain -- "$ARTIFACT_PATH"` runs before any artifact mutation; clean → append + `git add -- "$ARTIFACT_PATH"` (explicit `--`, never `-A`, never globs) + scoped commit; dirty → three-option picker (commit-prior-first / mix / abort-to-reference-file); handoff prompt prints only after `git commit` succeeds.
773
+ - ✅ Fold-back persistence safety contract honored: preflight `git status --porcelain -- "$ARTIFACT_PATH"` runs before any artifact mutation; clean → append + exact-path branch commit for shared/local or validated `oat project push --json` for synced; dirty → three-option picker (persist-prior-first / mix / abort-to-reference-file); handoff prompt prints only after the scope-appropriate receipt succeeds.
671
774
  - ✅ Handoff target for fold-back resolves correctly per `oat_workflow_mode` + `oat_pr_status`: `oat-project-plan` (spec-driven, no/closed PR) / `oat-project-quick-start` (quick, no/closed PR) / `oat-project-revise` (either mode, open PR).
672
775
  - ✅ Active-project 3-way router (related / independent / supplementary) fires before the standard pack-filtered picker when both `WORKFLOWS_INSTALLED == "true"` and `ACTIVE_PROJECT_VALID == "true"`.
673
776
  - ✅ Skill validates cleanly under `pnpm oat:validate-skills` (frontmatter contract, allowed-tools, mode-assertion structure).
@@ -138,10 +138,13 @@ Skill proposes `quick` vs `spec-driven` mode based on `chosenDirection` and scop
138
138
 
139
139
  The fold-back commit safety contract is non-negotiable:
140
140
 
141
- 1. Preflight `git status --porcelain -- "$ARTIFACT_PATH"` _before_ any artifact mutation.
142
- 2. If clean: append the synthesis section, then `git add -- "$ARTIFACT_PATH"` (explicit `--` form, never `-A`, never globs) followed by `git commit -m "chore(oat): integrate brainstorm into <artifact> for <project-name>"`.
143
- 3. If dirty: present the user with three options before any mutation — (a) commit current artifact changes first then fold-back as new scoped commit, (b) include current changes in the fold-back commit (warn that prior edits are mixed in; user explicitly accepts), or (c) abort fold-back and switch destination to "active project: brainstorming reference file" instead.
144
- 4. Handoff prompt prints only after the scoped commit succeeds. If `git commit` fails (pre-commit hooks reject, signing fails, etc.), surface the error and do NOT print the handoff prompt.
141
+ 1. Resolve scope fail-closed, then preflight the full nested checkout with `git -C "$ACTIVE_PROJECT" status --porcelain` for synced or the exact artifact with `git status --porcelain -- "$ARTIFACT_PATH"` for shared/local, _before_ any artifact mutation. Synced checks must include every project file because the later push persists the whole checkout.
142
+ 2. If clean: append the synthesis section, then use a validated `oat project push --json` receipt for synced (capture its project-ref `sha`) or `git add -- "$ARTIFACT_PATH"` followed by an exact-path branch commit for shared/local.
143
+ 3. If dirty: present the user with three options before any mutation. Every persistence step remains scope-aware:
144
+ - (a) persist the current artifact changes first, then fold back in a second persistence step. Each step uses a validated `oat project push --json` receipt for synced or an exact-path branch commit for shared/local.
145
+ - (b) include current changes in the fold-back persistence step (warn that prior edits are mixed in; user explicitly accepts), using a validated project-ref push for synced or an exact-path branch commit for shared/local.
146
+ - (c) abort fold-back and switch destination to "active project: brainstorming reference file" instead; that route independently resolves scope and uses the same synced-push versus shared/local-commit split.
147
+ 4. Handoff prompt prints only after the scoped commit or synced push succeeds. On persistence failure, surface the error and do NOT print the handoff prompt.
145
148
 
146
149
  **Handoff target:** Append synthesis to the chosen upstream artifact, commit immediately (per safety contract above), then print the handoff prompt template:
147
150
 
@@ -175,6 +178,6 @@ After printing the prompt, the skill stops. The user runs the plan-authoring ski
175
178
  **Trigger phrases:** "this is supplementary for the active project", "save this with the project but don't change the design", "park this as a reference for the project", "stash this in the project's brainstorming folder". Also offered as the third option when the active-project 3-way router fires (related but supplementary → reference file).
176
179
  **Required template fields:** `title` (slug-friendly), filename (defaults to `YYYY-MM-DD-<topic>.md`), the synthesized payload (rendered using the same shape as `templates/brainstorm-doc.md`).
177
180
  **Optional template fields:** `motivation`, `vision`, `openQuestions`, `nextSteps` — same as doc-to-path destination.
178
- **Confirmation pattern:** `minimal` (filename + commit hash). After the file is written, the skill commits it on the active branch and reports the short commit hash alongside the absolute path (for example: "Wrote `<absolute-path>` and committed as `<hash>`.").
179
- **Handoff target:** no downstream skill invocation. Write the synthesized payload to `<active-project>/brainstorming/YYYY-MM-DD-<topic>.md` using the doc-to-path template shape. The `brainstorming/` subdirectory is created if it doesn't exist (parallel to `pr/` and `reviews/`). The reference file is a **durable tracked artifact**: after writing, the skill stages only the new file via `git add -- <reference-path>` and commits it with `chore(oat): capture brainstorming reference for <project-name>` — mirroring the scoped-staging discipline of the fold-back commit safety contract so the working tree is clean when the skill exits.
181
+ **Confirmation pattern:** `minimal` (filename + persistence SHA). After the file is written, the skill reports the absolute path and scope-appropriate SHA: the exact-path branch commit for shared/local or the detached project-ref commit from the validated synced push receipt.
182
+ **Handoff target:** no downstream skill invocation. Write the synthesized payload to `<active-project>/brainstorming/YYYY-MM-DD-<topic>.md` using the doc-to-path template shape. The `brainstorming/` subdirectory is created if it doesn't exist (parallel to `pr/` and `reviews/`). The reference file is a **durable project artifact**: persist it with the fail-closed scope guard so synced projects use `oat project push --json` and capture its `sha`, while other scopes retain scoped staging and the existing branch commit.
180
183
  **If user wants to keep brainstorming after this is offered:** return to flow with destination = active-project-reference-file. Available regardless of active project's phase or PR status; no special probing.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-cursor-cloud-projects
3
- version: 1.0.2
3
+ version: 1.1.1
4
4
  description: Use when OAT work is mentioned in a Cursor Cloud environment. Orients agents to cloud detection, repo-rooted project homes, user-first assets, CLI availability, and Cursor dispatch context without owning lifecycle execution.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -153,8 +153,18 @@ Resolve from the target repository:
153
153
  PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
154
154
  PROJECTS_ROOT="${PROJECTS_ROOT%/}"
155
155
  PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
156
+ if [ -n "$PROJECT_PATH" ]; then
157
+ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || exit 1
158
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
159
+ oat project pull "$PROJECT_PATH"
160
+ fi
161
+ fi
156
162
  ```
157
163
 
164
+ Run this guard from the target repository before reading project artifacts. A
165
+ record-backed synced path whose checkout is absent is materialized by the pull;
166
+ remote-only projects are adopted by the same command.
167
+
158
168
  Rules:
159
169
 
160
170
  - **Single-repo workspace:** the sole target repository owns `.oat/`, local
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-doctor
3
- version: 1.0.2
3
+ version: 1.1.0
4
4
  description: Use when you need to diagnose your OAT setup, check for outdated skills, identify misconfigurations, or get a summary of installed tools and config. Runs health checks and recommends corrective actions.
5
5
  argument-hint: '[--summary]'
6
6
  disable-model-invocation: true
@@ -107,6 +107,11 @@ Check for issues:
107
107
  - **Stale `activeProject` pointer:** If `activeProject` is set, verify the directory exists. If not, warn.
108
108
  - **Stale `activeIdea` pointer:** If `activeIdea` is set, verify the directory exists. If not, warn.
109
109
  - **Missing `projects.root`:** If not configured and no default exists, warn.
110
+ - **Synced project health:** Report `project:synced_tracked_artifacts`,
111
+ `project:synced_gitignore`, `project:synced_projects`,
112
+ `project:synced_editor_hint`, and per-project
113
+ `project:synced_<slug>_<kind>` checks without treating an absent checkout as
114
+ proof that no synced project exists.
110
115
 
111
116
  For config key explanations, read from the bundled docs at `~/.oat/docs/`. Check `reference/file-locations.md` and `guide/cli-reference.md` for authoritative descriptions.
112
117
 
@@ -248,6 +253,7 @@ OAT ▸ DOCTOR SUMMARY
248
253
  | activeProject | .oat/projects/shared/foo | local |
249
254
  | activeIdea | (not set) | - |
250
255
  | projects.root | .oat/projects/shared | default |
256
+ | projects.defaultScope | synced | default |
251
257
  | documentation.root | (not set) | - |
252
258
  | worktrees.root | (not set) | - |
253
259
 
@@ -259,6 +265,7 @@ Read config key descriptions from `~/.oat/docs/reference/file-locations.md` and
259
265
  - **activeIdea:** Path to the currently active idea. Set by oat-idea-new.
260
266
  - **lastPausedProject:** Path to the last paused project for quick resume.
261
267
  - **projects.root:** Base directory for all OAT projects. Default: `.oat/projects/shared`.
268
+ - **projects.defaultScope:** Scope used by project creation when `--scope` is omitted. Default: `synced`; supported values are `shared`, `local`, and `synced`.
262
269
  - **documentation.root:** Root directory for documentation. Used by docs skills.
263
270
  - **documentation.config:** Path to docs config file (e.g., mkdocs.yml).
264
271
  - **documentation.tooling:** Docs tooling in use (e.g., mkdocs, fumadocs).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-autonomous
3
- version: 1.0.6
3
+ version: 1.0.9
4
4
  description: Use when a user explicitly asks to run an OAT project autonomously end-to-end. Activates session-only autonomy, resumes the correct lifecycle phase, and drives the existing OAT skills through final PR or a reported boundary.
5
5
  argument-hint: '<goal | project-slug | ticket-ref>'
6
6
  disable-model-invocation: true
@@ -152,6 +152,18 @@ Resolution order:
152
152
  2. A valid `activeProject` in `.oat/config.local.json`.
153
153
  3. A new project derived from a substantive goal or ticket reference.
154
154
 
155
+ Before reading artifacts for an existing project, resolve its scope and pull a
156
+ synced checkout. Scope resolution fails closed:
157
+
158
+ ```bash
159
+ if [ -n "$PROJECT_PATH" ]; then
160
+ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || exit 1
161
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
162
+ oat project pull "$PROJECT_PATH" || { echo "oat: project pull failed for $PROJECT_PATH; resolve the reported state before autonomous work continues" >&2; exit 1; }
163
+ fi
164
+ fi
165
+ ```
166
+
155
167
  For a new goal, derive a safe project slug but do not hand-create the project.
156
168
  Mode selection in Step 2 chooses `oat-project-new` or
157
169
  `oat-project-quick-start`, which owns scaffolding and pointer persistence. If
@@ -258,6 +270,22 @@ Use the state content hash expected by the adapter persistence contract. On a
258
270
  stale-write conflict, re-read `state.md`, rerun autonomous resolution, and
259
271
  persist only the newly returned record; never retry a stale record blindly.
260
272
 
273
+ Immediately persist the completed state write. Resolve scope again so a
274
+ failure cannot fall through to the shared/local Git path:
275
+
276
+ ```bash
277
+ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || {
278
+ echo "oat: cannot resolve project scope for $PROJECT_PATH; refusing to commit artifacts" >&2
279
+ exit 1
280
+ }
281
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
282
+ oat project push "$PROJECT_PATH" --message "chore(oat): persist autonomous explainer intent" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
283
+ else
284
+ git add "$PROJECT_PATH/state.md"
285
+ git diff --cached --quiet || git commit -m "chore(oat): persist autonomous explainer intent"
286
+ fi
287
+ ```
288
+
261
289
  ### Step 3: Perform External-Integration Research
262
290
 
263
291
  Before planning, extensively research every integrated system, service,
@@ -294,6 +322,22 @@ degraded routes, inventory gaps, unavailable verification, and reusable
294
322
  improvements. Never record secrets, token values, signed URLs, or active
295
323
  autonomy signals.
296
324
 
325
+ After creating the log and after every later append, persist that write before
326
+ continuing:
327
+
328
+ ```bash
329
+ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || {
330
+ echo "oat: cannot resolve project scope for $PROJECT_PATH; refusing to commit artifacts" >&2
331
+ exit 1
332
+ }
333
+ if [ "$PROJECT_SCOPE" = "synced" ]; then
334
+ oat project push "$PROJECT_PATH" --message "chore(oat): update autonomous execution learnings" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
335
+ else
336
+ git add "$PROJECT_PATH/oat-execution-learnings.md"
337
+ git diff --cached --quiet || git commit -m "chore(oat): update autonomous execution learnings"
338
+ fi
339
+ ```
340
+
297
341
  ### Step 5: Invoke Lifecycle Skills and Reviews
298
342
 
299
343
  Invoke each lifecycle skill by name and let it own its complete workflow,