Commit graph

308 commits

Author SHA1 Message Date
Meta Vens
a7b602ae65 WIP B3: route-proof readiness in the phase machine
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 10:48:33 +02:00
Meta Vens
a61540b93f Merge route continuity B1: a continuity abort cleans its own projection
A continuity abort demotes the shared key to Expected-only with its own
exact activation, and never withdraws the Expected. a148802 is reverted.
Pre-B1 terminal continuity aborts keep their phase under a
LegacySkippedBeforeB1 marker that only the lift can construct. Boot
reconciliation is the single owner of legacy residue and demotes only by
exact identity. Supervision records a failed pre-restart demotion and
defers instead of minting a continuity. Scheduler faults are isolated per
transaction and backed off, reported once and kept in the record. Queued
commands freeze every tick, so one wedged target cannot starve the
others. An unreadable history fails closed for freezing. boot is a
separate, tested step.

Soul made four passes. The first found boot-wedging on legacy records.
The second traced it to Self's ruling to reopen terminal records, which
was replaced with one owner for the cleanup. Pass three found
cross-target starvation, and pass four found fault re-arming. 241 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 10:37:54 +02:00
Meta Vens
5743a25389 B1 fix batch 4: faults re-arm only on recovery; notes reach marked records
- Fault reports clear only when a step ran and succeeded, not on a backoff
  skip or a handled failure.
- Fault notes are written through cleanup_evidence::last_error_envelope, so
  an unretirable pre-B1 terminal record shows its fault; a failed note is
  printed with the fault instead of swallowed.
- backoff_wait and is_waiting are pure and unit-tested; tick and resume
  return values are pinned.
- migrate_transaction_record is the migration's only entry; the encoder that
  can write a marker is private to cleanup_evidence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 10:28:34 +02:00
Meta Vens
287aa92382 B1 fix batch 3: progress means state advanced; one wedge starves no one
- A tick's progress is a state change, never a last_error rewrite; freezing a
  queued command no longer waits on other targets' progress (still at most
  one freeze per tick, busy targets refused as before).
- Failing transaction steps back off (process-local, doubling from the poll
  interval to 60s) instead of retrying every tick.
- Boot reconciliation runs the resident-issuer pass with history unreadable.
- Resume and retire faults are reported once per transaction and left in
  last_error, which status renders.
- The legacy marker is a private-constructor type inside cleanup_evidence;
  transaction_envelope refuses a record carrying it, the schema migration
  writes through its own path.
- Tests: changing-error wedge, backoff, dead-candidate post-fence branch,
  fault note, marker refusal, torn-history boot residue.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 08:41:25 +02:00
Meta Vens
8998cfcf02 Seed the wedged post-fence abort by hand
A transaction seeded at AwaitingReady fails validation (no fencing evidence),
and nothing at Fencing makes a workload error, so the post-fence abort is
begun directly and the test pins that its failing step only waits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:56:38 +02:00
Meta Vens
81478e6ddd Pin the scheduler's progress report and the post-fence abort path
Cargo-mutants on the previous commit missed the per-candidate progress flag
and the post-fence branch selection in resume_candidate. A repeated error
reports no progress; a dead candidate past the fence aborts; a wedged
post-fence abort only waits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:36:43 +02:00
Meta Vens
81ec1c7f40 Give the wedged-abort test the operator binding a freeze needs
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:21:21 +02:00
Meta Vens
b75fbdf96c Boot reconciliation owns legacy residue; the scheduler isolates per-record faults
Soul's pass on the B1 fix batch found the lift's reopen of a terminal pre-B1
continuity abort could stop Idunn booting (the reopened record claims target
authority beside a live transaction, and the store was already migrated to v4),
and that one wedged abort stopped the whole scheduler.

- The lift no longer reopens anything. A terminal pre-B1 continuity abort that
  issued an activation keeps its phase and completion and carries the typed
  marker CleanupEvidence::LegacySkippedBeforeB1 on its topology_reconciliation.
  Validation accepts that shape only for a terminal continuity abort. Boot
  reconciliation, already the exact-activation owner of that residue, is the
  only cleanup path. A pre-B1 abort still in flight lifts to Pending: it
  already holds its target's authority, so the lift adds no claimant.
- A failed step of a pre-fence abort is recorded as a resumable error, never
  handed to the post-fence abort, which refuses a pre-fence phase and failed
  every tick.
- One transaction's error no longer fails run_scheduler_tick: each candidate
  is resumed on its own and its fault logged, and retiring a terminal record
  tries the next one when an archive fails. An unreadable control store still
  fails the tick.
- serve is boot plus the loop, so a test can run the boot sequence.

Tests pin, through the Engine: the marker and no-reopen for each pre-B1
fixture; a resident terminal abort plus a live transaction plus a second
resident abort for one target; a withdrawn incarnation never re-published and
history keeping one copy after a crash between the archive steps; a wedged
abort leaving freezing alive; an unarchivable terminal leaving resume alive;
and boot demoting the residue.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:17:11 +02:00
Meta Vens
3d4c9d34f1 Correct the B1 legacy ruling: no reopen, reconciliation owns the residue
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 07:10:31 +02:00
Meta Vens
ff3cd51910 Pin the B1 fix batch's survivors
cargo-mutants over the batch's diff missed the lift's gate, the unexplained
projection accounting, the refusal count and the deferral clock. Tests now
cover each: the lift owes only a continuity that issued an activation; a live
transaction accounts for its own activation and nobody else's; three refusals
in history hold the restart ceiling; the deferral lands between now and now
plus its length.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 06:45:37 +02:00
Meta Vens
9e5b7f84fd Close the B1 transition: lift, precondition, boot reconciliation, closed history
Soul found B1's rule sound and its transition unsafe. This makes the rule's
old inputs impossible to reintroduce a stuck state from.

- The control store's legacy lift owns the transition. A pre-B1 continuity
  abort that issued an activation lifts with topology_reconciliation Pending,
  so the one resolution demotes its own activation. A record already terminal
  under the old rule is reopened at Starting, since a terminal record cannot
  owe work. History lifts records as written. Before this, one resident
  record of that shape failed validation and ControlSnapshot::read refused the
  whole store, so Idunn could not boot.
- Supervision owns the Expected-only precondition. When its pre-restart
  demotion fails it mints no continuity and writes next_restart_at_unix_millis
  on the generation's ContinuityBackoff (attempts and window untouched), so it
  neither restarts over an undemotable projection nor retries every tick.
- Boot reconciles once: a projected activation that exactly matches the
  activation a failed continuity in history (or a resident terminal record)
  issued is demoted. Nothing is adopted; an activation no admitted generation,
  live transaction or failed issuer accounts for is reported and left alone.
  New read-only CultCacheTopologyDriver::projected_activation.
- Unreadable history.cc fails closed. The continuity restart ceiling and the
  consumed-command check no longer read an empty history; they stop, and the
  fault is reported once while it lasts (ReportOnce). The undecodable-record
  report is a pure function, pinned.
- docs/deployment-authority.md no longer says the projection never drifts.

Tests: legacy fixtures written by the 9001b58 encoder for the three abort
shapes (a second throwaway generator, see the fixtures README), driven through
the Engine; the seeded-transaction helper now takes a command kind and an
incumbent, and a Deploy carries a frozen-source receipt and a signed brake
release, so Deploy commit, Deploy pre- and post-fence aborts and a continuity
abort over an incumbent run through the real phase machine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 06:11:29 +02:00
Meta Vens
4b5e60fb12 Merge origin/main into idunn/route-b1
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 05:13:07 +02:00
Meta Vens
6e5f87676b Merge route continuity F0: typed readiness, deadlines and actuation state
The generation moves to v3 and the transaction to v4. They carry
ReadinessEvidence (the class is derived from Expected by ReadinessClass::of),
phase deadlines owned by one writer (enter_phase), RouteSupervisionState,
ContinuityBackoff, LeaseAdoptionEvidence and TerminalRecovery. The plan
moves to v3 with frozen deadline durations. A boot migration lifts every
legacy record with stored_at preserved. No decision reads the new fields
yet, so behaviour does not change at this cut.

Soul closed it after one fix batch. The first pass found every commit and
post-fence abort wedged by a deadline nothing cleared; Engine tests now
drive admissions and aborts to Complete. 204 tests. Filed forward: B3 must
give Odin its own readiness class before any route-proof admission ships,
or boot wedges; an unreadable history.cc must fail closed (B1 fix batch).
Back up control.cc before deploying: an older binary refuses a v4 store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 05:08:50 +02:00
Meta Vens
c03d646ae6 Record S3 and C2 code status; hold the StreamPixels merge until B3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 04:15:58 +02:00
Meta Vens
4d8ac7a7e8 Drive the pre-fence abort through the Engine (F0 fix)
advance_pre_fencing_abort survived cargo-mutants as Ok(()): the earlier
pre-fence abort test ran with candidate cleanup already complete. The seeded
transaction now takes its phase, so a Warming transaction is aborted and
driven to Complete through the stub workload port, and the abort's terminal
write is checked to carry no deadline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:50:29 +02:00
Meta Vens
945cb0b322 Count undecodable history, refuse a route-proof Odin authority fallback, test the F0 rules (F0 fix)
History: read_history_transactions dropped undecodable records with .ok(),
which undercounts continuity restarts for backoff. decode_history_transactions
now returns each failure with its key and reason, and the reader prints every
one plus a count. An unreadable history.cc is reported instead of read as
empty. The pre-c848459 IsolationEvidence shape needs no Legacy arm: that
commit made the enum untagged with a Linux variant of the same six fields, and
a test now decodes the old shape under both MessagePack encodings to prove it.
The Legacy structs' stated death condition now says history.cc is never
migrated or pruned, so they die only when history is.

Odin authority: current_odin_authority fell back to the bootstrap key when the
admitted Odin generation carried none (route-proof readiness). It now refuses.
OdinReceipts.authority, read only by tests, is deleted.

Tests through the production path for the rules cargo-mutants showed
unexercised: ControlSnapshot::read of a lifted legacy generation; the
route-proof arm of AdmittedGeneration::validate and route-proof shape checks;
Odin readiness, lease adoption, route supervision and continuity backoff
validation; the admitted half of max_odin_sequence; and the receipt-equality
comparisons in AwaitingReady and Routing, driven through the Engine.

The awaiting-ready default gets a comment that it is unsafe for stateful
targets whose migrations run in AwaitingReady; B5 owns the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:25:20 +02:00
Meta Vens
fd75014b6e Route every phase write through one owner that sets the deadline with it (F0 fix)
Every admission commit and every post-fencing abort failed validation:
transition() stamped a phase deadline on entry to Fencing..Committing and
nothing cleared it, so the record cloned into Complete still carried a
Committing deadline and validate() refused it. The first deploy or continuity
past Fencing wedged in Committing; a post-fence abort never completed.

DeploymentTransaction::enter_phase is now the only writer of phase. It sets
the phase, the update time and the deadline together, so a record outside
Fencing..=Committing carries no deadline by construction. transition(), both
abort completions, the commit, rejected() and Starting/Warming all use it.

Wall-clock ordering rules are deleted: entered_at <= updated_at, created_at <=
updated_at and promoted_at <= updated_at each wedged a transaction after an
NTP step backwards, since same-phase writes stamp now_millis(). The deadline
is entered_at + duration, fixed at entry.

The Engine takes its systemd workload port as a trait object
(Engine::open_with_systemd_workload), which lets three Engine-level tests drive
a continuity transaction from Fencing through Leasing, AwaitingReady, Routing
and Committing to Complete, and a post-fence abort to Complete, with real
Odin-signed evidence and no systemd, nginx or network. deployment_plan's test
fixtures become pub(crate) for them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:11:21 +02:00
Meta Vens
b570114ae6 Record Soul on C1, and widen C2 to the StreamPixels service
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 03:01:45 +02:00
Meta Vens
35e4fad8ab Record Soul on B1 and rule its fix batch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 02:38:33 +02:00
Meta Vens
1450bf9513 Merge route continuity S1: supervision observes, and actuates only on drift
Soul accepted it on 2026-09-29. With an exact fragment, a stale
observation costs one challenge and zero actuations; rendering is
byte-deterministic; drift restores once. Its merge with idunn/cut1-fix5
is clean (213 lib tests). The storm paths it does not claim go to B2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 02:28:28 +02:00
Meta Vens
d795e09a9e Widen B2 to the two storm paths Soul found beyond S1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 02:28:28 +02:00
Meta Vens
5d8eb533ab Pin stored_at preservation in the legacy migration test
The fixture envelope's stored_at now differs from the record's own update
time, so a migration that re-stamps the envelope fails the test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:28:14 +02:00
Meta Vens
09222ad8eb Bump admitted generation to v3 and transaction to v4 with typed readiness (F0)
One migration for the route-continuity foundation. No decision reads the new
state.

- ReadinessEvidence (OdinCorrelated | RouteProof) replaces the bare Odin Ready
  receipt on both records. The class a target must collect is derived from its
  Expected (ReadinessClass::of): a shared-infrastructure odin.verse-rendezvous
  dependency means Odin-correlated, none means route-proof. It is not stored.
  RouteProof evidence is refused for a target that declares Odin.
- Generation carries route supervision state (challenge times, failures,
  degraded marker, actuation window) and continuity backoff. A new generation
  inherits the actuation window and backoff and starts unobserved and
  undegraded. route_repair_started_at stays readable.
