Conversation
…tags Edge v33.0.0's pre-stage branch (68bba8bb) and the persist commit it pins. TARGET_* names the final tags, so the substrate gate stays red until the pins move from rev to tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… descriptors - open_mls_state takes the Engine and returns custody (persist v50 #920, edge #694): a TPM-less host opens the MLS store ON DISK under its software master. Posture::Durable carries `custody`. - #690: withdrawn_by re-derives each withdraws at the depth it was ADMITTED under (check_withdraws_admission_as_admitted), not the new 5-hop default. - CIRISEdge#698: a sealed row's name and type are inside sealed_descriptor. Every drive path that shows, keeps or tests them (listing, metadata, read, raw headers, replace, move, the notes filter) goes through drive::describe; listings say `description: clear|opened|sealed`. STOPGAP body opens the bytes via open_described until edge's descriptor-only door (asked on CIRISEdge#702). - FileWrite.codec: None; SignedCommunity fixtures gain empty cosignatures and lineage (canonical-community only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…e registry is strict, Clause A closes upstream
Per-binary sweep: 141/149 green on the first pass; each red was read:
- A file row is signed by the PERSON (CIRISEdge#675, `files::file_author`).
require_author accepts the caller's person key as well as the node's, and
withdraw_rows signs each `withdraws` with the row's own attester (the
owner's pen for a person-authored row).
- Persist v50's registry is strict (CC 3.1.7 R2(b)): the self-declared age
row is `age_self_declared:band:{band}:v1` (the old spelling still parses).
New gate tests/emitted_dimensions_are_registered.rs runs every versioned
dimension literal in src/ through persist's matcher, with a positive control.
- covers() is grammar-aware (#924): the default-prefix gate now states the
byte-exact prefix half instead of probing with an invented dimension.
- abuse_surface fixtures use registered spellings (the pins still measure).
- Persist refuses a {node,agent} key at registration (Clause A); the test pins
that refusal.
- CIRISEdge#687 is fixed in v33: the inline_band corpus file uploads, so its
KNOWN_DEFECTS mark is removed.
Still red, by design or upstream: the substrate/rev-pin/README/blocked-upstream
gates (clear at the tag switch), the envelope-vocabulary hash (re-pinned once,
at the v51 tag), and rename (needs edge's re-seal door, asked on CIRISEdge#702).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…rify v18.0.0 - rev → tag on every persist and edge line; the lock resolves to the exact commits the tags name. - drive::describe is edge's FileRow::describe: a sealed row opens ONLY its descriptor, under the row's AAD (persist v51 refuses a transplanted pointer at that door). The open_described stopgap is gone. - Envelope vocabulary re-pinned in both gates, reviewed: four rc6 trust-root attach keys added (#937/#938), none removed or renamed, none written here; a6a84cc9… → c9558c98…, equal to persist's published constant. - README pins and the version headline's substrate clause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…the #693 stopgap goes - Pins: edge v33.1.0, persist v51.1.0 (verify v18.0.0 unchanged); no hash re-pin (edge's notice, and the gates agree). - Rename is edge's `files::rename` (CIRISEdge#702): a new row over the same bytes, the name re-sealed for it, signed by the old row's author with the owner's pen; the prior is retired by a `supersedes` once the new row crossed. The drive's hand-built rename_row is deleted. The response says `superseded`, not `withdrawn`: the bytes are the same bytes. - CIRISEdge#693 stopgap deleted: `files::belongs_to` and `in_room_with` are edge's. find_file answers 410 for a row edge's lifecycle calls Superseded or Recanted, and a `withdraws` is still re-derived. A file's metadata reads the prior of an edge rename off the prior's supersedes (`renamed_from`). - selffiles diagnosis: every non-matching corpus row in full (the 3000-byte head cut exactly the failing rows), and a byte probe of each corrupt file on BOTH devices (size vs expected, first differing offset, prefix or not), to place the three ≥1 MiB files that came back with different bytes. drive_crud: 16/16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… seconds `python -m harness.native <scenario> --binary <test-anchor ciris-server>`: N native processes on 127.0.0.1, the anchor block read from the mesh-repro compose file (one copy), production peering routes by default (the ladders' test-admit-peer is opt-in by name). Library + scenarios + CLI; `--keep` leaves the nodes up for the next question. Scenarios: `chat` (two people, pair room, message — the CIRISServer#698 path) and `corpus` (one person, two devices, the transfer corpus compared byte for byte on both). First run: booted, claimed, announced, peered and KEYED the pair room in 27 s; end to end 3.5 min against 45 for the ladder. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…tep with its log evidence, report.json, the client's values.json Every scenario prints what it will prove and how; a failed step says what it MEANS and shows the lines that decide it. `--keep` + `down`. Per-mesh port base (two meshes raced for one pair). Two gates the first runs found, each named as a step: `rooted` (edge's pair verdict, observe or wait) and `reachable_nodes>=1` on POST /v1/contacts (a contact added at 0 keyed a room whose bodies then read not_granted with no self-heal, 3/3 runs). `--direct` makes the second node a direct neighbour (scoped content is one-hop, CC 5.4.6). Chat PASSES end to end in 33 s with both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… apart from bytes that did not (409) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…ed (seal_mismatch), never served The selffiles byte probe (PR #697 CI) showed a second device serving 518 / 610 / 9,529 bytes of `{"chunk_tier":…` — the chunk-DAG manifest — as 1 MiB and 24 MiB files, status 200: edge's puller stores a DAG's manifest as an inline blob and fetches no chunks (CIRISEdge#717). The pointer declares the plaintext size (CIRISEdge#638), so open_whole compares and refuses under the existing `drive.seal_mismatch` id naming both lengths. drive_crud 16/16 (the author's own sizes agree). The ladder's corpus hint names the class. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
|
Edge side of the native-fixture findings:
|
… topology from the root(s) down, and the harness builds exactly it The vocabulary (roots → canonicals → nodes → persons → relations → actor → negatives), its realizability rules (§3), the derivations a CSD/4 checker consumes (node count, devices, direct links, the root ceremony, what is not buildable yet), and a builder that stands the declaration up layer by layer on the native mesh, naming the first layer whose predicate does not hold. Proving set: csd-091-user-chat, csd-092-share-contact-code, csd-093-second-device. First builds: 093 PASS (second device joins the self room, a file opens byte-identical on it, the outsider holds no row); the `reachable` gate now waits through a 404 as well as reachable_nodes=0 (known comes before reachable). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… 41 s, 092 in 35 s, 093)
Builder fixes, each found by a failing build and named in the code: the
keyed-wait polls BOTH sides every tick (the joiner's half advances on its
transcript reads; a short-circuit never read the joiner, so it never
published its KeyPackage); a `contact` after a `reachable` gate is recorded,
not re-POSTed; `contact_code("all")` omits the parameter (a literal `all` is
read as a node id); the `reachable` gate waits through a 404 (known comes
before reachable).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…-replayable row export
roots: founders → {seated, conferrable, node_bearing} (T7 needs seated ≥ M+1
and one conferrable, or recovery never fires); `k` derived (CC T6: K=⌊n/2⌋+1,
a declared k is refused); charter{attach_window_secs, witness_cadence_secs}
→ AttachWindow; lifecycle is a row recipe + asserted verdict, not a flag;
`kind: family` refused (no model behind it, CC 4.2.6); `infrastructure` is
the T7/T8 root, declared and refused as not-buildable by name. `derive`
prints the model constants (K, AttachWindow, Founders, NodeKeys).
Every build exports, per node, rows.jsonl (every federation_attestations
column, admission order) + keys.jsonl, with count and sha256 in the report —
the input CC replays V(rows, t) over for T8 (iii) and turns a trace into a
TLC check. csd-091 rebuilt: PASS, 22 rows on each person's node.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…d a one-word `standing`; the topology report records both per node persist v51 #938's `Engine::lineage_head(root)` → the witnessed head's digest + instant, the charter quorum, the judged index and the latest counting cosign — CC T8 (vii)'s per-node line (CIRISConstitution#131): every node holding the same rows reports the same pair. `standing` is `not_rooted` when the verdict fails or a halt is latched, else `rooted`; `stalled` (T7 liveness) follows when the resolution's `live` is wired. harness/native: rows_export.json / report.json carry, per node, the standing and lineage head for every root the node considers. On the anchor's key root the head is null by construction (no lineage chain); it fills in once an infrastructure root can be minted. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…ity resolves live=false (CC T7) persist v51's `resolve_community` carries the T7 liveness: `live: false` is valid and non-admitting (fewer than M+1 active founders; attached pairs stay rooted, new members refused — edge FIRST_CONTACT.md I12). The route now emits `live` and folds it into the one-word `standing`: not_rooted | stalled | rooted. A key root has no community to resolve and is never stalled. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
|
Correction to my earlier comment on finding 5: your Rule 4 reading is right, and I was wrong to call it an edge gap. A scoped address can't be announced, so it has no multi-hop path by construction, and edge's serve gate admits scoped bodies only over a direct link. CC 5.4.6 itself calls multi-hop reach for group-scoped destinations "an amendment-plane design question". The A/V relay I cited carries identity-plane traffic, not scoped content. One refinement: this doesn't need an N-clique. CC's model is that members relay for members, so for community rooms a connected graph of member nodes should suffice (a member that pulled a body re-serves it). That's not measured yet; CIRISEdge#718 is narrowed to that witness. Self and family rooms fetch from the author, so there a device needs a direct link to the author's node. Any member node can be the relay, a person's own home node included. The case that has no answer today is two people's phones behind the non-member public canonical in a pair room. That waits on a CC amendment, and whether to file it is the maintainer's call. |
…yed by declared id with `notes`, structured failures, 093→094 - values.json: PERSON_<id>_OWNER_KEY_ID, NODE_<id>_URL/KEY_ID, ACTOR_*, ROOM_ID from the room relation; PEER_* kept as the positional alias; `notes` names each value a flow might expect that this declaration did not produce. - step.fail carries `layer`, `rel`, `cc` as fields; a broken build reports `first_failing_layer` beside its error. - csd-093-second-device.yaml → csd-094-approve-new-device.yaml: it is CSD-094's post-state (the client's reading); CSD-093's own flow waits on CIRISServer#678's address answer. Held locally until the queued harness run on 9b4182b completes: every push since 7c13f96 cancelled the previous run before selffiles reported. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…ce, per-kind publish sets, first contact on the opaque plane Edge v34.0.0 pins persist v51.1.0 / verify v18.0.0 (unchanged here); 15 release assets. Source: two new WithholdReason arms classified as their docs read — IdentityRowNodeNotAnnounced is a verdict (Policy: the peer is outside the audience the owner chose, CIRISServer#655's per-node announce ruling), IdentityRowAnnounceUnresolved a read that could not be made (Fault). SERVE_ADVERTISE_POLICY_HASH re-pinned once, reviewed against the serve_policy.rs diff: one row — IdentityOccurrence and TransportDestination leave "public" for "announced → public; unannounced → owner's nodes only" (CIRISEdge#682). 6fbf0282… → e4c4d625…, equal to edge's constant. release_gates 42/42, substrate_contract_gate 9/9, replication_policy_gate 2/2. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… the holder negative; 6.5 min for the 45-minute reading Relations `note` (written on one device, listed on the others) and `corpus` (media_corpus written on one device, read raw on every other device, each file's outcome named by layer: row never crossed / bytes not pulled / wrong bytes / refused by name); negative `no_wider_self_rows` (every self-plane row on the person's own devices at cohort_scope self); `holds_no_row` now refuses to pass vacuously (the outsider must hold SOMETHING from the person's keys — it is peered as a contact in the declaration). topologies/selffiles.yaml on edge v34.0.0: self room on both devices, note listed, 22/25 corpus files byte-identical on the second device, both negatives green, control=5 on the contact's node; the three ≥1 MiB files refused as drive.seal_mismatch (CIRISEdge#717) — the same reading the Docker ladder gives, in a seventh of the time. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…e lists every device; an outsider sees announced devices only Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… the author's node; community rooms a connected member graph; pair-behind-canonical waits on CIRISConstitution#132 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
|
edge v34.1.0 is tagged ( |
…8 refusals leave the debt list, 39 take the client's wording edge v34.1.0 (3c8f1f45): a pin bump — persist v51.1.0 / verify v18.0.0 unchanged, no hash moved (three gates green). It carries the reverse-path fix (CIRISEdge#716: fragments cut to the packet MDU 431 while the link channel takes 425) and the named refusal for a stream pointer (#717 partial). Client 0.5.225 shipped this afternoon and its bundle covers 78 ids the server carried as KNOWN_UNLOCALIZED; the guard's honesty check requires paid debt removed (61 remain) and the pyproject floor moves to 0.5.225. For 39 of them the client wrote user-facing sentences that differ from the server's diagnostic prose; the guard's rule is equality (a prefix reads as the 80-char truncation defect), and the client is the tree of record for wording, so the server now emits the client's sentence verbatim at every site (drive 5, self_devices 16, family_api 16, contacts_chat 2). All six guard checks pass under 0.5.225. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…es the oldest client a consumer may resolve) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…estinations) beside its rows — the #393 item-2 operands (CIRISEdge#722) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…8), the self-diagnosing item-2 refusal (#725) persist v51.1.0 / verify v18.0.0 unchanged; no hash moved (three gates green). Two new WithholdReason arms (#718), both the scope gate reaching a verdict: BlobDiscriminatorUnheld, BlobDiscriminatorOnDerivedAddress → Policy. Measured on selffiles.yaml: every item-2 refusal on the direct link prints `held_signed_route=none` while the receiver's transport_destinations row for the sender is complete (kind, destination, attester, envelope, both signature halves) — the gate queries a key with no row (CIRISEdge#722, edge's). The per-node export now carries metrics.json beside rows and routes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…p (frames that went Resource-first over the Channel fragment cap; CIRISEdge#716/#722) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…n-shaped three-peer topology finds a node-wide deadlock (CIRISEdge#740) Pins: edge v34.3.0 at all three sites (root ×2, crates/ciris-lens-core), lock, README, TARGET_EDGE; substrate/vocabulary/policy gates green, no re-pin. v34.3.0 is #728 — a link belongs to one plane — and on a direct link the selffiles declaration reads 22/25 (the three ≥1 MiB files wait on the DAG pull, edge v34.4.0 / persist v51.3.0). That number is proven for the TWO-peer shape. GET /v1/federation/metrics folds three more of edge's receive-side ledgers the route never carried: transport_inbound_drops (#728), blob_pull_refusals (#717), first_contact_outcomes (#683) — reason → count. harness/native: a claimed node that dials a canonical now PEERS with it (`canonical_peered`, after claim + announce) — the owner's HTTP act in production (traceflow_prod.sh step 7). Dialling alone made the canonical a Reticulum relay: in every native run so far it admitted no node key, rooted with nobody, and distributed nothing, which is why a contact's node listed one of a person's two announced devices (X refused D2's binding for want of D2's key). With the canonical peered, D1 has three peers, and the node deadlocks at the self-room Welcome's kick, 3 of 3 runs: edge's sync StateProvider::local_refs does block_in_place + Handle::block_on per (peer, kind); each call parks a hand-off worker in a blocking-pool slot while awaiting a persist read that needs a slot; 3 peers × 14 kinds = 42 > 32. gdb evidence on CIRISEdge#740; fix goes out as edge v34.3.1 with this declaration as its acceptance. The native selffiles run is red at `self_room_NOT_joined` until then, by design — the peering stays. bigfile.yaml / bigfile-quick.yaml (CIRISEdge#734 lane 7): one 2 GiB (256 MiB) self file streamed in as multipart, pull timed from the row's arrival to byte-state `here`, read back through a streamed `?raw=1` compared by SHA-256, a resume rung that restarts the puller at half the pull; rates recorded, never asserted. Names the drive's own ceiling: UPLOAD_BODY_LIMIT (64 MiB whole-read cap ×4/3 + 1 MiB) answers 413 above it today — the server's lane beside edge #733/#737. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… their own consent The maintainer's ruling (2026-09-30): adding someone requires their consent, and reverse quorum is not a membership rule. Today every roster-growing door adds on the existing members' authority alone (family check_addable, community require_contact — our grant toward them, not their agreement). The design: invite = a proposal that grants nothing; the invitee's own signed acceptance is the condition of the widening; decline and expiry are terminal; every protocol, founder_only included. Admission rule asked of persist (CIRISPersist#955), normative text of CC (CIRISConstitution#133); the server's interim hold is to be deleted when persist's gate lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…ers accept too (maintainer, 2026-09-30) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…iter proposes, the quorum stays on the growth record, expiry on signed instants Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…igning the founding record is consent, a supersede never adds, leave/dissolve replicate at v52 (#956) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
…king pool (CIRISEdge#740) Edge v35.0.0 (b383fde, persist v51.1.0 / verify v18.0.0 unchanged) makes the state-provider read path async and bounds a kick, so a node with three peers no longer parks 3 × 14 block_in_place hand-offs in a 32-slot blocking pool. Pins at all three sites (root ×2, crates/ciris-lens-core with version = "35"), lock, README, TARGET_EDGE; substrate / vocabulary / policy gates green. The one server change is the in-process round harness: `tests/trace_round_e2e.rs` drives `Session::start_round` / `on_message` and `StateProvider::local_refs`, which are async now — `drive_round` awaits them. Production implements neither trait. ACCEPTANCE (the production-shaped three-peer declaration that wedged 3/3 on v34.3.0): `harness/native/topologies/selffiles.yaml` with `canonical_peered` — VERDICT PASS. Self room across both devices at t=72 s, roster, note, both privacy negatives (X control 7 rows, 0 self-plane), corpus 22/25; the three ≥1 MiB files are 409 drive.not_fetched on the second device, which is edge v36.0.0's chunk-DAG pull on persist v51.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… FileError (CIRISEdge#737) Pins at every site (root, crates/ciris-lens-core with version = "36", lock, README, TARGET_EDGE / TARGET_PERSIST); verify v18.0.0 unchanged; substrate / vocabulary / policy gates green, no hash re-pinned. `FileRow::open` now answers `FileError`: the drive's whole read and the notes read map `Unopened(reason)` to the same byte-state words as before, edge's own whole-read cap (reached only when a pointer declares no size) to the existing `drive.too_large_for_whole_read`, and anything else to the existing `drive.unopened` — no new refusal id. MEASURED, NOT YET THE CLAIM: the three-peer selffiles declaration still reads 22/25 — the three ≥1 MiB files on the second device answer drive.seal_mismatch (the row declares 1,048,575 / 1,048,577 / 25,165,824 bytes; the bytes are 518 / 610 / 9,529). D2's federation_blobs holds the three chunk-DAG MANIFESTS as `inline` blobs with the same sha256 as D1's `chunk_dag` rows (554 / 646 / 9,565 B), zero federation_stream_chunks, zero federation_streams, and blob_pull_refusals is empty: the DAG pull never ran for them. Reported to edge with the rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
… selffiles 25/25 on the three-peer shape (CIRISEdge#717) Edge v37.0.0 (5a93a64, persist v51.3.0 / verify v18.0.0 unchanged): a self-room chunk DAG pulls its chunks on the real replication path, and a chunk is served only under its own file. Pins at every site (root, lens-core version = "37", lock, README, TARGET_EDGE); gates green, no hash re-pinned. `WithholdReason` is `#[non_exhaustive]` from v37: the operator classifier names every variant at the pinned tag (the new `ChunkNotInNamedDag` as Policy — the scope gate refusing a chunk outside the file it names) and reads an unknown one from a newer edge as a Fault, never quietly as Policy. MEASURED — harness/native/topologies/selffiles.yaml, three peers with the canonical peered as production does: VERDICT PASS; self room across both devices at t=71 s; corpus 25/25 byte-identical on the second device, including the 1,048,575 / 1,048,577 / 25,165,824-byte files that were manifests on every edge before this (compared in 50 s, 300 s on v36.1.0); both privacy negatives. Device roster and self files work end to end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
DRAFT until the tags land. Pinned today to edge #710's head (
68bba8bb) and the persist commit it pins (789be5b3, v51), with verify at its v18.0.0 tag. At the tags: move the pins from rev to tag, re-pin the envelope-vocabulary hash once (after checking it equals persist's published constant), apply v51's differences from789be5b3(below), rerun the sweep and the ladders.Source changes
open_mls_state(engine, path)→(store, custody). A TPM-less host now opens the MLS store on disk under its software master;Posture::Durable { custody }.withdrawn_byre-derives at each row's admitted depth (check_withdraws_admission_as_admitted).drive::describe(listing, metadata, read, raw headers, replace, move, the notes filter). Listings saydescription: clear|opened|sealed. Its body opens the bytes until edge ships a descriptor-only door (asked on CIRISEdge#702).withdrawsis signed by the row's own attester.age_self_declared:band:{band}:v1, and the old spelling still reads. New gateemitted_dimensions_are_registered.Test sweep (one binary at a time): 141/149 green on the first pass, and every red has been read. Now red only:
substrate::gate_substrate_pins_at_target,gate_no_substrate_rev_pin_at_release,readme_substrate_pins_match_cargo_toml,blocked_upstream_gate.persist_envelope_vocabulary_hash_pinned,gate_envelope_vocabulary_is_the_one_we_adopted.At the v51 tag (from persist/edge's notes):
open_descriptor_for_blobgainscaller_aad; that's edge-internal plus the descriptor-only door.live=false. Re-checkmesh_genesis/mesh_config_surfacetrusted_roots_ofconsumers andGET /v1/trust-root.Ladders: not yet run on this graph. selffiles' negative rungs should go green here (CIRISPersist#919 fixed in v50; names sealed by #698).
🤖 Generated with Claude Code
https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf