Commit graph

591 commits

Author SHA1 Message Date
Meta Vens
495112565b Watchdog reporting target: Idunn decides incidents, Bifrost delivers
First typed Eureka campaign (idunn-watchdog). The typed target and rulings
live in Eureka's mind; this doc holds the rationale and design truths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:48:18 +02:00
Meta Vens
0c80a444f6 B5: literal control snapshots in tests carry the expiry requests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:46:21 +02:00
Meta Vens
3f4d7561d9 B5: every post-fencing phase ends
A deadline resolver runs before a live post-fence transaction's step. Once
the phase deadline F0 stamps on entry has passed, or an operator has asked
for it with `idunn expire`, the phase is resolved as Q3 rules:

- A candidate never issued a write lease (every stateless target, and a
  stateful one still in Fencing or early Leasing) aborts to the incumbent
  through the existing post-fencing path.
- A continuity always aborts: its candidate is the admitted release, and
  supervision restarts it under the continuity backoff. A granted lease
  with no adoption evidence names the failure `lease-not-adopted`.
- A deployment whose candidate was issued a lease is reported and left to
  the operator. That is the open fork: what holds the incumbent after an
  adopted-lease deployment, and whether a warming candidate's silence is
  evidence of non-adoption, are not ruled.

Resume paths cannot extend a deadline: only `enter_phase` writes it. A
record lifted from before deadlines existed is timed once, from the first
time the resolver sees it.

Lease adoption is recorded with Ready (the candidate's presence, or Odin's
Ready correlation, held exactly the granted lease), and the terminal
record names `RestartAdmitted` for a continuity whose candidate adopted it.

F16: Commit goes on from the topology it admitted instead of returning, so
Odin re-stamping every tick no longer sends it round forever.

`idunn expire <command-id>` writes an `idunn.expiry_request.v1` record and
nothing else; the resolver reads it as a passed deadline, and a spent
request is deleted. A new control-store document type: an Idunn from before
this commit refuses a store holding one.

Tests commit Soul's F1 and F2 probes: a continuity whose route proof keeps
failing ends at its Routing deadline, and a withdrawal whose `ufw delete`
keeps failing reloads once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:40:05 +02:00
Meta Vens
fa830c5f6f Route map: B2 + 3d installed on Yggdrasil (a96ad9d)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:33:26 +02:00
Meta Vens
6ff7d5a9c7 Route driver: a fragment already correct is neither written nor reloaded
`install` and `restore` skip the write, the firewall step and the reload
when the fragment on disk already equals what they would write. `restore`
still withdraws the endpoint when the prior membership is none, so a
withdrawal whose `ufw delete` failed repeats only that step.

That skip is sound only while bytes on disk are what nginx last loaded, so
every write whose reload fails is now undone: `restore` puts the previous
fragment back, and `install` puts the baseline back in both the rollback
and the fenced case (it used to retain the candidate for retry, which the
retry would now take for live). An install that never loaded needs no
reload to roll back.

Tests: a retry with an already-correct fragment performs zero reloads (install
and a withdrawal with a failing `ufw delete`); a failed reload puts the
fragment back so the retry reloads. Two engine tests that counted a reload
for withdrawing a never-installed route now count the endpoint withdrawal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:32:38 +02:00
Meta Vens
a96ad9d4e6 Merge B2-3d: the route actuation ceiling counts only Forward
Operator ruling 3d A. Survival actuations are recorded, never counted or
refused. Soul: verify.sh clean at 057bdd5 (341); own mutants killed. Known,
not new: Survival retries inside one transaction reload nginx unbounded
(~120/h per target) until B5, which is the next Idunn cut. Operator
approved installing B2 ahead of B5 (2026-09-30).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:11:18 +02:00
Meta Vens
5939abd87e Route map: B2-3d Soul result; the Survival-bound premise is false
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:09:24 +02:00
Meta Vens
057bdd5c6c B2-3d: status shows a survival-only record on a generation that no longer routes
cargo-mutants on the 3d diff missed `|| -> &&` in render_supervision: no
test held meters with only survival entries under an unrouted generation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:39:32 +02:00
Meta Vens
e9c718e073 B2-3d: the route actuation ceiling counts only Forward
Ruling 3d A (2026-09-30): the 12/h per-target route actuation ceiling
counts only Forward actuations (deploys). Survival actuations (continuity
restarts, rollbacks, withdrawals, admitted-route repairs) are recorded for
visibility in a separate TargetSupervision.route_survivals log (key 6,
newest 12 kept) and are never counted against the ceiling or refused by it.
A target whose continuity spent its six restarts can therefore always be
rescued by a deploy.

Each Survival path keeps its own bound: a continuity's actuations the
restart log and its doubling wait, an admitted-route repair the challenge
backoff, a deployment's rollback or withdrawal the Forward change it
undoes. A candidate whose route proof keeps failing now reloads at most
twice the ceiling per window (12 installs, each with its rollback) instead
of 12.

