@open-agent-toolkit/cli 0.1.54 → 0.1.59

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 (45) hide show
  1. package/assets/agents/oat-phase-implementer.md +195 -238
  2. package/assets/docs/cli-utilities/configuration.md +7 -6
  3. package/assets/docs/contributing/index.md +1 -0
  4. package/assets/docs/contributing/smoke-testing.md +284 -0
  5. package/assets/docs/provider-sync/providers.md +11 -11
  6. package/assets/docs/provider-sync/scope-and-surface.md +2 -2
  7. package/assets/docs/workflows/projects/dispatch-ceiling.md +29 -26
  8. package/assets/docs/workflows/projects/evidence-layers.md +123 -0
  9. package/assets/docs/workflows/projects/implementation-execution.md +160 -406
  10. package/assets/docs/workflows/projects/index.md +8 -0
  11. package/assets/docs/workflows/projects/orchestration-model.md +190 -0
  12. package/assets/docs/workflows/projects/programmatic-execution.md +137 -0
  13. package/assets/docs/workflows/projects/review-flavors.md +129 -0
  14. package/assets/docs/workflows/skills/repo-improve.md +14 -0
  15. package/assets/public-package-versions.json +4 -4
  16. package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +5 -4
  17. package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +5 -4
  18. package/assets/skills/oat-dispatch-subagents/SKILL.md +6 -1
  19. package/assets/skills/oat-dispatch-subagents/references/record-schema.md +5 -0
  20. package/assets/skills/oat-project-dispatch-subagents/SKILL.md +37 -15
  21. package/assets/skills/oat-project-implement/SKILL.md +63 -1904
  22. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +431 -0
  23. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +715 -0
  24. package/assets/skills/oat-project-implement/references/phase-execution.md +270 -0
  25. package/assets/skills/oat-project-implement/references/plan-and-resume.md +279 -0
  26. package/assets/skills/oat-project-import-plan/SKILL.md +16 -8
  27. package/assets/skills/oat-project-plan/SKILL.md +15 -7
  28. package/assets/skills/oat-project-plan-writing/SKILL.md +74 -40
  29. package/assets/skills/oat-project-quick-start/SKILL.md +16 -8
  30. package/assets/skills/oat-project-review-provide/SKILL.md +8 -5
  31. package/assets/skills/oat-repo-improve/SKILL.md +17 -2
  32. package/assets/skills/oat-repo-improve/references/audit-playbook.md +6 -0
  33. package/assets/skills/oat-worktree-bootstrap/SKILL.md +22 -12
  34. package/assets/skills/oat-worktree-bootstrap/references/worktree-conventions.md +8 -8
  35. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +233 -44
  36. package/dist/commands/docs/index-generate/index.d.ts.map +1 -1
  37. package/dist/commands/docs/index-generate/index.js +10 -5
  38. package/dist/commands/doctor/index.d.ts.map +1 -1
  39. package/dist/commands/doctor/index.js +7 -4
  40. package/dist/commands/gate/index.d.ts +9 -1
  41. package/dist/commands/gate/index.d.ts.map +1 -1
  42. package/dist/commands/gate/index.js +62 -2
  43. package/dist/commands/project/dispatch-ceiling/index.js +2 -2
  44. package/package.json +4 -4
  45. package/assets/skills/oat-worktree-bootstrap-auto/scripts/bootstrap.sh +0 -236
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-worktree-bootstrap-auto
3
- version: 1.4.0
3
+ version: 1.5.6
4
4
  description: Use when an orchestrator/subagent needs autonomous worktree bootstrap. Non-interactive companion to oat-worktree-bootstrap.
5
5
  argument-hint: '<branch-name> [--base <ref>] [--path <root>] [--baseline-policy <strict|allow-failing>]'
6
6
  disable-model-invocation: false
@@ -41,12 +41,13 @@ When this skill is executed, provide concise status updates:
41
41
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
42
 
43
43
  - Before major phases, print compact indicators, for example:
44
- - `[1/6] Resolving worktree root…`
45
- - `[2/6] Creating/reusing worktree…`
46
- - `[3/6] Verifying resolved base in worktree HEAD…`
47
- - `[4/6] Running baseline checks…`
48
- - `[5/6] Syncing provider directories…`
49
- - `[6/6] Returning structured status…`
44
+ - `[1/7] Resolving worktree root…`
45
+ - `[2/7] Detecting bootstrap mode from resolved base…`
46
+ - `[3/7] Creating/reusing worktree…`
47
+ - `[4/7] Verifying resolved base in worktree HEAD…`
48
+ - `[5/7] Running baseline checks…`
49
+ - `[6/7] Syncing providers or recording smoke skips…`
50
+ - `[7/7] Returning structured status…`
50
51
 
