Commit Graph
12 Commits
Author SHA1 Message Date
Claude d0c4f60194 FABRIC-3.5.md §XXIII: the sinking latch settled -- design phase complete
The last open design question. The signal is a plain scalar in
kernel-Hermes's own translation unit, written only by Hermes, read by
every VM through a registered primitive. That invents nothing: it is the
same registration path §XX already established when register_child_vm_
words() hands the eight STADIUM-* primitives to every VM and Hera's two
sites mirror them. Reading a scalar needs no queue, channel, routing
table or working arbiter, which is precisely the requirement -- the
transport is the thing that failed.

Names it accurately. "Semaphore" was the original framing but the
mechanism is a one-way latch, and the distinction carries correctness.
Per §VII.1 a VM attempts its own recovery before announcing anything, so
raising the latch means recovery already failed and there is no path back
to not-sinking. Single writer, many readers, one irreversible transition,
both observable values valid -- which is the discipline heartbeat.c:33-34
already states verbatim and §XXVIII Stage 3 already reused once rather
than inventing new locking. This is the third such variable and takes the
same route for the same reason. Calling it a semaphore in code would
imply counting and blocking semantics it must not acquire.

Settles who reads it, which is the part §XXVIII's shared C stack
constrains: a VM has no thread and cannot poll. So the check happens at
the dispatch point, and the split is the design -- the kernel delivers
the fact, the VM runs its own flush-and-BYE in its own context. The
kernel publishes, never decides, so §XV.3 and §XIV.5 hold, and each VM
running its own shutdown is what §IX.1 already ruled. The window needs no
deadline because Hera's halt is physically terminal.

Completes §VIII.2's two-mechanism rule with no exceptions list: floor VMs
send SOS through routing, the arbiter beneath raises the latch, and which
one applies is decided entirely by which side of the routing layer the
sender sits on.

Every design question this document opened is now ruled. What remains is
build sequencing plus two small local decisions, items 17 and 18. No code
is authorized.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-19 10:24:43 +00:00
Claude 3f65a86993 FABRIC-3.5.md §XXII: the surgical strip is punch item 1, and it is iterative
Captain Bob, 2026-09-19: strip the anticipated-dead FORTH before coding;
the real gaps reveal themselves as we code/test iterate, and further dead
FORTH falls out in the same loop. Re-orders the punch list to put the
strip first.

Draws the ordering distinction that protects it. Category A is dead today
independent of this reshuffle and can be stripped immediately. Category B
-- hermes/init.4th, most of messaging.4th, the routing table, the slot-3
pairing -- is dead only on arrival of kernel-Hermes and is load-bearing
until the replacement boots. "Strip before we code" must not be read as
deleting the working messaging layer with nothing behind it.

Records the trap this document nearly walked into while building the
inventory. A reference count over capsules/ and src/ put the six
init-l8-* personality capsules and sdk.4th at zero references. They are
not dead -- including experiments/, tools/ and docs/ finds 18-19 hits
each. Reachability cannot be established by grep in either direction: it
under-reports because capsules are birthed by name from runtime strings,
and over-reports because a capsule named for a common word returns prose
noise. So no strip list is authoritative, including any this document
produces; reachability is per capsule via boot path, tooling invocation,
or the baked capsule directory.

Names the asymmetry that makes "surgical" the right word. The three-arch
boot is the only acceptance test and it exercises the boot path, so a bad
Category A strip fails loudly. It does not exercise DoE capsules, so
deleting one passes all three architectures cleanly and surfaces months
later during a campaign -- and that infrastructure has an evidentiary
role, since CLAUDE.md records the logs as committed audit artifacts and
the campaign report as patent support material. Proposes treating every
experiments-reachable capsule as live by default.

Sets the loop: strip Category A in isolated commits, boot three arches
before writing anything new, then code, then strip each Category B item
in its own commit as it is proven dead. Notes dict_hash moves every time
and cross-arch identity is the property that must hold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-19 10:16:12 +00:00
Claude 8bdbfd1aad FABRIC-3.5.md §XXI: item 9 settled -- SOS travels up the birth graph
Actionability is a property of the relationship, not of the message.
To the sender's birther an SOS is actionable: the parent may re-birth,
exercising its own birth authority rather than inheriting the child's, so
§IX.2 is untouched. To every other VM it is advisory -- a peer may shed
its own dependence on the sender but may not act on its behalf. One rule,
no exceptions list: an SOS is actionable exactly where the birth graph
already grants authority.

Pressure-tested against the supervisor risk §XIV.5 warned about, and it
survives: message-driven rather than polling (the doctrine's own
sanctioned form), optional rather than obligatory, no declarer since the
sender reports its own trouble, and no authority transfer.

What this actually closes is larger than a message type. §VII.1's ladder
had no actor for rung 2, and now each rung has exactly one: the VM itself
warm-restarts while alive, the birther re-births on SOS, and nobody acts
on compudynamic death. That also shows §IX.1's fleet-shutdown rule is not
a special case bolted on for Hera -- she has no birther, so rung 2 has no
actor and the ladder falls through to rung 3. The ladder and §IX are the
same rule from two ends: rung 2 exists iff you have a birther.

Flags a hazard specific to this system. Payloads here are FORTH text
executed by the receiver, per messaging.4th block 5041's own comment. An
SOS carrying an executable payload would let a failing VM drive its
parent, inverting the authority direction at the moment the sender is
least trustworthy. SOS payloads are descriptive only -- a deliberate
departure from the convention, and the reason the message exists.

Number: 10, the next in sequence. Verified 5 and 6 are genuinely
unallocated, but monotonic allocation means a number in any log means one
thing forever, which matters while legacy constants and the new kernel
enum coexist during cleanup. Names the consumer explicitly so this does
not become another SPAWN-EVENT, which §I.4 recorded as having none.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-19 10:05:44 +00:00
Claude d984b16102 FABRIC-3.5.md §XX: item 3 settled -- delete the suffix from the mechanism
§XVIII.5 posed agent binding as widen-the-convention vs. add-a-word.
Both accept a premise the code does not support: the pairing is already
recorded explicitly at bind time, and the ~user reconstruction is a
redundant second derivation of information the mechanism already holds.

sk_repl_dispatch_line() does two separable things. The guard builds
console_get_vm_name() + "~user" and checks it is live. The actual relay
then sends to index 3 -- and repl.c's own comment says that slot is "set
once at pairing time," which PAIR-TEST's header confirms from the other
side. Routing never uses the derived string; only the liveness guard
does, and the stored pairing can answer that question without deriving
anything.

This is also the documented cause of a known silent failure.
CONSOLE-ATTACH's own comment records that a console named anything other
than the identity's base name reconstructs the wrong target and quietly
falls back to direct interpretation with no error. Its "takes exactly one
name" constraint is a workaround for that derivation, not a requirement
of the problem.

Ruling: the guard reads the recorded pairing, CONSOLE-ATTACH resolves the
target as given, and ~user survives as a naming convention rather than a
mechanism. Agent binding then stops being a special case -- a GPIO VM
binds by the same unchanged path, because nothing appends anything to its
name. Punch item 19 is retired rather than fixed: with no string to
mismatch there is nothing to make loud.

The six memcpy sites split cleanly -- three name a VM at birth and stay,
two re-derive a partner for lookup and go. Only the derivation sites
change, which is why the convention can survive without the mechanism.

Also separates what §V.1 conflated: reachability is kernel-Hermes's,
fabric access is vocabulary and ACL, and binding proper is the console
path. An agent VM does not routinely bind at all.

Scoped per §XIV.1: this states the principle kernel-Hermes must carry
forward, not a proposal to patch the legacy FORTH path in place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-19 09:58:10 +00:00
Claude 7a9a8ed698 FABRIC-3.5.md §XIX: the third Tripod leg is named Hestia
The Tripod is Hera, Artemis, Hestia. 99 occurrences renamed; three
verbatim quotations deliberately left saying Console.

Records the naming convention, which had never been written down and was
being re-litigated for want of it: a Greek deity name, evocative rather
than literal. Captain Bob's reasoning, and it generalizes -- Hera and
Hermes are close fits, Artemis for block storage and freemap arbitration
is a loose one that has never caused anyone a problem. Fidelity was never
the standard.

antiprosopos was considered first and rejected for being the wrong kind
of word: a common noun straining for literal accuracy, which is the
opposite of how the other three work. Hestia is a deity, is evocative --
the hearth is the fixed centre where everyone gathers, which is what a
bind point is -- and carries an incidental that was not the reason for
choosing it: Hestia is the one who never leaves, which is the pinned
session model FABRIC-2 §H.1 already describes. It also retires both costs
the longer name carried, restoring the pattern fully and cutting twelve
characters of unusual spelling to six in a path where a name mismatch
fails silently.

The rename itself is structural rather than cosmetic. §XVII.1 found three
distinct things all called console, and that collision is what led
§XIII.5 to the wrong conclusion about whether a singular Console existed.
"Hestia owns console.c" is unambiguous in a way "Console owns console.c"
cannot be.

Deliberately narrow: the HAL stays console.c, the proxies stay console
proxies, and CONSOLE-ATTACH keeps its name since CLAUDE.md's rule against
modifying a registered tested word applies with more force to renaming
one. Keeps the ~user suffix question separate and still open as item 3,
with the buffer analysis recorded so the two are not conflated later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-19 09:55:45 +00:00
Claude 38735e52c2 FABRIC-3.5.md §XVIII: the Console component designed in full
Console is three layers and only the middle one is new: the HAL fabric
(~98 KB of C) is unchanged, the per-attach proxies are unchanged, and
Console the VM is a capsule rather than a mechanism.

The finding that shapes the design is that 1,051 lines of Console
vocabulary already exist in the wrong dictionary. fabric.4th's own header
calls it "Console drawing-fabric coordinate machinery" and says outright
that it is the FORTH-side policy over the C pixel primitives -- and it
loads into Hera, along with font.4th, from init.4th block 2049. Moving
both to capsules/console/init.4th is a pure relocation and the clearest
evidence that the fabric wants an owner: it already has the vocabulary,
just attached to the wrong VM. PLOT/FB-WIDTH/FB-HEIGHT registration moves
with it; the implementations do not change.

Records the invariant that constrains everything else. console.h:220-224
states that console.c must have no dependency on capsule or WIREBIND
logic, calling it a real layering violation rather than a style
preference. So Console the VM cannot be built by making console.c
VM-aware: ownership flows one way, and where the HAL genuinely needs
something VM-shaped it takes the shape already established by
console_set_user_prefix_provider() -- a registered callback, never an
include. Console's ownership is therefore by vocabulary and registration,
not enforcement, which is weaker than it sounds and exactly right.

Carries the headless-until-login invariant onto this second path: Console
is born at boot, a console session is not, and Console's birth must not
touch g_wirebind_attached_username or mint a proxy. Same rule §XXXII.2
imposed on unattended birth, cheap to hold and easy to violate with a
well-meaning startup line.

Notes what Console does not own, since a component owning "the bind
point" attracts responsibilities belonging elsewhere, and records that
the three Tripod legs have three different failure characters -- Console
degrades gracefully because the fabric is HAL C and survives its owner,
which is why only Hermes needed the semaphore.

One genuinely open design question remains: whether agent-VM binding
widens the ~user convention or takes a sibling word.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 22:18:34 +00:00
Claude 887b34d0a7 FABRIC-3.5.md §XVII: item 12 CLOSED -- Console already exists as a singleton, it just has no VM face
Closes the largest remaining design item, the one gating §IV.

§XIII.5 got this wrong by comparing the wrong object. It measured the
Tripod legs against capsule_console_birth()'s per-attach proxies, found
Console "plural, ephemeral and capsule-less," and concluded a singular
Console did not exist -- so §IV.1 would be inventing one. Traced: there
are three distinct things called console here, not two. The HAL drawing
fabric (hal/console.c, framebuffer.c, vt100.c, font_8x16.c, ~98 KB of
kernel C) is already singular, already permanent, already kernel-resident.
It is not a VM and has no owner.

So the Console leg is that fabric given a VM face, not a promoted proxy.
The proxies stay plural and ephemeral, which is correct -- they are what
binding produces, not what Console is. §V.1's bind point then falls out
rather than being asserted: the VM owning the fabric is necessarily what
you bind to. §XIII.5's proposed shape was right; its justification was
wrong, and is corrected in place.

Records the evidence that the fabric actually wants an owner, which is an
argument for the reshuffle this document had not previously identified.
The ownerless console_set_vm_name() global has already caused a live bug,
documented in console.h:193-203 -- get_vm_name() is unsafe for
save-then-restore because an intervening set overwrites the saved
pointer's own bytes before the restore runs; found live 2026-08-28,
silently no-opping, with console_save_vm_name() existing solely to work
around it. That is the signature of shared mutable state with no owner.

Notes what the ruling commits to: a new capsules/console/init.4th (the
one genuinely new artifact, and it is a capsule rather than a mechanism),
the is_fleet_foundation triple changing membership, kernel_main.c's
Hermes birth becoming Console's, the DoE CSV schema change, and Console
needing BIRTH registered. §IV is unblocked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 22:05:05 +00:00
Claude bd0c23286c FABRIC-3.5.md §XVI: item 10 settled -- clean shutdown is forced flush + BYE, Hera's is suicide
Captain Bob, 2026-09-18. A clean shutdown is a VM termination where flush
is forced and the VM says BYE; Hera is the special case that halts the
processor instead.

