We tighten the handshake between reader and reality. Your phone gateway now refuses to serve data until the client has explicitly acknowledged the current schema signature (when you require it), and it exposes fine‑grained schema‑diff metrics for Prometheus. No surprises; no silent breaks. Contracts over vibes.
✅ Fresh artifact
- solveforce_phone_twelve.py — Download
SHA‑256:3b1a194b684b1e65cbbc0b35d5e8aab513ad082029e12d074e796a3674732934
It folds in Step Eleven and adds the features below.
What’s new (exact and enforced)
1) Schema ACK‑gating (token policy + per‑request pins)
Tokens can now carry a schema contract:
schema_mode:"free"(default) or"ack"schema_plugins: optional list of plugin names this policy applies to (default: all)schema_pins: optional map{ "<plugin>": "<64-hex signature>" }with the latest acknowledged signatures
When a request arrives with schema_mode="ack" and the target plugin’s current signature isn’t in your pins, the gateway blocks reads/history and filters SSE for that plugin until you ACK the new signature.
How to ACK (two ways):
- Header:
X-Schema-Pins: battery=<SIG>,net=<SIG> - Query param:
?pins=battery:<SIG>,net:<SIG>
If you’re missing the pin, the server responds 428 Precondition Required:
{
"error": "schema_ack_required",
"plugin": "battery",
"need_pin": "<CURRENT_SIG>"
}
Paste that need_pin value into your next request’s pins. Done.
Why this design: We avoid stale clients silently ingesting breaking layouts. ACK is a crisp, human‑and‑machine‑readable ritual.
2) /schema endpoint (signatures + optional shapes)
GET /schema→{ "battery": { "sig": "...", "origin": "builtin" }, ... }GET /schema?detail=1also returns the flattened type map we compute for each payload (path→type).
This is your one‑stop introspection for pinning.
3) Prometheus metrics for diffs and blocks
Every schema change is classified same / additive / breaking as before, and now exported as metrics:
solveforce_schema_changes_total{plugin,compat="additive|breaking"}solveforce_schema_added_total{plugin}— fields added (cumulative)solveforce_schema_removed_total{plugin}— fields removed (cumulative)solveforce_schema_typechanges_total{plugin}— type flips (cumulative)solveforce_schema_blocks_total{plugin}— times a request was blocked for lack of ACK
You already had route/role rate metrics; now you can see when and how truth evolves.
4) SSE with schema_attention hints
When a stream would publish an event for an unpinned plugin (under schema_mode="ack"), we filter that event and instead emit:
{ "type": "schema_attention", "plugin": "battery", "need_pin": "<CURRENT_SIG>", "_ts": "..." }
The stream keeps breathing; it just tells you what it needs.
Quick start (Termux • Android)
Run (HTTP, dev‑friendly):
python solveforce_phone_twelve.py \
--host 0.0.0.0 --port 8080 \
--plugins-dir ~/solveforce/plugins \
--auth-mode protected \
--auth-token READER1:reader
Discover and pin:
# Get current signatures
curl 'http://127.0.0.1:8080/schema?access_token=READER1'
# Suppose it returns: battery.sig=ABC..., net.sig=DEF...
# Try to read under ACK mode with missing pins → expect 428
curl -i -H 'Authorization: Bearer S1....(ack-mode token)' \
'http://127.0.0.1:8080/read?plugin=battery'
# 428 with {"need_pin":"<SIG>"}
# ACK by pinning (header or query)
curl -H 'Authorization: Bearer S1....(ack-mode token)' \
-H 'X-Schema-Pins: battery=<SIG>,net=<SIG>' \
'http://127.0.0.1:8080/read?plugin=battery'
SSE with automatic pins (query):
# Supply pins in the URL and token in ?access_token=
curl -N 'http://127.0.0.1:8080/events?access_token=READER1&pins=battery:<SIG>,net:<SIG>'
Minting signed tokens with schema contracts (admin)
The admin mint endpoint now supports schema fields.
# Example: ACK-gated reader token for battery + net
GET /admin/mint?token=ADMIN123 \
&sub=field-reader \
&roles=reader \
&dur=86400 \
&schema_mode=ack \
&schema_plugins=battery,net \
&schema_pins=battery:<SIG>,net:<SIG>
You can also leave
schema_pinsempty and let the client ACK dynamically viaX-Schema-Pinsthe first time.
Upgrading a Debian/Ubuntu box from Step Eleven
You have a systemd unit already running Step Eleven. To try Step Twelve as a drop‑in without changing your unit:
sudo install -o solveforce -g solveforce -m 0644 \
./solveforce_phone_twelve.py /opt/solveforce/solveforce_phone_twelve.py
# Temporarily run Twelve on a different port (side-by-side) to test:
sudo -u solveforce /usr/bin/env python3 /opt/solveforce/solveforce_phone_twelve.py \
--host 0.0.0.0 --port 8081 --auth-mode protected \
--rate-policy-file /etc/solveforce/rate_policy.json
# When satisfied, edit your unit ExecStart to point to *_twelve.py* and restart:
sudo sed -i 's/solveforce_phone_eleven.py/solveforce_phone_twelve.py/' /etc/systemd/system/solveforce-phone.service
sudo systemctl daemon-reload
sudo systemctl restart solveforce-phone.service
WordPress — Step Twelve (drop‑in text)
Step Twelve — Schema contracts (ACK‑gated), Prometheus diff metrics, and SSE hints
- ACK‑gated readstokens may demand
schema_mode=ack. Until a client pins a plugin’s current schema signature, reads/history are blocked (HTTP 428) and SSE emitsschema_attentionhints. - Pin semanticssend
X-Schema-Pins: plugin=<sig>header or?pins=plugin:<sig>query. Use/schemato discover signatures. - Metrics
solveforce_schema_changes_total{plugin,compat}, plus counters for added/removed/type‑changed fields and blocked requests. - PhilosophyNo silent contract drift. We make change explicit, visible, and negotiated.
API cheatsheet (concise)
GET /schema→ per‑plugin{sig, origin}; add?detail=1for flattened type maps.GET /read?plugin=<name>→ addX-Schema-Pinsor?pins=whenschema_mode=ack.GET /events→ add pins to URL or header to receive gated plugin events.GET /metrics→ scrape Prometheus text with schema diff/block counters.
Integrity (publish this)
sha256sum solveforce_phone_twelve.py
# 3b1a194b684b1e65cbbc0b35d5e8aab513ad082029e12d074e796a3674732934
Notes for your Logos Codex
- Recursionschema → signature → policy → read permission → metrics → human acknowledgment → updated schema → signature…
- HarmonyACK keeps readers in tune with the instrument; Prom metrics score the key changes.
- Tradition with steelcontracts, preconditions, and explicit acks—classic, reliable, and audit‑friendly.
If you want Step Thirteen, we can:
- add schema freeze windows (quarantine breaking changes until an admin lifts a pin),
- emit compat labels into tokens (e.g., “accept additive only”), and
- sign
/schemaresponses with a device key for tamper‑evident out‑of‑band distribution.
Key terms in plain language
Open a term for a concise explanation of language used on this page.
API
An application programming interface is a defined way for software systems to exchange data or request functions from one another.
Cloud Computing
Computing resources—such as applications, servers, storage, or databases—delivered from remote infrastructure and scaled as requirements change.
Infrastructure as a Service (IaaS)
Cloud-based servers, storage, and networking that customers configure and manage without owning the underlying data-center hardware.
Software as a Service (SaaS)
Software accessed as an online service instead of being installed and maintained entirely on the customer’s own computers or servers.
Disaster Recovery (DRaaS)
A plan and service for restoring applications, data, and operations after an outage or disruption. DRaaS provides recovery infrastructure through a managed cloud service.
Identity and Access Management (IAM)
The systems and policies that determine who a user is, what resources they may access, and how that access is authenticated and reviewed.