51
52
  ## Inputs
52
53
 
@@ -69,8 +70,15 @@ When this skill is executed, provide concise status updates:
69
70
  | `strict` | Fail fast on any baseline check failure. Return error status immediately. |
70
71
  | `allow-failing` | Continue on baseline failures. Emit structured warnings. Log failures to project artifacts when available. |
71
72
 
73
+ The baseline policy never downgrades smoke containment failures. A missing,
74
+ unsafe, or malformed smoke marker, or failure of the smoke-safe
75
+ repository bootstrap path, is always fatal.
76
+
72
77
  ## Process
73
78
 
79
+ Initialize `BOOTSTRAP_MODE=normal` at process entry so even failures before base
80
+ inspection return an explicit mode. Only Step 1.5 may change it to `smoke`.
81
+
74
82
  ### Step 1: Resolve Worktree Root
75
83
 
76
84
  Use the same resolution precedence as `oat-worktree-bootstrap`:
@@ -86,19 +94,104 @@ Use the same resolution precedence as `oat-worktree-bootstrap`:
86
94
 
87
95
  If the resolved root is project-local (`.worktrees` or `worktrees`), verify it is gitignored.
88
96
 
97
+ ### Step 1.5: Resolve Base and Detect Bootstrap Mode
98
+
99
+ Resolve the base commit and inspect that commit, not the caller's checkout or
100
+ the eventual target, before any worktree creation command:
101
+
102
+ ```bash
103
+ RESOLVED_BASE_SHA=$(git -C "$REPO_ROOT" rev-parse "$BASE_REF")
104
+ BOOTSTRAP_MODE=normal
105
+ SMOKE_MARKER_ENTRY=$(
106
+ git -C "$REPO_ROOT" ls-tree "$RESOLVED_BASE_SHA" -- ".oat/smoke-bootstrap.json"
107
+ )
108
+ if [[ -n "$SMOKE_MARKER_ENTRY" ]]; then
109
+ BOOTSTRAP_MODE=smoke
110
+ fi
111
+ ```
112
+
113
+ `BOOTSTRAP_MODE` is derived state, not a caller override. Set
114
+ `BOOTSTRAP_MODE=smoke` only when the resolved base commit tracks the marker
115
+ path. An absent path selects `normal`; a base-resolution or tree-inspection
116
+ error is a bootstrap error. This detection must complete before Step 2.
117
+
89
118
  ### Step 2: Create or Reuse Worktree
90
119
 
91
120
  - Validate branch name: `^[a-zA-Z0-9._/-]+$`
92
121
  - Resolve target path: `{root}/{branch-name}`
93
- - If branch exists locally: `git worktree add "{target-path}" "{branch-name}"`
94
- - If branch does not exist: `git worktree add "{target-path}" -b "{branch-name}" "{base-ref}"`
95
- - If worktree already exists at target path: reuse it (validate branch matches)
122
+ - In normal mode, preserve existing behavior:
123
+ - If the branch exists locally:
124
+ `git -C "$REPO_ROOT" worktree add "$TARGET_PATH" "$BRANCH_NAME"`
125
+ - If the branch does not exist:
126
+ `git -C "$REPO_ROOT" worktree add "$TARGET_PATH" -b "$BRANCH_NAME" "$BASE_REF"`
127
+ - If a worktree already exists at the target path, reuse it after validating
128
+ that its branch matches.
129
+ - In smoke mode, disable repository hooks only for each create/reuse command
130
+ invocation. Never mutate persistent Git configuration:
131
+
132
+ ```bash
133
+ # Existing branch
134
+ git -c core.hooksPath=/dev/null -C "$REPO_ROOT" worktree add \
135
+ "$TARGET_PATH" "$BRANCH_NAME"
136
+
137
+ # New branch
138
+ git -c core.hooksPath=/dev/null -C "$REPO_ROOT" worktree add \
139
+ "$TARGET_PATH" -b "$BRANCH_NAME" "$BASE_REF"
140
+
141
+ # Reused target validation uses the same invocation-scoped suppression.
142
+ git -c core.hooksPath=/dev/null -C "$TARGET_PATH" \
143
+ rev-parse --abbrev-ref HEAD
144
+ ```
145
+
146
+ Do not run `git config core.hooksPath ...`; the suppression must remain
147
+ invocation-scoped.
148
+
149
+ After smoke-mode creation or reuse, require the tracked marker in the target
150
+ before any propagation, sync, status, or test command:
151
+
152
+ ```bash
153
+ git -C "$TARGET_PATH" ls-files --error-unmatch -- ".oat/smoke-bootstrap.json"
154
+ SMOKE_MARKER="$TARGET_PATH/.oat/smoke-bootstrap.json"
155
+ test -d "$TARGET_PATH/.oat"
156
+ test ! -L "$TARGET_PATH/.oat"
157
+ test -f "$SMOKE_MARKER"
158
+ test ! -L "$SMOKE_MARKER"
159
+ ```
160
+
161
+ Any failed check is a fatal containment failure with
162
+ `reason: smoke-marker-invalid`, regardless of baseline policy. Do not fall
163
+ through to normal mode.
164
+
165
+ Immediately after those marker checks, register the child from the parent
166
+ orchestrator before running any command inside it:
167
+
168
+ ```bash
169
+ SMOKE_MANIFEST=$(
170
+ node -e \
171
+ "const marker=require(process.argv[1]); process.stdout.write(marker.manifestPath)" \
172
+ "$SMOKE_MARKER"
173
+ )
174
+ node "$TARGET_PATH/tools/smoke/runner/journal.mjs" register \
175
+ --manifest "$SMOKE_MANIFEST" \
176
+ --marker "$SMOKE_MARKER" \
177
+ --worktree "$TARGET_PATH"
178
+ ```
179
+
180
+ Registration is idempotent, so the repository's smoke-safe bootstrap may
181
+ register the same child again. This parent-side registration must happen before
182
+ the first child process: a package-manager, shell, or bootstrap-launch failure
183
+ must not leave an unjournaled worktree that cleanup cannot safely own.
96
184
 
