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
75 lines
5.2 KiB
Markdown
75 lines
5.2 KiB
Markdown
# 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).
|