@open-agent-toolkit/cli 0.1.5 → 0.1.6

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 (77) hide show
  1. package/assets/docs/workflows/projects/artifacts.md +17 -0
  2. package/assets/docs/workflows/projects/index.md +3 -0
  3. package/assets/docs/workflows/projects/splitting.md +79 -0
  4. package/assets/docs/workflows/skills/index.md +2 -0
  5. package/assets/public-package-versions.json +4 -4
  6. package/assets/skills/oat-brainstorm/SKILL.md +43 -3
  7. package/assets/skills/oat-project-discover/SKILL.md +72 -8
  8. package/assets/skills/oat-project-quick-start/SKILL.md +14 -5
  9. package/assets/skills/oat-project-split/SKILL.md +82 -0
  10. package/assets/templates/state.md +6 -1
  11. package/dist/__tests__/skills/split-flow-fixtures.d.ts +50 -0
  12. package/dist/__tests__/skills/split-flow-fixtures.d.ts.map +1 -0
  13. package/dist/__tests__/skills/split-flow-fixtures.js +161 -0
  14. package/dist/commands/init/tools/shared/skill-manifest.d.ts +1 -1
  15. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  16. package/dist/commands/init/tools/shared/skill-manifest.js +1 -0
  17. package/dist/commands/project/complete-discovery/index.d.ts +16 -0
  18. package/dist/commands/project/complete-discovery/index.d.ts.map +1 -0
  19. package/dist/commands/project/complete-discovery/index.js +123 -0
  20. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  21. package/dist/commands/project/complete-state/index.js +5 -0
  22. package/dist/commands/project/index.d.ts.map +1 -1
  23. package/dist/commands/project/index.js +4 -0
  24. package/dist/commands/project/list.d.ts +6 -0
  25. package/dist/commands/project/list.d.ts.map +1 -1
  26. package/dist/commands/project/list.js +37 -4
  27. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  28. package/dist/commands/project/new/scaffold.js +4 -0
  29. package/dist/commands/project/open/index.d.ts.map +1 -1
  30. package/dist/commands/project/open/index.js +9 -3
  31. package/dist/commands/project/pause/index.d.ts.map +1 -1
  32. package/dist/commands/project/pause/index.js +7 -1
  33. package/dist/commands/project/split/evaluate-signals.d.ts +8 -0
  34. package/dist/commands/project/split/evaluate-signals.d.ts.map +1 -0
  35. package/dist/commands/project/split/evaluate-signals.js +47 -0
  36. package/dist/commands/project/split/index.d.ts +3 -0
  37. package/dist/commands/project/split/index.d.ts.map +1 -0
  38. package/dist/commands/project/split/index.js +11 -0
  39. package/dist/commands/project/split/run.d.ts +21 -0
  40. package/dist/commands/project/split/run.d.ts.map +1 -0
  41. package/dist/commands/project/split/run.js +231 -0
  42. package/dist/commands/project/split/validate-plan.d.ts +14 -0
  43. package/dist/commands/project/split/validate-plan.d.ts.map +1 -0
  44. package/dist/commands/project/split/validate-plan.js +62 -0
  45. package/dist/commands/shared/frontmatter.d.ts +9 -0
  46. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  47. package/dist/commands/shared/frontmatter.js +46 -0
  48. package/dist/commands/state/generate.d.ts.map +1 -1
  49. package/dist/commands/state/generate.js +38 -6
  50. package/dist/projects/split/child-plan.d.ts +46 -0
  51. package/dist/projects/split/child-plan.d.ts.map +1 -0
  52. package/dist/projects/split/child-plan.js +107 -0
  53. package/dist/projects/split/document-validation.d.ts +14 -0
  54. package/dist/projects/split/document-validation.d.ts.map +1 -0
  55. package/dist/projects/split/document-validation.js +106 -0
  56. package/dist/projects/split/finalize.d.ts +7 -0
  57. package/dist/projects/split/finalize.d.ts.map +1 -0
  58. package/dist/projects/split/finalize.js +32 -0
  59. package/dist/projects/split/resume.d.ts +19 -0
  60. package/dist/projects/split/resume.d.ts.map +1 -0
  61. package/dist/projects/split/resume.js +107 -0
  62. package/dist/projects/split/seed-children.d.ts +9 -0
  63. package/dist/projects/split/seed-children.d.ts.map +1 -0
  64. package/dist/projects/split/seed-children.js +122 -0
  65. package/dist/projects/split/signals.d.ts +10 -0
  66. package/dist/projects/split/signals.d.ts.map +1 -0
  67. package/dist/projects/split/signals.js +18 -0
  68. package/dist/projects/split/validation.d.ts +14 -0
  69. package/dist/projects/split/validation.d.ts.map +1 -0
  70. package/dist/projects/split/validation.js +104 -0
  71. package/dist/projects/split/write-parent.d.ts +16 -0
  72. package/dist/projects/split/write-parent.d.ts.map +1 -0
  73. package/dist/projects/split/write-parent.js +176 -0
  74. package/dist/validation/project-state.d.ts +50 -0
  75. package/dist/validation/project-state.d.ts.map +1 -0
  76. package/dist/validation/project-state.js +279 -0
  77. package/package.json +2 -2
