@open-agent-toolkit/cli 0.2.41 → 0.2.46

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 (212) 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/cli-utilities/tool-packs.md +55 -9
  5. package/assets/docs/quickstart.md +9 -0
  6. package/assets/docs/reference/cli-reference.md +56 -1
  7. package/assets/docs/reference/file-locations.md +18 -1
  8. package/assets/docs/reference/oat-directory-structure.md +20 -4
  9. package/assets/docs/reference/troubleshooting.md +18 -11
  10. package/assets/docs/workflows/projects/artifacts.md +27 -1
  11. package/assets/docs/workflows/projects/implementation-execution.md +22 -0
  12. package/assets/docs/workflows/projects/index.md +6 -0
  13. package/assets/docs/workflows/projects/lifecycle.md +19 -5
  14. package/assets/docs/workflows/projects/picking-up-projects.md +75 -0
  15. package/assets/docs/workflows/projects/pr-flow.md +22 -1
  16. package/assets/docs/workflows/projects/reviewing-oat-prs.md +60 -0
  17. package/assets/public-package-versions.json +4 -4
  18. package/assets/skills/oat-brainstorm/SKILL.md +135 -32
  19. package/assets/skills/oat-brainstorm/references/destinations.md +9 -6
  20. package/assets/skills/oat-cursor-cloud-projects/SKILL.md +11 -1
  21. package/assets/skills/oat-doctor/SKILL.md +8 -1
  22. package/assets/skills/oat-project-autonomous/SKILL.md +45 -1
  23. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +8 -8
  24. package/assets/skills/oat-project-capture/SKILL.md +29 -9
  25. package/assets/skills/oat-project-complete/SKILL.md +610 -38
  26. package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +265 -0
  27. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +764 -0
  28. package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +134 -0
  29. package/assets/skills/oat-project-complete/scripts/validate-nonarchive-lifecycle-receipt.mjs +160 -0
  30. package/assets/skills/oat-project-design/SKILL.md +33 -9
  31. package/assets/skills/oat-project-discover/SKILL.md +16 -3
  32. package/assets/skills/oat-project-document/SKILL.md +10 -4
  33. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +8 -8
  34. package/assets/skills/oat-project-implement/SKILL.md +14 -3
  35. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +18 -6
  36. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +8 -8
  37. package/assets/skills/oat-project-implement/references/phase-execution.md +9 -3
  38. package/assets/skills/oat-project-implement/references/plan-and-resume.md +3 -0
  39. package/assets/skills/oat-project-import-plan/SKILL.md +15 -9
  40. package/assets/skills/oat-project-new/SKILL.md +7 -5
  41. package/assets/skills/oat-project-next/SKILL.md +32 -10
  42. package/assets/skills/oat-project-plan/SKILL.md +18 -3
  43. package/assets/skills/oat-project-pr-final/SKILL.md +23 -2
  44. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +8 -8
  45. package/assets/skills/oat-project-pr-progress/SKILL.md +23 -2
  46. package/assets/skills/oat-project-progress/SKILL.md +23 -9
  47. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +20 -2
  48. package/assets/skills/oat-project-quick-start/SKILL.md +48 -18
  49. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +8 -8
  50. package/assets/skills/oat-project-reconcile/SKILL.md +14 -10
  51. package/assets/skills/oat-project-retro/SKILL.md +3 -3
  52. package/assets/skills/oat-project-retro/references/apply-procedure.md +102 -6
  53. package/assets/skills/oat-project-retro-file/SKILL.md +57 -6
  54. package/assets/skills/oat-project-review-provide/SKILL.md +45 -4
  55. package/assets/skills/oat-project-review-receive/SKILL.md +16 -7
  56. package/assets/skills/oat-project-review-receive-remote/SKILL.md +9 -3
  57. package/assets/skills/oat-project-revise/SKILL.md +12 -3
  58. package/assets/skills/oat-project-spec/SKILL.md +16 -3
  59. package/assets/skills/oat-project-summary/SKILL.md +113 -13
  60. package/assets/skills/oat-wave-execute/SKILL.md +34 -2
  61. package/assets/skills/oat-worktree-bootstrap/SKILL.md +13 -1
  62. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +13 -1
  63. package/dist/commands/config/index.d.ts +1 -0
  64. package/dist/commands/config/index.d.ts.map +1 -1
  65. package/dist/commands/config/index.js +34 -3
  66. package/dist/commands/doctor/index.d.ts +2 -0
  67. package/dist/commands/doctor/index.d.ts.map +1 -1
  68. package/dist/commands/doctor/index.js +27 -3
  69. package/dist/commands/doctor/synced-projects.d.ts +12 -0
  70. package/dist/commands/doctor/synced-projects.d.ts.map +1 -0
  71. package/dist/commands/doctor/synced-projects.js +208 -0
  72. package/dist/commands/init/gitattributes.d.ts +4 -0
  73. package/dist/commands/init/gitattributes.d.ts.map +1 -0
  74. package/dist/commands/init/gitattributes.js +12 -0
  75. package/dist/commands/init/gitignore.d.ts +8 -1
  76. package/dist/commands/init/gitignore.d.ts.map +1 -1
  77. package/dist/commands/init/gitignore.js +146 -41
  78. package/dist/commands/init/index.d.ts +2 -0
  79. package/dist/commands/init/index.d.ts.map +1 -1
  80. package/dist/commands/init/index.js +3 -0
  81. package/dist/commands/init/managed-block.d.ts +10 -0
  82. package/dist/commands/init/managed-block.d.ts.map +1 -0
  83. package/dist/commands/init/managed-block.js +40 -0
  84. package/dist/commands/init/tools/index.d.ts +1 -0
  85. package/dist/commands/init/tools/index.d.ts.map +1 -1
  86. package/dist/commands/init/tools/index.js +37 -9
  87. package/dist/commands/init/tools/workflows/install-workflows.js +1 -1
  88. package/dist/commands/local/index.d.ts.map +1 -1
  89. package/dist/commands/local/index.js +5 -1
  90. package/dist/commands/local/sync.d.ts +4 -0
  91. package/dist/commands/local/sync.d.ts.map +1 -1
  92. package/dist/commands/local/sync.js +123 -2
  93. package/dist/commands/pjm/adoption.d.ts +2 -0
  94. package/dist/commands/pjm/adoption.d.ts.map +1 -1
  95. package/dist/commands/pjm/adoption.js +1 -1
  96. package/dist/commands/project/archive/archive-utils.d.ts +24 -0
  97. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  98. package/dist/commands/project/archive/archive-utils.js +349 -22
  99. package/dist/commands/project/archive/index.d.ts.map +1 -1
  100. package/dist/commands/project/archive/index.js +1 -0
  101. package/dist/commands/project/archive/push-runner.d.ts +5 -1
  102. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  103. package/dist/commands/project/archive/push-runner.js +33 -4
  104. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  105. package/dist/commands/project/complete-state/index.js +3 -1
  106. package/dist/commands/project/index.d.ts.map +1 -1
  107. package/dist/commands/project/index.js +12 -0
  108. package/dist/commands/project/links/compute.d.ts +9 -0
  109. package/dist/commands/project/links/compute.d.ts.map +1 -0
  110. package/dist/commands/project/links/compute.js +27 -0
  111. package/dist/commands/project/links/index.d.ts +17 -0
  112. package/dist/commands/project/links/index.d.ts.map +1 -0
  113. package/dist/commands/project/links/index.js +72 -0
  114. package/dist/commands/project/links/refresh.d.ts +26 -0
  115. package/dist/commands/project/links/refresh.d.ts.map +1 -0
  116. package/dist/commands/project/links/refresh.js +92 -0
  117. package/dist/commands/project/links/render.d.ts +24 -0
  118. package/dist/commands/project/links/render.d.ts.map +1 -0
  119. package/dist/commands/project/links/render.js +68 -0
  120. package/dist/commands/project/list.d.ts +5 -0
  121. package/dist/commands/project/list.d.ts.map +1 -1
  122. package/dist/commands/project/list.js +182 -9
  123. package/dist/commands/project/migrate/index.d.ts +22 -0
  124. package/dist/commands/project/migrate/index.d.ts.map +1 -0
  125. package/dist/commands/project/migrate/index.js +79 -0
  126. package/dist/commands/project/new/index.d.ts +2 -0
  127. package/dist/commands/project/new/index.d.ts.map +1 -1
  128. package/dist/commands/project/new/index.js +14 -2
  129. package/dist/commands/project/new/scaffold.d.ts +22 -1
  130. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  131. package/dist/commands/project/new/scaffold.js +287 -69
  132. package/dist/commands/project/open/index.d.ts +16 -0
  133. package/dist/commands/project/open/index.d.ts.map +1 -1
  134. package/dist/commands/project/open/index.js +151 -19
  135. package/dist/commands/project/pause/index.d.ts +8 -0
  136. package/dist/commands/project/pause/index.d.ts.map +1 -1
  137. package/dist/commands/project/pause/index.js +129 -19
  138. package/dist/commands/project/prune/index.d.ts +21 -0
  139. package/dist/commands/project/prune/index.d.ts.map +1 -0
  140. package/dist/commands/project/prune/index.js +95 -0
  141. package/dist/commands/project/pull/index.d.ts +28 -0
  142. package/dist/commands/project/pull/index.d.ts.map +1 -0
  143. package/dist/commands/project/pull/index.js +157 -0
  144. package/dist/commands/project/push/index.d.ts +22 -0
  145. package/dist/commands/project/push/index.d.ts.map +1 -0
  146. package/dist/commands/project/push/index.js +100 -0
  147. package/dist/commands/project/scope/index.d.ts +17 -0
  148. package/dist/commands/project/scope/index.d.ts.map +1 -0
  149. package/dist/commands/project/scope/index.js +107 -0
  150. package/dist/commands/project/split/run.d.ts +4 -0
  151. package/dist/commands/project/split/run.d.ts.map +1 -1
  152. package/dist/commands/project/split/run.js +48 -10
  153. package/dist/commands/project/sync/git.d.ts +18 -0
  154. package/dist/commands/project/sync/git.d.ts.map +1 -0
  155. package/dist/commands/project/sync/git.js +60 -0
  156. package/dist/commands/project/sync/record.d.ts +22 -0
  157. package/dist/commands/project/sync/record.d.ts.map +1 -0
  158. package/dist/commands/project/sync/record.js +133 -0
  159. package/dist/commands/project/sync/ref-sync.d.ts +120 -0
  160. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -0
  161. package/dist/commands/project/sync/ref-sync.js +962 -0
  162. package/dist/commands/project/sync/resolve-target.d.ts +27 -0
  163. package/dist/commands/project/sync/resolve-target.d.ts.map +1 -0
  164. package/dist/commands/project/sync/resolve-target.js +159 -0
  165. package/dist/commands/shared/oat-paths.d.ts +4 -1
  166. package/dist/commands/shared/oat-paths.d.ts.map +1 -1
  167. package/dist/commands/shared/oat-paths.js +2 -2
  168. package/dist/commands/shared/project-scope.d.ts +23 -0
  169. package/dist/commands/shared/project-scope.d.ts.map +1 -0
  170. package/dist/commands/shared/project-scope.js +106 -0
  171. package/dist/commands/tools/migrate/index.js +1 -1
  172. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
  173. package/dist/commands/tools/shared/pack-inventory.js +79 -8
  174. package/dist/commands/tools/shared/pack-lifecycle.js +1 -1
  175. package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -1
  176. package/dist/commands/tools/shared/pack-reconcile.js +4 -1
  177. package/dist/commands/tools/shared/project-tools-config.d.ts +6 -2
  178. package/dist/commands/tools/shared/project-tools-config.d.ts.map +1 -1
  179. package/dist/commands/tools/shared/project-tools-config.js +7 -5
  180. package/dist/commands/tools/update/index.d.ts.map +1 -1
  181. package/dist/commands/tools/update/index.js +38 -14
  182. package/dist/commands/tools/update/update-tools.d.ts +2 -0
  183. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  184. package/dist/config/oat-config.d.ts +6 -3
  185. package/dist/config/oat-config.d.ts.map +1 -1
  186. package/dist/config/oat-config.js +41 -7
  187. package/dist/config/resolve.d.ts.map +1 -1
  188. package/dist/config/resolve.js +2 -1
  189. package/dist/fs/io.d.ts +2 -1
  190. package/dist/fs/io.d.ts.map +1 -1
  191. package/dist/fs/io.js +5 -2
  192. package/dist/projects/split/finalize.d.ts.map +1 -1
  193. package/dist/projects/split/finalize.js +55 -2
  194. package/dist/projects/split/resume.d.ts +3 -0
  195. package/dist/projects/split/resume.d.ts.map +1 -1
  196. package/dist/projects/split/resume.js +34 -7
  197. package/dist/projects/split/seed-children.d.ts.map +1 -1
  198. package/dist/projects/split/seed-children.js +6 -0
  199. package/dist/projects/split/write-parent.d.ts +7 -0
  200. package/dist/projects/split/write-parent.d.ts.map +1 -1
  201. package/dist/projects/split/write-parent.js +7 -4
  202. package/dist/release/public-package-contract.d.ts.map +1 -1
  203. package/dist/release/public-package-contract.js +1 -0
  204. package/dist/validation/skills.d.ts.map +1 -1
  205. package/dist/validation/skills.js +434 -0
  206. package/package.json +4 -4
  207. package/dist/__tests__/skills/split-flow-fixtures.d.ts +0 -50
  208. package/dist/__tests__/skills/split-flow-fixtures.d.ts.map +0 -1
  209. package/dist/__tests__/skills/split-flow-fixtures.js +0 -161
  210. package/dist/commands/__tests__/helpers.d.ts +0 -12
  211. package/dist/commands/__tests__/helpers.d.ts.map +0 -1
  212. package/dist/commands/__tests__/helpers.js +0 -36
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-phase-implementer
3
- version: 1.0.12
3
+ version: 1.1.1
4
4
  description: Implements one plan phase end-to-end, commits each task separately, self-checks between tasks, and handles bounded review fixes when resumed by oat-project-implement.
