PayAna BountyBook monitor — 2026-09-07

  • Added read-only live reconciliation across BountyBook homepage, /jobs?status=open API, and /health.
  • Found and encoded a material surface divergence: homepage reports 0 open, while live API reports 120 rows marked open.
  • Integrity audit found those 120 rows total 598 USDC, all have contract_job_id=0 and payout_status=none, while /health reported treasury 0.396733 USDC and 39 failed payouts at the audit instant.
  • New invariant: API_STATUS_OPEN != ESCROW_FUNDED_OPEN; API rows are not promoted to executable revenue targets without funding/escrow proof.
  • Monitor persists bountybook_watch in Turso and only emits a MONITOR_CHANGE action receipt when material state changes; repeated identical runs do not duplicate change receipts.
  • On fetch failure, last-known opportunity state is preserved: FETCH_FAIL != ZERO_OPEN.
  • Added reusable read-only scanner and audit scripts under payana/.

PayAna Ledger 1.0 — 2026-09-07

  • Added dedicated Turso tables for PayAna state, opportunities, economic events, actions and receipts.
  • Seeded REV-000001 = USD 0.01 with USER_CONFIRMED_RECEIPT_UNVERIFIED instead of fabricating missing provenance.
  • Added explicit receipt-gap-REV-000001 to track missing platform/task/transaction/timestamp evidence.
  • Added five reconciled opportunity records: TermMax/Immunefi, BlockPI/Immunefi, Binance Agent OS 2026, OpenCV AI 2026, BountyBook current state.
  • Extended vault_bridge.ts to bridge version 0.6.0 with six PayAna actions and snapshot retrieval.
  • Added fail-closed validation for decimal values, HTTPS URLs and SHA-256 receipts.
  • Regression evidence: V0.4 bridge PASS, V0.5 PASS, V0.6 PASS, V0.7 preflight PASS, ZIP64 PASS, release audit PASS.

Changelog

2026-07-30 — Immutable asset caching

Frontend files are now served at version-addressed URLs (/__immutable/45/frontend/index.tsx) with Cache-Control: public, max-age=31536000, immutable, so repeat visits load the whole client graph from the browser cache — roughly 3× faster (~665ms → ~157ms measured). Publishing your val bumps its version, which changes every URL, so caches invalidate automatically. Old-version URLs return 404 after a publish (like Next.js build assets); a reload picks up the new version.

What changed in the template:

  • frontend/index.htmlfrontend/root.tsx: the HTML shell is now JSX and stamps asset URLs with immutableFileUrl()
  • index.ts: serves Root() at /, and one app.get("/__immutable/*", (c) => serveImmutableFile(c.req.path)) route serves all frontend files

Upgrading an existing remix

Your copy of this template doesn't update automatically. Two options:

Minimal (most of the benefit): point both routes at serveImmutableFile — your existing bare URLs redirect into versioned space, the new route serves them, and the whole module graph gets cached (costs one redirect per page view):

import { serveImmutableFile } from "https://esm.town/v/std/utils/index.ts"; app.get("/__immutable/*", (c) => serveImmutableFile(c.req.path)); app.get("/frontend/**/*", (c) => serveImmutableFile(c.req.path)); // was serveFile

Full upgrade (also removes the redirect): three self-contained steps — no other files needed. Adjust the <title>, favicon, and body of Root() to match your app's existing index.html, and stamp anything else your shell references directly (images, css) with immutableFileUrl().

  1. Create frontend/root.tsx:
/** @jsxImportSource npm:hono@4/jsx */ import { raw } from "npm:hono@4/html"; import { immutableFileUrl } from "https://esm.town/v/std/utils/index.ts"; // The HTML shell for the app. It is never cached, so immutableFileUrl can stamp // the current val version into each asset URL — the browser caches those // immutably, and publishing the val changes the URLs, refetching exactly once. export function Root() { return ( <> {raw("<!DOCTYPE html>")} <html lang="en"> <head> <meta charSet="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>React Hono Val Town Starter</title> <script src="https://cdn.twind.style" crossOrigin="" /> <link rel="icon" href={immutableFileUrl("/frontend/favicon.svg")} type="image/svg+xml" /> </head> <body className="font-sans text-gray-800 p-6"> <main> <div id="root" /> </main> <script src="https://esm.town/v/std/catch" /> <script src={immutableFileUrl("/frontend/index.tsx")} type="module" /> </body> </html> </> ); }
  1. In your Hono entrypoint, import Root and serveImmutableFile, and replace your / and frontend file routes with:
import { serveImmutableFile } from "https://esm.town/v/std/utils/index.ts"; import { Root } from "./frontend/root.tsx"; // Serve the (never-cached) HTML shell at the root / app.get("/", (c) => c.html(Root())); // Serve frontend files at the version-addressed URLs Root() stamps, cached immutably app.get("/__immutable/*", (c) => serveImmutableFile(c.req.path));
  1. Delete frontend/index.html (and any now-unused serveFile import).

0.5.0 — 2026-09-06

  • Added structured knowledge items and FTS5 index.
  • Added graph-lite relations.
  • Added ChatGPT-expanded hybrid retrieval with BM25 + reciprocal-rank fusion.
  • Added strict project/kind filters.
  • Added idempotent knowledge writes, stale-retry proof, invalid-relation negative control.
  • Updated GUI and personal guh-vault skill.

V0.6.0 — 2026-09-06

  • Added selective ZIP central-directory reader for conversations*.json.
  • Added resumable import cursor in Turso (vault_import_runs).
  • Added content-stable fingerprints and scope-specific import run IDs.
  • Added pre-cursor deduplication by explicit conversation ID, keeping the newest duplicate.
  • Added CRC32 corruption detection and fail-closed controls for unsupported ZIP modes.
  • Added export inventory/duplicate/cursor UI.
  • Added v06_selftest.ts and v06_release_audit.ts.
  • Promotion evidence: synthetic ZIP only; real official export remains UNVERIFIED.
  • Hardened resumability: conversation/messages/FTS/cursor advance are one Turso batch; repeated cursor replay does not double-count indexed messages.
  • Added post-write reconciliation and UNKNOWN_EXTERNAL_STATE fail-safe instead of blind retry after ambiguous network failures.

V0.6.1 — iPhone file picker hotfix

  • Remove accept filtering from the hidden file input because iOS Files/Safari exposed only JSON in the picker.
  • ZIP/JSON validation remains inside the Vault parser; unsupported formats are still rejected after selection.
  • Visible app/schema version bumped to 0.6.1.

V0.7.0 — real-export preflight

  • Added default dry-run preflight before Turso writes.
  • Import approval is scoped to exact fingerprint + selected limit and resets after completion.
  • Added ZIP64 selective central-directory/entry support; multidisk remains blocked.
  • Added content-type/ID/mapping/size anomaly report.
  • Updated stale V0.5 validator from frozen counts to currentness-safe invariants.