@@ -29,11 +29,28 @@ Mode-sensitive notes:
29
29
  - `reviews/*.md`: phase/final review files
30
30
  - `pr/*.md`: generated PR descriptions
31
31
  - `references/imported-plan.md`: preserved source plan for import mode
32
+ - `references/split-plan.json`: persisted split plan for a coordination parent, used as the durable resume source when `oat-project-split` is interrupted
32
33
 
33
34
  ## Contract
34
35
 
35
36
  Artifacts are the project system of record; automation and routing should derive from these files, not memory.
36
37
 
38
+ ## Coordination parents
39
+
40
+ Project splitting introduces a coordination-only parent artifact. It records shared context and child relationships, but it is not an executable lifecycle project.
41
+
42
+ A coordination parent uses:
43
+
44
+ - `oat_kind: coordination`
45
+ - `oat_phase: decomposition`
46
+ - `oat_phase_status: complete`
47
+
48
+ Coordination parents do not contain executable phase files. `spec.md`, `design.md`, `plan.md`, and `implementation.md` are removed from the parent and represented in state prose as not applicable.
49
+
50
+ The parent still keeps `state.md`, `discovery.md`, and `references/split-plan.json`. Child projects are flat siblings and link back to the parent through state metadata. Each child starts from a distilled discovery seed and must revalidate inherited context before moving beyond discovery/design.
51
+
52
+ See [Project Splitting](splitting.md) for the full parent/child model.
53
+
37
54
  ### plan.md frontmatter
38
55
 
39
56
  `plan.md` carries frontmatter that the implementation skill consumes. Notable fields:
@@ -17,12 +17,14 @@ This sub-section is the deep technical surface for how tracked OAT projects exec
17
17
 
18
18
  - Start with [Lifecycle](lifecycle.md) for the end-to-end flow.
19
19
  - Read [Artifacts](artifacts.md) once you need the file contract behind project execution.
20
+ - Use [Project Splitting](splitting.md) when one discovery or brainstorm should become coordinated child projects.
20
21
  - Use [HiLL Checkpoints](hill-checkpoints.md) when you want to understand pause/approval behavior.
21
22
 
22
23
  ## Common Tasks
23
24
 
24
25
  - Understand lifecycle order and alternate lanes in [Lifecycle](lifecycle.md).
25
26
  - Learn the artifact system of record in [Artifacts](artifacts.md).
27
+ - Split broad scopes into coordination parents and focused children in [Project Splitting](splitting.md).
26
28
  - Understand lifecycle and review transitions in [State Machine](state-machine.md).
27
29
  - Learn review and PR expectations in [Reviews](reviews.md) and [PR Flow](pr-flow.md).
28
30
 
@@ -32,6 +34,7 @@ This sub-section is the deep technical surface for how tracked OAT projects exec
32
34
  - [Design Modes](design-modes.md) - How full design balances collaborative, selective collaborative, and draft-and-review interaction.
33
35
  - [HiLL Checkpoints](hill-checkpoints.md) - Human-in-the-Loop Lifecycle configuration and approval behavior.
34
36
  - [Artifacts](artifacts.md) - What lives in `state.md`, `discovery.md`, `plan.md`, `implementation.md`, and related files.
37
+ - [Project Splitting](splitting.md) - How broad discoveries or brainstorms become coordination parents and child projects.
35
38
  - [State Machine](state-machine.md) - Lifecycle and review status transitions across a project.
36
39
  - [Reviews](reviews.md) - How review request/receive loops work inside OAT projects.
37
40
  - [PR Flow](pr-flow.md) - Progress and final PR generation expectations.
