FABRIC-3.9.0/3.9.8: observers and participants -- the Tripod steps outside the compudynamics (design + execution plan)

Captain Bob: Hera, Artemis and Hestia no longer participate in the
calculations; they observe them and act on events. Design (3.9.0):
observer role from is_fleet_foundation, excluded from decision/work
heat/floor, event-driven (mail, console input, device events), Hera's
own mail at the idle point, event-driven DoE driver replacing the busy
wait. Rulings O-1..O-4 + discard of the uncommitted heat-share charge
open. Plan (3.9.8): stages O-A..O-D then merge, evidence named in advance.
FABRIC-3.8 gets a continuation pointer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-24 08:44:41 -04:00
co-authored by Claude Opus 5.5
parent c86c80ba26
commit 04dbc3a5d3
3 changed files with 200 additions and 0 deletions
+4
View File
@@ -1398,3 +1398,7 @@ explicit instruction.
share), not in the DoE capsule.
- Only the one capsule line is reverted. This entry stays as the record; the two logs were
removed afterwards, on Captain Bob's instruction (see above).
- **Continued in `FABRIC-3.9.0.md` (design) and `FABRIC-3.9.8.md` (execution), 2026-09-24.**
Captain Bob: the Tripod (Hera, Artemis, Hestia) stops participating in the compudynamic
calculations. Its members observe them and act on events. That design, not a heat-share
charge, is how "Hera the major consumer" gets fixed. The DoE relaunch moves there as stage O-D.
+156
View File
@@ -0,0 +1,156 @@
# FABRIC-3.9.0.md — Observers and participants: the Tripod steps outside the compudynamics
**Status: DESIGN, for Captain Bob's review. Nothing here authorizes an edit.** The execution
plan and log are in `FABRIC-3.9.8.md`.
**Provenance.** Opened 2026-09-24. This design follows `FABRIC-3.8.md`, whose Stages A–I are
all done. The per-ISA DoE relaunch on the rebuilt driver (`FABRIC-3.8.md` §6) was stopped once a
progress check showed:
- Hera's `MU-WAIT-ALL` busy loop took an equal share of the CPU as workers finished;
- it wrote 43% of all heartbeat rows so far (Hera 75,117 against `mu0`'s 75,114).
Two fixes were tried and set aside:
- **A capsule-level `100 WAIT`,** reverted. Captain Bob: *"not liking this much … redistribute
work when hera is the major consumer."* The application must not steer its own scheduling.
- **A kernel-side absolute-heat-share charge.** Built and tested (a cfg-0 trial took about 150 s
against about 210 s), but never committed. It is superseded by this design (§5).
Captain Bob, 2026-09-24:
- *"Hera, Hestia, and Artemis no longer participate in the calculations. However, they observe
them and act on them."*
- *"let's do it."*
---
## 1. The idea
The fleet splits into two roles.
- **Participants** are every VM that does the work being done and measured: DoE workers,
WIREBIND user and console VMs, and anything `BIRTH`-ed. For these, FABRIC-3.8's compudynamics
stays exactly as built:
- per-beat charge;
- work heat, with floor on contact;
- coolest VM with work goes next;
- ties to the incumbent, then to the one waiting longest.
- **Observers** are Hera, Artemis and Hestia, the Tripod. They are not compared, not charged work
heat, and not counted in any floor. They **observe** the participants' physics and **act on
events**: mail, console input, device events.
**In thermodynamic terms,** the observers are the environment (the heat bath) and the
participants are the system under study.
- Hera already behaves like a reservoir: she starts holding all of `Q48_ONE`, as the root that
`vm_physics_retire()` returns heat to.
- Every problem since Stage G came from making the reservoir compete as if it were one more
particle:
- her endowment made her "hottest";
- her busy-wait took a fair share of the CPU and polluted the data;
- two fixes had to push her back out.
## 2. What changes for observers
**2.1 Who is an observer.** It's a structural fact, set by the kernel, not a name test in the
switcher.
- `capsule_birth_baby()` already computes `is_fleet_foundation` (Hera/Artemis/Hestia) for session
pinning. The observer role reuses that.
- Hera, born through `capsule_birth_mama()`, is marked where `kernel_main.c` registers her.
- Nothing a VM executes can set or clear the role.
**2.2 Not in the calculation.**
- `sk_vm_switch_decide()` never offers an observer as a heat candidate.
- `vm_physics_charge()` doesn't accrue observers' work heat.
- `sk_vm_switch_signal_note_work_gained()` leaves observers out of the floor.
- Proposed (ruling O-2): observers aren't charged **absolute** heat either. The reservoir doesn't
heat itself by running. Participants still pull absolute heat off it through their own charges,
and `retire` returns it, so fleet K stays conserved.
**2.3 Observers act on events.** An observer is runnable only when it has an event:
- **Mail:** its kernel-Hermes queue is non-empty (`MU-DONE`, `BLK-ATTACH`, `ELEVATE-REQUEST`, a
relayed console line).
- **Console input**, for Hera: `sk_console_key_available()`, as today.
- **A device event**, for Hera: xHCI and USB attach or detach. See §4, ruling O-4.
**2.4 When an observer runs (ruling O-1: the central question).** Proposed: **at the next clean
boundary, an observer with an event goes ahead of the participants.**
- The boundaries are the same owned checkpoints, trampoline points and idle point FABRIC-3.8
built.
- Among several observers with events, the one waiting longest (the existing unique wait stamps)
goes first, with no heat.
- Once it has no events left it parks, and the participants' physics resumes.
Why this isn't a scheduler:
- There is no run queue, no priority number, and no ordering computed or kept.
- It is a **role** (environment versus system), not a rank among peers.
- Observers never compete with participants on the same scale; they respond to what happens.
- The honest risk: an observer with a long event (a heavy command typed at Hera's own prompt)
holds the CPU until it finishes, because nothing displaces an observer. §4 lists this. Work
meant to share the CPU belongs in a participant. A user's commands already go to their own
WIREBIND user VM, which is a participant.
The alternative, observers run only when no participant has work, is pure but brings back
C-4 (α)'s starvation: under load, the console, USB and storage wait until every worker is idle.
**2.5 Hera's own mail is delivered at the idle point, not on the timer.**
- Today her queue is drained by `sk_repl_idle()`'s pump at the `SK_IDLE_BEAT_INTERVAL` cadence
(timer-paced; the last such delivery left, `FABRIC-3.8.md` Stage I).
- As an observer that acts on events, her mail must be acted on promptly, so her drain moves to
`sk_vm_idle_point()`.
- It keeps the readline `n > 0` mid-edit gate, so a drained payload never prints into a line
being typed.
## 3. What this lets the DoE become
**The driver becomes event-driven. Hera never waits in a loop.**
- `DOE` sets up the campaign and starts trial 1 (birth all, send all), then returns to the prompt.
- Each worker's final `SEND` delivers `MU-DONE` to Hera as mail.
- She acts on it at her idle point: increments the count, and on the last one ends the trial
(`KILL` all, marker, persist) and starts the next.
- After the last trial she prints `MU-CAMPAIGN: complete`.
- `MU-WAIT-ALL` is deleted. This is the §3.9 design's own "ordinary words" rule, applied: Hera
reacts to messages, which is what messages are for.
**The heartbeat rows then measure the system, not the environment.**
- An observer produces rows only while acting on an event.
- Proposed (ruling O-3): its rows stay in the CSV, tagged by `vm_name` as today, and the analysis
filters by role. This keeps the CSV layout unchanged. The alternative is to suppress them.
## 4. Known limits and open questions
- **O-4: device servicing.** xHCI event polling and USB attach/detach run in `sk_repl_idle()` at
the timer-paced `SK_IDLE_BEAT_INTERVAL`, and only when Hera reaches her idle point.
- Under participant load, Hera reaches it only when she has another event, so USB goes
unserviced. A USB keyboard is a device event that can only be *seen* by polling.
- Options: (a) treat "the device-poll interval elapsed" as a Hera event; that's I/O
housekeeping triggering a switch, not a scheduling decision, but it is timer-paced. (b) Move
xHCI polling to an interrupt path. (c) Accept it for now; the DoE doesn't need USB mid-run.
- Proposed: (c) for the relaunch, (b) as later work.
- **A long event on an observer holds the CPU** (§2.4). Accepted by the role design: heavy work
belongs in participants.
- **Artemis and Hestia become observers too.**
- Artemis's storage work (attach, block sync) and Hestia's framebuffer are responses to events,
which fits.
- If a future Tripod duty is compute-heavy, it would have to move to a participant.
- **Stage G's evidence** (two participants interleave) and C-b's walk-order property are
unaffected: observers aren't candidates.
- **The WIREBIND relay** stays participant-delivered: the user VM gets the console line as mail
and is switched to by heat among participants. Only Hera's own forwarding is observer work.
## 5. What this supersedes
- **Absolute-heat-share charge** (uncommitted: `capsule_vm_physics.c/.h` working-tree changes on
2026-09-24). No longer needed once Hera isn't compared. Proposed: discard it.
- **`MU-WAIT-ALL`**, and every busy-wait in the DoE driver.
- **The C-4 (α) consequence** recorded at C-b, where the console got no turn under worker load.
An observer with console input goes ahead of the participants at the next boundary.
## 6. Rulings needed from Captain Bob
1. **O-1:** observers with an event go ahead of participants at the next clean boundary
(proposed), or observers run only when no participant has work.
2. **O-2:** observers aren't charged absolute heat either (proposed), or they keep the C-a
absolute charge and are only left out of work heat.
3. **O-3:** observer heartbeat rows kept and tagged, filtered in analysis (proposed), or
suppressed.
4. **O-4:** device servicing under load: (c) accept for the relaunch and (b) interrupt-driven
later (proposed), or (a) treat the device-poll interval as a Hera event.
5. **Discard the uncommitted absolute-heat-share charge** (proposed), or keep it as a safety net.
+40
View File
@@ -0,0 +1,40 @@
# FABRIC-3.9.8.md — Observers and participants: execution plan and log
**Status: PLANNED. No stage started.** The design and its open rulings (O-1 to O-4, plus the
discard question) are in `FABRIC-3.9.0.md`.
Each stage:
- needs Captain Bob's explicit go;
- gets its own commit;
- gets its own three-architecture acceptance (`clean qemu`; amd64, then aarch64, then riscv64;
foreground; visible framebuffer; one at a time; coupled images reset before each).
Evidence is named **before** each stage runs.
**The standing acceptance sequence for every stage**, unchanged from `FABRIC-3.8.md`:
- a boot to `[zuse@Hera] ok>` with zero `UNKNOWN WORD`, faults and frame corruption;
- the `dict_hash` set identical across ISAs;
- the Stage G interleave (two workers, `A`/`B`), byte-identical across ISAs;
- mint → WIREBIND → `USE` → `1 2 + .` → `3`;
- 0 bytes of idle log growth over 20 s.
## 1. Staged plan
| Stage | Change | Evidence (named in advance) |
|---|---|---|
| **O-A** | Observer role (`FABRIC-3.9.0.md` §2.1). The absolute-heat-share charge is discarded (ruling 5). Observers are left out of the decision's candidates, the work-heat charge and the floor. (Also the absolute charge, if O-2 is ruled so.) Observers with events go ahead at clean boundaries, among themselves by wait stamp (§2.4, per O-1). | The standard sequence. A probe (reverted after capture) shows the decision never returning an observer as a heat candidate, and an observer with mail switched to at the next participant checkpoint. **The busy-wait DoE driver, unchanged, run as a cfg-0 trial with rows on for a fixed window:** Hera's share of rows falls from about ½ (the stopped relaunch's tail) to near 0 while both workers have work. That is the measured symptom this design exists to fix. |
| **O-B** | Hera's own mail drained at `sk_vm_idle_point()`, with the readline `n > 0` gate; the timer-paced pump drain removed (§2.5). | The standard sequence, plus: a message sent to Hera while she sits idle at the prompt is acted on **without waiting for the idle beat**. A probe records the delay in beats from admission to drain; it must be well under `SK_IDLE_BEAT_INTERVAL`. The relay and BLK-ATTACH flows are unchanged. |
| **O-C** | An event-driven DoE driver (§3): `DOE` starts trial 1 and returns to the prompt; `MU-DONE` counts, ends trials and starts the next; `MU-WAIT-ALL` is deleted. Capsule only. | A 1-rep smoke campaign on amd64 runs all 6 cells to `MU-CAMPAIGN: complete`, with every trial `fail=0` and N/N `KILL … dead`. Hera's rows during trials are only event handling. The prompt answers typed input while trials run. Then the standard sequence on all three ISAs. |
| **O-D** | The DoE relaunch: `12345 3 S" <isa>" DOE`, amd64, then aarch64, then riscv64, with the ring extracted between ISAs and `artemis.img` **not** reset in between. | A fresh time estimate from O-C's measured row rate, **before** launch. Then per ISA: 18 `MU-TRIAL` markers, `fail=0`, `MU-CAMPAIGN: complete`. |
| **Merge** | This branch to `master`, once all three ISAs have completed O-D. | Per this project's own merge practice, at Captain Bob's word. |
**Stop conditions** (re-plan rather than push on):
- `dict_hash` diverges across ISAs;
- conservation (`vm_physics_conserved()`, `stadium_conserved()`) goes false;
- an observer is ever returned as a heat candidate;
- a switch storm: log growth at an idle prompt, with QEMU pinned;
- a trial that never produces its marker.
## 2. Execution log
*(empty: no stage started)*