97
185
  On failure: return structured error, do not prompt.
98
186
 
99
187
  ### Step 2.5: Propagate Local-Only Config + Local Paths
100
188
 
101
- After the worktree is created or reused, copy gitignored local-only config and sync configured local paths.
189
+ **Smoke mode:** skip source config propagation and `oat local sync` entirely.
190
+ The safe init path owns the only permitted config transfer. Do not read or copy
191
+ the invoking checkout's local-only config here.
192
+
193
+ **Normal mode:** after the worktree is created or reused, copy gitignored
194
+ local-only config and sync configured local paths as before.
102
195
 
103
196
  **Config propagation:**
104
197
 
@@ -126,11 +219,7 @@ oat local sync "$TARGET_PATH" 2>/dev/null || true
126
219
 
127
220
  Before any baseline checks run, verify the worktree actually branched from the resolved base. This catches host-native or git-internal misbehavior that would otherwise silently land the worktree at the wrong base.
128
221
 
129
- 1. Resolve the base SHA:
130
-
131
- ```bash
132
- RESOLVED_BASE_SHA=$(git -C "$REPO_ROOT" rev-parse "$BASE_REF")
133
- ```
222
+ 1. Reuse `RESOLVED_BASE_SHA` from Step 1.5.
134
223
 
135
224
  2. Capture the worktree HEAD:
136
225
 
@@ -149,23 +238,76 @@ Before any baseline checks run, verify the worktree actually branched from the r
149
238
 
150
239
  **On base mismatch:** treat as a bootstrap failure. Do **not** silently land at the wrong base, do **not** proceed to baseline checks. Apply the configured baseline policy to the failure:
151
240
 
241
+ - `smoke` → return immediately with `status: failed` and
242
+ `reason: smoke-base-mismatch`. This is a containment failure and cannot be
243
+ downgraded by `allow-failing`.
152
244
  - `strict` → return immediately with `status: failed`, `reason: base-mismatch`, populated `expected_base_sha` and `observed_head_sha`, and the worktree path. The orchestrator is expected to cancel the dispatch and degrade.
153
245
  - `allow-failing` → emit a structured warning (`reason: base-mismatch`, with `expected_base_sha` and `observed_head_sha`), append a base-mismatch entry to `implementation.md` if an active project exists, and continue to Step 3 only if the caller has explicitly opted into a degraded outcome. In all other cases prefer fail-fast — base mismatch is rarely recoverable.
154
246
 
155
247
  ### Step 3: Run Baseline Checks
156
248
 