@@ -0,0 +1,79 @@
1
+ ---
2
+ title: Project Splitting
3
+ description: 'How OAT splits broad discoveries or brainstorms into a coordination parent and focused child projects.'
4
+ ---
5
+
6
+ # Project Splitting
7
+
8
+ Use project splitting when one discovery or brainstorming thread turns into several independently shippable projects that should keep shared context but execute separately.
9
+
10
+ `oat-project-split` is the handoff skill for that moment. It creates a durable coordination parent, scaffolds flat sibling child projects, seeds each child with focused discovery context, and activates the first child by dependency or value order.
11
+
12
+ ## When To Split
13
+
14
+ Split when the work has multiple deliverables that can ship independently, no single shared design surface owns all of them, separate PRs are expected, or the scope clearly spans distinct subsystems.
15
+
16
+ Do not split just because a project has many tasks. A large but coherent implementation can stay one project when it has one design surface and one release boundary.
17
+
18
+ ## Entry Paths
19
+
20
+ Splitting can start from either discovery or brainstorming:
21
+
22
+ - **Declared:** the user states multi-project intent up front. `oat-brainstorm` skips detection and hands off to `oat-project-split`.
23
+ - **Detected mid-stream:** `oat-project-discover` evaluates codified split signals during solution-space exploration and prompts when the threshold is crossed.
24
+ - **Detected at convergence:** `oat-project-discover` performs an end-of-discovery scope check, and `oat-brainstorm` can expose a split destination when the accumulated scope is large.
25
+
26
+ Declared non-interactive runs can proceed. Detected non-interactive runs record the split recommendation and fail fast rather than silently creating projects.
27
+
28
+ ## Coordination Parent
29
+
30
+ The parent becomes a coordination artifact, not an implementation project.
31
+
32
+ It stays in place under `.oat/projects/<scope>/<parent>/` with:
33
+
34
+ - `oat_kind: coordination`
35
+ - `oat_phase: decomposition`
36
+ - `oat_phase_status: complete`
37
+ - broad context, split rationale, shared constraints, child registry, and integration sketch
38
+ - `references/split-plan.json` as the durable resume source
39
+
40
+ Coordination parents do not keep executable phase artifacts. They should not contain `spec.md`, `design.md`, `plan.md`, or `implementation.md`.
41
+
42
+ ## Child Projects
43
+
44
+ Children are flat sibling projects under the same projects root. They are not nested under the parent.
45
+
46
+ Each child gets:
47
+
48
+ - parent backlink and sibling links in `state.md`
49
+ - `depends-on` metadata when ordering or dependency constraints exist
50
+ - a seeded `discovery.md` with Origin, Inherited Context, Child Scope, Known Dependencies, Assumptions To Revalidate, Likely Workflow Mode, and Sibling Projects
51
+ - `oat_inherited_context_revalidated: false` until the child revalidates inherited assumptions
52
+
53
+ Only one child is activated immediately. The rest remain parked until opened or resumed.
54
+
55
+ ## Resume And Recovery
56
+
57
+ The split plan is persisted before child writes. If a split is interrupted, resume reads `references/split-plan.json` from the coordination parent instead of reconstructing child inputs from state.
58
+
59
+ Resume requires explicit confirmation and seeds only missing child projects.
60
+
61
+ ## Listing And Dashboard Behavior
62
+
63
+ Completed coordination parents are hidden from default `oat project list` output so normal project lists stay focused on executable work.
64
+
65
+ Use:
66
+
67
+ ```bash
68
+ oat project list --include-coordination
69
+ ```
70
+
71
+ to show them. Completed coordination parents render as `decomposition (complete)` with recommendation `none`.
72
+
73
+ `oat state refresh` also groups completed coordination parents under the repo dashboard's decompositions section.
74
+
75
+ ## Related Pages
76
+
77
+ - [Lifecycle](lifecycle.md)
78
+ - [Artifacts](artifacts.md)
79
+ - [Implementation Execution](implementation-execution.md)
@@ -18,6 +18,7 @@ Use this section when you want to choose the right OAT skill for a task. If you
18
18
  - Resume an existing project: `oat-project-open` and `oat-project-progress`
19
19
  - Execute a ready plan: `oat-project-implement`
20
20
  - Import an existing plan: `oat-project-import-plan`
21
+ - Split a broad discovery or brainstorm into child projects: `oat-project-split`
21
22
  - Retroactively capture existing work: `oat-project-capture`
22
23
  - Run or receive reviews: `oat-project-review-provide`, `oat-project-review-receive`, or the non-project review variants
23
24
  - Capture a scoped, shippable backlog item: `oat-pjm-add-backlog-item` directly when the work is already scoped, or `oat-brainstorm` when the thought hasn't converged yet — the brainstorm dispatcher's "scoped backlog item" destination pre-fills the title / description / acceptance criteria / scope estimate / priority from the conversation and then runs `oat-pjm-add-backlog-item` with confirmed inputs
@@ -53,6 +54,7 @@ Use this section when you want to choose the right OAT skill for a task. If you
53
54
  - `oat-project-design`
54
55
  - `oat-project-plan`