status prints the survival record beside the ceiling line.

TargetSupervision stays at v1 with the added slot: no installed Idunn has
written the record (B2 is merged, not installed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:21:58 +02:00
Meta Vens
08d346dfae Map the cut that moves binding secrets out of every printable surface
Operator: "do map the cut that'll ensure it doesn't happen again". Q3 A is
ruled (rotate before prod); Q1 A and Q2 A are Self defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:21:48 +02:00
Meta Vens
ecf163ae1c Route map: record 3d A (the actuation ceiling counts only Forward)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:15:57 +02:00
Meta Vens
46d9c2f9dc Merge B2: one per-target route ledger, a typed gate, generation v4
TargetSupervision holds a sliding actuation log and the continuity restart
log (Q-B2-1 a); Forward can be refused (fails at once with the reopen
time, Q-B2-2), Survival is never refused and counted when it can be;
continuity restarts are Survival; a full disk neither spins supervision
nor reports unlanded writes as progress. Generation v4 with a typed lift
from v3 (irreversible; back up control.cc and history.cc before install).
Four Soul passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:36:34 +02:00
Meta Vens
ed07241f34 B2 final: drop the merged history-ceiling test that counts in its own closure
continuity_gives_up_on_a_release_that_will_not_start came from main with the
old rule (three failed restarts per generation, counted from history). The
branch owns the ceiling in TargetSupervision meters now (six per window), and
the test exercised no production code: it filtered transactions in a local
closure and compared to the constant, which the meters changed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 06:33:56 +02:00
Meta Vens
8b9ed0e8d9 B2 final: pass the pass's snapshot to the lost-race test that predates it
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 06:28:40 +02:00
Meta Vens
eceb742ea3 B2 final: an in-memory challenge wait ends with the write that outlives it
The wait spacing a challenge whose record failed to land was removed only
when a challenge record for that target landed. It now carries the stamp of
the target's stored records (generation, meters, transactions) as they were
when the record failed, and the supervision pass drops it as soon as the
stamp differs: any write for the target landing, or the target retired or
withdrawn, returns the schedule to the stored value. A wait can no longer
hold a drift repair after the disk recovers.

Soul's probes become tests named for the rules: one reload per wait for a
re-drifting fragment, a proved wait of one observation age, a failed wait
that follows the stored doubling, a lost race leaving no wait, the wait
ending on a landed write, the wait ending with its target. The reloads()
helper is gated to unix (its use of the route stubs broke the Windows
--lib --tests check). Comments on the wait field and the failed-challenge
record now say what the code does.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 06:26:04 +02:00
Meta Vens
c127b53211 B2 final: verify the Windows lib and tests, gate the unix-only reloads helper
reloads() reads unix-only route stubs and has broken
`cargo check --target x86_64-pc-windows-gnu --lib --tests` since 8212b9d.
Gate it, and add that check to scripts/verify.sh so unix-only test code
cannot leak out of its cfg unnoticed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 06:25:57 +02:00
Meta Vens
cccfe8e174 x
# Conflicts:
#	src/control_plane.rs
2026-09-30 06:23:11 +02:00
Meta Vens
d83b1a9c95 B2 fix batch: give the stale-route test a wait that starvation cannot outrun
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 05:04:18 +02:00
Meta Vens
b6e78e5366 B2 fix batch: pin the in-memory wait against the attempt's start, not the clock after fifty laps
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 04:53:25 +02:00
Meta Vens
0703691790 B2 fix batch: widen the stale-route test's wait so load cannot expire it
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 04:49:33 +02:00
Meta Vens
05881ea8d8 B2 fix batch: say a failed challenge record once, not once per temp file name
The store error chain carries a fresh temp file name per attempt, so the
report-once key never matched twice. Report the root cause.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 04:31:48 +02:00
Meta Vens
74e7ed495e B2 fix batch: a lost record race is progress, a refused write is not
replace_generation now tells a lost compare-exchange (another writer moved the
store: the pass ends and re-reads) from a write the store refused.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 04:27:03 +02:00
Meta Vens
757e55be8f B2 fix batch: an unwritable store is not progress and not a hot loop
A supervision pass whose challenge record could not be written reported
progress, so serve() skipped its sleep, and the challenge wait lived only in
the store: a drifted fragment with a failing reload was reloaded every lap.
Progress is now a record that landed; the wait is also held in memory per
target until a record lands; the failed write is said once per target.

The stopped-restarting message says when the route ceiling reopens when the
ledger is full, so "free for a deployment" is true.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 04:15:49 +02:00
Meta Vens
012853529c Idunn map: storm (b) under Survival-always-counted; B2 Soul rulings
Continuity restarts are Survival; Survival counting is best-effort when
the ledger cannot record it, Forward stays fail-closed (2026-09-30).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:54:02 +02:00
Meta Vens
76aaff1e71 B2 fix batch: the stateful routed world names its command kind
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 02:48:34 +02:00
Meta Vens
8447c22201 B2 fix batch: a continuity is survival, and survival runs uncounted
The route gate derives the charge from the transaction's command kind: a
continuity's preflight and install are Survival (never refused, counted), only
a deployment's are Forward. A Survival that cannot be recorded is logged and
proceeds; a Forward that cannot be recorded is refused. A proved route
challenge whose write is lost ends the pass like a failed one instead of
failing it. status() draws its target union from one function.

Tests: continuity through a full ledger, uncounted survival vs refused forward,
the second-failure wait, the lost proved-challenge write, each v3 route
supervision field, and the admitted-or-metered union. The routed world takes a
command kind, so the refusal tests run as deployments.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 02:44:43 +02:00
Meta Vens
bc0f82e4f1 Merge origin/main 2026-09-30 02:35:18 +02:00
Meta Vens
bb0d23c780 Merge W1, T1, T2: Windows actuator check in verify.sh, one cleanup rule, strict chunk sizes
Soul found W1 unenforced, T1 respelled in the validator and two T2 rows
unpinned; all fixed with mutation-killed tests (1afe046).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:03:15 +02:00
Meta Vens
ef6cfb177f B2 rework: pin the resume wait's clock-step guard; correct the actuator doc
cargo-mutants-style probe C26 (the resume backoff read without its longest
wait) survived: the clock-step test called is_waiting directly, not the resume
site. An Engine-level test now sets a real half-minute backoff, which holds,
and a day-ahead one, which is attempted.

docs/host-actuator.md said continuity gives up after three attempts; it is six
restarts inside an hour.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 01:53:38 +02:00
Meta Vens
1afe0466a4 verify.sh runs the Windows check before the tests
The probe at d32395a hung inside a library test and never reached the
Windows check. The check is fast and independent of the tests, so it
goes first and cannot be masked by a hang.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:58:19 +02:00
Meta Vens
b55bb97f46 B2 rework: the refused-preflight test drives the abort cleanup by steps
The resume backoff, not the ceiling, spaces the cleanup retries after the
abort is recorded; the test asserts the abort at once and then steps it out.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:43:29 +02:00
Meta Vens
bdcd23768b Abort cleanup test rows carry only the activation
The workload rows were refused by the fixture on grounds outside the
rule, so they were dropped instead of asserted. The workload operand of
the owed rule stays pinned by the method-level test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:41:58 +02:00
Meta Vens
55f433eb2d B2 rework: read the unsettled meters for the stepped-back wait check
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:41:04 +02:00
Meta Vens
e7605efe26 B2 rework: a stepped-back clock is settled where the meter decides
live_entries only reads future entries as now, so a log that is never
written kept looking recent until the clock caught up: a refused route
actuation or an exhausted restart log stalled for the length of the step, not
one window. A refused forward actuation now writes the clamped log when it
changed, and a supervision pass settles the target's meters before deciding
from them, ending the pass with the write. The restart due time comes from the
raw last entry so the longest-wait guard is the one deciding a stepped-back
wait.

Also: the ported restart test tolerates an empty live set, the refused-preflight
test reads the transaction from history, and a held-record test no longer
depends on the host having no nginx.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:37:56 +02:00
Meta Vens
e7ee053427 Drop the workload-only rows from the abort cleanup test
A transaction holding a workload and no activation is refused by the
fixture before the cleanup rule is reached, so those rows could not
speak for the rule. The method-level owed test keeps the workload-only
case.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:36:31 +02:00
Meta Vens
0bb791d913 B2 rework: name the routed world's killable workload apart from the candidate's
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:33:35 +02:00
Meta Vens
8212b9d15d B2 rework: rebuild the tests on the routed world and the target meters
The route-proof world's hand-built promotion is deleted: the world runs over
stub host programs, so Routing installs and proves the route for real and
every former promote_by_hand is a real step. The salvage fixtures of the old
B2 are not ported.

New tests pin each ruling under its own mutation: a full ledger still admits
and counts every survival actuation, first deployments are metered, a refused
preflight starts no private-mount unit and fails at once with the reopen time,
the actuation log slides, a clock step stalls nothing past one window, a
failed challenge ends the pass instead of losing a CAS, a proved challenge
clears the degradation, both storms are bounded, restarts are spaced,
counted in the mint and read from the target's own log (unreadable history no
longer stops crash recovery), and the v3 lift is pinned over golden bytes cut
with the 583b2a7 encoder, refusing a record that shows retired meters.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:31:12 +02:00
Meta Vens
88ce30905f Judge the post-fencing abort test only on terminal shapes
The Pending post-fencing rows sat in a Fencing-phase transaction that is
refused for unrelated reasons, so the row could not say what it claimed.
Post-fencing rows now cover the recorded values a terminal abort carries.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:31:03 +02:00
Meta Vens
916caed9dd Merge guide text: Muninn no longer carries daemon health flags
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:27:40 +02:00
Meta Vens
61842a3952 Pin the chunk-size line against vertical tab and carriage return
Rows for a vertical tab before an extension, a carriage return before an
extension, and a size line ending in one or two carriage returns, so a
wider trim than SP and HTAB, or a stripped trailing carriage return,
cannot be taken.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:17:27 +02:00
Meta Vens
36467153b5 An abort's recorded candidate cleanup is judged by candidate_cleanup_owed
The pre-fencing validator respelled the owed rule inline. Both abort
validators now compare against candidate_cleanup_owed, so the post-fencing
abort, which had no check on its recorded candidate cleanup, is held to
the same rule. One test drives both aborts through every activation and
workload row.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:17:23 +02:00
Meta Vens
9f17a733dc guide: Muninn no longer carries daemon health flags
The retired --idunn-rudp-health family is rejected by the binary; Raven is
liveness by runtime presence, Starfire and Nightwing by witness scripts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:16:30 +02:00
Meta Vens
525856e9cd scripts/verify.sh is the one verification command
The Windows check on idunn-host lived only in README prose, so nothing
ran it and d32395a broke the Windows build unnoticed. verify.sh runs the
library tests and the x86_64-pc-windows-gnu check of idunn-host, and the
README names it as the verification command.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:15:32 +02:00
Meta Vens
3cedfef50a Map: fold in the Odin-lifecycle authority audit and the 2026-09-30 rulings
Records Q-O1 (Idunn proves; supersedes Q1 (b)), Q-O2, Q-O4, Q-O5 and the struck
Q-B4 held clause; Q-O3 open. Adds the audit site table and target authority
map (section 5), cuts X1, A1, B4prime, A2, A3, O-R, L-R, marks R1 superseded by
A1, records Odin's temporary fatal rule and the Soul open items, and updates the
Cut status block.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:14:51 +02:00
Meta Vens
76c7b13b33 B2 rework: per-target supervision, typed route gate, generation v4 (production)
A target's route actuations and continuity restarts are sliding logs in one
TargetSupervision record (idunn.target_supervision.v1), created by the first
charge so first deployments are metered. The route driver asks a
RouteActuationGate before every group of host mutations; Forward changes can
be refused with a typed RouteActuationRefused, Survival ones (restoring the
admitted or incumbent route) are always admitted and always counted.

