--- id: signal-driven-updates name: Wire signal changes to prepareUpdate/commitUpdate status: pending depends_on: [mount-with-fibers] created: 2026-05-18T16:22:57.167895441Z modified: 2026-05-18T16:22:57.167895878Z scope: moderate risk: high impact: phase level: implementation --- # Description Bridge the reactive layer to the host layer by wiring signal changes to `HostConfig.prepareUpdate`/`commitUpdate` via fibers. This is the core of ADR-005: signals handle 90% of updates (property changes), reconciliation handles structural changes. When a signal that drives a `ReactiveNode` changes, the `computed` recomputes and an `effect` fires. This effect should: 1. Compare the fiber's current props to the new element's props via `host.prepareUpdate` 2. If `prepareUpdate` returns a non-null payload, queue an "update" effect on the fiber 3. Call `host.commitUpdate` with the payload Multiple signal changes within a batch are collapsed into one reconciliation pass (Preact signals already batch within `batch()` calls). Updates are committed top-down (parent before child) to ensure parent state is consistent when child updates fire. ## Acceptance Criteria - [ ] Signal change triggers `scheduleUpdate(fiber, nextNode)` on the associated fiber - [ ] `scheduleUpdate` batches pending updates and queues `flushUpdates` via microtask - [ ] `flushUpdates` calls `host.prepareUpdate(fiber.instance, fiber.tag, fiber.props, nextNode.props, ctx)` - [ ] If `prepareUpdate` returns non-null payload, fiber gets `effect: { type: "update", payload }` - [ ] `commitEffects` calls `host.commitUpdate(fiber.instance, payload, tag, prevProps, nextProps, ctx)` - [ ] Commit order is top-down (parent before child) - [ ] Signal effect disposers are stored in `fiber.signalDisposers` for later cleanup - [ ] `host.prepareUpdate` and `host.commitUpdate` are optional — if not implemented, update is a no-op - [ ] Existing tests pass - [ ] New test: signal change on a reactive element triggers `prepareUpdate` + `commitUpdate` - [ ] New test: batch of signal changes results in single reconciliation pass ## References - docs/architecture/reconciler.md — Step 1 (Schedule Update), Step 2 (Reconcile Props), Step 4 (Commit Effects) - docs/architecture/decisions/005-signal-driven-updates-over-tree-diffing.md — ADR-005 - docs/architecture/reactive-layer.md — ReactiveNode, ReactiveRoot, signal/computed/effect - docs/architecture/host-config.md — prepareUpdate, commitUpdate methods ## Notes > To be filled by implementation agent ## Summary > To be filled on completion