55
56
  - `oat-project-plan-writing`
57
+ - `oat-project-split`
56
58
  - `oat-project-implement`
57
59
  - `oat-project-progress`
58
60
  - `oat-project-next`
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.1.5",
3
- "docs-config": "0.1.5",
4
- "docs-theme": "0.1.5",
5
- "docs-transforms": "0.1.5"
2
+ "cli": "0.1.6",
3
+ "docs-config": "0.1.6",
4
+ "docs-theme": "0.1.6",
5
+ "docs-transforms": "0.1.6"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-brainstorm
3
- version: 1.0.2
3
+ version: 1.0.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
@@ -29,6 +29,21 @@ Enter OAT brainstorm mode immediately when the user invokes `/oat-brainstorm` or
29
29
 
30
30
  Hard Activation runs the full Process flow below: print the mode banner (Step 2), assess visual need (Step 3), detect packs and active project (Step 4), and proceed.
31
31
 
32
+ ### Declared Multi-Project Mode
33
+
34
+ If the opening request explicitly says the scope is multiple projects, several sub-projects, an umbrella project, or otherwise declares decomposition intent, still enter brainstorm mode through Hard Activation, but switch the conversation shape immediately to umbrella framing. This is a first-class split path, not an ordinary destination guess.
35
+
36
+ Do not treat ambiguous exploratory phrasing as declared mode. Put another way: do not treat ambiguous exploratory phrasing as declared mode. Messages like "help me think through a broad thing", "what if this has multiple parts", or "this might get big" remain on the Soft Exploratory Path unless the user explicitly declares that the desired outcome is multiple projects.
37
+
38
+ In declared mode, ask this boundary question before ordinary free brainstorming:
39
+
40
+ > "Do you already know the child projects, or should we decompose the scope together?"
41
+
42
+ - If the user already knows the children, capture light parent-level context: shared context, child list, dependencies, sequencing, and integration risks.
43
+ - If the children are unknown, brainstorm the boundaries first until a child list is clear.
44
+
45
+ Once the child list is clear, invoke `oat-project-split` with a `SplitPayload` using `origin: "declared"`, `interactive: true`, `declaredChildren`, and the parent/umbrella slug when known. The brainstorm hook only frames and hands off; `oat-project-split` owns normalization, parent writing, child scaffolding, and activation.
46
+
32
47
  ### Soft Exploratory Path
33
48
 
34
49
  Do **not** print the banner, assert mode, run pack detection, or offer the visual companion on the first response. Answer normally with brainstorm-quality structure (options, tradeoffs, open questions, no premature implementation, no destination guess). Examples:
@@ -278,7 +293,21 @@ If "keep going", return to step 5. If "wrap up", surface the **pack-filtered ter
278
293
  - Gated by `PJM_INSTALLED == "true"`: `Scoped backlog item`.
279
294
  - Gated by `WORKFLOWS_INSTALLED == "true"` AND `ACTIVE_PROJECT_VALID != "true"`: `Promote to new OAT project`.
280
295
  - 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.
281
- 3. Present the filtered list to the user. Wait for selection.
296
+ 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:
297
+
298
+ ```bash
299
+ oat project split evaluate-signals --fired "<comma-list>"
300
+ ```
301
+
302
+ Use the local-development fallback only when the installed `oat` command is unavailable:
303
+
304
+ ```bash
305
+ pnpm run cli -- project split evaluate-signals --fired "<comma-list>"
306
+ ```
307
+
308
+ If the JSON result has `triggered: true`, add `Promote to N projects` to the picker. Below 2 split signals, do not show this option.
309
+
310
+ 4. Present the filtered list to the user. Wait for selection.
282
311
 
283
312
  Once a destination is identified (either path), proceed to step 7.
284
313
 
@@ -581,6 +610,16 @@ git commit -m "chore(oat): capture brainstorming reference for <project-name>"
581
610
 
582
611
  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.
583
612
 
613
+ #### 9k — Promote to N projects
614
+
615
+ This branch is available only when the step 6 picker added `Promote to N projects` after `oat project split evaluate-signals` returned `triggered: true`.
616
+
617
+ Confirm the parent/umbrella slug and the inferred child list at step 8 using the minimal confirmation pattern. If the child list is still unclear, ask one boundary question and return briefly to step 5 to decompose the scope.
618
+
619
+ When confirmed, invoke `oat-project-split` with a `SplitPayload` using `origin: "brainstorm-picker"`, `interactive: true`, `inferredChildren`, the parent/umbrella slug when known, and the brainstorm session note as inherited parent context. The brainstorm hook does not create project directories itself; `oat-project-split` owns normalization, `SplitPlanDocument` validation, coordination-parent writing, child seeding, activation, and dashboard refresh.
620
+
621
+ End mode assertion when the split handoff completes or reports its own blocker.
622
+
584
623
  ## Success Criteria
