FABRIC.md -> FABRIC-0.md FABRIC-2.md -> FABRIC-1.md FABRIC-3.md -> FABRIC-2.md (the current/living document) FABRIC-4.md unchanged (new #3 to follow separately) Every cross-reference repo-wide updated to match, including doc-comment citations inside kernel source (.c/.h) files -- done via an ordered placeholder substitution (FABRIC-3.md->placeholder2, FABRIC-2.md-> placeholder1, FABRIC.md->placeholder0, then placeholders resolved to final names) in a single pass per file to avoid double-shifting already-renamed references. One line in capsules/font.4th grew past the 64-char block-format limit as a side effect of the longer filename; shortened it and reverified with mkcapsule --lint (34/34 pass) before rebuilding. Verified 3-arch boot to ok> (amd64/aarch64/riscv64, each in the foreground) after the fix; logs and DoE CSVs from this session's verification runs included per this repo's own audit-artifact convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
5.2 KiB
FABRIC-4.md — forward-looking design notes
Status: Not a successor to FABRIC-2.md and not a punch-list document. FABRIC-2.md is
still the living document — nothing here supersedes it, and this file doesn't follow the
close-and-carry-forward discipline FABRIC-0.md → FABRIC-1.md → FABRIC-2.md used (that
chain triggers on closing a document; FABRIC-2.md isn't closed). This is a separate,
lower-discipline scratchpad for design ideas caught early — theory-stage, pre-punch-list,
often missing a stated "why" on purpose (captured as raised, not fully justified yet). An idea
graduates out of here into FABRIC-2.md §I (or wherever FABRIC-2.md is by then) once it has
a real scope, not before.
1. Stadium-level "wheel" — a second clock alongside the heartbeat (2026-09-03)
Raised in conversation with Captain Bob, theory stage — no code, no scope, deliberately not punch-listed yet.
The mechanism. A second clock, independent of but derived from the true heartbeat
(HeartbeatState, Loop #7), advanced by a fixed-point (Q48.16, this project's standard)
phase accumulator: each master heartbeat tick adds a rate scalar to the wheel's own
phase; whenever phase crosses 1.0 the wheel fires (advances its own state) and the
crossing remainder carries forward. This is a continuous scalar, not an integer tick-divisor
— rate can sit anywhere, including above 1.0. A wheel with rate > 1 fires more than
once per master tick (multiple threshold-crossings per tick, remainder still carried); one
with rate < 1 accumulates across several master ticks before firing once. Nothing about the
mechanism privileges either side of 1.0 — "runs ahead of baseline" and "runs stretched
behind baseline" are the same math with a different scalar.
What feeds it. Not a new signal source — this wheel listens to two already-real, already-
built mechanisms: rolling_window_of_truth.c (Loop #2's circular-buffer execution history —
rolling_window_measure_diversity(), rolling_window_find_hottest_word(),
rolling_window_count_transition(), rolling_window_pattern_capture_rate(),
rolling_window_is_warm()) and inference_engine.c (Loops #5/#6 — InferenceOutputs:
decay-slope, variance-inflection point, fit quality). Both exist today at the per-VM
level (each patron/word-owning VM has its own rolling window and runs its own inference
pass) — the wheel itself is meant to live at the Stadium level, one layer up. This is a
genuinely new axis: nothing today aggregates RWOT/inference-engine output across the whole
Stadium floor into one fleet-wide signal. Open, not decided: what the aggregation actually
is (sum across patrons? mean? the hottest patron's own values only? something else) — flagged
in conversation, not resolved.
What it's for. Not a sieve itself. The wheel is a scheduler/gate: it decides when to slip an appropriate sieve into a stack of sieves that doesn't exist yet (see §2 below) — running its own clock, potentially ahead of the true heartbeat, is what buys it lead time to notice a transition worth reacting to before the baseline heartbeat would get there on its own. It is not itself the thing doing the sieving.
Build sequencing, decided in conversation. rate starts as a fixed build parameter (same
shape as ACL-BASE-TTL/Q.SLOT — a plain constant or Kconfig symbol, not adaptive from day
one). Reasoning, Captain Bob's own: a fixed rate is the only version that can go through this
project's existing DoE apparatus and produce a clean, attributable measurement (rate held
constant, everything else varies) — if the rate self-tunes from day one there's no fixed
baseline to compare "does the wheel actually help" against. Only after a real, measured
baseline exists does rate itself graduate to adaptive/self-tuning — reusing the same
inference-engine machinery the wheel already listens to, not new plumbing. This mirrors the
L8 Jacquard selector's own real history: hardcoded compudynamics constant first, later
replaced by the VM Fleet Attractor's dynamically-inferred rate
(docs/working/architecture/VM-FLEET-ATTRACTOR-DESIGN-20260705.md). Same graduation, one
level up the stack.
Explicitly not decided yet, per Captain Bob ("we'll talk about why later"):
- The actual purpose — why this wheel, what real problem it solves. Deferred on purpose.
- The sieve stack itself — what a "sieve" is concretely, what gets sieved, how many. A larger, separate vision (128–256 wheels, each fed by an "appropriate" — possibly learned/neural, vocabulary not yet resolved against anything this codebase currently has — source, forming a coincidence-pattern sieve) was raised earlier in the same conversation as a distinct, further-out idea; this single-wheel scheduler is deliberately scoped smaller and doesn't presuppose that larger picture is right.
- Whether "trivial to add a wheel" (an earlier framing) still matters once there's only one —
a generic
{rate, phase, state}table is a premature abstraction for a single instance; build the one wheel concretely first, generalize only if/when a second one is actually needed (this project's own standing convention — three similar lines beat a premature abstraction).