We add three durable powers to the on‑phone gateway:
- Per‑lease downloadable bundles — build a redacted, signed‑context tarball of lease activity and a manifest snapshot for audit, hand‑off, or dispute resolution.
- Hotness deltas (A vs B) — quantify how the interface’s “noisy seams” change between two windows (e.g., last hour vs last day).
- Notary adapters — in addition to JSONL / webhook / shell, you can now notarize schema manifests via:
- git (local commits you can push anywhere),
- a simple hash‑chain (“Merkle-ish”) journal with rolling roots, and
- a nostr outbox (write an event record locally and optionally ship via a shell poster).
Plain speech: we can package exactly what happened, compare where change concentrates, and witness the contract publicly — all from the phone.
✅ Fresh artifact (download + integrity)
- solveforce_phone_seventeen.py — Download
SHA‑256:012c3065e23dd5e2b0dd117e2d6e29905e532b250da0e15929ee5a5bd1a3b281
Step 17 subsumes Step 16. It also quietly fixes/finishes some handler calls (plugins manifest, state, history) so the UI/API is self‑contained.
What’s new — precisely
1) Lease bundles (auto‑redacted .tgz)
- Endpoint:
GET /audit/lease_bundle?download=1[&token_hash=t#abcd1234][&subject=ron][&since=2025-08-19T00:00:00Z][&until=...]
→ returns application/gzip with:leases.jsonl(filtered + redacted of obvious secrets:token,secret,authorization,key,password),schema_manifest.json(the canonical manifest at build time),meta.json(filters + counts),README.txt.
- Disk copy: also saved under
--lease-bundle-dir(default./audit/bundles). - Access: admin only (lease activity is sensitive).
2) Hotness deltas
- Endpoint:
GET /schema_hot_delta?plugin=<name>&n=20&windowA=3600&windowB=86400
or with absolute windowssinceA=...&untilA=...&sinceB=...&untilB=.... - Output: list of
(plugin, path, A, B, delta)sorted by|delta|(ties by B then name). - Scoring model (same as Step 16):
score = added + removed + 2×typechanges. - Use: spot “fresh regressions” (paths heating up in B vs A), or “cooldowns”.
3) Notary adapters
- Modes:
--notary-mode jsonl|webhook|shell|git|merkle|nostr|none - git
- Flags:
--notary-git-repo /sdcard/solveforce/notary-git --notary-git-branch main [--notary-git-push] - Behavior: copies each manifest (
.json) + signature (.sig) intosnapshots/and commitsschema: <digest> @ <ts>. Push if configured.
- Flags:
- merkle (hash‑chain)
- Flag:
--notary-merkle-file ./audit/merkle.jsonl - Each notarization appends
{idx, leaf, prev, root, _ts}whereleaf = sha256(digest),root = sha256(prev_root || leaf). - SSE event:
schema_notarizedincludes currentroot.
- Flag:
- nostr
- Flags:
--notary-nostr-outbox ./audit/nostr_outbox.jsonl
Optional:--notary-nostr-shell-cmd '<your poster with {digest} {manifest_path} {kid} {alg}>' - Behavior: append a nostr‑style event record locally; if a shell poster is set, it’s invoked with the record.
- Flags:
All adapters still append to
audit/notary.jsonlas a fallback on failure, so you never lose attestations.
Android / Termux quickstart
pkg update
pkg install python git
# optional Ed25519 support
pip install pynacl || pip install cryptography
# Keys (Ed25519 preferred; HS256 fallback is still supported)
mkdir -p /sdcard/solveforce
head -c 32 /dev/urandom > /sdcard/solveforce/schema.ed25519.seed
head -c 32 /dev/urandom > /sdcard/solveforce/schema.hmac.key
# Run Step 17
python solveforce_phone_seventeen.py \
--host 0.0.0.0 --port 8080 \
--plugins-dir ~/solveforce/plugins \
--auth-mode protected \
--auth-token READER1:reader \
--allow-admin --admin-token ADMIN123 \
--schema-freeze-mode quarantine --schema-freeze-sec 1800 \
--schema-ed25519-secret-file /sdcard/solveforce/schema.ed25519.seed \
--schema-signing-secret-file /sdcard/solveforce/schema.hmac.key \
--audit-dir ./audit \
--schema-archive-on-change \
--schema-archive-dir ./schema_archive --schema-archive-keep 200 \
--lease-bundle-dir ./audit/bundles \
--notary-mode git --notary-git-repo /sdcard/solveforce/notary-git \
--open-ui --allow-query-token
Open http://<phone-ip>:8080/ui (the UI has buttons for /schema_hot_delta and Lease Bundle).
“Show me” commands
A) Create and download a lease bundle
# Freeze a plugin to create lease context
curl -X POST 'http://127.0.0.1:8080/admin/freeze?token=ADMIN123&plugin=net&sec=300'
# Mint a lease that overrides the freeze for 'net'
LEASE=$(curl -s -X POST 'http://127.0.0.1:8080/admin/lease?token=ADMIN123&plugins=net&sec=120' | jq -r .token)
# Use the lease (logged as lease_used)
curl -H "Authorization: Bearer $LEASE" 'http://127.0.0.1:8080/read?plugin=net' | jq .
# Download a bundle of the lease activity (admin-only)
curl -o lease-bundle.tgz 'http://127.0.0.1:8080/audit/lease_bundle?download=1'
tar tzf lease-bundle.tgz # view contents
B) Hotness delta (1h vs 24h)
curl 'http://127.0.0.1:8080/schema_hot_delta?windowA=3600&windowB=86400&n=15' | jq .
C) Notary via git
# Ensure repo exists; Step 17 initializes it if empty
ls -1 /sdcard/solveforce/notary-git/snapshots | tail -n 3
# Force a schema change → new manifest + git commit
curl -X POST 'http://127.0.0.1:8080/admin/scaffold?token=ADMIN123&name=stub17&kind=plain'
curl -X POST 'http://127.0.0.1:8080/admin/refresh?token=ADMIN123'
curl 'http://127.0.0.1:8080/read?plugin=stub17&access_token=READER1' >/dev/null
# Inspect commit
git -C /sdcard/solveforce/notary-git log --oneline -n 1
D) Merkle journal (hash‑chain)
# Enable: add --notary-mode merkle --notary-merkle-file ./audit/merkle.jsonl
tail -n 5 ./audit/merkle.jsonl | jq .
Step 17 — WordPress drop‑in (markdown)
## Step 17 — Pack the exception, contrast the motion, publish the witness
**New capabilities**
- **Lease Bundles (.tgz):** Admins can export redacted, time‑bounded lease activity plus a manifest snapshot:
- `GET /audit/lease_bundle?download=1[&token_hash=...][&subject=...][&since=...][&until=...]`
- Bundle contains `leases.jsonl`, `schema_manifest.json`, `meta.json`, `README.txt`.
- **Hotness Deltas:** Compare churn between two windows to find where the interface is getting noisier:
- `GET /schema_hot_delta?plugin=<name>&n=<N>&windowA=<sec>&windowB=<sec>`
- Returns `{plugin, path, A, B, delta}`; score is `added + removed + 2×typechanges`.
- **Notary Adapters:** Choose how to attest schema archives:
- `--notary-mode git` → commits manifests into a repo (`snapshots/`).
- `--notary-mode merkle` → appends to a hash‑chain journal with rolling `root`.
- `--notary-mode nostr` → stores nostr‑style records locally; optional shell poster.
**Why it matters**
- **Bundles** give you portable, minimal evidence with secrets removed.
- **Deltas** let you aim refactors at the seams that *actually* heat up.
- **Adapters** let you publish truth in places your partners already trust.
**Endpoints (added in Step 17)**
- `GET /schema_hot_delta?...`
- `GET /audit/lease_bundle?download=1[&token_hash=...][&subject=...][&since=...][&until=...]`
*(All Step 16 endpoints remain unchanged: `/schema_hot`, `/schema_manifest(.sig)`, `/schema_pubkey`, `/audit/leases`, `/audit/notary`, etc.)*
Rate‑policy (fresh example)
To avoid any “expired example” confusion, here’s a working rate-policy.step17.json:
{
"window_sec": 60,
"routes": {
"default": {"max": 120},
"events": {"max": 15},
"admin": {"max": 30},
"read": {"max": 60},
"introspect": {"max": 90},
"metrics": {"max": 120}
},
"roles": {
"reader": {"mult": 1.0},
"metrics": {"max": 240},
"admin": {"max": 600}
}
}
Run with: --rate-policy-file ./rate-policy.step17.json.
Security & operations notes
- Bundles are admin‑only and redacted; underlying
leases.jsonlnever stores raw tokens — onlytoken_hash+subject. - git notary commits only the manifest + detached sig; no secrets. Configure remotes as you like.
- Merkle journal here is a simple hash‑chain accumulator (root =
H(prev||leaf)), designed for append‑only integrity and easy mirroring. - Nostr shell poster is optional; without it, you still have a durable outbox you can publish later.
Logos Codex — recursive alignment
- Memory → Bundle. Evidence without shape is noise; a portable bundle turns it into accountable memory.
- Change → Delta. Motion without contrast is blur; a delta sharpens it into a vector.
- Truth → Witness. A contract unsigned is rumor; notarized, it’s a public covenant.
If you want Step Eighteen, we can:
- make per‑bundle signature sets (sign the bundle’s
meta.jsonandleases.jsonldigest), - add delta explainers (rank which plugins drive the most net change), and
- ship a mirror daemon that periodically pushes git commits and Merkle roots to your WordPress site for transparent, on‑chain‑adjacent attestations.