585
624
 
586
625
  - ✅ Activation Contract is honored: Hard Activation fires only on explicit brainstorm-verb phrasing or `/oat-brainstorm`; Soft Exploratory Path messages ("help me think through", "I've been thinking about", "what if we") respond conversationally without the banner and offer mode only after ≥2 sustained exploratory turns; No Activation Path messages (advisory / review / debug / PR / status / implementation / active-workflow) get a direct response with no banner and no offer.
@@ -590,9 +629,10 @@ Use only `git add -- <path>` so unrelated working-tree changes are not swept int
590
629
  - ✅ Pack and active-project detection (`oat config get tools.<pack>` and `oat config get activeProject`) runs once per session at step 4, before the conversation starts.
591
630
  - ✅ Conversation cadence holds the Superpowers contract: one question at a time, multiple-choice preferred, 2-3 distinct approaches with a recommendation, per-question visual-companion routing.
592
631
  - ✅ Destination is identified via either trigger-phrase opportunistic surfacing (loose substring + paraphrase tolerance, not regex; ambiguity → ask) or convergence cue (pack-filtered terminal-state picker).
632
+ - ✅ The terminal-state picker conditionally includes `Promote to N projects` only when `oat project split evaluate-signals` reports `triggered: true`; small-scope convergence keeps the option hidden.
593
633
  - ✅ Synthesis payload is built per the design Data Models `SynthesizedPayload` schema: `title`, `summary`, `motivation`, `vision`, `approachesConsidered[]`, `chosenDirection`, `openQuestions[]`, `nextSteps[]`, `transcriptSessionNote`.
594
634
  - ✅ 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.
595
- - ✅ Each handoff branch (9a-9j) 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.
635
+ - ✅ 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.
596
636
  - ✅ 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).
597
637
  - ✅ 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.
598
638
  - ✅ 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).
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: oat-project-discover
3
- version: 2.0.0
3
+ version: 2.0.2
4
4
  description: Use when starting a project or when requirements are still unclear. Runs structured discovery to gather requirements, constraints, and context.
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
7
- allowed-tools: Read, Write, Bash(git:*), Glob, Grep, AskUserQuestion
7
+ allowed-tools: Read, Write, Bash(git:*), Bash(oat:*), Bash(pnpm:*), Glob, Grep, AskUserQuestion
8
8
  ---
9
9
 
10
10
  # Discovery Phase
@@ -262,6 +262,59 @@ This focuses the conversation on what matters most to the user.
262
262
 
263
263
  Before converging on an approach, invest in genuine divergent exploration. Simple projects are where unexamined assumptions cause the most wasted work.
264
264
 
265
+ **Step 9 Split Detection: Evaluate Multi-Project Signals**
266
+
267
+ During solution-space exploration, silently evaluate whether the current thread is really multiple loosely related projects. Re-evaluate after each user turn while approaches are being shaped; do not interrupt normal discovery unless the threshold is met.
268
+
269
+ Track the four codified signals:
270
+
271
+ 1. `independently-shippable` — at least two deliverables can ship independently.
272
+ 2. `no-shared-design-surface` — the work lacks a single shared design surface.
273
+ 3. `expect-separate-prs` — a reviewer would reasonably expect separate PRs.
274
+ 4. `distinct-subsystems` — the work spans distinct subsystems, packages, layers, or ownership areas.
275
+
276
+ Evaluate the current comma-separated signal list through the installed CLI:
277
+
278
+ ```bash
279
+ oat project split evaluate-signals --fired "<comma-list>"
280
+ ```
281
+
282
+ Use the local-development fallback only when the installed `oat` command is unavailable:
283
+
284
+ ```bash
285
+ pnpm run cli -- project split evaluate-signals --fired "<comma-list>"
286
+ ```
287
+
288
+ Parse the JSON output:
289
+
290
+ ```json
291
+ { "fired": [], "triggered": false, "confidence": "below" }
292
+ ```
293
+
294
+ Branch on `confidence`:
295
+
296
+ - `high` — both load-bearing signals 1 and 2 fired. Use high-confidence wording and ask directly: "This looks like multiple independent projects. Split now, do one round of broad cross-cutting discovery first, or keep this as one project?"
297
+ - `soft` — at least two signals fired, but not both load-bearing signals. Use soft wording: "This may be multiple projects. Split, do one round of broad cross-cutting discovery first, or keep it as one project?"
298
+ - `below` — Below 2 signals, do not surface a split offer.
299
+
300
+ If the user confirms split, invoke the `oat-project-split` skill with a `SplitPayload` using `origin: "detected-mid-stream"`, `interactive: true`, the active discovery path as `priorDiscovery.path`, and any inferred children already named in the conversation. The discover hook only detects and hands off; it does not scaffold children or write the coordination parent itself.
301
+
302
+ **Non-interactive branch:** if `OAT_NON_INTERACTIVE=1` and detection triggers (`confidence` is `high` or `soft`), do not show an offer prompt and do not silently choose. Append this section to `"$PROJECT_PATH/discovery.md"` and exit non-zero:
303
+
304
+ ```markdown
305
+ ## Detected Split Recommendation
306
+
307
+ Discovery detected multi-project scope via `oat project split evaluate-signals`.
308
+
309
+ - Fired signals: <comma-list>
310
+ - Confidence: <high|soft>
311
+ - Recommendation: rerun discovery interactively and choose whether to invoke `oat-project-split`.
312
+ ```
313
+
314
+ ```bash
315
+ exit 1
316
+ ```
317
+
265
318
  **Step 9a: Propose Approaches**