Traced, and the ruling is almost entirely existing mechanism.
blk_flush(0) is already the documented flush-all sentinel
(block_subsystem.c:988-990) and already the Stadium's own write-back
action. A child's BYE already terminates it -- system_word_bye sets
vm->halted, which mama_forth_words.c's own doc comment describes as the
child path. arch_halt() exists on all three architectures
(amd64:207, aarch64:126, riscv64:170), so three-arch parity holds
without new per-arch work.

The one real finding is a behavioural change rather than a gap: Hera's
BYE does not halt today, it cold-restarts. mama_word_bye() reaps children
then calls arch_cold_reset(). The reaping half already matches the
ruling; the terminal action is the opposite of it. Flagged so the change
is made knowingly -- CLAUDE.md forbids modifying a registered tested word
to "fix" it, and this is a ruled change rather than a fix, but it should
not surface first in a diff. Whether suicide replaces BYE or becomes a
separate word is left open as item 17, noting cold-restart-on-BYE is
plausibly wanted for an operator typing BYE at Hera's REPL.

Records a constraint on where the flush goes: system_word_bye lives in
shared vendored source that must keep working in the hosted build, so the
forced flush belongs in the kernel-side shutdown path, not inside BYE.

§VIII.3's bounded-window question answers itself -- the window ends when
Hera halts, a bound by construction with no timeout to tune, which is
consistent with §XV.3's no-owner invariant. Item 9 is now half-answered.

Raises one residual edge as analysis only: if Hera is already dead,
nobody performs the halt, leaving a live kernel over an empty floor. An
empty floor is arguably a kernel-observable condition rather than a VM's
decision, which would terminate without any VM inheriting her authority.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 22:01:00 +00:00
Claude a842789ae6 FABRIC-3.5.md §XV: the authority questions answered, three by rejecting the premise
Captain Bob, 2026-09-18. Any VM may birth a near-clone of itself carrying
its own ACL DNA; nobody declares a VM dead, it dies a compudynamic death;
nobody owns turn order, turn order is compudynamic.

These close six punch items. Birth-by-near-clone settles what "ACL/DNA"
refers to -- inheritance by copy, using the existing ACL-INHERIT
semantics, needing no fifth DictEntry field -- and settles "standing" as
decorative, confirming the minimal reading. The authority bound holds
literally rather than aspirationally: a child cannot exceed its parent
because it is built from it, so there is no gate to bypass.

Compudynamic death retires the largest scheduler-shaped risk in the
design. §VII's ladder appeared to need a supervisor watching liveness,
and a supervisor with a timer is a scheduler's twin; with death as a
physical outcome rather than a judgment, that component is not needed and
does not exist. §VII.3 and §IX.3 both asked the wrong question and are
marked withdrawn and premise-rejected in place.

Turn order gets a stronger invariant than the firewall previously
proposed: that one named an owner, and naming an owner is what a
conventional scheduler is. Nothing owns turn order. Flags one honest
seam for later, predating this work and belonging to §XXVIII:
SK_SWITCH_READINESS_THRESHOLD is a hardcoded 50, the same category of
fixed policy §XIX rejected.

Reframes the message-durability question that was posed badly enough to
be unintelligible. It is not persistence but conservation: a message
holds Q.SLOT of heat (MSG-ALLOC pulls, MSG-FREE-NODE evicts), so a dying
arbiter holds N x Q.SLOT of fleet heat. Payloads may vanish; the heat may
not, or K breaks. Nothing survives except K. This dissolves the
Artemis-at-death-time hazard entirely rather than trading against it --
there is nothing to persist, and since death is already a Stadium
eviction, returning heat is what dying consists of.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 21:50:27 +00:00
Claude 9b69c1f447 FABRIC-3.5.md §XIV: two rulings collapse the root dependency
Captain Bob, 2026-09-18. The existing FORTH messaging layer is legacy --
kernel Hermes is greenfield C, not a migration of messaging.4th, and the
dead FORTH gets retired by a separate cleanup pass. Persistence goes
through Artemis wherever possible; that part is ratified.

Together these dissolve rather than answer four open questions. §III.4,
named the root dependency throughout §X, is resolved in the "full
centralization" direction but without the migration cost that made it
frightening: with the FORTH legacy there is no live state to port. §III.3
loses its subject, and §XIII.1's 14-site inventory changes purpose rather
than content -- it now feeds the cleanup. §IV.2 dissolves via its own
option 3, exactly as that section predicted. The MANIFEST corrections are
absorbed into the cleanup pass. All four marked superseded in place with
pointers rather than rewritten.

Traced the layering question the persistence ruling raises, and it
answers cleanly: storage is already two layers, so no inversion is
needed. The block subsystem is kernel C below the floor
(block_subsystem.c, blkio_*.c, virtio_blk.c; capsule_loader.c:98-100
calls it with no Artemis involved), while Artemis is the storage policy
arbiter on the floor. Fleet persistence goes through Artemis; anything
kernel Hermes needs uses the same block layer Artemis sits on.

Flags the one hazard that ruling carries: Hermes must not depend on
Artemis for persistence at its own death, since reaching Artemis requires
the mechanism that is broken -- the same trap §VIII solved for signalling
with a semaphore. Recommends a stateless arbiter holding only
registry-reconstructible state, offered as analysis, not a ruling.

Also records the scheduler firewall as raised-but-unruled, and why the
legacy ruling makes it more urgent: eligibility marking moves inside the
arbiter by default once kernel Hermes replaces FORTH MSG-SEND as the
caller of sk_vm_switch_signal_mark_work().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 21:43:15 +00:00
Claude bcf41e5618 FABRIC-3.5.md §XIII: work punch items 1 and 2, CLOSED with evidence
Items 1 and 2 were the two pure-investigation entries, carrying no design
commitment, so they were executable without a ruling. Traced against the
tree at e56974e. No code written, no open design question answered.

Item 1 CLOSED: the by-name Hermes inventory is 14 FORTH sites across 5
files, 3 C-side sites, and a DoE CSV schema site -- not the two this
document's own §I.2 claimed. §I.2 corrected in place with a pointer
rather than rewritten, per the series' never-silently-drop rule. Good
news in the count: only 3 of the 14 are live production paths, which
materially lowers the estimated cost of §III.3.

Item 2 CLOSED: FABRIC-2 §H.1 (line 3699/3713), §H.12 (line 4057, also
cited from capsule_birth.c:785-788), and FABRIC-3 §XVIII (K held at
Q48_ONE) all verified against source. §V.3.4 and §VII.4 may now be
relied on.

Three findings not previously recorded. The Tripod is hardcoded as a
name-triple in C at capsule_birth.c:793 (is_fleet_foundation, the line
that makes a VM pinned), kernel_main.c:865 and :1007, plus six DoE CSV
columns in doe_log.c -- so changing Tripod membership changes the CSV
schema and bears on campaign comparability. Seven of the inventoried
FORTH sites are dead code in two capsules loaded by nothing, and
MANIFEST.md still carries a block-4055 "immutable ABI" claim FABRIC-2
declared stale and nobody corrected; reported, not fixed, as new punch
item 13.

Most consequential: Console today is plural, ephemeral and capsule-less
-- a 3-line C string literal, deliberately off the routing table, minted
fresh per attach. It is none of the five things the other Tripod legs
are, so "Console takes the vacated third slot" is not a relocation as
stated. Raised as punch item 12, gating §IV. A resolution shape is
offered as analysis, explicitly not ratified. Also notes that §V and §VI
are one change rather than two: Console cannot be the bind point while
BIRTH stays Hera-exclusive, since binding mints a proxy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 21:26:45 +00:00
Claude 0e4e6673a9 FABRIC-3.5.md: open the Tripod/kernel reshuffle as its own document
Opened by direct instruction as a standalone document rather than a
FABRIC-4 scratchpad entry: the reshuffle is a ratified architectural
direction needing full FABRIC discipline, but it is not bare-metal boot,
so it does not belong in FABRIC-3 and does not close it. FABRIC-3 stays
open, living and authoritative for its own topic.

Records what was decided 2026-09-18 (Hermes into the kernel as arbiter
rather than client; Tripod reconstituted as Hera/Artemis/Console; Console
as the fleet bind point; BIRTH general with authority bounded by
inheritance; one gentle -> from-scratch -> brutal recovery ladder; SOS as
a standard message type with Hermes excepted via a sinking semaphore; no
provisional handoff of a failed birther's authority), and separates it
from what is still open.

Grounded against the tree rather than recalled, with provenance marked
per claim. Notes the concrete consequences the move runs into: Artemis's
two by-name S" Hermes" VM-EXEC call sites, the routing table's written
"never renumbered" commitment on slots 0/1/2, and the per-VM CREATE/ALLOT
message arenas that decide whether this stays a reshuffle or becomes a
rewrite.

Design only. No code authorized, nothing else in the tree touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
2026-09-18 21:21:38 +00:00