Claude/implement ai native spawning go wal#31
Merged
Conversation
Spawner bodies now invoke pre-authored templates by writing
`<id>/spawn.yml` files (three fields: template, depends_on, params)
instead of hand-authoring JSONL manifests. The framework discovers
the invocations, validates params against the template's PARAMS.yml,
expands `{{paramName}}` placeholders, and either applies the resulting
SpawnRows via the existing RFC 0021 engine or rejects the whole batch
with a STATUS.md the AI reads to repair.
New modules under `packages/core/src/task/spawn/`:
- templates.ts — registry loader; PARAMS.yml schema, EXAMPLES.yml,
fallback inference from `{{...}}` references.
- discover.ts — single-level scan of the spawn cwd; skips `_`-prefix
scratch; surfaces YAML / shape errors as per-file evidence.
- expand.ts — template resolution, param validation (required /
defaults / unknown / type-mismatch), Levenshtein "did you mean"
hints, mustache interpolation.
- strays.ts — anti-goal locks: SPAWN_TASKMD_AUTHORED_BY_BODY and
SPAWN_MANIFEST_AUTHORED_BY_BODY.
- status.ts — the single AI-facing transparency surface. One
markdown row per child, `[x]`/`[ ]`, with `fix:` blocks on failures.
- ingest.ts — orchestrator. Preview-then-apply: no journal mutation
until every invocation expands cleanly; on failure the AI repairs
STATUS.md `[ ]` rows and re-runs. Writes EXPANDED.md adjacency for
every ok child.
`run-spawner.ts` wires the new path: if the body produced any
`<id>/spawn.yml` files under `<execDir>/spawn/`, the new ingest
pipeline runs; otherwise the legacy `spawn.plan.jsonl` applier still
fires, so unmigrated example spawners keep working. Pre-body the spawn
dir is created and exposed as `CONVERGE_SPAWN_DIR`.
Tests cover the full RFC 0024 test plan (templates, discovery,
expansion, strays, status rendering, end-to-end ingest atomicity,
idempotency, repair loop) plus integration tests for the three
patterns the RFC calls out: reasoning-driven, data-driven, nested.
Zero new regressions in the 1171-test core suite.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the JSONL-manifest narrative with the new four-step loop: discover templates, write `<id>/spawn.yml`, read STATUS.md, repair. Update the dynamic-container pattern section, the spawner mode table row, the spawner checklist, and the CLI table (apply / spawn become framework-internal verbs). All references to body-authored spawn.plan.jsonl are gone — the AI's vocabulary now stops at template + depends_on + params. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small bugs in the mode pipeline that surfaced once legacy
fixtures ran through the typed validator:
1. `inferMode` classified `passthrough + body has "converge spawn"` as
`spawner`. When the same task also declared a `converge:` block
(legacy `{cmd, prompt}` shape OR RFC 0022), the body really is a
wave loop, not a one-shot fan-out. `resolveTaskMode` now reclassifies
to `converger` whenever a converge block is present alongside the
inferred spawner — the wave loop is the dominant primitive.
2. `run-executor` always dispatched `mode: converger` to `run-converger`,
which then bailed with `mode: converger declared without converge:
config` whenever the task used the legacy `{cmd, prompt}` shape (no
RFC 0022 fields like `max_waves` / `halt_when` / `wave_check`). The
dispatcher now routes to `run-converger` only when `modeConverge` is
populated; otherwise it falls through to the standard chain so the
repair strategy can execute the passthrough body.
3. `validateSpawner` required `spawn.plan.jsonl` even when the body
produced RFC 0024 `<id>/spawn.yml` invocations or imperatively
spawned children via the `converge spawn` CLI (childCount > 0). The
validator now accepts any of the three surfaces as valid evidence
that the mode contract was met; the fix-hint mentions both authoring
paths.
Net effect: legacy converger fixtures (`test-incremental-seeding`'s
nested-loop, etc.) once again run end-to-end, and the typed spawner
validator stops blocking RFC 0024 bodies that haven't (yet) been
migrated off the implicit `converge:` pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- `tests/codex-real.test.ts`: zod was imported at the top level but
isn't a root devDependency, so the import-time crash bypassed the
`describeReal` skip-gate. Lazy-import zod inside the test that uses
it; the binary-not-found check still short-circuits the suite.
- `tests/test-incremental-seeding/run-test.sh`: the CLI path was
hardcoded to a user-specific absolute path. Resolve relative to
the repo root so the fixture is portable.
- `tests/incremental-seeding-runtime.test.ts`: bump the test timeout
to 120s — the nested-loop case alone takes ~30s.
- `tests/playbook-seeds.test.ts`: the queue-pattern fixture migrated
from `seed: { mode: cli }` to RFC 0022 `mode: converger` +
`halt_when:`; update the assertions to match.
- `packages/cli/tests/init-command.test.ts`: the YAML dumper now
emits double-quoted scalars for URL/env values; assert on
regex-tolerant field patterns instead of literal `key: value`
strings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sweep every doc and skill mentioning `spawn.plan.jsonl` / `converge spawn` and update them to the new authoring surface: `<id>/spawn.yml` invocation files under `$CONVERGE_SPAWN_DIR`, with templates owning the contract (TASK.md + PARAMS.yml + EXAMPLES.yml) and STATUS.md as the single AI-facing transparency surface. Touches: - `skills/converge-planning/SKILL.md` + every reference file (task-modes.md, schema.md, phases.md, patterns.md, model.md, anti-patterns.md, tests.md, skills.md) — all spawner narrative rewritten for RFC 0024. - `skills/converge-control/SKILL.md` + reference/events.md + troubleshooting/playbook.md — exec-dir file map, FRONTIER_UNRESOLVED diagnosis, spawner-apply-failed recipe. - `skills/converge-development/SKILL.md` + reference/framework-map.md + reference/observability.md — framework module pointers (new files under `packages/core/src/task/spawn/`) and on-disk schema for the spawn/ subtree. - `.codex/skills/converge-planning/` and `.claude/skills/` — agent- specific skill copies synced/updated. - `docs/GLOSSARY.md` — canonical names: `ingestSpawnDir`, `loadTemplates`, `discoverInvocations`, `expandInvocation`, `writeStatusMarkdown`, `detectStrayManifests`, `detectStrayTaskMd`, plus `CONVERGE_SPAWN_DIR` env var, exec-dir schema, RFC 0024 row. - `docs/reference/task-md.md` — mode table + `mode: spawner` example. - `docs/concepts/convergence.md` — diverge → execute → converge narrative; mermaid diagram updated. - `docs/concepts/dynamic-work-breakdown.md` — "One surface", manifest schema → invocation schema, fail-fix-pass loop, trade-offs, codebase pointers. - `docs/concepts/playbook.md` — dynamic fan-out line. - `docs/guides/build-a-software-project.md` and `docs/guides/generate-something-repeatedly.md` — worked examples rewritten with the new heredoc pattern. - `docs/troubleshooting/README.md` — dynamic-task contract. Legacy `spawn.plan.jsonl` references are kept as "framework-internal" markers where the legacy ingest still fires (unmigrated examples). No behaviour change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ative-spawning-GoWAL
minhlucvan
added a commit
that referenced
this pull request
May 22, 2026
* feat(core): RFC 0024 spawn invocation surface — preview→apply pipeline
Spawner bodies now invoke pre-authored templates by writing
`<id>/spawn.yml` files (three fields: template, depends_on, params)
instead of hand-authoring JSONL manifests. The framework discovers
the invocations, validates params against the template's PARAMS.yml,
expands `{{paramName}}` placeholders, and either applies the resulting
SpawnRows via the existing RFC 0021 engine or rejects the whole batch
with a STATUS.md the AI reads to repair.
New modules under `packages/core/src/task/spawn/`:
- templates.ts — registry loader; PARAMS.yml schema, EXAMPLES.yml,
fallback inference from `{{...}}` references.
- discover.ts — single-level scan of the spawn cwd; skips `_`-prefix
scratch; surfaces YAML / shape errors as per-file evidence.
- expand.ts — template resolution, param validation (required /
defaults / unknown / type-mismatch), Levenshtein "did you mean"
hints, mustache interpolation.
- strays.ts — anti-goal locks: SPAWN_TASKMD_AUTHORED_BY_BODY and
SPAWN_MANIFEST_AUTHORED_BY_BODY.
- status.ts — the single AI-facing transparency surface. One
markdown row per child, `[x]`/`[ ]`, with `fix:` blocks on failures.
- ingest.ts — orchestrator. Preview-then-apply: no journal mutation
until every invocation expands cleanly; on failure the AI repairs
STATUS.md `[ ]` rows and re-runs. Writes EXPANDED.md adjacency for
every ok child.
`run-spawner.ts` wires the new path: if the body produced any
`<id>/spawn.yml` files under `<execDir>/spawn/`, the new ingest
pipeline runs; otherwise the legacy `spawn.plan.jsonl` applier still
fires, so unmigrated example spawners keep working. Pre-body the spawn
dir is created and exposed as `CONVERGE_SPAWN_DIR`.
Tests cover the full RFC 0024 test plan (templates, discovery,
expansion, strays, status rendering, end-to-end ingest atomicity,
idempotency, repair loop) plus integration tests for the three
patterns the RFC calls out: reasoning-driven, data-driven, nested.
Zero new regressions in the 1171-test core suite.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(skills): teach the RFC 0024 spawn surface in converge-planning
Replace the JSONL-manifest narrative with the new four-step loop:
discover templates, write `<id>/spawn.yml`, read STATUS.md, repair.
Update the dynamic-container pattern section, the spawner mode table
row, the spawner checklist, and the CLI table (apply / spawn become
framework-internal verbs). All references to body-authored
spawn.plan.jsonl are gone — the AI's vocabulary now stops at template
+ depends_on + params.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(core): make mode dispatch honour RFC 0024 and legacy converger flows
Three small bugs in the mode pipeline that surfaced once legacy
fixtures ran through the typed validator:
1. `inferMode` classified `passthrough + body has "converge spawn"` as
`spawner`. When the same task also declared a `converge:` block
(legacy `{cmd, prompt}` shape OR RFC 0022), the body really is a
wave loop, not a one-shot fan-out. `resolveTaskMode` now reclassifies
to `converger` whenever a converge block is present alongside the
inferred spawner — the wave loop is the dominant primitive.
2. `run-executor` always dispatched `mode: converger` to `run-converger`,
which then bailed with `mode: converger declared without converge:
config` whenever the task used the legacy `{cmd, prompt}` shape (no
RFC 0022 fields like `max_waves` / `halt_when` / `wave_check`). The
dispatcher now routes to `run-converger` only when `modeConverge` is
populated; otherwise it falls through to the standard chain so the
repair strategy can execute the passthrough body.
3. `validateSpawner` required `spawn.plan.jsonl` even when the body
produced RFC 0024 `<id>/spawn.yml` invocations or imperatively
spawned children via the `converge spawn` CLI (childCount > 0). The
validator now accepts any of the three surfaces as valid evidence
that the mode contract was met; the fix-hint mentions both authoring
paths.
Net effect: legacy converger fixtures (`test-incremental-seeding`'s
nested-loop, etc.) once again run end-to-end, and the typed spawner
validator stops blocking RFC 0024 bodies that haven't (yet) been
migrated off the implicit `converge:` pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test: heal pre-existing failures in test:all sweep
- `tests/codex-real.test.ts`: zod was imported at the top level but
isn't a root devDependency, so the import-time crash bypassed the
`describeReal` skip-gate. Lazy-import zod inside the test that uses
it; the binary-not-found check still short-circuits the suite.
- `tests/test-incremental-seeding/run-test.sh`: the CLI path was
hardcoded to a user-specific absolute path. Resolve relative to
the repo root so the fixture is portable.
- `tests/incremental-seeding-runtime.test.ts`: bump the test timeout
to 120s — the nested-loop case alone takes ~30s.
- `tests/playbook-seeds.test.ts`: the queue-pattern fixture migrated
from `seed: { mode: cli }` to RFC 0022 `mode: converger` +
`halt_when:`; update the assertions to match.
- `packages/cli/tests/init-command.test.ts`: the YAML dumper now
emits double-quoted scalars for URL/env values; assert on
regex-tolerant field patterns instead of literal `key: value`
strings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: teach the RFC 0024 spawn surface across skills and docs
Sweep every doc and skill mentioning `spawn.plan.jsonl` /
`converge spawn` and update them to the new authoring surface:
`<id>/spawn.yml` invocation files under `$CONVERGE_SPAWN_DIR`, with
templates owning the contract (TASK.md + PARAMS.yml + EXAMPLES.yml)
and STATUS.md as the single AI-facing transparency surface.
Touches:
- `skills/converge-planning/SKILL.md` + every reference file
(task-modes.md, schema.md, phases.md, patterns.md, model.md,
anti-patterns.md, tests.md, skills.md) — all spawner narrative
rewritten for RFC 0024.
- `skills/converge-control/SKILL.md` + reference/events.md +
troubleshooting/playbook.md — exec-dir file map, FRONTIER_UNRESOLVED
diagnosis, spawner-apply-failed recipe.
- `skills/converge-development/SKILL.md` + reference/framework-map.md +
reference/observability.md — framework module pointers (new files
under `packages/core/src/task/spawn/`) and on-disk schema for the
spawn/ subtree.
- `.codex/skills/converge-planning/` and `.claude/skills/` — agent-
specific skill copies synced/updated.
- `docs/GLOSSARY.md` — canonical names: `ingestSpawnDir`,
`loadTemplates`, `discoverInvocations`, `expandInvocation`,
`writeStatusMarkdown`, `detectStrayManifests`, `detectStrayTaskMd`,
plus `CONVERGE_SPAWN_DIR` env var, exec-dir schema, RFC 0024 row.
- `docs/reference/task-md.md` — mode table + `mode: spawner` example.
- `docs/concepts/convergence.md` — diverge → execute → converge
narrative; mermaid diagram updated.
- `docs/concepts/dynamic-work-breakdown.md` — "One surface", manifest
schema → invocation schema, fail-fix-pass loop, trade-offs,
codebase pointers.
- `docs/concepts/playbook.md` — dynamic fan-out line.
- `docs/guides/build-a-software-project.md` and
`docs/guides/generate-something-repeatedly.md` — worked examples
rewritten with the new heredoc pattern.
- `docs/troubleshooting/README.md` — dynamic-task contract.
Legacy `spawn.plan.jsonl` references are kept as "framework-internal"
markers where the legacy ingest still fires (unmigrated examples).
No behaviour change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Related Issues
Type
Testing Done
Checklist
pnpm test)