- Transaction carries the current phase deadline (stamped by transition from
  the plan's frozen durations) and lease adoption evidence.
- FailedAfterFencing names its recovery: RestartAdmitted, RestoreIncumbent
  (the default for older records) or OperatorRequired{reason}.
- Every v2 generation lifts as Odin-correlated with its receipts unchanged;
  v2 and v3 transactions lift through LegacyDeploymentTransaction. The boot
  migration rewrites both, preserving stored_at, and history reads lift the
  same way. The Legacy structs die when no older record can remain.

Fixtures under tests/fixtures/idunn-control-legacy are the bytes the 9001b58
encoder wrote for records built through its own constructors.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:14:47 +02:00
Meta Vens
6fcc1ba6f3 Freeze per-phase deadline durations into the compiled plan (F0)
An operator binding may now declare a [deadlines] table naming any of the
five post-fencing phases (fencing, leasing, awaiting_ready, routing,
committing) in seconds, 1..=86400. compile_deployment_plan resolves the
binding over Idunn's defaults and freezes the result in the plan, so a later
change to a default cannot move an in-flight plan.

The plan becomes schema v3, with the frozen durations as a trailing field.
A v2 plan keeps its nine-field encoding (the field is skipped when absent),
so every existing plan id still verifies; it runs on Idunn's defaults at read
time. Nothing reads the durations yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:14:47 +02:00
Meta Vens
4a9fe87787 Import incarnation_key into the continuity projection tests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:32:59 +02:00
Meta Vens
44277698c3 A continuity abort resolves its own projection (route continuity B1)
A continuity candidate shares the admitted Expected key. Both abort intents
marked its topology reconciliation Skipped, so a failed continuity left its
candidate activation projected under the admitted key while the admitted
receipt named the older one, and a later deploy's post-fence demotion refused
as substituted.

DeploymentTransaction::abort_topology_reconciliation is now the one rule for
both intents and pre-fence validation: a deployment owes the projection when it
published its Expected, a continuity owes it when it issued an activation.
reconcile_failed_candidate_projection is the one resolution for both abort
paths: a deployment withdraws its own key, a continuity demotes the shared key
to Expected-only with its own exact activation and never withdraws the
Expected. The post-fence incumbent demotion stays deployment-only and exact.

Tests read the persisted topology store after the production
publish/demote sequence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:30:19 +02:00
Meta Vens
87fa57dd8c Revert "Recover fenced rollback from current activation"
This reverts commit a148802cb6.

Rollback after fencing adopted whatever activation was projected under the
shared Expected key, so a continuity abort's leftover activation could be
demoted by a later deploy. The drift is closed at its source by the next
commit: a continuity abort demotes its own exact activation. Rollback demotes
the admitted generation's exact activation again.

The doc paragraph is dropped; the 9f00e7a paragraph above it stays until B4.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:30:09 +02:00
Meta Vens
b619f9875c idunn: route supervision observes; it actuates only on drift (S1)
Delete the stale-observation -> repair-intent -> restore path from
supervise_admitted_route. An exact fragment with a stale observation now
yields one route challenge and nothing else. restore_admitted_membership
returns before nginx -t, the private-mount unit, ufw and reload when the
fragment already equals the admitted membership. route_repair_started_at
stays readable but no longer decides anything.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 00:56:30 +02:00
Meta Vens
9001b58f4b Record the operator's rulings on route continuity Q1-Q6
All six were ruled as recommended, one at a time, on 2026-09-29. Q6 adds
a Soul pass on the weekend CultLib branch before it merges. The campaign
moved to the Eureka session "Codebase audit".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:54:05 +02:00
Meta Vens
5bbb4616dd Add route continuity cut map, Imagination pass 0b
Body facts, identity/lifecycle/authority table, six operator questions and a
draft cut list (S1, B1, F0, B2-B5, S2, C1, S3/C2) for the route-continuity
target. Campaign handed to the "Codebase audit" Self session; operator forks
are ruled there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:48:49 +02:00
Meta Vens
d719485825 Add route continuity and admission target
Eureka target for the route-continuity rebuild after the 2026-09-28 StreamPixels
deployment failure: observation never actuates routing, failure never
accelerates actuation, web apps prove over their own HTTP route, every
post-fencing phase ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:33:20 +02:00
Meta Vens
8ae00a1244 Allow Idunn to cancel stateless candidates 2026-09-28 17:59:02 +02:00
Meta Vens
29946bbe66 Wait for Idunn stable route listener 2026-09-28 17:29:25 +02:00
Meta Vens
ae8ac45df4 Treat process title as launch evidence 2026-09-28 17:11:37 +02:00
Meta Vens
5e94eb82f0 Name native identity fields that drift 2026-09-28 17:02:46 +02:00
Meta Vens
e0f514745a Revert "Expose current pre-fence cleanup blocker"
This reverts commit 4200330fcc.
2026-09-28 17:00:38 +02:00
Meta Vens
4200330fcc Expose current pre-fence cleanup blocker 2026-09-28 16:48:39 +02:00
Meta Vens
e976d32243 Name fields when workload identity drifts 2026-09-28 16:41:57 +02:00
Meta Vens
865190611f Accept dynamic primary group in workload audit 2026-09-28 15:19:52 +02:00
Meta Vens
9f00e7ab84 Replay admitted provider receipts at admission time 2026-09-28 14:47:55 +02:00
Meta Vens
f0465e5c9a Document Rust container shell requirement 2026-09-28 14:20:51 +02:00
Meta Vens
7a61c77420 Revert "Continue commit from refreshed topology receipt"
This reverts commit 55e5d559d6.
2026-09-28 14:20:26 +02:00
Meta Vens
55e5d559d6 Continue commit from refreshed topology receipt 2026-09-28 14:18:22 +02:00
Meta Vens
a148802cb6 Recover fenced rollback from current activation 2026-09-28 13:56:05 +02:00
Meta Vens
02e27a1048 Grant Idunn exact StreamPixels deployment roots 2026-09-27 23:35:51 +02:00
Meta Vens
022096c45e Place StreamPixels on Idunn v2 migration path 2026-09-27 22:20:36 +02:00
Meta Vens
9ede4cd8a0 Let Idunn write Ghostlight Dungeon's three roots on Yggdrasil
The first v2 Ghostlight deploy sealed its release and then failed creating
the runtime bundle: /etc/gamecult/ghostlight/runtime was read-only under
ProtectSystem=full. Runtime root only, not the credential directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 17:05:38 +02:00
Meta Vens
99d3e86d03 Record the ninth batch: the frozen-source digest was exposed too
The version tag could not be recorded where the ruling said, because the
stored value is validated to a bare sha256 shape by a pinned dependency in
another repository. Hands implemented an equivalent implicit version read,
flagged the divergence, and asked whether proceeding was right. It was: the
ruling named a mechanism, the hazard was live, and halting would have left the
fleet exposed.

Five tests prove it by failing without the fallback, which is the point, since
the whole finding was that nothing had ever exercised the stored path.

The frozen-source digest turned out to have the same exposure through a
narrower window, and this cut's own sixth and seventh batches crossed it
twice. Same answer applied, with the prior shapes reproduced from git history
rather than from memory.

Hands also spotted a third instance and declined to chase it: the systemd
actuator compares a raw content-only digest read through procfs against a
stored value now carrying mode, gid and xattr terms. Two different algorithms
compared to each other, which is the same defect a third time. Flagged for its
own look rather than guessed at.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 05:54:43 +02:00
Meta Vens
b029cd29b7 Record the eighth batch, and a migration hazard it did not raise
The bypass is a compile error now, proven by builds that fail on Soul's exact
spellings rather than by reading the lint config. The repository had no CI
surface at all before this, so there was nothing for "denied in CI" to attach
to until now.

Hands flagged that the single-file artifact digest format changed and reasoned
nothing compares against literals. That holds for fixtures and not for
receipts: two call sites in host.rs compare a freshly computed digest against
a stored value. So the first upgrade past this commit makes every already
installed workload fail "installed executable differs from Expected", and
every running one fail "the installed executable changed under the running
process". Idunn is the deployment and daemon-survival authority, and this
would land silently at restart across the fleet.

The ruling versions the digest and verifies in the version the receipt names,
rather than re-sealing admitted state to make new code agree with itself. It
is not closed until a test seals under the old format and verifies under the
new, because the whole finding is that nothing exercised the stored path.

Two bugs in this batch were found by running the suite rather than trusting
it, including a test that set an attribute on a root whose own metadata is
never hashed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 05:27:33 +02:00
Meta Vens
098febb996 Record Soul pass 8, and the cause under three passes of symptoms
The port can be walked around. Two spellings of the original bug restore it
with all 193 tests green, and the proof it leaks is already in the file: one
function still calls fs::read_link directly, and a probe measured sixteen
counted calls beside three uncounted syscalls. My record claimed the count was
total rather than conventional. It is still conventional; the convention moved
from remembering the counter to remembering the port. That is the second time
this record has overclaimed what a pin does.

The artifact digest's single-file path never got the ruling, and it is the
path the installed executable actually takes. Setuid, mode and a file
capability are all invisible there, immediately before launch. Every test for
it wraps the file in a directory so the other path runs, and one of their doc
comments claims to pin exactly the scenario it does not reach.

The xattr framing is sound and nothing proves it. The suite stays green with
values dropped entirely, so a capability edited from cap_setuid to
cap_sys_admin is covered by no test.

Soul named one cause with three faces: every pin here is a convention a later
edit steps around, and the fixtures use the convenient shape rather than the
one production uses. So the eighth batch makes the bypass a compile error and
moves the tests onto the production shape, instead of adding a ninth round of
point fixes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 04:51:18 +02:00