5
5
  tools: Read, Write, Edit, Bash, Grep, Glob, Task
6
6
  color: cyan
@@ -131,6 +131,16 @@ After formatting, run the repository's applicable gate set over the produced
131
131
  diff, explicitly including artifact writes. This supplements rather than
132
132
  replaces every task and phase verification command below.
133
133
 
134
+ ## Synced-Scope Bookkeeping
135
+
136
+ Artifact and recovery-ledger bookkeeping commits must first resolve scope with
137
+ `oat project scope "$PROJECT_PATH" --format value`. A `synced` project uses
138
+ `oat project push` with the original bookkeeping message; other scopes keep the
139
+ existing scoped `git add` and `git commit` commands. Scope resolution fails
140
+ closed. A nonzero project-push exit stops bookkeeping until the reported
141
+ recovery is resolved and the push is retried. Planned code task commits such as
142
+ `feat(pNN-tNN)` are unchanged.
143
+
134
144
  ## Prevention and Post-Commit Recovery
135
145
 
136
146
  Prevention is the first recovery control. Before every planned task commit:
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.2.41"
3
+ "oatVersion": "0.2.46"
4
4
  }
@@ -76,7 +76,17 @@ Earlier CLI versions returned `config.json` / `config.local.json` / `env` / `def
76
76
 
77
77
  Common keys in `.oat/config.json`:
78
78
 
79
- - `projects.root` — where tracked projects live
79
+ - `projects.root` — shared-scope project root. Relative values resolve from the
80
+ repository root; absolute values remain absolute. OAT derives the `local`
81
+ and `synced` roots as sibling directories named `local` and `synced` under
82
+ this root's parent, so a custom value relocates all three scope roots as one
83
+ layout. Synced project creation requires the derived `synced` root to resolve
84
+ inside the repository; an external absolute root remains usable for `shared`
85
+ and `local` projects but is rejected before any synced checkout, ref, record,
86
+ active pointer, or Git index mutation.
87
+ - `projects.defaultScope` — scope used by project creation when `--scope` is
88
+ omitted (`synced` by default). `OAT_PROJECTS_DEFAULT_SCOPE` overrides the
89
+ configured value for the current process.
80
90
  - `worktrees.root` — where OAT-managed worktrees live
81
91
  - `git.defaultBranch` — base branch fallback for PR workflows
82
92
  - `documentation.root`, `documentation.tooling`, `documentation.config` — docs-surface ownership
@@ -140,6 +140,12 @@ Two independent facts describe a pack:
140
140
  release manifest declares for that pack and scope, its presence, and its
141
141
  version or content digest.
142
142
 
143
+ Versioned skills and agents must match on both version metadata and canonical
144
+ content. A same-version content change is therefore reported as outdated rather
145
+ than current. Content comparison ignores the executable-bit normalization OAT
146
+ intentionally applies while materializing managed scripts, but still detects
147
+ file content, entry-type, and symlink-target changes.
148
+
143
149
  Commands report both. `oat tools list` and `oat tools info` show placement,
144
150
  intent source, and completeness. `oat status` and `oat doctor` report drift
145
151
  between intent and inventory with a scoped recovery command.
@@ -182,11 +188,12 @@ without qualification. Install the pack at **project scope** when you need its
182
188
  agents; `oat tools update` cannot repair this, because it is a scope limitation
183
189
  rather than drift.
184
190
 
185
- Repository templates under `.oat/templates/` are **owner overrides**. Once a
186
- project-scope template exists, OAT will not rewrite it: the managed default now
187
- lives at user scope and in the bundle. Delete the repository copy to resume
188
- managed-default behavior. `oat status` and `oat doctor` report retained
189
- overrides so the divergence is visible rather than silent.
191
+ Repository templates under `.oat/templates/` are **owner-owned seeds**. OAT
192
+ compares a source-backed seed with its bundled default: a byte-equivalent copy
193
+ is reported as current, while an edited copy is retained and reported as a
194
+ `retained-override`. OAT will not rewrite the retained copy. Delete a repository
195
+ template only when you intentionally want the bundled default seeded again;
196
+ never delete edited mutable seed content merely to clear the diagnostic.
190
197
 
191
198
  ### Evolving pack membership
192
199
 
@@ -454,8 +461,15 @@ Key behavior:
454
461
  - Every pack's fresh-install default is user scope (`defaultScope` in the release manifest); existing installs keep their current placement on re-install, so a re-install never moves a pack between scopes or creates a second copy at the other one. This applies to the per-pack subcommands too: a bare `oat tools install docs` in a repository where `docs` is already at project scope stays at project scope, and only an explicit `--scope` overrides that
455
462
  - Removing a pack from a scope happens only when you explicitly choose a narrower end-state in the interactive flow (e.g. a pack at `both` set to `project` only). All staged removals are shown in a single change summary and applied only after one batch confirmation — declining makes no changes
456
463
  - Non-interactive installs (including `--scope project`, `--scope user`, and the default pack set) are strictly additive and never remove a pack from a scope. Removal is interactive-only
457
- - Tracks installed vs bundled skill versions and reports outdated skills
464
+ - Tracks installed versus bundled skill and agent versions and canonical
465
+ content, reporting same-version content drift as outdated while ignoring
466
+ expected executable-bit normalization
458
467
  - Writes pack intent into the config file for the scope you installed into: a project install sets `tools.<pack>: true` in `.oat/config.json`, and a user install sets it in `~/.oat/config.json`. A user-only install never writes repository config
468
+ - When a project install discovers existing project-scoped packs whose intent
469
+ is missing, it writes those exact intents in canonical pack order. Human
470
+ output prints `Adopted project tool pack: <pack>` once per adopted pack;
471
+ JSON output adds `adoptedPacks` only when the list is non-empty. This is pack
472
+ intent reconciliation, not repository PJM adoption
459
473
  - A user-only install needs no Git repository and performs no repository writes
460
474
  - Refreshes the managed `OAT tools` section in the repository-root `AGENTS.md` **only for project-scope runs of the aggregate `oat tools install`**. The per-pack subcommands (`oat tools install workflows`, `oat tools install docs`, and the rest) never write `AGENTS.md`, at either scope
461
475
  - Repository `AGENTS.md` guidance for project management is owned by adoption, not by pack placement. Installing the `project-management` pack no longer upserts a managed `OAT project-management` section; `oat pjm init` writes that repository guidance when the repository actually adopts PJM
@@ -474,12 +488,17 @@ Key behavior:
474
488
 
475
489
  - Accepts a tool name, `--pack <pack>`, or `--all` (mutually exclusive)
476
490
  - With no target, exits without mutation and suggests the explicit bulk command `oat tools update --all`; invalid packs and conflicting targets keep their own targeted diagnostics
477
- - Compares installed versions against bundled versions and copies updated assets
491
+ - Compares installed versions and canonical content against bundled assets and
492
+ copies updates; equal version metadata does not hide content drift
478
493
  - For `--pack <pack>` and `--all`, an already-installed pack is reconciled to the **current** release membership in the scopes where it is installed, adding newly bundled skills, agents, templates, and scripts
479
494
  - A pack whose managed assets are all missing but whose intent is still declared is repaired from intent rather than skipped
480
495
  - Managed template and script companions are refreshed at **user** scope. A project-scope repository template is an owner override and is left alone
481
496
  - Non-versioned assets are compared by content digest, so an identical refresh is a no-op instead of a rewrite
482
497
  - Update persists inferred legacy intent only after a successful explicit mutation, so a read never rewrites your config
498
+ - A successful project-scope update reports the exact newly adopted legacy pack
499
+ intents in canonical order. Human output uses
500
+ `Adopted project tool pack: <pack>`; JSON output adds the optional
501
+ `adoptedPacks` array only when at least one intent was written
483
502
  - `--scope all` outside a Git repository completes the user-scope work instead of failing. Unlike `oat status` and `oat doctor`, update skips project scope silently and does not name it in the result; an explicitly requested `--scope project` outside a repository is still a hard failure
484
503
  - Dry-run mode with `--dry-run`; auto-sync after mutations by default
485
504
  - Use `--no-sync` to skip auto-sync
@@ -735,8 +754,9 @@ Removal and migration use the symmetric contract: the follow-up sync prunes exac
735
754
  User-scope tool packs and explicit PJM adoption changed several defaults and
736
755
  exit codes. Nothing here is data-destructive, and legacy config keeps working —
737
756
  `tools.<pack>: false` still parses, complete pre-adoption PJM scaffolds are
738
- grandfathered as `inferred-legacy`, and no CLI flag was removed or renamed. But
739
- several commands you already run behave differently.
757
+ grandfathered as `inferred-legacy`, and existing installs remain additive. One
758
+ inert per-pack install flag was removed, and several commands you already run
759
+ behave differently.
740
760
 
741
761
  ### Install scope defaults flipped to user
742
762
 
@@ -781,6 +801,26 @@ is not installed. Test for a truthy value instead. Legacy `false` values that
781
801
  already exist in a config file are still read (see
782
802
  [Legacy `false` intent](#legacy-false-intent)) — they are just never written.
783
803
 
804
+ Direct config writes now enforce the same true-or-absent contract.
805
+ `oat config set tools.<pack> false` exits `1` without changing the config. To
806
+ remove a project-scoped pack and clear its intent, run:
807
+
808
+ ```bash
809
+ oat tools remove --pack <pack> --scope project
810
+ ```
811
+
812
+ Existing legacy `false` values remain readable migration input.
813
+
814
+ ### Per-pack install `--force` was removed
815
+
816
+ `oat tools install <pack> --force` is now rejected as an unknown option. The
817
+ flag was inert in the unified additive lifecycle. To reconcile installed
818
+ assets, use the scoped update command instead:
819
+
820
+ ```bash
821
+ oat tools update --pack <pack> --scope <scope>
822
+ ```
823
+
784
824
  ### Per-pack install `--json` changed shape
785
825
 
786
826
  The per-pack subcommands (`oat tools install docs`, `oat tools install