Generation moves to v4 with a typed lift from v3 that retires keys 18 and 20,
refuses a record showing the retired meters were written, and adds last_error
at key 21. Continuity restarts are counted in the mint CAS against the
target's own log; the history scan and both carry compensators are gone. Any
write to a generation or to its target record ends that target's supervision
pass. A due time further ahead than its owner's longest wait reads as due.

Tests do not build in this commit; the next one rebuilds them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:02:24 +02:00
Meta Vens
97fb2b8871 Map: B2 rework plan, D1/T1/T2/W1/R1 cuts, and the 2026-09-30 rulings
Splice the B2 rework map (owner map, per-file cut, verification, live
relevance, subtraction estimate) under B2; add cuts D1, T1, T2, W1 and R1;
record Q-B2-1 (a), Q-B2-2 (fail at once), Q-R1 (a) and Q-B4 (routed by
Idunn's route proof, unrouted by admission plus workload; the Odin non-Ready
veto clause held open). B4 is blocked on the Odin-lifecycle authority audit.
B2, D1, R1 ready for Hands; W1, T1, T2 in progress on hands/idunn-w1-t1-t2.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 23:44:25 +02:00
Meta Vens
bf5347c370 The chunk-size line admits whitespace only before an extension
RFC 9112 7.1 allows whitespace before a chunk extension and nowhere
else. The reader trimmed both ends of the size, so " 3" and "3 " were
taken. It now splits at the first ';', trims trailing SP and HTAB only
when an extension follows, and leaves parse_digits as the digit
authority. Rows use an honest body so only the size line differs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 23:40:11 +02:00
Meta Vens
5f8417589d Candidate cleanup owed is one method both abort intents share
The two-flag helper let either call site swap or fold an argument
unnoticed. DeploymentTransaction::candidate_cleanup_owed reads the
transaction itself, and a four-row table drives the method and both
intents.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 23:38:26 +02:00
Meta Vens
94c7691cb6 Map: the C2 acceptance hour passed; Odin 5c37860 deployed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 22:56:10 +02:00
Meta Vens
7480ee9d1c Map: StreamPixels ship completed through Idunn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:55:34 +02:00