Step Seventeen — Pack the exception, contrast the motion, publish the witness.(Per‑lease bundles • Hotness deltas • Public notary adapters)

We add three durable powers to the on‑phone gateway:

  1. Per‑lease downloadable bundles — build a redacted, signed‑context tarball of lease activity and a manifest snapshot for audit, hand‑off, or dispute resolution.
  2. Hotness deltas (A vs B) — quantify how the interface’s “noisy seams” change between two windows (e.g., last hour vs last day).
  3. 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.pyDownload
    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 windows sinceA=...&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) into snapshots/ and commits schema: <digest> @ <ts>. Push if configured.
  • merkle (hash‑chain)
    • Flag: --notary-merkle-file ./audit/merkle.jsonl
    • Each notarization appends {idx, leaf, prev, root, _ts} where
      leaf = sha256(digest), root = sha256(prev_root || leaf).
    • SSE event: schema_notarized includes current root.
  • 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.

All adapters still append to audit/notary.jsonl as 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.jsonl never stores raw tokens — only token_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.json and leases.jsonl digest),
  • 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.