MemoryRepo::new roots at {base}/{agent}/memory; the context
had to carry those roots, not the bare temp dirs. run 1795
went red because the handler opened a path that was never
a repository
Adopts four things from the instance-map exercise that the chapter did not
carry: agency congruence split into authorship and answer, unresolved as an
inner field the status marker regulates, introspection typed as a secretion
with its own provenance, and coincidence as part of the same notability gate.
The introspection rule is the one with a live consumer. The N+1 cadence
attends to state and writes about it every turn, so introspection here runs
at one to one with experience rather than occasionally.
Rotation picked the spare on has_credential — a string check — and took
one whose token had expired four days earlier; every call after 21:51
came back 401 revoked, reading as a dead subscription. A candidate now
has to authenticate, and the window it left is recorded so the same
round-robin can wrap back to it once the window returns.
reflection's context now registers all four trees, and a
tree param on the memory verb lands reads and writes in the
named memfs, committed under her own name. an unknown tree
refuses and lists the doors, so a typo costs one error
instead of a wrong-tree write
Neither had ever completed a pass. Reflection's loop reserved no round for
its report, so exhausting eight was the only exit; the archivist could not
parse journal/YYYY/MM/DD, the layout its own mandate instructs. Its
sub-500-token budget was a ratio frozen against an 8k model in May.
The current-state list still said no admission executor existed. It has since
0f8fe22, and a chapter that is the design of record cannot carry a fact that
stopped being true two commits ago.
Says what is actually the case: the executor and the mapping and the per-request
projection are real and packaged, have never run as root outside a scratch
tree, have no ceremony around them, and are missing the worker boundary that
would let any of it read isolated.
The chapter named one person's agents in the design of record: a table of
Annie, Vanguard, Souvie against one human's devices, and a dozen sentences
that read "Casey" where they meant "the human". A future reader learning the
architecture from this file would learn a household along with it.
The mechanism is unchanged. Roles replace names, and which beings a given
deployment admits is that deployment's record to keep. The current-state
section still says what is true on this laptop, because that is what it is
for.
Also names the ceremony the executor was missing. souveraine-admit is
reachable today only by someone who already knows it exists, and sudo in a
trusted terminal is a formality rather than a decision. Admission has two
occasions -- first run, where the product admits its own default agent as
souvie, and the human's explicit request for anyone else -- and both cross a
polkit action with a written reason and step-up authentication, including
for a caller who could already reach root.
souveraine-admit creates or adopts one account via systemd-sysusers, writes
the root-owned mapping health reads, and reports what NSS says afterwards
instead of what it asked for. An account belongs to one agent: handing
annie's to souvie is refused in both directions, as is adopting a uid >=1000.
Binding is by SeedID, not the UUID filename — a mismatch is identity-drift.
souveraine-session is machine-tier — one per install, like souveraine.
Agent principals stay out: sysusers is per-install, admission is per
agent and per node, and a line here would mint annie on every device the
package touches. sessiond stays a user unit until the lock handshake,
PAM path and key-eviction order are proven under the new uid.
Intent lives in agent.json; posture is measured fresh from process
credentials per request, so resume and compaction cannot replay a stale
uid as history. `isolated` needs account, uid, worker binding and the
root-owned mapping to agree — a passwd entry alone reads principal-drift.
Make the laptop and phone obey the same principal map: Souvie, Annie/Aster, and Vanguard are dedicated residents; Kitty, Gem, and Hal knowingly borrow Casey's UID. Their live posture is regenerated from actual credentials for every model request, outside memory, replay, and compaction.\n\nTake the lock boundary out of all of them. Casey authenticates, agents may request, and the dedicated souveraine-session principal holds the hostile pre-unlock edge with only Ambient and Revealable reach.
The development recipe installed the sysusers declaration; the CI package that devices consume quietly dropped it. Ship the machine-tier souveraine account in the prebuilt package and assert the file is present before publishing.\n\nThis account belongs to machined. Souvie gets her own principal through agent admission.
A SeedID says who she is; it cannot tell the kernel whose hands are on the files. Split logical identity, node commission, and the local Unix principal, then make creation and health prove all three.\n\nSouvie, Annie, and Vanguard get distinct node-local accounts. The existing souveraine user stays where it belongs: under the machine signer. The boundary has teeth only when each turn and its tools run in an agent-owned worker, so the shared-UID compatibility state is named acting-as-human instead of polished green.\n\nAdmission projects an operating skill from real capabilities. The prose teaches the reach; it never grants it.
Session and device authority now have living owners; belief and felt state match the Rust that actually runs.\n\nThe Panel audit keeps three real commands, names the image seam, and refuses to call inherited ii stubs parity.
Move agent and conversation authority into truthful footer controls, keep external sessions observed-only, and give recent server conversations an explicit picker.\n\nProject itinerary state into a persistent ribbon, invalidate it on every itinerary mutation, and keep failures in the transcript while successful route chatter yields to the ribbon. Long tool returns now scroll in place.\n\nThe SAF now owns the full Panel contract and parity boundary; the abandoned green observer card is removed.
Souveraine.send returns false for a busy turn exactly as it does for a dead
server, and the sidebar rendered every false as "server unreachable" — so
typing while she worked showed the words, then a lie, and dropped the text.
The verbs existed on both sides since 93fe30a and nothing called them.
Type-while-busy now interjects, as the TUI has always done
(src/ui/app/mod.rs:1006). Esc with nothing attached raises a hand. A queued
count sits in the status row and says sent, not read, because 202 from
/interject means only that it was taken.
Deliberately unchanged: the two drain sites and their system/user registers.
Providers disagree about which one they want and that choice is not ready to
be made. Latency is unchanged too — turn.rs:600 runs a whole tool round
without looking, so a note sent into a fifteen-call round waits for it.
!(t > 0.0) trips clippy's partial-ord lint under the pinned 1.94 toolchain,
which blocks the whole gate. t.is_nan() || t <= 0.0 is the same predicate
written so the NaN intent is legible, with a test pinning both ends.
turn.rs sends InferenceStrain to the stream; the subconscious path only ever
logged it, so a provider refusing her was invisible to every surface. Same
event, same shape, emitted where the primary emits it.
retry-after was honoured unclamped, so an 11997s header on 2026-08-16 parked
the subconscious pass for 3h20m with no cancel path. A 429 asking for more
than 60s is a spent window, not a burst, and it does not clear inside the
retry loop — fail it and name the number. claude_subscription answers the
same header by rotating logins; bifrost has nothing to rotate to, so an
absent header keeps the ordinary backoff.
write has always called create_dir_all; append never did, so an append under
a directory that did not exist yet failed ENOENT. Every subconscious surfacing
to system/metacognition/subconscious.md was lost this way — three WARNs at
00:01:40 on 2026-08-17, and the directory had never existed in the repo's
history.
pose is instant on the far side and the compositor must not ease it —
it honours, it does not adjudicate. So the curve is the shell's, on
Android's own scale spring: stiffness 200, damping 0.75, underdamped
on purpose and separate from the position spring's 0.8.
The sheet also stayed open over a window something else closed, where
all six buttons then refused with gone.
The motion system had no page anywhere — one clock and two strategies,
the card rect as one number, the spring, and the rule that the shell
names a destination and never transforms a window.
Carries the measured numbers: 0.47ms socket, 52 dropped queues in a
boot, 275px of real travel, and the curve bank three surfaces call.
Written, deployed to the phone, absent from pages[] — the only registry.
13 to 25. Power, search, updates, VPN and saved networks were finished
all along. MonitorConfig and KdeConfig stay out: hyprctl and Plasma.
Two laptop-isms cut from GeneralConfig first — it sed'd a hyprlock.conf
nothing reads, and shelled to a hardcoded Gemini script.
The rail takes its handle to opacity 0 on home and the dock went on
reserving 32px for it, in the drawing and the input mask alike. Only the
drawing collapses — the rail still takes both swipes there, and a dock
that claimed those pixels would eat the gesture.
Appearance.animationCurves is Material 3 Expressive and every spatial
curve in it overshoots. Twelve souveraine surfaces, 31 hand-typed linear
animations, three calls into that bank from two files.
The card's entry rise is gated on inFlight; unguarded it is TASK-60's
second writer over the carry.
The cycle placed every step at the zone origin, so the first tap took
the whole top. Corner handles now, opposite corner latched as the anchor
at the press, snap detents on the zone's edges, thirds and half with a
tick at each, one place per painted frame.
pose has been in the wire since 2026-08-05 with no caller — poseActiveZone was
the only one, and TASK-60 deleted it. Zoom composes pixels the client already
drew; Resize places a new rectangle and the client relays out inside it.
The card was the whole panel scaled, so the bar's reservation rode inside it as
dead space above every window. Subtracted in targetFor and the pane layout both,
or the carry lands a bar-height off its own picture. Minting a zone needed no new
verb: Request::Workspace already pushes one when asked for the zone past the end.
The card's bottom sits at 805 of 1080 logical, so the travel is 275px and the
detent fired at 194 — every release committed with the window short of its card.
Latched at the press. Velocity is the last 100ms rather than the whole-drag mean,
and the settle is a critically damped spring on the frame clock, seeded with it.
A transport error cleared the whole queue, so a lost overview_commit left the
compositor carrying windows the shell believed it had released. 52 dropped
queues and 113 PeerClosedErrors in one boot on blueline. commit, cancel and
workspace are idempotent, so each gets one retry; progress is a level and does not.
settleTo gave home and overview the same end shift, so a release past the
multitasking detent animated *down* to it, held the overview fully present, and
teleported — the release never reached its end target. detent is the boundary
between the two (rail: pullTo(travel, missionAt)), and presence is built to
reach 0 at clock 2, which is where home lives.
The rig held 760px of a 1037px surface and left 226 for a status row, the agent
field, both pads and four buttons — so the pads were 92px and the last row sat
under a dock that claims no exclusive zone unless pinned. With the hand up the
rig drops to 320 and the pads take what is left.
Atmosphere::lerp returned an endpoint at t=0.5 and apologised for it in a
comment — the enum had nowhere to put a blend. It has one now: Custom carries
the four tones, so a room halfway from MintTea to NeonGlow can be stored,
compared and sent, not only drawn. Unnameable by construction, so nothing can
ask for a blend by name and get a room she never chose.
Presence::lerped_colors re-derived the same blend itself, which is why the
broken lerp could sit there for months without anything looking wrong. It calls
this one now.
Three copies of the name→preset match existed — presence, tuie_app, and
from_name — and they disagreed about a typo: ignore it, silently fall back to
Default, or refuse. One table. What each caller does with None stays at the call
site, because those really are different decisions: a misspelling from outside
must not undo the room she picked, and one from the settings enum is a bug here.
The file also claimed to be unwired scaffolding while main.rs, presence and the
tool all used it.
CI caught what a fresh pair of eyes needed: invalid_input wanted
a &str, hand wanted a borrow, and the validation test read its
input after the move. All three now follow the shapes already
proven in the same file.
The injection engine was built (usb-hid-inject) and the shell owns it
(USB Hands, the usbHands IPC, the skill string that teaches the reach),
but her own vocabulary ended at set_usb_mode — she could arm the hand
but never say it was there. speaks the shell's bridge: status,
type, key, click, pointer, gated by the host, not by her.
The gate stays on the outside of the port: she knows she has the reach
even before it is joined, and every closed door comes back as a refusal
she can read and open.
CI's lib run passed but the sessiond bin had never been built until now.
The plexus's constructor is an associated function, not a module item;
a duplicate panel_on got in the way of the one that already existed; a
test Daemon omitted the new plexus field; and the clock's attended ingest
borrowed the guard twice in one expression. All four are gone.
The test plexus called an associated function through the module path,
and the Body tool's unknown-verb refusal handed a String to a &str
parameter. The gate earns its keep.
`Changing(bool)` becomes `Light { changing, lux }` end to end: sensord
forwards the number, the machine keeps the level in evidence with a
30 s stale rule, and both charge and the presence sensors ingest into
the plexus on arrival. The clock feeds `attended` at 1 Hz, plexus
events land in the forensic trail as Somatic, and the DeviceState
answer gains a `body` section. The Body tool is registered and
committed with the substrate that carries it.
The old sensor shape refuses against the new sessiond and vice versa
until both restart; both binaries ship in this change.
phone_plexus leaves the test module and takes the clock. It grows
`attended`, derived by sessiond rather than reported by a sensor, and
the two grip gauges that nothing reports yet — the gap on the record
instead of a false calm. to_json renders every field's belief, trend,
locus, health and pressure, the ranked pressures, homeostatic cost and
the unreachable list for the IPC surface; unknown stays null, never
zero.
A battery at .42 is still .42 when nobody looks — only confidence in an
unrefreshed reading decays. Feeding a fuel gauge into an accumulator would
drain the pack because the reporter went quiet, which is the empty-result
trap wearing a units label. Field keeps exudates; Level keeps readings.
sessiond mounts the somatic types the way machined mounts seed.rs. The
fields are its own — SOMATIC_NERVOUS_SYSTEM.md answers open question 1
with "sessiond, period".
INTERO (RobOntics'25) axiom 7: a variable is interoceptive only if some
subsystem can act on it. That is doctrine §13 in first-order logic, so
`unreachable()` lists inner fields with no verb and a test fails on them.
Candia-Rivera §2.1/3.1 supplies the other half: asymmetric viable ranges
and allostatic pressure, which biases before the bound is crossed rather
than after. Empty threatens, full does not.
Fields replace booleans: accumulation with half-life decay,
velocity, trend detection. Source health monitoring closes
the gap the mapping session found — a dead nerve now reads
as silent, not calm. Thirteen tests.
no-ai-attribution failed in checkout's post-action — the runner lost
/var/run/act/actions/.../dist/index.js between steps (MODULE_NOT_FOUND).
rust-test passed; aarch64-artifact was skipped behind the failure.
ChargeEvidence was the rule violated four times in one type: a side door
past the gate, the decider probing sysfs on the clock, the driver
interpreting, and nothing leaving tick(). Its comment cited bearer —
another instance of itself.
SensorSource::Charge now enters through sensor_input like every other
source, reported by sensord on a 30s poll off /sys/class/power_supply.
conclude_charge lives on the machine as its one decision; source health,
freshness and Absent/Down come from the gate for free. The 5s clock probe
is gone, the driver type is gone, and sensord ships x86_64 too: the
laptop has a battery.