Skip to content

0.5.218: client-review fixes (#680–#686, #688, #692) - #695

Open
emooreatx wants to merge 9 commits into
integ/0.5.218from
fix/client-review-0.5.218
Open

emooreatx wants to merge 9 commits into
integ/0.5.218from
fix/client-review-0.5.218

Conversation

@emooreatx

Copy link
Copy Markdown
Contributor

Fixes found by CIRISClient's CSD reviews, against integ/0.5.218. Each commit closes (or partly closes) one issue:

Local: full cargo test green (the one red was a new test built against the pre-edit lib; rerun green), clippy -D warnings clean.

Not in this PR: #687 (households: rename is S; listing pending quorum changes needs a decision on node-local vs replicated proposals).

🤖 Generated with Claude Code

https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf

emooreatx and others added 9 commits September 28, 2026 10:22
)

rescale re-derived quorum:M/N whenever the roster moved, keeping the ratio and
flooring at a strict majority, so 3/5 shrinking to three members became 2/3
and 2/3 growing to four became 3/4: a rule change no member decided, and a
client could not state how many signatures a change needs. CC 4.4.3.4.2.1
(normative) makes M an absolute count and N documentary, and persist v49's
evaluator counts it that way. carry_quorum keeps M and updates N, lowering M
only when the roster falls below it (persist refuses M > N, and a household
that could never act again is a deadlock). A stored quorum no longer has to be
a strict majority to parse; a DECLARED one still does (normalize_protocol).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
… is family|key (#681)

accepted was read from a user_accepts field persist's TrustRootVerdict never
had, so every root, including the one the node is entrenched under, read
accepted:false. It is now the typed verdict's edge_exists (a live
delegates_to(node -> root)). root_kind serialized as persist's enum spelling
(Family/Key) against a route contract of family/key; it is now mapped from the
typed field. A handler test through the real router pins both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
…RSON keys (#683)

GET /v1/federation/peers/{key_id}/sas derived the code from THIS NODE's key
and the contact's PERSON key, so Alice's node showed sas(nodeA, Bob) and Bob's
showed sas(nodeB, Alice) — two different pairs, so an honest comparison always
read as a mismatch. When the peer's record is a person (identity_type user),
the local side is now this node's OWNER, the pair a chat uses; node-to-node
peers are unchanged. A node with no owner refuses by name
(peers.sas_no_owner, 409; on the localization debt list, MAX_UNCOVERED 140).
Pinned by a two-node, two-person test that both sides derive the same words
and digits for each other. Also: an unused binding left by #686.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
POST …/peering/revoke takes a grant's attestation_id, and nothing listed them,
so the app could withdraw only a grant it had received in the same session —
consent met on paper and missed in practice (CC 1.5). The owner-gated GET
returns every LIVE replication grant this node holds as receipts (the same
revocation-folded read revoke checks against, owner-authored rows first), with
peer_key_ids and withdrawable (exactly: the owner signed it — the rule revoke
applies). The peering test lists the grant it just made and pins the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
The response now carries audit_event_id: the hard_case:trace_erasure row persist
records, found by its own coordinates (kind, target = the agent hash, emitted AT
the erasure instant), so a client can point the person at the record of their
erasure; null when nothing was erased (a repeat records no new row).
scope_note cited closed CIRISPersist#573; the live gap is CIRISPersist#914. A
test ingests a real batch, erases it, and requires the lookup to find the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
`/v1/accord/provision` is not a route. The refusal is now the localized
`accord.family_not_supersedable` and names the real remedy:
genesis/remint-source → genesis/propose + cosign → trust-root/import.
The reserved change/supersede routes say why they refuse. MAX_UNCOVERED 140 → 141.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
`PUT …/sas {result: match|mismatch|withdrawn}` records the outcome and stamps
it (`sas_result`, `sas_result_at`). `{verified: bool}` still works: true is a
match, false is a withdrawal. Peer rows carry sas_verified, verified_at,
sas_result and sas_result_at. `PUT …/appearance` writes `alias_override`
(the local name; "" clears it), which the rows used to hard-code null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
…om rows carry an envelope

The detail read returns `moderators: null` with `moderators_readable: false`
on a store error (widenings/revocations likewise null), where it used to
return []. Every room row carries its envelope (subject, attester from the
signed record by persist_row_hash, cohort_scope, dimension, persist_row_hash).
The appoint route (2) waits on the per-community lens in persist's
`appointed_moderators_of`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125h5ochAX5H79GWi2AR4WF
…apped per client

Every insert first drops grants more than 10 minutes past expiry (and their
user_code index entries), so a late poll still reads 410 expired_token but the
map no longer grows with uptime. The unauthenticated code-request leg refuses
a ninth live pending code for one client_id (429 slow_down); the owner-session
/delegate path is pruned, not capped.

Also two clippy fixes in federation_admin.rs from the #680/#685 commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QdM21U8xUmHk2TwrMTKJPf
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@emooreatx

Copy link
Copy Markdown
Contributor Author

Note for after the substrate adoption (#697, persist v51.0.0): a stalled trust root now resolves with live=false while trust_root_valid stays valid (CC 3.2 T7; edge's ruling in FIRST_CONTACT.md I12: already-attached pairs stay rooted, new members are refused). GET /v1/trust-root (#681, this PR) should report that stall, not only accepted. Small follow-up once both land.

🤖 Generated with Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant