Skip to content

Claude/implement ai native spawning go wal#31

Merged
minhlucvan merged 6 commits into
mainfrom
claude/implement-ai-native-spawning-GoWAL
May 20, 2026
Merged

Claude/implement ai native spawning go wal#31
minhlucvan merged 6 commits into
mainfrom
claude/implement-ai-native-spawning-GoWAL

Conversation

@minhlucvan

Copy link
Copy Markdown
Contributor

Summary

Related Issues

Type

  • Bug fix
  • Feature
  • Documentation
  • Refactor

Testing Done

Checklist

  • Tests pass (pnpm test)
  • Documentation updated (if applicable)
  • No breaking changes (or documented in summary)

claude added 6 commits May 20, 2026 14:35
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>
@minhlucvan minhlucvan merged commit 14fd2f5 into main May 20, 2026
3 of 7 checks passed
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants