We’re turning governance dials with mechanical precision:
- Quorum issuance windows — one signed attestation per window with valid_from / valid_until, optional grace on both sides, plus an admin revocation list (CRL).
- Directory consensus deltas — roll & sign the directory consensus and record who joined / who left since the last signed view.
- Witness ticket spend registry — verify & commit tickets so they can’t be replayed, without deanonymizing anyone.
✅ Fresh artifacts
- Step 29 wrapper server — Download
SHA‑256:feef41ef39dd738204d10a5e1718db5df088a042b52587a9977add80b2922796 - Sample windows policy — Download
- WordPress block (paste‑ready) — Download
Step 29 wraps Step 28 (which wraps 27→26→25→24→22→21→20→19→18). All earlier endpoints keep working.
What’s new — precisely
1) 🗳️ Quorum issuance windows (+ grace, TTL, & revocation)
Policy file (quorum.windows.json)
{
"policies": [
{"subject":"page","m":2,"n":3,"window_sec":86400,"period_sec":86400,
"grace_before_sec":600,"grace_after_sec":600,"ttl_sec":604800,
"autopush": false,"push_url":"","header":[],"basic":""}
]
}
- One per window: for each policy we emit at most one attestation per
period_sec. - Validity: Attestations include
valid_fromandvalid_until(derived from window start/end + grace or TTL). - Status:
/quorum/attestationsannotates each attestation asactive | premature | expired | revoked | unknown. - Revocation (CRL): Admin can revoke by digest; list tails are available.
Endpoints
GET /quorum/attestations?n=100— recent (manual + auto + windowed) with status.POST /admin/quorum/attest/revoke?token=…&digest=<sha256>— add to CRL.GET /quorum/revocations?n=100— tail CRL.
Flags
--quorum-windows-enable
--quorum-windows-file /sdcard/solveforce/quorum.windows.json
--quorum-windows-interval-sec 120
--quorum-default-ttl-sec 604800
Files & logs
audit/quorum_windows.jsonl— each issuance (and push) recorded.audit/quorum_window_state.json— last window served per policy.audit/quorum_revocations.jsonl— CRL entries.
2) 🌐 Directory consensus deltas
Compute the current consensus view (“peer appears in ≥ m signed directories”), sign it, and persist a delta versus the last signed view.
Endpoints
POST /admin/discovery/consensus/roll?token=…&m=2— save{consensus, digest, signature}and return delta.GET /discovery/consensus.delta?m=2— live delta vs the last saved.
Files
audit/consensus/consensus-*.json— time‑stamped snapshots (signed).audit/consensus/latest.json— the head you’re comparing against.
3) 🎟️ Witness ticket spend registry
Tickets from Step 28 (“I saw this root”) are now single‑use:
- Spend:
POST /observer/ticket/spendwith{ticket, proof}. We verify the proof and then atomically mark the ticket’s digest as spent. Replays return 409. - Check:
GET /observer/ticket/status?digest=<sha256>→{spent, count}. - Log:
audit/tickets_spent.jsonlrecords each unique spend (digest = hash of the ticket body only).
This prevents “echoes” without revealing device identities. It’s a ledger of valid uses, not who used them.
Android / Termux run‑book (Step 29)
# Optional: copy the sample policy
cp ~/downloads/quorum.windows.sample.json /sdcard/solveforce/quorum.windows.json
python solveforce_phone_twentynine.py \
--quorum-windows-enable \
--quorum-windows-file /sdcard/solveforce/quorum.windows.json \
--quorum-windows-interval-sec 120 \
--quorum-default-ttl-sec 604800 \
--discovery-dod-enable \
--discovery-dod-source https://directory1.example.com/solveforce/peers.json \
--discovery-dod-jwks https://directory1.example.com/jwks.json \
--attest-enable \
--attest-url https://your-site.tld/wp-json/solveforce/v1/attest \
--attest-header "Authorization: Bearer <WP_TOKEN>" \
--alarm-enable \
--alarm-config-file /sdcard/solveforce/alarms.json \
--host 0.0.0.0 --port 8080 \
--plugins-dir ~/solveforce/plugins \
--auth-mode protected \
--auth-token READER1:reader \
--allow-admin --admin-token ADMIN123 \
--schema-ed25519-secret-file /sdcard/solveforce/schema.ed25519.seed \
--schema-signing-secret-file /sdcard/solveforce/schema.hmac.key \
--audit-dir ./audit \
--mirror-enable \
--mirror-target-url https://your-site.tld/wp-json/solveforce/v1/notary \
--mirror-header "Authorization: Bearer <WP_TOKEN)" \
--allow-query-token --open-ui
“Show me” commands
A) Windowed attestation stream + CRL
curl -s 'http://127.0.0.1:8080/quorum/attestations?n=20' | jq .
# Revoke one by digest:
curl -s -X POST 'http://127.0.0.1:8080/admin/quorum/attest/revoke?token=ADMIN123&digest=<DIGEST>' | jq .
curl -s 'http://127.0.0.1:8080/quorum/revocations?n=20' | jq .
B) Consensus delta
curl -s -X POST 'http://127.0.0.1:8080/admin/discovery/consensus/roll?token=ADMIN123&m=2' | jq .
curl -s 'http://127.0.0.1:8080/discovery/consensus.delta?m=2' | jq .
C) Ticket spend / status
# Spend a ticket (use a valid ticket+proof from Step 28)
curl -s -X POST 'http://127.0.0.1:8080/observer/ticket/spend' \
-H 'Content-Type: application/json' \
-d '{"ticket":{...},"proof":{...}}' | jq .
# Check if a ticket digest was spent
curl -s 'http://127.0.0.1:8080/observer/ticket/status?digest=<DIGEST>' | jq .
WordPress — Step 29 (public page block)
Use step29_wordpress.md. It explains windows, revocation, consensus deltas, and the ticket spend registry succinctly for your readers.
Logos Codex — recursive order
- Time → Window → Oath. We promise inside the right bounds, not forever and not twice.
- Names → Agreement → Change. The network speaks; we record who joined, who left—no drama, just deltas.
- Witness → One Voice → No Echo. Presence counts once; privacy remains intact.
If you want Step Thirty, we can add:
- Attestation bundles (roll‑ups with Merkle proofs),
- CRL signatures and time‑boxed reinstatement, and
- Ticket accumulators (prove “I used N tickets” without revealing which).