docs: publish foreach back-edge semantics

This commit is contained in:
lda
2026-09-04 08:13:24 +07:00 Verified
parent 7a5635b1a2
commit 8a550f7c69
4 changed files with 26 additions and 12 deletions
+5 -6
View File
@@ -795,12 +795,6 @@ stable.
- Native subgraph polish: optional per-use-site child deployment overrides and
clearer child trace inspection.
- Active concurrent foreach correction: replace item-body `END` routes with
canonical back-edges to the owning foreach. The approved semantics are in the
[`foreach back-edge design`](superpowers/specs/2026-09-04-foreach-back-edge-design.md).
This slice also makes foreach control regions fail-closed, rejects unreachable
workflow nodes, and gives repeated visits to one foreach node distinct
persisted activation identities.
- After that correction, reuse the foreach barrier/lineage machinery for
fork/gather. The proposed control semantics are recorded in
[`ADR-0006`](adr/0006-explicit-fork-and-topology-driven-gather.md).
@@ -942,6 +936,11 @@ stable.
routes, or outputs. Python, JSON-RPC, MCP, and local/remote CLI surfaces are
aligned. Implementation plan:
[`capability step updates`](historical/superpowers/plans/2026-07-26-capability-step-update.md).
- Completed: foreach bodies now return through validated back-edges to their
immediate owner, with unique static control regions and fresh persisted
activation identities for every dynamic visit. Design:
[`foreach back-edge design`](superpowers/specs/2026-09-04-foreach-back-edge-design.md).
Fork/gather remains explicitly deferred.
Agent evaluation cohort status and policy:
@@ -2,9 +2,9 @@
## Status
Approved in conversation on 2026-09-04. This document specifies canonical
foreach body-return semantics. It does not include the separately planned
ergonomic Python DSL or authorize fork/gather implementation.
Implemented on 2026-09-04. This document specifies canonical foreach
body-return semantics. It does not include the separately planned ergonomic
Python DSL or authorize fork/gather implementation.
## Purpose
+11
View File
@@ -228,6 +228,17 @@ step with item-local child lineages:
In async execution, admitted async item node handlers may run at the same time.
Run-state mutation, tracing, and barrier commits remain deterministic.
An iteration body returns through its immediate owning foreach:
```python
g.connect(each, "loop", record)
g.connect(record, "ok", each)
g.connect(each, "done", END)
```
Region conflicts, unreachable nodes, body terminals, non-local returns, empty
bodies, and bodies without possible returns fail validation.
See `examples/authoring_concurrent_foreach.py` for a runnable example covering:
- sync concurrent foreach with `item_error={"action": "collect", ...}`;
+7 -3
View File
@@ -74,9 +74,10 @@ interrupted, failed, or deadlocked. This replaces the older assumption that
## Foreach
Serial foreach creates one iteration child frame, records typed
`ForeachIterationMetadata`, blocks on that child, and enqueues the child. When
the child reaches `END`, `wake_parent_if_children_complete` wakes the blocked
parent so it can create the next iteration or emit `done`.
`ForeachIterationMetadata`, blocks on that child, and enqueues the child. An
item child returns by targeting its immediate owning foreach. The child
finishes at that owner location without executing the controller; the parent
activation consumes the result and continues or completes its barrier.
Concurrent foreach uses the same frame machinery but admits multiple item
lineages according to `ForeachConcurrentPolicy`. Each item lineage reads through
@@ -98,6 +99,9 @@ See `examples/raw_concurrent_foreach.py` for the canonical raw workflow shape an
- validate edge sources, destinations, duplicate outcomes, and declared outcomes
- validate reachable nodes have all required outcome edges
- validate explicit `EndNode` outcomes against `Workflow.outcomes`
- validate foreach control regions once: region conflicts, unreachable nodes,
body terminals, non-local returns, empty bodies, and bodies without possible
returns fail validation
Validation reports multiple issues through `ValidationReport` instead of
raising at the first failure.