157
- Execute in the target worktree directory:
158
-
159
- ```bash
160
- pnpm run worktree:init # install + build + sync
161
- oat status --scope project
162
- pnpm test
163
- ```
164
-
165
- Continue to Step 4 for provider directory setup, the `git_clean` baseline
166
- check, and the all-scope sync. The `git_clean` check must run after provider
167
- directory creation but before the all-scope sync sweep, so it measures inherited
168
- worktree state plus setup output rather than the sync sweep's generated output.
249
+ Execute in the target worktree directory.
250
+
251
+ First resolve the repository bootstrap contract:
252
+
253
+ 1. Read the applicable agent instructions and contributing/setup guidance.
254
+ 2. Inspect repository task definitions, manifests, and lockfiles.
255
+ 3. Prefer an explicit worktree bootstrap command when the repository declares
256
+ one.
257
+ 4. If no command exists, derive the minimum safe setup for a fresh worktree
258
+ from repository context.
259
+ 5. Select the repository's documented readiness check and a proportionate
260
+ baseline verification. Do not default to a full test suite when setup
261
+ guidance specifies a narrower readiness check.
262
+ 6. Record the exact selected commands and the evidence used to choose them.
263
+
264
+ Never assume Node.js, pnpm, a dependency store, or a particular install, build,
265
+ or test command. For example, this repository declares its own `worktree:init`
266
+ procedure in `AGENTS.md` and `package.json`; that repository context, not this
267
+ skill, supplies the invocation.
268
+
269
+ **Normal mode:**
270
+
271
+ Run the selected repository bootstrap, readiness, and baseline commands. Run
272
+ `oat status --scope project` when the initialized repository contains an OAT
273
+ project.
274
+
275
+ Continue to Step 4 for normal provider directory setup, the `git_clean`
276
+ baseline check, and the all-scope sync. The `git_clean` check must run after
277
+ provider directory creation but before the all-scope sync sweep, so it measures
278
+ inherited worktree state plus setup output rather than the sync sweep's
279
+ generated output.
280
+
281
+ **Smoke mode:**
282
+
283
+ Source smoke preflight already owns dependency, build, and repository-wide test
284
+ readiness for the source commit. A nested smoke child must run only the
285
+ repository bootstrap's smoke-safe containment path: validate the marker,
286
+ register ownership in the locked manifest journal, verify the expected base,
287
+ copy and hash-check the provisioned config, and run fixture-scoped readiness
288
+ checks.
289
+
290
+ The smoke-safe path must not install dependencies, build the repository, run
291
+ repository-wide tests, or invoke provider sync. Those operations are neither
292
+ retried nor downgraded in a child. After containment succeeds, verify the
293
+ fixture project artifacts and declared writable task files, then run
294
+ `git status --porcelain`.
295
+
296
+ The first command is the safe-init boundary. Any nonzero exit is a containment
297
+ failure: return immediately with `status: failed` and
298
+ `reason: smoke-init-failed`, regardless of whether the marker is missing,
299
+ unsafe, or malformed or a journal/config/bootstrap check failed. Never
300
+ apply `allow-failing` to that result. Run the remaining read-only/local checks
301
+ only after safe init succeeds. Never run PATH-resolved `oat` in smoke mode; the
302
+ built repository-local CLI entrypoint is the only permitted OAT executable.
303
+ Invoke the repository's direct smoke-safe entrypoint, not a package-manager
304
+ wrapper that may perform installation before reaching it. In this repository
305
+ that command is `bash scripts/worktree/init.sh`, not
306
+ `pnpm run worktree:init`.
307
+ Set the child worktree itself as the process working directory. Use the
308
+ equivalent of `(cd "$TARGET_PATH" && bash scripts/worktree/init.sh)`; invoking
309
+ the child script by absolute path while the shell remains in the outer
310
+ worktree is a containment failure.
169
311
 
170
312
  Check behavior per baseline policy:
171
313
 
@@ -183,8 +325,21 @@ Check behavior per baseline policy:
183
325
 
184
326
  ### Step 4: Create Provider Directories and Sync
185
327
 
186
- Worktrees do not inherit gitignored provider directories. Create them if
187
- missing, run the `git_clean` baseline check, and then run sync:
328
+ **Smoke mode:** skip provider-directory creation, all-scope sync, staging, and
329
+ sync commits. Do not run `mkdir` for provider views, `oat sync --scope all`,
330
+ `git add`, or `git commit`. After the safe local status/test checks in Step 3,
331
+ run only the final clean check:
332
+
333
+ ```bash
334
+ git status --porcelain
335
+ ```
336
+
337
+ Record `provider_sync: skip` and `sync_commit: skip`, plus every structured
338
+ smoke skip listed in Step 5. Any dirty result is handled as the `git_clean`
339
+ baseline check; it does not authorize cleanup, staging, or a commit.
340
+
341
+ **Normal mode:** worktrees do not inherit gitignored provider directories.
342
+ Create them if missing, run the `git_clean` baseline check, and then run sync:
188
343
 
