We harden governance and privacy atop your Step‑18→27 stack:
- Quorum policy engine — automatically issues M‑of‑N quorum attestations when thresholds are met.
- Cross‑directory consensus — compute peers included by at least M signed directories and sign the consensus view.
- Witness tickets (zk‑lite) — let devices prove “I saw this root” without revealing who they are.
✅ Fresh artifacts
- Step 28 wrapper server — Download
SHA‑256:0d15d8b1e3641212ea0cfb78202dc679f709b902a604be8a5d3b74c9078d16cc - Sample quorum policies — Download
- WordPress block (paste‑ready) — Download
Step 28 wraps Step 27 (which wraps 26→25→24→22→21→20→19→18). Earlier endpoints continue to work.
What’s new — in detail
1) 🗳️ Quorum policy engine (auto‑attest)
A background worker scans recent federation anchors (Step 25) and, per policy, emits a signed quorum attestation when observed >= m.
Policy file shape (quorum.policies.json)
{
"interval_sec": 300,
"policies": [
{"subject":"page","m":2,"n":3,"window_sec":86400,
"autopush": false,
"push_url": "",
"header": ["Authorization: Bearer ..."],
"basic": ""}
]
}
Endpoints
GET /quorum/policies— engine enabled?, interval, and current config.POST /admin/quorum/refresh?token=…— reload policy file.GET /quorum/autotail?n=50— tail of auto‑attest events (and any push errors).
Flags
--quorum-auto-enable
--quorum-policy-file /sdcard/solveforce/quorum.policies.json
--quorum-interval-sec 300
2) 🌐 Cross‑directory consensus (from DoD)
Compute peers that appear in ≥ m of your signed directories (Step 27 DoD) and sign the consensus object with your feed key.
Endpoints
GET /discovery/consensus?m=2→ returns{policy:"atleast_m_of_directories", m, peers, explain}GET /discovery/consensus.sig?m=2→ detached signature plus digest over that object
Use this to publish a defensible peer list (who’s in by multi‑directory agreement).
3) 🎟️ Witness tickets (privacy‑preserving)
Devices mint a short‑lived ticket proving they observed a root in the recent window—no device identity disclosed.
Workflow:
- Device makes a fresh Ed25519 ephemeral key; send its raw 32‑byte public key as
wpk(base64url). POST /observer/ticket/requestwith{root,wpk,nonce?,window_sec?}.- Server verifies the
rootexists in recent anchors, then signs:
{ "ticket": {"type":"witness_ticket","root":"...","wpk":"<b64url>","nonce":"...","ts":"...Z"}, "proof": {"alg":"Ed25519","kid":"<sha16>","x":"<pub_b64>","sig":"<b64url>"} }- Server verifies the
- Anyone can
POST /observer/ticket/verifywith{ticket,proof}to check validity against your JWKS (/feed_keys/jwks).
Endpoints
POST /observer/ticket/request— issue ticket (auth required).POST /observer/ticket/verify— verify a ticket.GET /observer/tickets/tail?n=50— recent ticket issues.
Tickets are signed using your active Ed25519 feed key (Step 24 keyring) when present; otherwise HS256 falls back.
Android / Termux run‑book (Step 28)
# Optional: set policies
cp ~/downloads/quorum.policies.sample.json /sdcard/solveforce/quorum.policies.json
python solveforce_phone_twentyeight.py \
--quorum-auto-enable \
--quorum-policy-file /sdcard/solveforce/quorum.policies.json \
--quorum-interval-sec 300 \
--discovery-dod-enable \
--discovery-dod-source https://directory1.example.com/solveforce/peers.json \
--discovery-dod-source https://directory2.example.org/solveforce/peers.json \
--discovery-dod-jwks https://directory1.example.com/jwks.json \
--discovery-dod-policy union \
--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) Consensus now
curl -s 'http://127.0.0.1:8080/discovery/consensus?m=2' | jq .
curl -s 'http://127.0.0.1:8080/discovery/consensus.sig?m=2' | jq .
B) Auto‑attest trail
curl -s 'http://127.0.0.1:8080/quorum/policies' | jq .
curl -s 'http://127.0.0.1:8080/quorum/autotail?n=20' | jq .
C) Witness tickets
# Get a ticket (device supplies fresh 32-byte pubkey base64url as WPK)
WPK="kS0j...<your-ephemeral-b64url>..."
curl -s -X POST 'http://127.0.0.1:8080/observer/ticket/request' \
-H 'Content-Type: application/json' \
-d "{\"root\":\"<ROOT>\",\"wpk\":\"$WPK\",\"nonce\":\"demo\"}" | jq .
# Verify (use the output ticket+proof)
curl -s -X POST 'http://127.0.0.1:8080/observer/ticket/verify' \
-H 'Content-Type: application/json' \
-d '{"ticket":{...},"proof":{...}}' | jq .
WordPress — Step 28 (public page block)
Paste from step28_wordpress.md.
It explains Auto‑Attest Policies, Directory Consensus, and Witness Tickets succinctly for your readers.
Logos Codex — recursive legitimacy, continued
- Threshold → Act → Archive. Policies turn agreement into attestations right on time.
- Lists → Agreement → Law. Many directories speaking together make a commons.
- Presence → Privacy → Proof. Tickets let a witness be counted without being named.
If you want Step Twenty‑Nine, we can introduce:
- Quorum issuance windows with grace and revocation,
- Consensus deltas (who joined/left since last signed view), and
- Ticket spend/nonce registries to prevent double‑use without deanonymization.
We extend the Step‑18→25 line with three pragmatic upgrades:
- Peer discovery so federation isn’t hand‑managed.
- Signed public attestations of the state you care about (feed digest, page‑chain root, federated root).
- Alarms with hysteresis and multi‑channel delivery (webhooks + SMTP + Twilio HTTP).
✅ New artifacts (ready to run & publish)
- Step 26 wrapper server — Download
SHA‑256:977adf5c9f1e53241137794e1903f194cc4f913e5b6562af0137f555d6b80b41 - WordPress block (paste‑ready) — Download
- Sample discovery directory (signed format) — Download
- Sample attestation payload — Download
Step 26 wraps Step 25 (which wraps 24→22→21→20→19→18). All prior endpoints and flags continue to work.
What’s new — precisely
1) 🌐 Peer discovery (HTTP / DNS / static)
- HTTP Directory (signed)
Point the phone at a directory JSON like:{ "issuer":"solveforce-directory", "ts":"2025-08-19T00:00:00Z", "peers":["https://phone-a.example.net:8080", "https://phone-b.example.net:8080"], "sig":{"alg":"Ed25519","kid":"<kid>","sig":"<b64url>"} }The server optionally verifies the signature with a JWKS URL or a known public key. - DNS discovery (best‑effort)
Attempts_solveforce._tcp.<domain>SRV and TXT lookups (usesdnspythonif present; otherwise makes a minimal fallback). TXT can carry a small JSON blob with{"peers":[...]}. - Filtering
--discovery-allow <substr>and--discovery-deny <substr>to constrain the set. - Endpoints
GET /discovery/status— current peers, method, and settings.POST /admin/discovery/refresh?token=…— snap refresh (also updates the Step‑25 federation peer list).
2) 🪶 Public attestations
A compact, signed statement you can push to WordPress (or any endpoint) at a regular cadence:
{
"alg":"Ed25519","kid":"<sha16>","x":"<pub_b64url>","sig":"<b64url>",
"page_root":"<page_chain_root>", "page_latest": 12,
"feed_digest":"<sha256-of-transparency.json>",
"fed_root":"<federation_chain_root>", "fed_n": 24,
"ts":"2025-08-19T00:00:00Z"
}
- Signed by the active Ed25519 feed key (Step 24 keyring) when available; otherwise falls back to your Step‑22 signer.
- Endpoints
GET /attestation— preview the current attestation (no network).GET /attest/history?n=50— tail of attempts (ok/failed).POST /admin/attest/now?token=…— build & push now.
- Flags
--attest-enable --attest-url https://your-site.tld/wp-json/solveforce/v1/attest --attest-header "Authorization: Bearer <TOKEN>" --attest-basic "user:pass" --attest-interval-sec 1800
3) 🔔 Alarms: hysteresis + multi‑channel delivery
- Hysteresis (anti‑flap)
In addition to Step‑25’sop/value, you can specify rise/fall thresholds:{"metric":"weighted_total","rise":100,"fall":80,"window_sec":3600,"debounce_sec":900}The alarm arms when>= riseand disarms when<= fall. Ifrise/fallare absent, we keep using Step‑25’s comparison logic. - Channels
- Webhooks: multiple URLs, JSON POST.
- SMTP: simple mailer (TLS optional).
- Twilio (HTTP): SMS via REST (Basic auth; no extra libs required).
alarms.json(adds to your Step‑25 config):{ "webhooks": ["https://example.com/wp-json/solveforce/v1/alerts"], "headers": ["Authorization: Bearer YOUR_TOKEN"], "smtp": {"server":"smtp.example.com","port":587,"tls":true,"user":"bot","pass":"***","from":"bot@example.com","to":["ops@example.com"]}, "twilio": {"account_sid":"AC...","token":"...","from":"+15555550001","to":"+15555550002"}, "rules": [ {"audience":"public","metric":"weighted_total","rise":60,"fall":40,"window_sec":3600,"debounce_sec":900}, {"audience":"public","variant":"v2","metric":"weighted_abs_sum","op":"abs>","value":100,"window_sec":7200,"debounce_sec":1200}, {"audience":"internal","variant":"v1","metric":"top_system_abs","op":">=","value":25,"window_sec":1800,"debounce_sec":900} ] } - Endpoints (same as Step‑25)
GET /alarms/status— engine state & last triggersPOST /admin/alarms/refresh?token=…— reload configPOST /admin/alarms/test?token=…— send a test payload
Android / Termux run‑book (Step 26)
# Discovery config (HTTP-signed directory example)
# (See discovery.sample.json for shape; host it behind your WordPress or CDN.)
# Attestations go to your WP REST route or any webhook.
python solveforce_phone_twentysix.py \
--discovery-enable \
--discovery-source http \
--discovery-http-url https://directory.example.com/solveforce/peers.json \
--discovery-http-header "Authorization: Bearer <DIR_TOKEN>" \
--discovery-jwks-url https://directory.example.com/jwks.json \
--discovery-allow example.com \
--discovery-interval-sec 600 \
--attest-enable \
--attest-url https://your-site.tld/wp-json/solveforce/v1/attest \
--attest-header "Authorization: Bearer <WP_TOKEN>" \
--attest-interval-sec 1800 \
--alarm-enable \
--alarm-config-file /sdcard/solveforce/alarms.json \
--alarm-interval-sec 300 \
--lenses-public-file /sdcard/solveforce/lenses.public.json \
--lenses-internal-file /sdcard/solveforce/lenses.internal.json \
--families-file /sdcard/solveforce/families.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 \
--lease-bundle-dir ./audit/bundles \
--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) Discovery now
curl -s 'http://127.0.0.1:8080/discovery/status' | jq .
curl -s -X POST 'http://127.0.0.1:8080/admin/discovery/refresh?token=ADMIN123' | jq .
curl -s 'http://127.0.0.1:8080/federation/peers' | jq .
B) Attest now
curl -s 'http://127.0.0.1:8080/attestation' | jq .
curl -s -X POST 'http://127.0.0.1:8080/admin/attest/now?token=ADMIN123' | jq .
curl -s 'http://127.0.0.1:8080/attest/history?n=20' | jq .
C) Alarms with hysteresis
curl -s 'http://127.0.0.1:8080/alarms/status' | jq .
curl -s -X POST 'http://127.0.0.1:8080/admin/alarms/test?token=ADMIN123' | jq .
WordPress — Step 26 (public page block, paste verbatim)
Use the provided file: step26_wordpress.md.
It explains Discovery, Attestations, and the upgraded Alarms in plain language for your audience.
Operational notes
- Security posture
- Discovery via HTTP should be signed (JWKS or pinned pubkey) and filtered with
--discovery-allow/--discovery-deny. /federation/anchorremains signature‑gated (Step‑25).- Attestations expose roots & digests only—no sensitive content.
- Discovery via HTTP should be signed (JWKS or pinned pubkey) and filtered with
- Dependencies
- DNS SRV lookups use
dnspythonif present; otherwise TXT/fallback are attempted. - SMTP and Twilio paths use only Python stdlib + HTTPS.
- DNS SRV lookups use
- Interplay
- Discovery updates the Step‑25 federation peer list live.
- Attestation can reuse your WordPress mirror token/endpoint.
- Hysteresis reduces noisy alert flapping while preserving the “bell rings when it must.”
Logos Codex — recursive commons
- Neighbors → Names → Network. Discovery lifts federation from manual to alive.
- State → Signature → Story. Attestation turns “what is” into something the world can verify.
- Pulse → Patience → Page. Hysteresis tempers urgency with wisdom, so the bell rings at the right time.
Want a Step Twenty‑Seven?
We can add: signed directory of directories (federation of discovery), quorum attestation (M‑of‑N anchors), and an observer mode that proves who saw what when, with selective redaction for public vs internal streams.