266
319
 
267
320
  Propose 2-3 **genuinely distinct** approaches (not minor variations). For each:
@@ -313,6 +366,19 @@ Update discovery.md sections:
313
366
 
314
367
  ### Step 11: Human-in-the-Loop Lifecycle (HiLL) Gate (If Configured)
315
368
 
369
+ Before the HiLL gate or discovery completion, run the same split signal evaluation one final time.
370
+
371
+ **Non-interactive convergence branch:** if `OAT_NON_INTERACTIVE=1`, do not show the scope-check prompt and do not silently choose. Parse the final `oat project split evaluate-signals --fired "<comma-list>"` result:
372
+
373
+ - `high` or `soft` — append the same section to `"$PROJECT_PATH/discovery.md"` as the Step 9 non-interactive branch, using the final fired signal list and confidence, then exit non-zero.
374
+ - `below` — proceed as one cohesive project without prompting.
375
+
376
+ For interactive runs, show an always-visible scope-check confirmation. The prompt is required even when no mid-stream offer fired:
377
+
378
+ > "This reads as one cohesive project — proceed, or split into multiple?"
379
+
380
+ Pre-fill the recommendation from `oat project split evaluate-signals --fired "<comma-list>"`: recommend splitting for `high`, suggest considering a split for `soft`, and recommend proceeding as one cohesive project for `below`. If the user chooses split at this convergence point, invoke `oat-project-split` with `origin: "detected-convergence"` and `interactive: true`.
381
+
316
382
  Read `"$PROJECT_PATH/state.md"` frontmatter:
317
383
 
318
384
  - `oat_hill_checkpoints`
@@ -342,13 +408,11 @@ If discovery is not configured as a HiLL checkpoint, or user explicitly approves
342
408
 
343
409
  ### Step 12: Mark Discovery Complete
344
410
 
345
- Update frontmatter:
411
+ Use the CLI completion boundary so split-created child discoveries cannot
412
+ complete until inherited context has been revalidated:
346
413
 
347
- ```yaml
348
- ---
349
- oat_status: complete
350
- oat_ready_for: oat-project-design
351
- ---
414
+ ```bash
415
+ oat project complete-discovery "$PROJECT_PATH" --ready-for oat-project-design
352
416
  ```
353
417
 
354
418
  ### Step 13: Update Project State
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-quick-start
3
- version: 2.1.0
3
+ version: 2.1.1
4
4
  description: Use when a task is small enough for quick mode or rapid iteration is preferred. Scaffolds a lightweight OAT project from discovery directly to a runnable plan, with optional brainstorming and lightweight design.
5
5
  argument-hint: '<project-name> ["project description"]'
6
6
  disable-model-invocation: true
@@ -211,10 +211,12 @@ Use `AskUserQuestion` to present this choice.
211
211
 
212
212
  **If user chooses "Promote to spec-driven":**
213
213
 
214
- - Update `discovery.md` frontmatter:
215
- - `oat_status: complete`
216
- - `oat_ready_for: oat-project-design`
217
- - `oat_last_updated: {today}`
214
+ - Complete discovery through the CLI validation boundary:
215
+
216
+ ```bash
217
+ oat project complete-discovery "$PROJECT_PATH" --ready-for oat-project-design
218
+ ```
219
+
218
220
  - Update `state.md`:
219
221
  - `oat_workflow_mode: spec-driven`
220
222
  - `oat_phase: discovery`
@@ -287,6 +289,13 @@ fi
287
289
  # Route the user accordingly. Do NOT loop back into the gate.
288
290
  ```