189
344
  ```bash
190
345
  mkdir -p "{target-path}/.claude/skills"
@@ -224,22 +379,35 @@ branch: '{branch-name}'
224
379
  base_ref: '{base-ref}'
225
380
  resolved_base_sha: '{sha resolved from base-ref}'
226
381
  observed_head_sha: '{sha of worktree HEAD after add}'
382
+ bootstrap_mode: normal | smoke
227
383
  checks:
228
- worktree_init: pass | fail | skip
229
- project_status: pass | fail | skip
230
- tests: pass | fail | skip
384
+ repository_bootstrap: pass | fail | skip
385
+ repository_readiness: pass | fail | skip
386
+ baseline_verification: pass | fail | skip
387
+ smoke_child_readiness: pass | fail | skip
231
388
  git_clean: pass | fail | skip
232
389
  provider_sync: pass | fail | skip
233
390
  sync_commit: pass | fail | skip
391
+ smoke_skips:
392
+ local_config_propagation: true | false
393
+ local_paths_sync: true | false
394
+ provider_directory_creation: true | false
395
+ provider_sync: true | false
396
+ sync_staging: true | false
397
+ sync_commit: true | false
234
398
  warnings: [] # List of warning messages (allow-failing mode)
235
399
  error: null # Error message (strict mode failure)
236
- reason: null # Structured reason on failure (e.g., base-mismatch)
400
+ reason: null # e.g., base-mismatch, smoke-marker-invalid, smoke-init-failed, smoke-readiness-failed
237
401
  expected_base_sha: null # Populated when reason is base-mismatch
238
402
  baseline_policy: strict | allow-failing
239
403
  ```
240
404
 
241
405
  `resolved_base_sha` and `observed_head_sha` are populated on **every** terminal status (success, warning, error, failed) so callers can perform belt-and-suspenders post-verification on the success path as well as diagnose the failure path.
242
406
 
407
+ `bootstrap_mode` is populated on every terminal status after Step 1.5.
408
+ `smoke_skips` is explicit on every terminal status: all six values are `true`
409
+ for smoke mode and `false` for normal mode.
410
+
243
411
  **Status determination:**
244
412
 
245
413
  - `success`: All checks passed and Step 2.7 base-resolution verification passed.
@@ -248,19 +416,31 @@ baseline_policy: strict | allow-failing
248
416
  - `error`: `sync_commit` failed under `strict` policy.
249
417
  - `warning`: `sync_commit` failed under `allow-failing` policy.
250
418
  - `failed` (with `reason: base-mismatch`): Step 2.7 base-resolution verification failed. Callers should treat this distinctly from a generic baseline error — it is a contract violation, not a flaky check.
419
+ - `failed` (with `reason: smoke-marker-invalid`): smoke mode was detected from
420
+ the resolved base but the target marker is missing or unsafe.
421
+ - `failed` (with `reason: smoke-init-failed`): the marker is malformed or the
422
+ safe-init containment path failed. Both smoke failure statuses are fatal
423
+ under `strict` and `allow-failing`.
424
+ - `failed` (with `reason: smoke-readiness-failed`): fixture-scoped child
425
+ readiness failed after containment. Stop immediately; do not dispatch a
426
+ phase implementer, reviewer, or gate and do not degrade to sequential
427
+ execution.
251
428
 
252
429
  ## Error Handling
253
430
 
254
- | Scenario | Behavior |
255
- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
256
- | Worktree creation fails | Return error status with git error message |
257
- | Branch already checked out elsewhere | Return error with worktree location info |
258
- | Base mismatch (Step 2.7 fails, strict) | Return `status: failed`, `reason: base-mismatch`, with `expected_base_sha` and `observed_head_sha`. Do not run baselines. |
259
- | Base mismatch (Step 2.7 fails, allow-fail) | Emit structured warning with `reason: base-mismatch`, log to artifacts, prefer fail-fast unless caller opted into degrade. |
260
- | Baseline check fails (strict) | Return error with check name and failure output |
261
- | Baseline check fails (allow-failing) | Add to warnings, continue, log to artifacts |
262
- | No active project | Skip artifact logging, use console only |
263
- | Invalid branch name | Return error before attempting creation |
431
+ | Scenario | Behavior |
432
+ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
433
+ | Worktree creation fails | Return error status with git error message |
434
+ | Branch already checked out elsewhere | Return error with worktree location info |
435
+ | Smoke marker missing or unsafe | Return `status: failed`, `reason: smoke-marker-invalid`; never run propagation, sync, status, or tests |
436
+ | Smoke marker malformed or safe init fails | Return `status: failed`, `reason: smoke-init-failed`; never downgrade under `allow-failing` |
437
+ | Smoke fixture readiness fails | Return `status: failed`, `reason: smoke-readiness-failed`; abort the run before any phase implementer, reviewer, or gate launch |
438
+ | Base mismatch (Step 2.7 fails, strict) | Return `status: failed`, `reason: base-mismatch`, with `expected_base_sha` and `observed_head_sha`. Do not run baselines. |
439
+ | Base mismatch (Step 2.7 fails, allow-fail) | Emit structured warning with `reason: base-mismatch`, log to artifacts, prefer fail-fast unless caller opted into degrade. |
440
+ | Baseline check fails (strict) | Return error with check name and failure output |
441
+ | Baseline check fails (allow-failing) | Add to warnings, continue, log to artifacts |
442
+ | No active project | Skip artifact logging, use console only |
443
+ | Invalid branch name | Return error before attempting creation |
264
444
 
