@widnyana/design-thinking 0.0.6 → 0.1.0

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.
@@ -1,238 +1,313 @@
1
1
  ---
2
2
  name: graph-protocol
3
3
  description: >
4
- Graph Protocol — notation spec for Design Graphs. Fixed sections (PROBLEM,
5
- SHAPES, GRAPH, CARDINALITY, BOUNDARIES, BEHAVIOR, SCOPE, TEST LAYERS,
6
- VERDICT) and fixed markers (⟳retry ↯escape ☠die 🔒boundary (1)(N)(T) ⛈layer
7
- @scope). Use when writing, reviewing, or checking any Design Graph so
8
- notation is mechanically checkable and identical across languages.
4
+ Graph Protocol: the orchestration method. X → Graph → Delegation<A, E, R>:
5
+ task nodes, execution graph in waves, delegation break points, worker
6
+ requirements, AGENT SUBGRAPH prompt blocks, RETURN blocks, retry and
7
+ evolution, IMPLEMENTED GRAPH compare. Use when splitting work across
8
+ subagents or workers.
9
+ disable-model-invocation: true
9
10
  ---
10
11
 
12
+ > **Source**: Graph Protocol by [r17x](https://github.com/r17x), from
13
+ > https://gist.github.com/r17x/90eb2f7be93932b5693753aedb09c01a (`OPT_GRAPH_PROTOCOL.md`).
14
+ > Method text bundled as-is. The block formats at the end (execution graph,
15
+ > AGENT SUBGRAPH, IMPLEMENTED GRAPH, retry and evolution) are taken from r17x's
16
+ > "Meta Research Prompt Generator" ([meta-research.md](../../references/meta-research.md)) and
17
+ > made generic for any delegated task.
18
+
11
19
  # Graph Protocol
12
20
 
13
- The notation spec for **Design Graphs**. A Design Graph is the annotated call graph
14
- of a concrete problem: nodes are functions, edges are data flow, and every node
15
- carries annotations for data (A), cardinality, failure (E), and requirements (R).
21
+ The same method, turned on the orchestration. A task is not a checklist — it is a graph with nodes, edges, and channels, and the delegation you write is the subgraph the worker walks.
16
22
 
17
- The Protocol is stack-agnostic. A graph written for Go, Rust, Python, TypeScript,
18
- SQL, or a spreadsheet renders identically. Only the vocabulary inside the
19
- annotations changes (e.g. what "retry" means in your language).
23
+ Design Thinking answers what flows through the program. Graph Protocol answers what flows through the orchestration. Same three-channel discipline: one channel for the work, one channel for where delegation breaks, one channel for what each agent needs.
20
24
 
21
- Every tool in this package (`/cg`, `/cg-plan`, `/cg-review`, `/cg-map`, and the
22
- `/dt` active mode) MUST emit output in the format below.
25
+ ```
26
+ X → Graph → Delegation<A, E, R>
27
+ │ │ │ │ │
28
+ │ │ │ │ └─ what each agent needs (§5)
29
+ │ │ │ └──── where the delegation breaks (§4)
30
+ │ │ └─────── what flows through agents (§2)
31
+ │ │
32
+ │ └─ nodes = tasks, edges = data dependencies
33
+ │
34
+ └─ the problem: what you're trying to build
23
35
 
24
- ---
36
+ §1 Task Nodes the nouns: files, modules, domains, workers
37
+ §2 A happy path as execution graph
38
+ §3 Cardinality one worker (SMALL) or many (MEDIUM/LARGE)
39
+ §4 E break points: wrong context, missing input, misinterpretation
40
+ §5 R requirements: subgraph, design method, verification, WHY
41
+ §6 Boundary subgraph in, implemented graph out — structured at edges
42
+ §7 Behavior observe wraps delegation without changing the graph
43
+ §8 Scope worker attention is acquired and must be released
44
+ §9 Proof compare delegated subgraph vs implemented graph
45
+ §10 Structure prompt = subgraph, return = implemented graph
46
+ ```
25
47
 
26
- ## Canonical output skeleton
48
+ Read the problem. Draw the task flow as an execution graph. Delegate work that IS the subgraph. If the implemented graph does not match the delegated subgraph, the delegation is wrong.
27
49
 
28
- Sections appear in this fixed order. Omit a section only when it is genuinely
29
- empty for the problem at hand (say so: `SCOPE: none`), never to skip thinking.
50
+ ## 1. Name the task nodes
30
51
 
31
- ```
32
- PROBLEM: <one-line statement of what you're building or examining>
52
+ What are the units of work? Before drawing an execution graph, define the orchestration language.
33
53
 
34
- X → DesignGraph<A, E, R>
35
- │ │ │ │ │
36
- │ │ │ │ └─ R: what each node needs (§5)
37
- │ │ │ └──── E: where the graph breaks (§4)
38
- │ │ └─────── A: what flows through nodes (§2)
39
- │ │
40
- │ └─ nodes = functions, edges = data flow
41
- │
42
- └─ the problem
54
+ - **Nodes** -- the discrete units of work. A service change, a component update, a config edit. Each has a domain and a worker.
55
+ - **Domains** -- who owns the node. Each domain maps to a worker with the right expertise. One node, one owner.
56
+ - **Edges** -- data dependencies between nodes. Node C needs the output of nodes A and B. No edge means independent.
57
+ - **Waves** -- groups of independent nodes that run in parallel. Edges between waves create gates.
43
58
 
44
- SHAPES: <the nouns: records, IDs, variants, errors>
59
+ These are the nouns. The execution is the verbs. You cannot delegate until you know what depends on what.
45
60
 
46
- GRAPH:
47
- <ascii call graph, annotated inline>
61
+ ## 2. Think A first
48
62
 
49
- CARDINALITY: <node (1|N|T) list>
50
- BOUNDARIES: <every edge crossing untrusted → trusted>
51
- BEHAVIOR: <cross-cutting layers that wrap nodes>
52
- SCOPE: <resources: acquire@… → release@…>
53
- TEST LAYERS: <the R that tests provide — same GRAPH, zero code change>
54
- VERDICT: <code matches graph? what is missing/tangled?>
63
+ Map the successful task as an execution graph before spawning any worker.
64
+
65
+ ```
66
+ wave1[A∥B] → gate → wave2[C] → wave3[D]
55
67
  ```
56
68
 
57
- ---
69
+ What is the happy path through the task? Which nodes are independent (parallel)? Which depend on prior results (sequential)? This graph IS your delegation plan. Draw it first. The spawning follows.
58
70
 
59
- ## The header tree
71
+ ## 3. One or many?
60
72
 
61
- The header names the problem and anchors the three channels. `X` is your problem;
62
- everything after it is the graph you build.
73
+ Is the task one worker or many?
63
74
 
64
- ```
65
- X → DesignGraph<A, E, R>
66
- │ │ │ │ │
67
- │ │ │ │ └─ R: what each node needs (§5)
68
- │ │ │ └──── E: where the graph breaks (§4)
69
- │ │ └─────── A: what flows through nodes (§2)
70
- │ │
71
- │ └─ nodes = functions, edges = data flow
72
- │
73
- └─ the problem: what you're trying to build
74
- ```
75
+ - **One worker** -- a small or trivial task. Single node, no execution graph needed. Inline the task in the prompt.
76
+ - **Many workers** -- a medium or large task. Multiple nodes, draw the execution graph. Each worker gets its subgraph.
77
+ - **Waves** -- independent nodes in the same wave spawn in parallel. The gate between waves waits for all prior nodes.
75
78
 
76
- ---
79
+ Same three channels (A, E, R) in all cases. Different cardinality. Mark it on the graph so the delegation matches.
77
80
 
78
- ## Section rules
81
+ ## 4. Think E second
79
82
 
80
- ### PROBLEM
83
+ Mark where the delegation can break. Each break point is one of three things:
81
84
 
82
- One line. The thing you're building or the question you're answering. If you
83
- cannot write it in one line, the problem is not understood — stop and refine.
85
+ - **Wrong context** -- the worker does not understand the problem as deeply as the coordinator. Missing files, missing WHY, missing constraints.
86
+ - **Missing input** -- a node in wave 2 needs the output of wave 1, but the coordinator did not pass it. The edge is invisible.
87
+ - **Misinterpretation** -- the worker implements the LETTER of the delegation, not the INTENT. The subgraph was ambiguous.
84
88
 
85
- ### SHAPES
89
+ Delegation failures are not worker failures — they are coordinator failures. The coordinator controls the prompt. If the worker misunderstands, the prompt was wrong.
86
90
 
87
- The domain nouns. Name them before drawing anything:
91
+ ## 5. Think R third
88
92
 
89
- - **Records** — entities that flow through nodes (User, Order, Config).
90
- - **IDs** — identity, never a bare primitive (UserId, Email).
91
- - **Variants** — internal state transitions (pending|active|cancelled).
92
- - **Errors** — named failure modes, structured, carrying context (not strings).
93
+ Mark what each worker needs before it can do the work. "The worker cannot do X if it does not have Y."
93
94
 
94
- Format: comma-separated list. These are the nouns; the graph is the verbs.
95
+ R is the delegation prompt completeness check. Every worker needs:
96
+ - **Subgraph** -- what to implement, in the notation the worker's domain expects
97
+ - **Design method** -- which methodology applies to this worker's domain, and which sections govern the work
98
+ - **Verification command** -- how the worker proves the work is correct
99
+ - **WHY** -- the reason this node exists, not just what to change
95
100
 
96
- ### GRAPH
101
+ If any R is missing from the prompt, the worker will guess. Guessing is the source of misinterpretation (§4).
97
102
 
98
- ASCII call graph. Nodes are functions/steps; edges are data flow. Annotate
99
- **inline**, using the branch conventions from the header tree:
103
+ ## 6. Trust at boundary
100
104
 
101
- ```
102
- parse → Handler → Service → Repo
103
- │ │ │
104
- │ │ └─ R: DbConn · (N)
105
- │ └─ E: timeout ⟳retry×3 → ↯escape(cached)
106
- └─ 🔒 HTTP body → trusted
107
- ```
105
+ Where does unstructured data cross the orchestration boundary? The coordinator sends a prompt. The worker sends a result.
106
+
107
+ Structure at the boundary. The coordinator includes the subgraph in the prompt — not prose, not "fix the thing," but the graph the worker must implement. The worker returns the implemented graph in its result — not a bare signal, but the graph it actually built.
108
+
109
+ Trust nothing at the boundary. Trust everything inside. The boundary is the only place the graph is transferred. After that, the worker owns its subgraph.
110
+
111
+ ## 7. Layer behavior
112
+
113
+ What wraps the delegation without changing the graph? Observations, session tracking, phase transitions.
114
+
115
+ The coordinator records the delegated subgraph BEFORE spawning. The worker records the implemented graph AFTER implementing. These observations wrap the delegation without changing what the worker does. The happy path stays clean — you can read it without wading through session tracking.
108
116
 
109
- Inline annotation grammar:
117
+ ## 8. Scope attention
110
118
 
111
- | Annotation | Meaning | Example |
112
- |---|---|---|
113
- | `R: a, b` | what the node requires (§5) | `R: DbConn, Config` |
114
- | `E: <err> ⟳retry[×n] → ↯escape(alt)` | failure handling (§4) | `E: NetErr ⟳retry×3 → ↯escape(fallback)` |
115
- | `E: <err> ☠die` | defect, not domain error (§4) | `E: NullConfig ☠die` |
116
- | `🔒 x → y` | untrusted → trusted boundary (§6) | `🔒 JSON → Settings` |
117
- | `(1) (N) (T)` | cardinality (§3) | `(N)` = many over time |
118
- | `⛈ name` | behavior layer wrapping the node (§7) | `⛈logging wraps Service` |
119
- | `@scope` | resource bound to a scope (§8) | `DbConn @main` |
119
+ A worker is a resource. It is acquired (spawned) and must be released (completed with structured data).
120
120
 
121
- ### CARDINALITY
121
+ The coordinator acquires a worker's attention by spawning it. The worker releases attention by completing with the implemented graph. Between acquire and release, the worker owns its subgraph. The coordinator does not interfere — it waits at the gate.
122
122
 
123
- One line listing each node's arity:
123
+ If a worker is spawned without a clear subgraph, its attention is wasted. If a worker completes without reporting its implemented graph, the data is lost. Acquire with structure. Release with data.
124
124
 
125
- - `(1)` — one-shot: runs once, produces one value.
126
- - `(N)` — many: emits values over time (stream, iterator, subscription, pages).
127
- - `(T)` — time-bounded: result valid for a window; cache it, dedupe concurrent lookups.
125
+ ## 9. Compare to prove it
128
126
 
129
- Same three channels (A, E, R) in all cases. Different cardinality. The code must
130
- match: don't implement a `(N)` node as a one-shot.
127
+ The delegated subgraph and the implemented graph must match. If they do not, something is wrong.
131
128
 
132
- ### BOUNDARIES
129
+ After the worker completes, the coordinator reads both records:
130
+ - The delegated subgraph (what was asked)
131
+ - The implemented graph (what was built)
133
132
 
134
- Every place untrusted data enters the graph: HTTP requests, file reads, env
135
- vars, user input, third-party responses. The rule: **parse, don't validate** —
136
- convert `unknown → trusted` once, at the edge, then trust the types everywhere
137
- inside. One definition per shape = type + validator + transformer, reused
138
- everywhere.
133
+ Same nodes. Same A flowing through. Same E possible. If the implemented graph has nodes the delegated subgraph did not mention, the worker went off-script. If the delegated subgraph has nodes the implemented graph did not cover, the worker missed something. This is the payoff of structuring at the boundary — you prove the delegation correct by comparing graphs.
139
134
 
140
- ### BEHAVIOR
135
+ ## 10. Prompt is subgraph, return is implemented graph
141
136
 
142
- Cross-cutting concerns that wrap nodes WITHOUT changing the core graph:
143
- retry policies, timeouts, logging, tracing, caching. Composed orthogonally
144
- (middleware, decorators, higher-order wrappers, aspects). The graph says WHAT
145
- happens; the layers say HOW it behaves under pressure. If removing logging
146
- forces you to edit business logic, behavior is not orthogonal.
137
+ The separation of delegation (§6) and return (§7) maps directly to orchestration structure:
147
138
 
148
- ### SCOPE
139
+ - **The prompt** -- carries the subgraph. The graph the worker must implement, in the notation the domain expects, with context and verification.
140
+ - **The return** -- carries the implemented graph. The graph the worker actually built, structured so the coordinator can compare it against the delegated subgraph.
149
141
 
150
- Resources that must be released: connections, file handles, sockets, child
151
- processes. Acquire/release must be structurally bound (RAII, `defer`, context
152
- managers, `try/finally`) — never convention or a TODO. Notation:
142
+ This is not a stylistic preference. If the subgraph lives in prose and the return is a bare string, the delegation and verification are tangled — you cannot read what was asked without parsing natural language, and you cannot verify what was built without reading the entire diff. The prompt IS the delegated graph. The return IS the implemented graph.
143
+
144
+ ---
145
+
146
+ ## The Protocol Pipeline
153
147
 
154
148
  ```
155
- SCOPE: DbConn acquire@main → release@main · WS acquire@Handler → release@Handler
149
+ TASK
150
+ -> "What are the task nodes?" -> define nodes, domains, edges
151
+ -> "What is the happy path?" -> draw the execution graph (A)
152
+ -> "One worker or many?" -> mark cardinality
153
+ -> "Where can the delegation break?" -> annotate break points (E)
154
+ -> "What does each worker need?" -> annotate requirements (R)
155
+ -> "Where does the graph cross boundaries?" -> subgraph in, implemented graph out
156
+ -> "What wraps delegation without changing it?" -> observe before and after
157
+ -> "What resources need release?" -> scope worker attention
158
+ -> "Does the implemented graph match?" -> compare delegated vs implemented
159
+ -> "Does my prompt separate subgraph from prose?" -> prompt = subgraph, return = graph
160
+ -> DELEGATION -> the delegation IS the subgraph
156
161
  ```
157
162
 
158
- ### TEST LAYERS
163
+ **If the implemented graph does not match the delegated subgraph, the delegation is wrong.**
159
164
 
160
- The R that tests provide. The call graph does not change between production and
161
- tests — only R changes. Same graph, same A, same E, different layers behind R.
162
- If the graph can't run with a test R, the design has hidden dependencies. If
163
- you must mock the world to test one node, the node does too much.
165
+ ---
164
166
 
165
- ### VERDICT
167
+ ## Block formats
166
168
 
167
- The structural check. Answer explicitly:
169
+ The method says the prompt IS the subgraph and the return IS the implemented
170
+ graph. These are the fixed blocks that carry them. Emit them with no prose
171
+ around them.
168
172
 
169
- - Is the happy path (A) readable on its own, free of failure handling?
170
- - Is every E the graph can produce handled at a defined join point?
171
- - Do per-layer E scopes translate errors (inner errors never leak through)?
172
- - Does the code match the graph? **If the code doesn't match the call graph,
173
- the implementation is wrong.**
173
+ ### When to use them
174
174
 
175
- ---
175
+ Apply §3 first. One worker (a small task, one node) needs no execution graph:
176
+ do the work, or inline the task in one prompt. Many workers (two or more
177
+ nodes, or any node a separate agent will run) get all blocks below.
176
178
 
177
- ## E scoping at graph layers
179
+ ### 1. Execution graph (the delegated graph)
178
180
 
179
- Each layer scopes its own E before passing to the next:
181
+ Emit before any agent is spawned.
180
182
 
181
183
  ```
182
- Services → Auth → Handlers
183
- E=SqlErr E=DbErr E=AuthErr E=RPC errs
184
- ↓ scope ↓ scope ↓ scope
185
- DbErr AuthErr RPC errs
186
- ```
184
+ DELEGATED GRAPH: <task name>
187
185
 
188
- A service catches `SqlErr` and produces `DbErr`. Auth catches `DbErr` and
189
- produces `AuthErr`. The handler catches `AuthErr` and produces the declared
190
- error. Each layer's handling enumerates what IT receives — never what originated
191
- three layers down. Consumers never see implementation errors from deeper layers.
186
+ NODES:
187
+ N1 domain=<owner> output=<file, dir, or commit> status=pending|pre-done
188
+ N2 domain=<owner> output=<...> status=pending|pre-done
189
+ ...
192
190
 
193
- ## Divergent strategies (the one exception)
191
+ EDGES:
192
+ N1 → N3 (N3 reads N1.output)
193
+ N2 → N3
194
194
 
195
- When two nodes in the same happy path need different failure semantics — one
196
- must fail hard, another must fall back gracefully — handle that node's E
197
- inline at the fork, because the outer layer cannot distinguish which node
198
- produced which error. Mark it clearly; it should be rare.
195
+ WAVES:
196
+ WAVE 1 : [N1 ∥ N2] — <purpose>
197
+ WAVE 2 : [N3] — <purpose>
198
+ ```
199
199
 
200
- ---
200
+ Constraints:
201
+ - One node, one owner, one output.
202
+ - No edge between two nodes means they are independent and share a wave.
203
+ - A node whose output already exists and is non-empty is `pre-done`: do not
204
+ spawn it, count it as done for gating.
205
+ - Nodes that touch the same files never share a wave.
206
+
207
+ ### 2. AGENT SUBGRAPH (the prompt)
201
208
 
202
- ## Worked example (non-TS: Python CLI)
209
+ One per node, passed to the agent verbatim with values filled in. No preamble.
210
+ This block covers every R from §5: subgraph, design method, verification, WHY.
203
211
 
204
212
  ```
205
- PROBLEM: sync a list of URLs to local files, resumable, with a status line
213
+ ═══════════════════════════════════════════════════
214
+ AGENT SUBGRAPH — <node id> <short title>
215
+ ═══════════════════════════════════════════════════
216
+
217
+ WHY : <the reason this node exists, not only what to change>
218
+ INPUTS : <outputs of upstream nodes this node reads, or none>
219
+ OUTPUT : <exact path(s) or artifact this node must produce>
220
+ METHOD : <which method and sections govern the work, e.g. Design Thinking §2 §4 §6>
221
+ SUBGRAPH : <this node's slice of the design graph, in the method's notation>
222
+ VERIFY : <command that proves the work, or "coordinator verifies">
223
+ CONSTRAINTS : <files it may touch, files it must not touch, rules>
224
+
225
+ TASK
226
+ ────
227
+ 1. <bounded step>
228
+ 2. <bounded step>
229
+ ...
230
+
231
+ OUTPUT must exist before returning.
232
+
233
+ RETURN:
234
+ STATUS : done | failed | evolved
235
+ OUTPUT : <path(s)>
236
+ IMPLEMENTED GRAPH : <the graph actually built, same notation as SUBGRAPH>
237
+ VERIFY_RESULT : <pass | fail + first failing line | not run>
238
+ SUMMARY : <3-5 sentences>
239
+ EVOLVED_SCOPE : <new scope, only if evolved>
240
+ FAILURE_REASON : <only if failed>
241
+
242
+ RETRY : coordinator re-spawns once on failure with identical subgraph.
243
+ EVOLVE: coordinator re-plans the node on evolved; see Evolution.
244
+ ═══════════════════════════════════════════════════
245
+ ```
206
246
 
207
- X → DesignGraph<A, E, R>
208
- │ │ │ │ │
209
- │ │ │ │ └─ R: Http, Clock, Logger (§5)
210
- │ │ │ └──── E: NetErr, DiskErr (§4)
211
- │ │ └─────── A: (url, bytes), Status (§2)
212
- │ │
213
- │ └─ nodes = functions, edges = data flow
214
- │
215
- └─ the problem
216
-
217
- SHAPES: Url, Target(path), Downloaded(url, bytes), Status(pending|done|failed), NetErr, DiskErr
218
-
219
- GRAPH:
220
- load_state → plan → fetch … download → write → report
221
- │ │ │ │
222
- │ │ ├─ E: NetErr ⟳retry×3(-backoff) → ↯escape(skip, mark failed)
223
- │ │ └─ 🔒 raw bytes → Downloaded (size, content-type checked)
224
- │ └─ R: StateFile · (1)
225
- └─ 🔒 state file → trusted (schema-validated; corrupt → ↯escape(empty, warn))
226
-
227
- CARDINALITY: load_state (1) · plan (1) · fetch (N) · download (1) · write (1) · report (T)
228
- BOUNDARIES: load_state 🔒 file → State · fetch 🔒 wire → Downloaded
229
- BEHAVIOR: ⛈retry wraps fetch · ⛈rate-limit wraps fetch · ⛈progress wraps write
230
- SCOPE: Http acquire@main → release@main · StateFile @main (context manager)
231
- TEST LAYERS: R = {Http: FakeHttp, Clock: FrozenClock, Logger: Silent} — same GRAPH, no stubs in nodes
232
- VERDICT: happy path reads as the pipeline above; all NetErr handling lives at the
233
- write/report join, not inside download; state corruption escapes at the edge.
234
- Matches graph → implementation valid.
247
+ ### 3. Gates
248
+
249
+ After each wave: collect every RETURN. Re-spawn any `failed` node once.
250
+ Handle `evolved` nodes (below) before the next wave. A node that fails twice is
251
+ FAILED: downstream nodes proceed without its output and say so. WAVE n+1 never
252
+ starts before WAVE n is done or FAILED.
253
+
254
+ ### 4. Retry
255
+
256
+ 1. Agent returns `STATUS=failed`.
257
+ 2. Re-spawn once with the identical subgraph. No changes.
258
+ 3. Second failure: mark FAILED, add to FAILURES.
259
+ 4. Never retry more than once. Never change the subgraph on retry.
260
+
261
+ ### 5. Evolution
262
+
263
+ When a node returns `STATUS=evolved` (the work showed the scope must change to
264
+ produce a useful output), the coordinator, not the worker, updates the node:
265
+
266
+ 1. Rewrite that node's AGENT SUBGRAPH with the new scope. Keep every other
267
+ field.
268
+ 2. If the change adds or removes edges, update the DELEGATED GRAPH and say so.
269
+ 3. Re-spawn the node with the updated subgraph. If it then fails, apply Retry.
270
+ 4. Record the change in EVOLUTIONS.
271
+
272
+ ### 6. Implemented graph (the return)
273
+
274
+ Emit after the last wave. No prose around it.
275
+
276
+ ```
277
+ ═══════════════════════════════════════════════════
278
+ IMPLEMENTED GRAPH: <task name>
279
+ ═══════════════════════════════════════════════════
280
+
281
+ WAVE 1 — <purpose>
282
+ N1 status=done|pre-done|failed output=... verify=...
283
+ N2 status=done|pre-done|failed output=... verify=...
284
+
285
+ WAVE 2 — <purpose>
286
+ N3 status=... output=... verify=...
287
+
288
+ FAILURES : [node ids that failed after retry, or none]
289
+ EVOLUTIONS : [{ node, original_scope, evolved_scope }, or none]
290
+ OFF-SCRIPT : [nodes or files in implemented graphs that no subgraph asked for, or none]
291
+ GAPS : [delegated nodes or files no implemented graph covers, or none]
292
+ VERDICT : matches | mismatches listed above
293
+ ═══════════════════════════════════════════════════
235
294
  ```
236
295
 
237
- Note the stack vocabulary: `context manager` for scope, exceptions caught at
238
- layer joins for E, plain functions for nodes. Protocol unchanged.
296
+ Compare every RETURN's IMPLEMENTED GRAPH with its SUBGRAPH (§9). Do not trust
297
+ a worker's own "pass": re-run VERIFY yourself where you can.
298
+
299
+ ### 7. Invariants
300
+
301
+ 1. One node, one owner, one output.
302
+ 2. Every spawned agent gets an AGENT SUBGRAPH. No free-text delegation.
303
+ 3. Every agent returns a RETURN block. A bare "done" is a failed return.
304
+ 4. WAVE n+1 never starts before WAVE n completes (modulo FAILED nodes).
305
+ 5. The implemented graph is structurally the same as the delegated graph, or
306
+ the VERDICT names each difference.
307
+
308
+ ### Harness note
309
+
310
+ Spawn each node with the harness's subagent tool: `Agent` in Claude Code, the
311
+ built-in task tool in omp, a subagent package in pi. When no subagent tool
312
+ exists, run the nodes yourself in wave order. Use the same AGENT SUBGRAPH as
313
+ your own instructions for that node, and write the same RETURN block.