289
291
 
292
+ Before continuing to Step 3, complete discovery through the CLI validation
293
+ boundary:
294
+
295
+ ```bash
296
+ oat project complete-discovery "$PROJECT_PATH" --ready-for oat-project-quick-start
297
+ ```
298
+
290
299
  ### Step 2.75a: Lightweight Design Mode Choice
291
300
 
292
301
  Resolve the interaction mode before drafting. Same mechanics as the full `oat-project-design` skill (Component 1): argument precedes env var, config fallback, **explicit** non-interactive fallback to draft.
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: oat-project-split
3
+ version: 1.0.0
4
+ description: Use when a discovery or brainstorm should split one broad scope into coordinated OAT child projects.
5
+ argument-hint: '--plan-file <path>'
6
+ disable-model-invocation: true
7
+ user-invocable: true
8
+ allowed-tools: Read, Write, Bash(oat:*), Bash(pnpm:*), Glob, Grep, AskUserQuestion
9
+ ---
10
+
11
+ # Split OAT Project
12
+
13
+ Decompose a confirmed multi-project discovery or brainstorm into a coordination-only parent and flat child projects.
14
+
15
+ ## Mode Assertion
16
+
17
+ Use this skill only after one of these split triggers is present:
18
+
19
+ - The user explicitly declared the work is multiple projects.
20
+ - Discovery signals crossed the split threshold and the user confirmed.
21
+ - End-of-discovery convergence confirmed that the scope should split.
22
+ - The brainstorm destination picker selected a split into projects.
23
+
24
+ Detected split recommendations in non-interactive mode must fail fast through the CLI run command; do not silently split or silently continue as one project.
25
+
26
+ ## Progress Indicators (User-Facing)
27
+
28
+ Print a banner once at start:
29
+
30
+ ```text
31
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
+ OAT ▸ PROJECT SPLIT
33
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
34
+ ```
35
+
36
+ Before multi-step work, print step indicators:
37
+
38
+ - `[1/5] Writing coordination parent...`
39
+ - `[2/5] Scaffolding and seeding children...`
40
+ - `[3/5] Marking parent terminal...`
41
+ - `[4/5] Selecting active child...`
42
+ - `[5/5] Refreshing dashboard...`
43
+
44
+ ## Process
45
+
46
+ ### Step 1: Resolve Split Plan
47
+
48
+ Require a persisted `SplitPlanDocument` JSON file. If `$ARGUMENTS` does not include `--plan-file <path>`, ask for the plan file path before proceeding.
49
+
50
+ ### Step 2: Run Split Orchestrator
51
+
52
+ Invoke the CLI as the single execution entry point:
53
+
54
+ ```bash
55
+ oat project split run --plan-file "{plan-file}"
56
+ ```
57
+
58
+ Use `--non-interactive` only when the caller is running without a human confirmation path.
59
+
60
+ ### Step 3: Write Coordination Parent
61
+
62
+ The run command writes the parent project as `oat_kind: coordination`, persists `references/split-plan.json`, records ordered children in `state.md`, writes the broad `discovery.md` with any integration sketch, and removes executable phase files.
63
+
64
+ ### Step 4: Scaffold + Seed Children
65
+
66
+ The run command scaffolds each child in plan order and writes split-specific child discovery content from scratch with the required inherited-context revalidation gate.
67
+
68
+ ### Step 5: Mark Parent Terminal + Select Active Child
69
+
70
+ The run command marks the parent `oat_phase: decomposition` and `oat_phase_status: complete`, then activates the initial child using the repo-relative project path.
71
+
72
+ ### Step 6: Resume From Partial State
73
+
74
+ If a previous split wrote a coordination parent but did not finish all children, the run command resumes from `references/split-plan.json`. Do not reconstruct missing child seed data from slugs alone.
75
+
76
+ ## Success Criteria
77
+
78
+ - Coordination parent exists and has no `spec.md`, `design.md`, `plan.md`, or `implementation.md`.
79
+ - Parent `state.md` records `oat_kind: coordination`, ordered `oat_children`, and terminal decomposition status.
80
+ - `references/split-plan.json` contains the full `SplitPlanDocument`.
81
+ - Every child has seeded discovery content, parent/sibling/dependency links, and `oat_inherited_context_revalidated: false`.
82
+ - `.oat/config.local.json.activeProject` points at the repo-relative initial child path.
@@ -3,10 +3,15 @@ oat_current_task: null
3
3
  oat_last_commit: null
4
4
  oat_blockers: []
5
5
  associated_issues: [] # [{type: backlog|project|jira|linear, ref: "identifier"}]