265
445
  ## Artifact Logging
266
446
 
@@ -304,6 +484,10 @@ When a base mismatch is detected (Step 2.7) and an active project exists, append
304
484
  | `strict` | Fail fast, return error immediately | Error in status output | `status: error` |
305
485
  | `allow-failing` | Continue, collect warnings | Append to `implementation.md` (or console) | `status: warning` |
306
486
 
487
+ Containment failures are outside this table's baseline-failure policy. A
488
+ missing, unsafe, or malformed smoke marker and any smoke safe-init failure are
489
+ fatal under both policies.
490
+
307
491
  **Orchestrator integration:**
308
492
 
309
493
  - When invoked by `oat-project-implement` in parallel mode, the baseline policy is passed through from the orchestration run policy.
@@ -316,10 +500,15 @@ When a base mismatch is detected (Step 2.7) and an active project exists, append
316
500
  - **Never** create fallback artifact files — log to existing artifacts or console only.
317
501
  - **Never** modify implementation code — bootstrap and checks only.
318
502
  - **Never** override or conflict with `oat-worktree-bootstrap` manual-safe behavior.
503
+ - **Never** propagate caller-local config, sync local paths/providers, stage, or
504
+ commit from smoke mode.
505
+ - **Never** use a PATH-resolved `oat` executable for smoke checks.
319
506
 
320
507
  ## Success Criteria
321
508
 
322
509
  - Worktree exists and is on the correct branch.
510
+ - Bootstrap mode was derived from the resolved base before creation.
323
511
  - Baseline checks executed per policy.
512
+ - Smoke mode completed safe init without any skipped side-effect path running.
324
513
  - Structured status returned for orchestrator consumption.
325
514
  - Failures logged to appropriate destination without user interaction.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/index-generate/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,eAAO,MAAM,uBAAuB,iIAC4F,CAAC;AAOjI,UAAU,6BAA6B;IACrC,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,UAAU,EAAE,KAAK,MAAM,CAAC;IACrE,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,OAAO,oBAAoB,EAAE,SAAS,CAAC,CAAC;IACrD,cAAc,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,oBAAoB,EAAE,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAgFD,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAsBT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/index-generate/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,eAAO,MAAM,uBAAuB,iIAC4F,CAAC;AAOjI,UAAU,6BAA6B;IACrC,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,UAAU,EAAE,KAAK,MAAM,CAAC;IACrE,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,OAAO,oBAAoB,EAAE,SAAS,CAAC,CAAC;IACrD,cAAc,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,oBAAoB,EAAE,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAqFD,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAsBT"}