@@ -803,6 +843,12 @@ above. The previous single-scope payload's `scope`, `targetRoot`, `assetsRoot`,
803
843
  keying on them reads `undefined` rather than failing. Read `scopes` for the
804
844
  scopes acted on, and `results[].request.scopeRoot` for the target root of each.
805
845
 
846
+ When a project-scope aggregate install, direct pack install, or update adopts
847
+ missing legacy pack intents, the same single payload also contains
848
+ `"adoptedPacks": ["docs", "workflows"]`. The field is omitted when nothing was
849
+ adopted, and entries follow the manifest's canonical pack order. Human output
850
+ reports the same set as one `Adopted project tool pack: <pack>` line per pack.
851
+
806
852
  ### Other behavior changes worth knowing
807
853
 
808
854
  - `oat tools remove --pack <pack>` deletes every managed asset the release
@@ -9,6 +9,15 @@ Use this page to choose the OAT path that matches what you are actually trying t
9
9
 
10
10
  This page is intentionally lightweight. It is not the full command manual. Once you choose a path, continue into the owning section for the deeper operational detail.
11
11
 
12
+ ## Prerequisites
13
+
14
+ - Node.js 22.17 or newer
15
+ - Git 2.31 or newer
16
+
17
+ OAT does not run an up-front Git version check. Git compatibility is evaluated
18
+ best-effort by each command, and a missing or unsupported Git operation exits as
19
+ a system error.
20
+
12
21
  ## Choose a Path