6
+ oat_kind: implementation # implementation | coordination; coordination parents may use oat_phase: decomposition
7
+ oat_parent: null # optional child-only coordination parent slug
8
+ oat_siblings: [] # optional child-only sibling slugs
9
+ oat_depends_on: [] # optional child-only sibling dependencies
10
+ oat_children: [] # optional coordination-parent child slugs
6
11
  oat_hill_checkpoints: { OAT_HILL_CHECKPOINTS } # Configured: which phases require human-in-the-loop lifecycle approval
7
12
  oat_hill_completed: [] # Progress: which HiLL checkpoints have been completed
8
13
  oat_parallel_execution: false
9
- oat_phase: { OAT_PHASE } # Current phase: discovery | spec | design | plan | implement
14
+ oat_phase: { OAT_PHASE } # Current phase: discovery | spec | design | plan | implement | decomposition
10
15
  oat_phase_status: in_progress # Status: in_progress | complete | pr_open
11
16
  # oat_orchestration_retry_limit: 2 # optional; override fix-loop retry limit (range 0-5)
12
17
  oat_workflow_mode: { OAT_WORKFLOW_MODE } # spec-driven | quick | import
@@ -0,0 +1,50 @@
1
+ import { type SplitChildInput, type SplitPayload, type SplitPlanDocument } from '../../projects/split/child-plan.js';
2
+ import { type Signal } from '../../projects/split/signals.js';
3
+ export type TranscriptSpeaker = 'assistant' | 'user';
4
+ export interface TranscriptTurn {
5
+ speaker: TranscriptSpeaker;
6
+ text: string;
7
+ }
8
+ export type StubbedUserChoice = 'broad-first' | 'children-known' | 'decompose-children' | 'inline-only' | 'keep-one-project' | 'promote-n-projects' | 'split-now';
9
+ export interface StubbedQuestion {
10
+ id: string;
11
+ prompt: string;
12
+ options: string[];
13
+ response: StubbedUserChoice;
14
+ }
15
+ export interface TranscriptFixture {
16
+ transcript: TranscriptTurn[];
17
+ parentSlug: string;
18
+ children: SplitChildInput[];
19
+ discoveryPath?: string;
20
+ inheritedContext?: string;
21
+ integrationSketch?: string;
22
+ }
23
+ export declare const SPLIT_HANDOFF_TARGET: {
24
+ readonly skill: "oat-project-split";
25
+ readonly hookCreatesProjects: false;
26
+ readonly responsibilities: readonly ["normalize-split-plan", "write-coordination-parent", "scaffold-children", "activate-initial-child"];
27
+ };
28
+ export declare function inferSplitSignals(transcript: TranscriptTurn[]): Signal[];
29
+ export declare function runDiscoverDetectionFixture(fixture: TranscriptFixture, responses: Record<string, StubbedUserChoice>): {
30
+ asked: StubbedQuestion[];
31
+ confidence: 'below' | 'high' | 'soft';
32
+ decision?: StubbedUserChoice;
33
+ document?: SplitPlanDocument;
34
+ payload?: SplitPayload;
35
+ triggered: boolean;
36
+ };
37
+ export declare function runDeclaredBrainstormFixture(fixture: TranscriptFixture, responses: Record<string, StubbedUserChoice>): {
38
+ asked: StubbedQuestion[];
39
+ document?: SplitPlanDocument;
40
+ handoffTarget: typeof SPLIT_HANDOFF_TARGET;
41
+ payload?: SplitPayload;
42
+ };
43
+ export declare function runBrainstormPickerFixture(fixture: TranscriptFixture, responses: Record<string, StubbedUserChoice>): {
44
+ asked: StubbedQuestion[];
45
+ document?: SplitPlanDocument;
46
+ handoffTarget: typeof SPLIT_HANDOFF_TARGET;
47
+ options: string[];
48
+ payload?: SplitPayload;
49
+ };
50
+ //# sourceMappingURL=split-flow-fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split-flow-fixtures.d.ts","sourceRoot":"","sources":["../../../src/__tests__/skills/split-flow-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAE5E,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,gBAAgB,GAChB,oBAAoB,GACpB,aAAa,GACb,kBAAkB,GAClB,oBAAoB,GACpB,WAAW,CAAC;AAEhB,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,oBAAoB;;;;CASvB,CAAC;AAsBX,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CA+BxE;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC3C;IACD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACpB,CAqDA;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC3C;IACD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,aAAa,EAAE,OAAO,oBAAoB,CAAC;IAC3C,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB,CAmCA;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC3C;IACD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,aAAa,EAAE,OAAO,oBAAoB,CAAC;IAC3C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB,CA4CA"}