--- created: '2026-06-04' path: Sources/Dev project: synthesis-layer tags: - dispatch - lovebug - claude-code - mcp - automation type: session-notes --- Working session refining `synthesis-layer` from record-keeping draft toward a v3-executable plan (v3 of `petal-dispatch`). Goal: surface data-model and interface decisions now, since petal-dispatch's Phase 0 schema and read surface will be designed around them. These notes supersede parts of the original `synthesis-layer` draft; a full superseding project-plan is expected once the extraction contract (Open Item below) is settled. ## Outcome Resolved the core handoff model. Five decisions locked; the extraction contract remains open and is the next work item. **1. Handoff is derived, not worker-emitted (Option B).** The worker stays dumb — one prompt, one response, exit. An *extractor* reads the worker's raw final output and produces a structured handoff. Rejected Option A (worker emits its own structured handoff event) as fragile: it makes journal correctness depend on a language model electing to emit well-formed output, the same "worker elects to signal" failure mode petal-dispatch Principle #5 rejects for completion. **2. This means there IS a per-step synthesizer in v1.** The original draft's "no synthesizer agent in Phase 1, synthesis layer is a pure read pattern" was only true under Option A. Under B, the extractor is a real (small, per-step) producer. The phase model splits cleanly: the per-step extractor exists from day one (one task's raw output → one structured handoff); the cumulative compression layer stays correctly deferred to Phase 2, still scale-triggered. "No synthesizer in v1" was a fiction that only held if the worker did the extractor's job for free. **3. One store, two tiers — not two stores.** Everything lives in the journal. Records carry a tier: `raw` (machine-emitted: stdout, spawns, exits, deltas — high-volume, never read in the hot path) vs `derived` (extractor-produced — the handoff, low-volume, what the harness actually reads). The handoff is the first `derived`-tier record type. The "report"/read surface is a query filtered to the `derived` tier. Kept as one store so derived records reconcile by construction (own `seq`, append-only, point back at the raw events they distilled) — avoids the second-source-of-truth / sync problem a separate store would create. **4. ID hierarchy, all `id` fields, never slugs.** Hard constraint: every identifier is an `id`. Hierarchy: `project_id` 1—