@@ -35,11 +35,16 @@ async function runIndexGenerate(context, options, deps) {
35
35
  await deps.writeFile(outputPath, content, 'utf8');
36
36
  const repoRoot = await deps.resolveRepoRoot(context.cwd);
37
37
  const config = await deps.readOatConfig(repoRoot);
38
- config.documentation = {
39
- ...config.documentation,
40
- index: relative(repoRoot, outputPath) || 'index.md',
41
- };
42
- await deps.writeOatConfig(repoRoot, config);
38
+ const indexPath = relative(repoRoot, outputPath) || 'index.md';
39
+ if (config.documentation?.index !== indexPath) {
40
+ await deps.writeOatConfig(repoRoot, {
41
+ ...config,
42
+ documentation: {
43
+ ...config.documentation,
44
+ index: indexPath,
45
+ },
46
+ });
47
+ }
43
48
  if (context.json) {
44
49
  context.logger.json({
45
50
  status: 'ok',
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
@@ -313,11 +313,12 @@ async function resolveDoctorCodexMaxDepth(scope, parsedConfig, userHome, depende
313
313
  }
314
314
  }
315
315
  function createCodexMaxDepthCheck(scope, entry) {
316
- const topology = 'root (0) → phase coordinator (1) → task worker (2)';
316
+ const topology = 'root (0) → phase implementer (1)';
317
+ const optionalTopology = 'optional nested child (2)';
317
318
  const numericDepth = typeof entry.value === 'number' && Number.isFinite(entry.value)
318
319
  ? entry.value
319
320
  : null;
320
- const sufficient = numericDepth !== null && numericDepth >= 2;
321
+ const sufficient = !entry.present || (numericDepth !== null && numericDepth >= 1);
321
322
  let state;
322
323
  if (!entry.present) {
323
324
  state = 'agents.max_depth is missing';
@@ -330,10 +331,12 @@ function createCodexMaxDepthCheck(scope, entry) {
330
331
  }
331
332
  return {
332
333
  name: `${scope}:codex_max_depth`,
333
- description: 'Codex managed-role nested dispatch depth',
334
+ description: 'Codex managed-role phase dispatch depth',
334
335
  status: sufficient ? 'pass' : 'warn',
335
336
  message: sufficient
336
- ? `${state}; sufficient for ${topology}.`
337
+ ? numericDepth !== null && numericDepth >= 2
338
+ ? `${state}; sufficient for ${topology} and ${optionalTopology}.`
339
+ : `${state}; sufficient for ${topology}. Depth 2 enables ${optionalTopology} when useful.`
337
340
  : `${state}; OAT managed implementation requires ${topology}.`,
338
341
  fix: sufficient
339
342
  ? undefined
@@ -18,18 +18,26 @@ interface GateCommandDependencies {
18
18
  runProcess: (command: string, args: string[], options: ProcessRunOptions) => Promise<ProcessRunResult>;
19
19
  parseReviewGateVerdict: typeof parseReviewGateVerdict;
20
20
  processEnv: NodeJS.ProcessEnv;
21
+ writeDiagnostic: (message: string) => void;
21
22
  }
22
23
  interface ProcessRunOptions {
23
24
  cwd: string;
24
25
  env: NodeJS.ProcessEnv;
26
+ livenessIntervalMs?: number;
27
+ onLiveness?: (snapshot: GateLivenessSnapshot) => void;
25
28
  purpose: 'host-detection' | 'availability' | 'execute';
26
- stdio: 'ignore' | 'inherit';
29
+ stdio: 'ignore' | 'inherit' | 'pipe';
27
30
  timeoutMs: number;
28
31
  }
29
32
  interface ProcessRunResult {
30
33
  exitCode: number;
31
34
  timedOut?: boolean;
32
35
  }
36
+ interface GateLivenessSnapshot {
37
+ elapsedMs: number;
38
+ hardBudgetMs: number;
39
+ idleMs: number;
40
+ }
33
41
  type CrossProviderAvoid = 'same-family' | 'same-runtime' | 'none';
34
42
  type GateDiversityAchieved = 'different-family' | 'degraded-to-different-slug' | 'same-family - no diverse target available' | 'unknown-producer';
35
43
  export interface SelectedExecTarget {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ const DEFAULT_DEPENDENCIES = {
29
29
  runProcess: runChildProcess,
30
30
  parseReviewGateVerdict,
31
31
  processEnv: process.env,
32
+ writeDiagnostic: (message) => process.stderr.write(message),
32
33
  };
33
34
  const VALID_ON_FAILURE = ['block', 'prompt', 'warn'];
34
35
  const VALID_WRITE_LAYERS = [
@@ -56,6 +57,7 @@ const VALID_IDENTITY_PROVENANCES = [
56
57
  const REVIEW_GATE_CONTEXT_NOTE = 'This review is gate-originated. If you run `oat-project-review-provide`, set `oat_review_invocation: gate` in the review artifact. Write a canonical review artifact with `### Critical`, `### Important`, `### Medium`, and `### Minor` headings in that order, using `None` for empty sections.';
57
58
  const GATE_CHECK_TIMEOUT_MS = 5_000;
58
59
  const GATE_EXEC_TIMEOUT_MS = 15 * 60 * 1_000;
60
+ const GATE_LIVENESS_INTERVAL_MS = 30_000;
59
61
  function reviewGateProjectContext(project) {
60
62
  return [
61
63
  `Resolved OAT project path: ${project.path}. Run the review for this project path.`,
@@ -196,11 +198,35 @@ async function runChildProcess(command, args, options) {
196
198
  return new Promise((resolve, reject) => {
197
199
  let timedOut = false;
198
200
  let killTimeout = null;
201
+ const startedAt = Date.now();
202
+ let lastActivityAt = startedAt;
199
203
  const child = spawn(command, args, {
200
204
  cwd: options.cwd,
201
205
  env: options.env,
202
- stdio: options.stdio,
206
+ stdio: options.stdio === 'pipe' ? ['inherit', 'pipe', 'pipe'] : options.stdio,
203
207
  });
208
+ const recordActivity = () => {
209
+ lastActivityAt = Date.now();
210
+ };
211
+ child.stdout?.on('data', (chunk) => {
212
+ recordActivity();
213
+ process.stdout.write(chunk);
214
+ });
215
+ child.stderr?.on('data', (chunk) => {
216
+ recordActivity();
217
+ process.stderr.write(chunk);
218
+ });
219
+ const livenessInterval = options.onLiveness && options.livenessIntervalMs
220
+ ? setInterval(() => {
221
+ const now = Date.now();
222
+ options.onLiveness?.({
223
+ elapsedMs: now - startedAt,
224
+ hardBudgetMs: options.timeoutMs,
225
+ idleMs: now - lastActivityAt,
226
+ });
227
+ }, options.livenessIntervalMs)
228
+ : null;
229
+ livenessInterval?.unref();
204
230
  const timeout = setTimeout(() => {
205
231
  timedOut = true;
206
232
  child.kill('SIGTERM');
@@ -212,6 +238,9 @@ async function runChildProcess(command, args, options) {
212
238
  timeout.unref();
213
239
  child.on('error', (error) => {
214
240
  clearTimeout(timeout);
241
+ if (livenessInterval) {
242
+ clearInterval(livenessInterval);
243
+ }
215
244
  if (killTimeout) {
216
245
  clearTimeout(killTimeout);
217
246
  }
@@ -219,6 +248,9 @@ async function runChildProcess(command, args, options) {
219
248
  });
220
249
  child.on('close', (code) => {
221
250
  clearTimeout(timeout);
251
+ if (livenessInterval) {
252
+ clearInterval(livenessInterval);
253
+ }
222
254
  if (killTimeout) {
223
255
  clearTimeout(killTimeout);
224
256
  }
@@ -321,6 +353,17 @@ function resolveGateExecTimeoutMs(env) {
321
353
  }
322
354
  return parsed;
323
355
  }
356
+ function resolveGateLivenessIntervalMs(env) {
357
+ const rawValue = env.OAT_GATE_LIVENESS_INTERVAL_MS?.trim();
358
+ if (!rawValue) {
359
+ return GATE_LIVENESS_INTERVAL_MS;
360
+ }
361
+ const parsed = Number(rawValue);
362
+ if (!Number.isInteger(parsed) || parsed < 1) {
363
+ return GATE_LIVENESS_INTERVAL_MS;
364
+ }
365
+ return parsed;
366
+ }
324
367
  function parseArgvJson(value, flag) {
325
368
  let parsed;
326
369
  try {
@@ -827,6 +870,7 @@ async function executeTarget(selected, prompt, context, dependencies) {
827
870
  ? ['--model', selected.model]
828
871
  : [];
829
872
  const timeoutMs = resolveGateExecTimeoutMs(dependencies.processEnv);
873
+ const livenessIntervalMs = resolveGateLivenessIntervalMs(dependencies.processEnv);
830
874
  if (!context.json) {
831
875
  context.logger.info(`Running gate target ${selected.id} (${selected.target.runtime}); timeout=${timeoutMs}ms.`);
832
876
  }
@@ -834,8 +878,24 @@ async function executeTarget(selected, prompt, context, dependencies) {
834
878
  return await dependencies.runProcess(command, [...baseArgs, ...modelArgs, ...prompt], {
835
879
  cwd: context.cwd,
836
880
  env: dependencies.processEnv,
881
+ livenessIntervalMs,
882
+ onLiveness: ({ elapsedMs, hardBudgetMs, idleMs }) => {
883
+ const telemetry = {
884
+ elapsedMs,
885
+ hardBudgetMs,
886
+ idleMs,
887
+ target: selected.id,
888
+ type: 'gate-liveness',
889
+ };
890
+ if (context.json) {
891
+ dependencies.writeDiagnostic(`${JSON.stringify(telemetry)}\n`);
892
+ }
893
+ else {
894
+ context.logger.info(`Gate liveness: target=${selected.id} elapsed_ms=${elapsedMs} idle_ms=${idleMs} hard_budget_ms=${hardBudgetMs}.`);
895
+ }
896
+ },
837
897
  purpose: 'execute',
838
- stdio: 'inherit',
898
+ stdio: 'pipe',
839
899
  timeoutMs,
840
900
  });
841
901
  }