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.