Module split

Module split 

Source
Expand description

Stage 8 — signal-graph slicing, and the boundaries it synthesises.

docs/04-compiler-architecture.md §4.3: “Slice the signal graph. Every signal edge that crosses tiers becomes a subscription: the server side gets a diff operator (DOM patches for Mode-A components), the client side a resumable (subscription, seq) consumer; send becomes the upstream command channel into the ingress. There is no cache-invalidation wiring to synthesise — views are downstream of the log by construction.”

§What slicing means concretely

The program declares a graph, not a pipeline:

proposals = merge_clients()                        ! ingress   @on(server)
events    = decide(proposals, todos, validate)                 @on(server)
todos     = durable(fold(apply_event, empty, events))          @on(data)
remaining = signal_map(todos, count_remaining)                 (unplaced)
page      = per_session(todos, view)                           @on(client)

crate::signal builds that graph. This module slices it: for each role the runtime drives it produces a Core function, because the roadmap says Phase 1’s views are “full recompute per event — semantically final, later made incremental”.

§What changed when the general slicer arrived

Phase 1 and Phase 2 recognised one topology and refused every other by name — legitimate narrowness, named as debt by docs/19-phase-1-report.md §19.9 and again by docs/20-phase-2-report.md §20.5. Three things are different now, and each is a property of working from a graph rather than from a pattern:

  1. Any number of durable folds. They are fused into one accumulator — a synthetic record with a field per fold — because §3.7 fixes one totally-ordered log per application, and two durable folds are two projections of one log rather than two logs. Under the old splitter a second fold was not refused: it was accepted and sliced with both folds reading the first accumulator, which is the one outcome the narrowness was supposed to prevent.
  2. Any depth and any sharing above the fold. A signal read by two consumers is computed once, as a let in the sliced function, instead of being inlined per use. That is what §5.3 means by sharing an arrangement, expressed at the only place a Phase-3 view engine could read it: the plan.
  3. Every tier crossing is enumerated, with the content-derived id a resumable subscription is keyed by, instead of one hard-coded sentence about the single crossing the old shape had.

The refusals that remain are refusals about meaning — a cycle with no fold in it, a stream where a value is required, two pages and no router — and each says which.

Structs§

Placed
A program with its signal graph sliced into the roles the runtime drives.
Roles
The five things the runtime needs, each a Core value it can call.
StateRole
One durable accumulator the program declared.

Enums§

Kind

Functions§

crossings
Every tier crossing, for beck explain flow and for the report.
flow_report
What beck explain flow prints: the graph as a graph, rather than the four names the one recognised topology had.
slice_of
Every vertex reachable from a sink, in dependency order — the sub-plan one role executes.
split
Slice a checked, placement-verified program.