13
22
 
14
23
  ### Provider Sync
@@ -56,6 +56,61 @@ The first practical expansion path is to keep improving the existing owners: [Do
56
56
 
57
57
  Notable commands introduced in the current CLI surface:
58
58
 
59
+ - `oat project new <slug> --scope shared|local|synced [--force]` - create a
60
+ project in an explicit scope. Without `--scope`, creation uses
61
+ `projects.defaultScope`, which defaults to `synced`. Project slugs are
62
+ unique across all scopes by default, including recorded or remotely
63
+ published synced projects. `--force` deliberately permits a duplicate; use
64
+ an explicit project path with `project open` or `project pause` whenever a
65
+ slug is ambiguous across scopes.
66
+ - `oat project scope [project] --format value|json` - resolve a project's
67
+ storage scope without inspecting its path manually.
68
+ - `oat project push [project] [--message <message>]` - commit pending synced
69
+ artifacts, reconcile with the exact project ref on `origin`, publish it, and
70
+ refresh an open PR's artifact-links block. Use `--no-refresh-pr` to skip the
71
+ PR edit. With `--json`, success returns `status` (`pushed` or `up-to-date`),
72
+ the full project-ref `sha`, the retained `ref`, and optional `prRefresh`;
73
+ conflict and rejected outcomes return their corresponding `status` and exit
74
+ nonzero.
75
+ - `oat project pull [project] [--no-commit]` - fetch and materialize or update a synced
76
+ checkout. Resolve a rebase conflict and run `pull --continue`, or use
77
+ `pull --abort` to return to the pre-pull state. Coordination children are
78
+ pulled by default; `--no-children` limits the operation to the selected
79
+ project. When pull adopts a remote project with no local discovery record,
80
+ `--no-commit` leaves the new record uncommitted for the caller to persist.
81
+ With `--json`, the receipt includes `status`, `sha`, and `ref`, plus
82
+ `conflicts` when applicable and per-child results when coordination children
83
+ were requested.
84
+ - `oat project links [project] --format markdown|json` - render SHA-pinned
85
+ links for the linkable artifacts on the project ref. On GitHub origins the
86
+ artifacts become full-SHA blob links; other hosts degrade to the retained ref
87
+ and short SHA without guessing a web URL. `--durable-summary <path>` accepts
88
+ only a path contained in the repository, normalizes it repository-relative,
89
+ and renders it as a code span rather than a guessed remote link.
90
+ - `oat project pause [project]` - persist the pause state and clear the active
91
+ project pointer. If synced publication is declined or fails after the pause
92
+ commit is created, that clean commit is retained; address the publication
93
+ failure and rerun `pause` to publish it.
94
+ - `oat project prune [project] [--force] [--no-commit]` - remove every
95
+ checkout, the local and remote project refs, and the tracked record. When the
96
+ project is omitted, the active project is used. This is the explicit
97
+ destructive operation; `--force` may discard dirty or unpushed artifacts,
98
+ while `--no-commit` leaves the parent-record deletion for a library caller to
99
+ commit. If remote deletion succeeds but local checkout removal fails, the
100
+ local ref, record, and checkouts are retained. Resolve the reported local
101
+ obstruction and retry `prune --force`; do not run `project push`, which would
102
+ republish the deleted remote ref.
103
+ - `oat project migrate <path> --to synced [--no-commit]` - migrate an existing
104
+ shared project to synced storage while preserving its artifacts and
105
+ retargeting the active project pointer. `--no-commit` leaves the parent
106
+ record and source-tree transition uncommitted for a library caller.
107
+ - `oat project list --scope shared|local|synced` - filter tracked projects by
108
+ scope. Add `--remote` to discover project refs that do not yet have a local
109
+ record or checkout, and `--include-coordination` to include coordination
110
+ parents. A malformed discovery record with no materialized checkout appears
111
+ as a `recorded-invalid` row. When the checkout is materialized, its existing
112
+ row instead carries the restore hint and `recordError` parse diagnostic in
113
+ `--json` output.
59
114
  - `oat tools migrate --pack <pack> --from <scope> --to <scope>` - move one installed pack between project and user scope. Always previews first, installs and re-inventories the destination before touching the source, and offers source removal only after the destination is verified complete. Declining or running non-interactively leaves the pack installed at both scopes rather than failing. `--dry-run` stops after the preview; there is no force flag. See [Tool Packs](../cli-utilities/tool-packs.md#oat-tools-migrate).
60
115
  - `oat pjm doctor --json` - read-only repository PJM diagnostics whose result carries an additive `adoption` object (`state` of `declared` | `inferred-legacy` | `partial-initialization` | `none`, `repoRoot`, and `recovery`). This, not `oat tools has project-management`, is the check that answers whether _this repository_ adopted PJM.
61
116
  - `oat config dump --json` - merged config with source attribution
@@ -66,7 +121,7 @@ Notable commands introduced in the current CLI surface:
66
121
  - `oat review latest --json` - find the newest review artifact by `oat_generated_at`, scanning the active or specified project's `reviews/` and `reviews/archived/` directories plus ad-hoc review locations. Same-time candidates use target priority, then lifecycle recency (`final` > higher phase/task > lower phase/task). The JSON contract returns `path`, `scope`, `generatedAt`, `kind` (`project` or `adhoc`), `archived`, and `actionable`, with `null` values when no review exists. Archived project reviews remain discoverable as history but return `actionable: false`.
67
122
  - `oat project list --json` - summary state for tracked projects under the configured projects root
68
123
  - `oat project complete-state <project-path>` - apply the canonical completed-state mutation to a project's `state.md`; used by `oat-project-complete` during lifecycle closeout
69
- - `oat project archive [project-path] [--project-recap-run <project-relative-path>]` - archive a tracked project through the same local move, summary export, and optional S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive stages the selected complete package into `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies every manifest-declared immutable file byte, then atomically installs the export before deleting the active project. Existing destinations, incomplete legacy hash coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project.
124
+ - `oat project archive [project-path] [--project-recap-run <project-relative-path>] [--no-commit]` - archive a tracked project through the same local move, summary export, and optional S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive stages the selected complete package into `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies every manifest-declared immutable file byte, then atomically installs the export before deleting the active project. Existing destinations, incomplete legacy hash coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project. `--no-commit` is a manual/library-only option: for a synced project it still removes the checkout but deliberately omits the lifecycle commit receipt. Never pass it through `oat-project-complete`, which requires that receipt.
70
125
  - `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. The old `oat project archive sync` path remains as a deprecated shim.
71
126
  - `oat project validate-plan --project-path <path>` - validates `oat_plan_parallel_groups` metadata in `plan.md`; exits non-zero on invalid. See [Implementation Execution](../workflows/projects/implementation-execution.md#parallel-phase-groups).
72
127
  - `oat project log append|check|synthesize|rollup` - manage the optional append-only project observation log: append validated judgment or structural entries, inspect grammar and synthesis status, complete end-of-run synthesis, and roll observations into `summary.md` plus the configured repository ledger. See [Project Log](../cli-utilities/project-log.md).
@@ -52,6 +52,8 @@ Pack intent is stored per scope:
52
52
  - Local runtime config (per-developer state): `.oat/config.local.json`
53
53
  - Active idea: `activeIdea` in `.oat/config.local.json` (repo) or `~/.oat/config.json` (user)
54
54
  - Projects root config: `projects.root` in `.oat/config.json` (read via `oat config get projects.root`)
55
+ - Default project scope: `projects.defaultScope` in `.oat/config.json`
56
+ (`synced` by default; override with `OAT_PROJECTS_DEFAULT_SCOPE`)
55
57
  - Archive config: `archive.s3Uri`, `archive.s3SyncOnComplete`, `archive.summaryExportPath`, `archive.wrapUpExportPath`, `archive.awsProfile`, and `archive.awsRegion` in `.oat/config.json`
56
58
  - Workflow gate config: `workflow.gates.skills` and `workflow.gates.execTargets` in `.oat/config.json`, `.oat/config.local.json`, or `~/.oat/config.json` (manage via `oat gate`)
57
59
  - Project sync manifest/config: `.oat/sync/`
@@ -87,16 +89,31 @@ Config ownership note:
87
89
  ## Project artifact trees
88
90
 
89
91
  - Shared: `.oat/projects/shared/<project>/`
92
+ - Synced checkout: `.oat/projects/synced/<project>/` (gitignored nested
93
+ worktree)
94
+ - Synced record: `.oat/projects/synced/<project>.json` (tracked on the parent
95
+ branch)
96
+ - Synced ref: `refs/oat/projects/<project>` on `origin`
90
97
  - Local: `.oat/projects/local/<project>/`
91
98
  - Archived: `.oat/projects/archived/<project>/`
92
99
 
100
+ The OAT-managed block in the repository root `.gitattributes` marks shared
101
+ project artifacts as generated for repository hosting UIs. `oat init` and
102
+ `oat tools update` own that block; preserve non-OAT entries outside its markers
103
+ and do not hand-edit the managed entry.
104
+
93
105
  Archive sync surfaces:
94
106
 
95
107
  - Local archive root: `.oat/projects/archived/`
96
108
  - Remote archive base: `archive.s3Uri` in `.oat/config.json`
97
109
  - Archive sync command: `oat repo archive sync` or `oat repo archive sync <project-name>`
98
110
  - Remote archive snapshot shape: `<archive.s3Uri>/<repo-slug>/projects/YYYYMMDD-<project-name>/`
99
- - Summary export target: `<repo>/<archive.summaryExportPath>/YYYYMMDD-<project-name>.md` when configured
111
+ - Summary export target:
112
+ `<repo>/<archive.summaryExportPath>/YYYYMMDD-<project-name>.md` when
113
+ configured. The archive report returns this absolute filesystem path, while
114
+ `oat project links --durable-summary` normalizes a contained path to a
115
+ repository-relative code span. It does not invent a GitHub-style URL for
116
+ non-GitHub remotes.
100
117
  - Wrap-up export target: `<repo>/<archive.wrapUpExportPath>/YYYY-MM-DD-wrap-up-<label>.md` when configured; otherwise `oat-wrap-up` falls back to `<repo>/.oat/repo/reference/wrap-ups/`
101
118
 
102
119
  ## Ideas — project level (gitignored)
@@ -24,6 +24,9 @@ Project scope is used for project workflows and repo-local sync state. User scop
24
24
  config.local.json
25
25
  projects/
26
26
  shared/
27
+ synced/
28
+ <project>.json
29
+ <project>/
27
30
  local/
28
31
  archived/
29
32
  ideas/
@@ -47,7 +50,7 @@ Project scope is used for project workflows and repo-local sync state. User scop
47
50
  | `.oat/config.json` | Shared repo runtime config for non-sync settings | Includes `worktrees.root`, `projects.root`, `git.defaultBranch`, `archive.*`, and `documentation.*` |
48
51
  | `.oat/config.local.json` | Local per-developer runtime state | Gitignored; includes `activeProject`, `lastPausedProject`, `activeIdea` |
49
52
  | `.oat/state.md` | Generated repo state dashboard | Gitignored; rebuilt with `oat state refresh` from config, project artifacts, and knowledge metadata |
50
- | `.oat/projects/` | OAT project artifacts | `shared`, `local`, `archived` scopes |
53
+ | `.oat/projects/` | OAT project artifacts | `shared`, `synced`, `local`, and lifecycle `archived` locations |
51
54
  | `.oat/ideas/` | Project-level ideas store | Often gitignored |
52
55
  | `.oat/sync/` | Interop sync state/config | See details below |
53
56
  | `.oat/templates/` | Artifact templates used by OAT skills | Source for scaffolding. Includes `docs-app-fuma/` (Fumadocs) and `docs-app-mkdocs/` (MkDocs) templates. |
@@ -105,6 +108,7 @@ Current schema keys:
105
108
  | `version` | `number` | `1` | Schema version |
106
109
  | `worktrees.root` | `string` | `".worktrees"` | Root directory for git worktrees (repo-relative or absolute) |
107
110
  | `projects.root` | `string` | `".oat/projects/shared"` | Default root directory for OAT projects |
111
+ | `projects.defaultScope` | `string` | `"synced"` | Scope used by project creation when `--scope` is omitted: `shared`, `local`, or `synced`. Environment override: `OAT_PROJECTS_DEFAULT_SCOPE`. |
108
112
  | `localPaths` | `string[]` | - | Gitignored directories to sync between main repo and worktrees. Supports glob patterns. Managed via `oat local add/remove`. |
109
113
  | `documentation.root` | `string` | - | Root directory containing documentation source files (e.g., `apps/docs/docs`) |
110
114
  | `documentation.tooling` | `string` | - | Documentation framework identifier (`mkdocs` or `fumadocs`) |
@@ -139,7 +143,8 @@ Example:
139
143
  {
140
144
  "version": 1,
141
145
  "projects": {
142
- "root": ".oat/projects/shared"
146
+ "root": ".oat/projects/shared",
147
+ "defaultScope": "synced"
143
148
  },
144
149
  "worktrees": {
145
150
  "root": ".worktrees"
@@ -173,12 +178,23 @@ For repo-relative values (levels 3-4), paths are resolved from the repository ro
173
178
  Each OAT project lives under:
174
179
 
175
180
  - `.oat/projects/shared/<project>/`
181
+ - `.oat/projects/synced/<project>/` for a gitignored nested worktree whose
182
+ history is published to `refs/oat/projects/<project>`
183
+ - `.oat/projects/synced/<project>.json` for the tracked discovery record that
184
+ identifies the ref, remote, and active or complete status
176
185
  - `.oat/projects/local/<project>/`
177
186
  - `.oat/projects/archived/<project>/`
178
187
 
179
- Archive sync behavior:
188
+ Completion and archive sync behavior:
180
189
 
181
- - `oat-project-complete` always archives locally into `.oat/projects/archived/<project>/`.
190
+ - When archiving is selected, `oat-project-complete` archives locally into
191
+ `.oat/projects/archived/<project>/`. For a synced project, the snapshot omits
192
+ the nested checkout's `.git` pointer and `reviews/`, then completion marks
193
+ the tracked record complete, removes the nested worktree, and retains the
194
+ project ref so pinned links keep resolving.
195
+ - When archiving is disabled or declined, completion leaves the synced
196
+ checkout and ref in place, pushes the finalized artifacts, and exact-path
197
+ commits the tracked record as complete.
182
198
  - If `archive.s3SyncOnComplete=true` and `archive.s3Uri` is configured, completion also uploads a dated snapshot such as `<archive.s3Uri>/<repo-slug>/projects/20260401-<project>/`.
183
199
  - `oat repo archive sync` syncs all repo archived projects down from S3 into `.oat/projects/archived/`.
184
200
  - `oat repo archive sync <project-name>` syncs the latest dated remote snapshot for a single project into `.oat/projects/archived/<project-name>/`.
@@ -77,8 +77,10 @@ Use [Instruction Sync](../provider-sync/instruction-sync.md) for the full strate
77
77
 
78
78
  - Run `oat init tools` to install/update bundled OAT tool packs.
79
79
  - In TTY mode, select which outdated skills to update when prompted.
80
- - In non-interactive mode, rerun the relevant pack subcommand with `--force` if you want to overwrite outdated installed skills.
81
- - For pack-level drift rather than a single skill, prefer the scoped command doctor prints: `oat tools update --pack <pack> --scope <scope>`.
80
+ - In non-interactive mode, run the scoped command doctor prints:
81
+ `oat tools update --pack <pack> --scope <scope>`.
82
+ - Per-pack install commands no longer accept the previously inert `--force`
83
+ option.
82
84
 
83
85
  ## `sync` reports an unsafe provider parent
84
86
 
@@ -147,18 +149,23 @@ Both commands report managed pack state with a scoped recovery command:
147
149
 
148
150
  - `partial` — some managed assets are missing, or intent is declared with none
149
151
  installed. Fix with `oat tools update --pack <pack> --scope <scope>`.
150
- - `stale` — installed assets are behind the bundled release. Same fix.
152
+ - `stale` — installed assets are behind the bundled release, or a managed skill
153
+ or agent has the bundled version metadata but different canonical content.
154
+ Expected executable-bit normalization on managed scripts is ignored. Fix with
155
+ the same scoped update command.
151
156
  - `newer` — installed assets are ahead of the bundle. This is informational and
152
157
  usually means the CLI is older than the assets; update the CLI rather than
153
158
  downgrading the pack.
154
- - `retained-override` — an owner-owned seeded asset exists at the scope, so the
155
- managed default is intentionally not applied there. This covers repository
156
- templates under `.oat/templates/` **and** seeded content such as
157
- `.oat/ideas/backlog.md` and `.oat/ideas/scratchpad.md`. Deleting the file is
158
- the right move only for a **template** you want OAT to manage again; never
159
- delete seeded content you have edited, because the next install or update
160
- reseeds the bundled default in its place and your edits are gone. The finding
161
- is informational and carries no recovery command for exactly that reason.
159
+ - `retained-override` — a source-backed owner-owned seed differs from its
160
+ bundled default, so OAT retains the edited copy instead of overwriting it. A
161
+ bundle-equal seed is current and does not produce this finding. Retained
162
+ overrides cover repository templates under `.oat/templates/` **and** seeded
163
+ content such as `.oat/ideas/backlog.md` and `.oat/ideas/scratchpad.md`.
164
+ Deleting the file is the right move only for a **template** you intentionally
165
+ want OAT to seed from the bundle again; never delete seeded content you have
166
+ edited, because the next install or update reseeds the bundled default in its
167
+ place and your edits are gone. The finding is informational and carries no
168
+ recovery command for exactly that reason.
162
169
  - `user-agent-unmaterialized` — the pack installed canonical agents into
163
170
  `~/.agents/agents/`, but user scope materializes no provider view for them
164
171
  beyond the bundled managed role files. `oat tools update` cannot fix this.
@@ -5,7 +5,33 @@ description: 'Project artifact contracts: state.md, spec.md, design.md, plan.md,
5
5
 
6
6
  # Project Artifacts
7
7
 
8
- Project artifacts live under `.oat/projects/<scope>/<project>/`.
8
+ Project artifacts use one of three active scopes:
9
+
10
+ - `shared` artifacts live directly on the feature branch under
11
+ `.oat/projects/shared/<project>/`.
12
+ - `synced` artifacts live in a gitignored nested worktree at
13
+ `.oat/projects/synced/<project>/`, backed by
14
+ `refs/oat/projects/<project>` on `origin`. The feature branch tracks only
15
+ `.oat/projects/synced/<project>.json`.
16
+ - `local` artifacts stay untracked on the current machine under
17
+ `.oat/projects/local/<project>/`.
18
+
19
+ `projects.defaultScope` controls creation when a command does not pass
20
+ `--scope`; its default is `synced`.
21
+
22
+ ## Synced artifact bookkeeping
23
+
24
+ Lifecycle skills write the same project files in every scope. After a synced
25
+ write, they use `oat project push` instead of staging the artifact path on the
26
+ parent branch. The command makes an artifact commit in the nested checkout,
27
+ rebases it on the fetched project ref, and pushes only that ref. Arrival skills
28
+ run `oat project pull` before reading artifacts so a record or remote ref can
29
+ materialize the checkout first.
30
+
31
+ The tracked JSON record is routing metadata, not a copy of the project. It
32
+ identifies the slug, `origin`, ref, status, and archive snapshot when present.
33
+ The project ref remains the source of truth for active artifact content and
34
+ history.
9
35
 
10
36
  ## Core artifacts
11
37
 
@@ -406,6 +406,28 @@ For a plan-declared parallel group, the root:
406
406
  Containment, ownership, base, or fixture-readiness failure in smoke mode aborts
407
407
  the run. It never authorizes replacement or sequential degradation.
408
408
 
409
+ ## Synced projects in worktrees
410
+
411
+ A tracked `.oat/projects/synced/<project>.json` record lets every repository
412
+ worktree discover the same synced project without putting its artifacts on the
413
+ feature branch. On arrival, project skills run `oat project pull` before they
414
+ read state. Pull fetches the exact `refs/oat/projects/<project>` ref and, when
415
+ needed, materializes a fresh nested checkout at
416
+ `.oat/projects/synced/<project>/`.
417
+
418
+ Each parent worktree gets an independent detached nested checkout. Those
419
+ checkouts do not share an index or working tree; they reconcile artifact
420
+ history through the project ref on `origin`. If a pull or push encounters an
421
+ overlapping change, resolve the files in the nested checkout and run
422
+ `oat project pull --continue`. Use `oat project pull --abort` to restore the
423
+ pre-pull state instead.
424
+
425
+ `oat local sync` skips these nested repositories, so local-path hydration does
426
+ not copy or overwrite synced artifact checkouts. Removing a parent worktree
427
+ also needs no special nested-checkout cleanup: the ignored nested worktree does
428
+ not prevent parent removal, and the next `oat project pull` prunes stale Git
429
+ worktree registrations before materializing or updating the current checkout.
430
+
409
431
  ## Codex Depth
410
432
 
411
433
  Default execution needs the root-to-phase-agent depth. `agents.max_depth >= 2`
@@ -24,6 +24,8 @@ Projects are where the workflow layer becomes concrete: lifecycle phases, `state
24
24
  - [Programmatic Execution](programmatic-execution.md) - Per-harness headless/CLI execution surfaces and where OAT uses them.
25
25
  - [Project Artifacts](artifacts.md) - What lives in `state.md`, `discovery.md`, `plan.md`, `implementation.md`, and related files.
26
26
  - [Implementation Execution](implementation-execution.md) - Phase dispatch, runtime selection, review/fix loop, and dry-run behavior.
27
+ - [Reviewing OAT PRs](reviewing-oat-prs.md) - Read synced-project records and SHA-pinned reviewer links in a PR.
28
+ - [Picking Up Projects](picking-up-projects.md) - Continue a synced project on another machine or from another user.
27
29
  - [Project Splitting](splitting.md) - How broad discoveries or brainstorms become coordination parents and child projects.
28
30
  - [State Machine](state-machine.md) - Lifecycle and review status transitions across a project.
29
31
  - [Reviews](reviews.md) - How review request/receive loops work inside OAT projects.
@@ -50,6 +52,8 @@ This sub-section is the deep technical surface for how tracked OAT projects exec
50
52
  - Split broad scopes into coordination parents and focused children in [Project Splitting](splitting.md).
51
53
  - Understand lifecycle and review transitions in [State Machine](state-machine.md).
52
54
  - Learn review and PR expectations in [Reviews](reviews.md) and [PR Flow](pr-flow.md).
55
+ - Review a synced project's durable context in [Reviewing OAT PRs](reviewing-oat-prs.md).
56
+ - Continue remote project work with [Picking Up Projects](picking-up-projects.md).
53
57
 
54
58
  ## Go Deeper
55
59
 
@@ -68,4 +72,6 @@ This sub-section is the deep technical surface for how tracked OAT projects exec
68
72
  - [State Machine](state-machine.md) - Lifecycle and review status transitions across a project.
69
73
  - [Reviews](reviews.md) - How review request/receive loops work inside OAT projects.
70
74
  - [PR Flow](pr-flow.md) - Progress and final PR generation expectations.
75
+ - [Reviewing OAT PRs](reviewing-oat-prs.md) - Record metadata, pinned links, and editor discovery for synced projects.
76
+ - [Picking Up Projects](picking-up-projects.md) - Remote discovery, adopting pull, coordination children, and retention boundaries.
71
77
  - [Repository PR Comment Analysis](repo-analysis.md) - Repo-wide PR comment collection and triage workflows.
@@ -70,13 +70,23 @@ After implementation closeout finishes:
70
70
  - GitHub PR feedback delegates to `oat-project-review-receive-remote`
71
71
  - Review artifacts delegate to `oat-project-review-receive`
72
72
  - After revision tasks complete, state returns to `pr_open`
73
- 5. **Complete** (`oat-project-complete`) — accepts any phase status (`pr_open`, `complete`, `in_progress`), auto-refreshes `summary.md` before closeout when needed, and always archives the project locally
73
+ 5. **Complete** (`oat-project-complete`) — accepts any phase status (`pr_open`, `complete`, `in_progress`), auto-refreshes `summary.md` before closeout when needed, and archives when selected by the workflow preference or completion prompt
74
74
 
75
75
  ### Completion archive behavior
76
76
 
77
- On completion, OAT now treats archive handling as part of the closeout lifecycle:
78
-
79
- - Local archive is always written to `.oat/projects/archived/<project>/`.
77
+ On completion, OAT treats archive handling as an explicit closeout choice:
78
+
79
+ - When archiving is selected, the local archive is written to `.oat/projects/archived/<project>/`.
80
+ - When archiving is disabled or declined, durable projects remain at their
81
+ active path. Synced completion still finalizes and pushes the project ref,
82
+ commits the discovery record as `complete`, retains the checkout and ref, and
83
+ attests a selected recap against the project-ref history.
84
+ - For a synced project, closeout first finalizes the project artifacts and
85
+ pushes them to `refs/oat/projects/<project>`. Archive then requires a clean,
86
+ fully pushed checkout; copies it without the `.git` pointer or `reviews/`;
87
+ marks the tracked record complete; commits the record and configured durable
88
+ exports on the parent branch; removes the nested checkout; and retains the
89
+ ref. This order keeps SHA-pinned PR links valid after completion.
80
90
  - If `.oat/config.json` enables `archive.s3SyncOnComplete` and sets `archive.s3Uri`, completion also attempts an S3 upload for a dated snapshot such as `<archive.s3Uri>/<repo-slug>/projects/20260401-<project>/`.
81
91
  - If `.oat/config.json` sets `archive.awsProfile` and/or `archive.awsRegion`, those values are forwarded to every `aws` invocation triggered by completion (preflight checks + `aws s3 sync`) and override any ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` / `AWS_REGION` / `AWS_DEFAULT_REGION` values. The repo's archive-scoped credentials are treated as deliberate intent so users don't have to unset shell env vars before running completion. See [`config-and-local-state.md`](../../cli-utilities/config-and-local-state.md) for the full precedence chain.
82
92
  - If `.oat/config.json` sets `archive.summaryExportPath`, completion copies `summary.md` to `<archive.summaryExportPath>/20260401-<project>.md`.
@@ -130,7 +140,7 @@ summary, documentation, PR, or project completion.
130
140
 
131
141
  ### Retrospective completion safety net
132
142
 
133
- Before an interactive completion archives the project,
143
+ Before an interactive completion closes the project,
134
144
  `oat-project-complete` checks for
135
145
  `{PROJECT_PATH}/references/project-retro.md`. If the artifact is missing, it
136
146
  offers to generate one before completion. If the artifact exists, completion
@@ -292,6 +302,10 @@ Capture lane progression:
292
302
  ## Operational rules
293
303
 
294
304
  - Keep `state.md`, `plan.md`, and `implementation.md` synchronized.
305
+ - For a synced project, publish lifecycle artifact writes with
306
+ `oat project push`; do not stage `.oat/projects/synced/<project>/` on the
307
+ parent branch.
308
+ - On arrival, run `oat project pull` before reading a synced project's state.
295
309
  - Stop at configured HiLL checkpoints.
296
310
  - Do not move lifecycle forward when required review gates are unresolved.
297
311
  - Project entry skills (`oat-project-new`, `oat-project-quick-start`, and `oat-project-import-plan`) surface inherited dirty git state before scaffolding. If the dirty list includes `.oat/sync/manifest.json`, `.claude/`, `.cursor/`, or `.codex/`, the skill calls out that those paths are typically sync output and offers Commit now, Proceed anyway, or Abort.