Skip to content

feat(loops): the Program op-set + runProgram tree executor (worker- AND loop-layer parallelism) - #141

Merged
tangletools merged 2 commits into
mainfrom
feat/program-opset
Jun 3, 2026
Merged

feat(loops): the Program op-set + runProgram tree executor (worker- AND loop-layer parallelism)#141
tangletools merged 2 commits into
mainfrom
feat/program-opset

Conversation

@tangletools

@tangletools tangletools commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Lands the Program model from architecture.md §1 AND the recursive runProgram executor — the runtime now expresses parallelism at both layers the architecture describes.

Worker layer (one loop, one fanout round)

fork{branches: Task[]} / sample{n} → N concurrent worker attempts in a single runLoop, round-robined across agentRuns (heterogeneous). compileProgram(program) → TopologyPlanner executes a straight-line program over the existing per-round kernel (free history threading across seq).

Loop layer (concurrent sub-loops / dynamic workflows)

parallel{branches: Program[]} → N concurrent sub-loops, each its own multi-round runLoop; a branch may itself be a seq/fork/parallel tree. runProgram(program, opts) runs the largest straight-line subtree as one loop (preserving threading) and forks into concurrent loops only at a parallel node — merging iterations (re-indexed), cost, and tokens, selecting a global winner with the kernel's own defaultSelectWinner (single-sourced). runAgent drives the recursive Agent atom over the tree.

Honest seams (encoded + fail-loud)

  • compileProgram throws on parallel (a per-round move queue can't express a sub-loop).
  • a select after a parallel boundary throws (cross-branch selection is the merge's job).
  • per-branch adaptive re-planning (a branch that re-emits its own program each round) is the next generalization; today a branch is a fixed sub-program.

Verification

  • 599/599 package tests, tsc + biome clean (171 files).
  • A tracking sandbox client asserts maxActive === 2proving the sub-loops actually overlap, not just that the merge picks the right winner. Plus merge re-indexing, the seq-of-fanout-then-parallel workflow, the maxParallel bound, and both fail-loud cases.
  • Concurrency review: mapPool index/firstError mutations span no await (atomic); a failing branch stops new scheduling but drains in-flight sub-loops and aborts siblings via the shared ctx.signal (mirrors the kernel's runBatch); winner index correct by construction.

drewstone added 2 commits June 3, 2026 11:35
…le topology language

architecture.md §1 describes an Agent atom whose act() emits a Program over
{sample, steer, fork, select, seq, stop}; the runtime shipped only the flat one-move-
per-round TopologyMove. This lands the Program as a real, composable, emittable artifact.

- Program<Task> ADT (sample/steer/fork/select/seq/stop), seq + fork compose.
- compileProgram(program) → TopologyPlanner: executes a composable program over the
  EXISTING runLoop kernel (seq runs steps across rounds; fork/sample → a parallel
  fanout round; select declares the winner; short-circuits on the first valid attempt).
- agentProgramPlanner(agent) — the recursive-atom bridge: act() emits a Program, the
  kernel executes it.
- flattenProgram fails loud on empty fork/seq and a non-positive sample n.

Honest limit (encoded + documented): fork branches are LEAF tasks, so parallelism is
at the WORKER layer (N concurrent worker attempts per round, heterogeneous across
agentRuns). Parallel SUB-LOOPS / sub-agents (a fork branch that is itself a multi-round
program — the doc's "loop whose step contains a loop") need a tree-walking executor —
the next increment.

tsc + biome clean; tests/loops/program.test.ts (flattenProgram unit + 4 kernel
integration cases); 36/36 loops tests.
…lelism + dynamic workflows)

The Program op-set landed worker-layer parallelism (fork/sample → N concurrent
attempts in one fanout round of a single loop). This adds the LOOP layer: a new
parallel{branches: Program[]} op + a recursive executor that runs concurrent
SUB-LOOPS, so an agent can drive multiple loops / a dynamic workflow tree, not just
a per-round move queue.

- parallel{branches: Program[]}: N concurrent sub-loops, each its own multi-round
  runLoop; a branch may itself be a seq/fork/parallel tree.
- runProgram(program, opts): runs the largest STRAIGHT-LINE subtree as ONE runLoop
  (keeping the kernel's free history threading across seq rounds) and forks into
  concurrent runLoops only at a parallel node — merging iterations (re-indexed),
  cost, and tokens, then selecting a global winner with the kernel's OWN selector.
- runAgent(agent, rootTask, opts): drives the recursive Agent atom over the tree
  executor (act() emits the program, runProgram executes the tree).
- isStraightLine / ProgramResult / RunProgramOptions exported; maxParallel bounds the
  concurrent-branch count (caps multiplicative sandbox load).
- defaultSelectWinner exported from run-loop so merge-point selection is single-sourced,
  not a forked copy of the kernel's argmax.

Honest seams (encoded + documented, fail-loud): compileProgram FAILS LOUD on parallel
(a per-round move queue can't express a sub-loop); a select placed after a parallel
boundary FAILS LOUD (cross-branch selection is the merge's job). Per-branch ADAPTIVE
re-planning (a branch that re-emits its own program from its own context each round)
is the next generalization; today a branch is a fixed sub-program.

Concurrency review: mapPool index/firstError mutations span no await (atomic); a
failing branch stops new scheduling but drains in-flight sub-loops and aborts siblings
via the shared ctx.signal (mirrors the kernel's runBatch); winner index is correct by
construction (recomputed over the merged set, never remapped).

Tests: a tracking sandbox client asserts maxActive===2 — PROVING branches overlap, not
just that the merge picks the right winner; merge re-indexing, the seq-of-fanout-then-
parallel workflow, maxParallel bound, and both fail-loud cases. 599/599 package tests,
tsc + biome clean.

@drewstone drewstone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved tangletools PR — fc5f1243

This PR was opened by the trusted tangletools automation account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: tangletools_author · 2026-06-03T17:50:33Z

@tangletools tangletools changed the title feat(loops): the Program op-set — the recursive Agent atom's composable topology language feat(loops): the Program op-set + runProgram tree executor (worker- AND loop-layer parallelism) Jun 3, 2026
@tangletools
tangletools merged commit 490360a into main Jun 3, 2026
1 check passed
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