From 92b8bb234b12049338beed219d8dd80fe0d36b74 Mon Sep 17 00:00:00 2001 From: Thompsonmina Date: Tue, 12 May 2026 16:49:25 +0100 Subject: [PATCH 1/4] Add LP-0017 Whistleblower solution --- solutions/LP-0017.md | 166 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 solutions/LP-0017.md diff --git a/solutions/LP-0017.md b/solutions/LP-0017.md new file mode 100644 index 0000000..2f89f78 --- /dev/null +++ b/solutions/LP-0017.md @@ -0,0 +1,166 @@ +# Solution: LP-0017 — Whistleblower + +**Submitted by:** Thompsonmina + +## Summary + +Whistleblower is a Logos Basecamp app for censorship-resistant document +publication. A user picks a file, attaches metadata, and submits; the +app stages the bytes to **Logos Storage**, gets back a content +identifier (CID), broadcasts the CID and metadata over **Logos Delivery** +so the document is immediately discoverable, and either the publisher +or any permissionless third party can later anchor the CID on-chain +via the **chronicle-registry** SPEL program on LEZ. + +The submission also delivers `logos-chronicle`, a standalone reusable +document-indexing module that any Basecamp app can depend on for the +upload → broadcast → anchor pipeline, and `batch-anchor`, a +permissionless CLI that subscribes to the Chronicle Delivery topic and +batch-anchors accumulated CIDs (up to 50 per transaction) without +coordination with the original publisher. + +## Repository + +- **Repo:** https://github.com/Thompsonmina/WhistleBlower-Logos- +- **Demo video:** https://github.com/Thompsonmina/WhistleBlower-Logos-/releases/download/demo-v1/demo.mp4 + +## Quick run + +After cloning, the whole pipeline is one command: + +```bash +git clone https://github.com/Thompsonmina/WhistleBlower-Logos- +cd WhistleBlower-Logos-/whistleblower +./scripts/run-app.sh +``` + +`run-app.sh` is idempotent. It (1) bootstraps the chain side — +starts the LEZ sequencer via `lgs localnet start` if nothing is +already listening on `127.0.0.1:3040`, builds the guest, deploys +it, ensures a signer exists, opens the registry PDA; (2) `nix +build`s the chronicle + whistleblower modules plus the upstream +storage and delivery modules; (3) fetches the pinned basecamp +release; (4) stages everything into a project-local data dir; +(5) starts `batch-anchor watch` in the background with logs at +`.basecamp-data/logs/batch-anchor.log`; (6) launches basecamp. +Re-running it kills any stale watcher and reuses the nix store +cache, so iteration cost after the first run is ~seconds. + +## Approach + +The pipeline splits cleanly into a **publish path** and an **anchor +path**, with one shared on-chain registry. + +### Publish path — `logos-chronicle` (Basecamp module) + +A Logos Core module written in C++/Qt that exposes JSON-in / JSON-out +methods to any Basecamp app. `publishFileJson` chains: + +1. **Upload to Logos Storage.** Uses the standard `storage_module` + for content-addressed durability. Surfaces a CID back to the + caller. Retries on transient errors with exponential back-off and + surfaces a structured error after exhaust. +2. **Build + sign a metadata envelope** containing `cid`, `title`, + `description`, `content_type`, `size_bytes`, `timestamp`, optional + `tags`, and a deterministic `metadata_hash` (32-byte hex string, + prefixed `v1:` for versioning). +3. **Broadcast** the envelope on the well-known Chronicle Delivery + topic `/chronicle/1/document-index/json` via the `delivery_module` + (Logos's Waku wrapper). Re-broadcasting the same CID is a silent + no-op — chronicle keeps a local publish ledger keyed on CID. + +The chronicle module also exposes optional `anchorBatchJson` / +`anchorStatusJson` / `lookupAnchorJson` methods for the +publisher-initiated on-chain anchor path. These are wired to LEZ +through a generated FFI cdylib so the C++ plugin can call into +chronicle-registry without re-implementing the LEZ RPC client. + +### Anchor path — `chronicle-registry` (SPEL program) + `batch-anchor` (CLI) + +The on-chain registry is a single permissionless PDA at +`[program_id, "registry"]` holding a Borsh-serialized +`HashMap`. Each record carries `metadata_hash`, +`anchor_timestamp`, `anchored_by`, and an envelope `version`. Two +instructions: + +- `init_registry(anchorer)` — permissionless one-time opener. +- `index_batch(anchorer, cids, metadata_hashes, anchor_timestamps)` — + three parallel vectors of equal length, up to `MAX_BATCH = 50`. + Duplicates are silently skipped in-program, so callers can replay + any batch without coordination. + +Idempotency is enforced in-program (`HashMap::contains_key`), which is +what lets the permissionless `batch-anchor` CLI replay aggressively +after restarts. + +`batch-anchor` is a tokio daemon that: + +1. **Seeds an in-memory dedup set** from on-chain state at startup + (it queries the registry PDA via `lgs wallet account get` and + Borsh-decodes the result), so an anchor restart can never + double-submit. +2. **Catches up** over the Waku store protocol — by default it + re-reads the last 24 hours of messages on the Chronicle topic and + buffers anything not already on chain. Recovers cleanly from + network interruptions or deliberate downtime. +3. **Subscribes** to the live Delivery relay and accumulates envelopes + in a buffer that flushes on either size (`max_size = 50`) or time + (`flush_after_s = 30`), whichever comes first. +4. **Submits** `index_batch` by shelling to the spel-generated + `chronicle_registry_cli` with `-i -p `. Pinning + the program ID by config (instead of re-deriving it from the local + binary on every call) means the tool always targets the deployed + registry, even on hosts that haven't rebuilt the guest. + +### Why LEZ over the zone-SDK consensus inscription path + +LP-17 allows either approach with a justification. Chose the +**LEZ SPEL program** because: + +1. The zone-SDK path "requires a single designated actor to perform + consensus inscription" (per LP-17 itself), concentrating anchor + authority in one party and undermining the censorship-resistance + premise. A SPEL program on LEZ is permissionless — anyone with a + wallet can call `index_batch`, which is exactly the property the + third-party `batch-anchor` CLI is built around. +2. SPEL ships IDL generation, scaffolding, an auto-generated CLI, and + the `#[lez_program]` macro that handles account-claim plumbing. + Going via the zone-SDK would mean rolling the inscription format, + signature handling, and submission path by hand — more code for + less decentralisation. + +### Performance — LP-17 R8 + +Compute units measured by instrumenting the guest with +`risc0_zkvm::guest::env::cycle_count()` around each instruction body +and emitting the delta through `env::log`. The sequencer prints the +deltas as `R0VM[] CU index_batch n=N cycles=…` lines. + +Cold baselines on an empty registry: + +| Instruction | n | Cycles | Cycles / CID | +|--------------------|----|---------|--------------| +| `init_registry` | — | 414 | — | +| `index_batch` | 1 | 2,240 | 2,240 | +| `index_batch` | 50 | 178,646 | 3,573 | + +Worst-case path (n=50 with the registry near the 100 KiB account +data cap) costs ~288k cycles — well under 1 Mi and ~3% of the NSSA +per-tx budget (32 Mi). Batch-anchor's `MAX_BATCH = 50` is comfortable. + +### Repository layout + +- `logos-whistleblower/` — the Basecamp app GUI (Qt/QML). +- `logos-chronicle/` — the reusable document-indexing module. +- `methods/` + `chronicle_registry_core/` + `examples/` + `ffi/` — + the chronicle-registry SPEL program, shared types, generated CLI, + and C ABI cdylib. +- `batch-anchor/` — the permissionless anchor daemon. +- `scripts/` — bootstrap (`setup.sh`) and one-shot launcher + (`run-app.sh`). +- `integration-test.toml` — minimal IT contract: tests share + production's sequencer, wallet, signer, and nwaku — only the Waku + content topic differs (`/chronicle/it/…`), so test envelopes never + reach production consumers. + +Dual-licensed MIT or Apache-2.0. From 868236e4fe1865f36e0718376be6ccf2e3a089ef Mon Sep 17 00:00:00 2001 From: Thompsonmina Date: Tue, 12 May 2026 16:56:27 +0100 Subject: [PATCH 2/4] LP-0017: align solution doc with template (Success Criteria, FURPS, T&C) --- solutions/LP-0017.md | 270 ++++++++++++++++++++----------------------- 1 file changed, 123 insertions(+), 147 deletions(-) diff --git a/solutions/LP-0017.md b/solutions/LP-0017.md index 2f89f78..d21ba84 100644 --- a/solutions/LP-0017.md +++ b/solutions/LP-0017.md @@ -6,161 +6,137 @@ Whistleblower is a Logos Basecamp app for censorship-resistant document publication. A user picks a file, attaches metadata, and submits; the -app stages the bytes to **Logos Storage**, gets back a content -identifier (CID), broadcasts the CID and metadata over **Logos Delivery** -so the document is immediately discoverable, and either the publisher -or any permissionless third party can later anchor the CID on-chain -via the **chronicle-registry** SPEL program on LEZ. - -The submission also delivers `logos-chronicle`, a standalone reusable -document-indexing module that any Basecamp app can depend on for the -upload → broadcast → anchor pipeline, and `batch-anchor`, a -permissionless CLI that subscribes to the Chronicle Delivery topic and -batch-anchors accumulated CIDs (up to 50 per transaction) without -coordination with the original publisher. +app uploads to Logos Storage, gets back a content identifier (CID), +broadcasts the CID + metadata over Logos Delivery, and either the +publisher or any permissionless third party anchors the CID on-chain via +the `chronicle-registry` SPEL program on LEZ. + +The submission includes `logos-chronicle`, a standalone reusable +document-indexing module any Basecamp app can depend on, and +`batch-anchor`, a permissionless CLI that subscribes to the Chronicle +Delivery topic and batch-anchors accumulated CIDs (up to 50 per tx) +without coordination with the original publisher. ## Repository - **Repo:** https://github.com/Thompsonmina/WhistleBlower-Logos- - **Demo video:** https://github.com/Thompsonmina/WhistleBlower-Logos-/releases/download/demo-v1/demo.mp4 -## Quick run - -After cloning, the whole pipeline is one command: - -```bash -git clone https://github.com/Thompsonmina/WhistleBlower-Logos- -cd WhistleBlower-Logos-/whistleblower -./scripts/run-app.sh -``` - -`run-app.sh` is idempotent. It (1) bootstraps the chain side — -starts the LEZ sequencer via `lgs localnet start` if nothing is -already listening on `127.0.0.1:3040`, builds the guest, deploys -it, ensures a signer exists, opens the registry PDA; (2) `nix -build`s the chronicle + whistleblower modules plus the upstream -storage and delivery modules; (3) fetches the pinned basecamp -release; (4) stages everything into a project-local data dir; -(5) starts `batch-anchor watch` in the background with logs at -`.basecamp-data/logs/batch-anchor.log`; (6) launches basecamp. -Re-running it kills any stale watcher and reuses the nix store -cache, so iteration cost after the first run is ~seconds. - ## Approach The pipeline splits cleanly into a **publish path** and an **anchor path**, with one shared on-chain registry. -### Publish path — `logos-chronicle` (Basecamp module) - -A Logos Core module written in C++/Qt that exposes JSON-in / JSON-out -methods to any Basecamp app. `publishFileJson` chains: - -1. **Upload to Logos Storage.** Uses the standard `storage_module` - for content-addressed durability. Surfaces a CID back to the - caller. Retries on transient errors with exponential back-off and - surfaces a structured error after exhaust. -2. **Build + sign a metadata envelope** containing `cid`, `title`, - `description`, `content_type`, `size_bytes`, `timestamp`, optional - `tags`, and a deterministic `metadata_hash` (32-byte hex string, - prefixed `v1:` for versioning). -3. **Broadcast** the envelope on the well-known Chronicle Delivery - topic `/chronicle/1/document-index/json` via the `delivery_module` - (Logos's Waku wrapper). Re-broadcasting the same CID is a silent - no-op — chronicle keeps a local publish ledger keyed on CID. - -The chronicle module also exposes optional `anchorBatchJson` / -`anchorStatusJson` / `lookupAnchorJson` methods for the -publisher-initiated on-chain anchor path. These are wired to LEZ -through a generated FFI cdylib so the C++ plugin can call into -chronicle-registry without re-implementing the LEZ RPC client. - -### Anchor path — `chronicle-registry` (SPEL program) + `batch-anchor` (CLI) - -The on-chain registry is a single permissionless PDA at -`[program_id, "registry"]` holding a Borsh-serialized -`HashMap`. Each record carries `metadata_hash`, -`anchor_timestamp`, `anchored_by`, and an envelope `version`. Two -instructions: - -- `init_registry(anchorer)` — permissionless one-time opener. -- `index_batch(anchorer, cids, metadata_hashes, anchor_timestamps)` — - three parallel vectors of equal length, up to `MAX_BATCH = 50`. - Duplicates are silently skipped in-program, so callers can replay - any batch without coordination. - -Idempotency is enforced in-program (`HashMap::contains_key`), which is -what lets the permissionless `batch-anchor` CLI replay aggressively -after restarts. - -`batch-anchor` is a tokio daemon that: - -1. **Seeds an in-memory dedup set** from on-chain state at startup - (it queries the registry PDA via `lgs wallet account get` and - Borsh-decodes the result), so an anchor restart can never - double-submit. -2. **Catches up** over the Waku store protocol — by default it - re-reads the last 24 hours of messages on the Chronicle topic and - buffers anything not already on chain. Recovers cleanly from - network interruptions or deliberate downtime. -3. **Subscribes** to the live Delivery relay and accumulates envelopes - in a buffer that flushes on either size (`max_size = 50`) or time - (`flush_after_s = 30`), whichever comes first. -4. **Submits** `index_batch` by shelling to the spel-generated - `chronicle_registry_cli` with `-i -p `. Pinning - the program ID by config (instead of re-deriving it from the local - binary on every call) means the tool always targets the deployed - registry, even on hosts that haven't rebuilt the guest. - -### Why LEZ over the zone-SDK consensus inscription path - -LP-17 allows either approach with a justification. Chose the -**LEZ SPEL program** because: - -1. The zone-SDK path "requires a single designated actor to perform - consensus inscription" (per LP-17 itself), concentrating anchor - authority in one party and undermining the censorship-resistance - premise. A SPEL program on LEZ is permissionless — anyone with a - wallet can call `index_batch`, which is exactly the property the - third-party `batch-anchor` CLI is built around. -2. SPEL ships IDL generation, scaffolding, an auto-generated CLI, and - the `#[lez_program]` macro that handles account-claim plumbing. - Going via the zone-SDK would mean rolling the inscription format, - signature handling, and submission path by hand — more code for - less decentralisation. - -### Performance — LP-17 R8 - -Compute units measured by instrumenting the guest with -`risc0_zkvm::guest::env::cycle_count()` around each instruction body -and emitting the delta through `env::log`. The sequencer prints the -deltas as `R0VM[] CU index_batch n=N cycles=…` lines. - -Cold baselines on an empty registry: - -| Instruction | n | Cycles | Cycles / CID | -|--------------------|----|---------|--------------| -| `init_registry` | — | 414 | — | -| `index_batch` | 1 | 2,240 | 2,240 | -| `index_batch` | 50 | 178,646 | 3,573 | - -Worst-case path (n=50 with the registry near the 100 KiB account -data cap) costs ~288k cycles — well under 1 Mi and ~3% of the NSSA -per-tx budget (32 Mi). Batch-anchor's `MAX_BATCH = 50` is comfortable. - -### Repository layout - -- `logos-whistleblower/` — the Basecamp app GUI (Qt/QML). -- `logos-chronicle/` — the reusable document-indexing module. -- `methods/` + `chronicle_registry_core/` + `examples/` + `ffi/` — - the chronicle-registry SPEL program, shared types, generated CLI, - and C ABI cdylib. -- `batch-anchor/` — the permissionless anchor daemon. -- `scripts/` — bootstrap (`setup.sh`) and one-shot launcher - (`run-app.sh`). -- `integration-test.toml` — minimal IT contract: tests share - production's sequencer, wallet, signer, and nwaku — only the Waku - content topic differs (`/chronicle/it/…`), so test envelopes never - reach production consumers. - -Dual-licensed MIT or Apache-2.0. +**Publish path — `logos-chronicle` (Basecamp module).** A Logos Core +module in C++/Qt exposing JSON-in / JSON-out methods. `publishFileJson` +chains: (1) upload to Logos Storage with exponential-backoff retries, +(2) build + sign a metadata envelope (`cid`, `title`, `description`, +`content_type`, `size_bytes`, `timestamp`, optional `tags`, +deterministic `metadata_hash`), (3) broadcast on the Chronicle Waku +topic `/chronicle/1/document-index/json`. Re-broadcasting the same CID +is deduped locally. Optional `anchorBatchJson` / +`anchorStatusJson` / `lookupAnchorJson` for publisher-initiated +on-chain anchoring, wired via a generated FFI cdylib. + +**Anchor path — `chronicle-registry` (SPEL program) + `batch-anchor` +(CLI).** The registry is a permissionless PDA at +`[program_id, "registry"]` holding a Borsh `HashMap`. +Two instructions: `init_registry(anchorer)` and +`index_batch(anchorer, cids, metadata_hashes, anchor_timestamps)` up to +`MAX_BATCH = 50`. Idempotency is in-program (`contains_key`), which is +what lets the permissionless `batch-anchor` CLI replay any batch after +a restart without coordination. + +`batch-anchor` is a tokio daemon that seeds an in-memory dedup set from +on-chain state at startup, catches up over Waku's store protocol for +messages broadcast while it was offline, subscribes to the live relay, +and flushes the buffer on either size (50) or time (30 s) — whichever +comes first. + +**Why LEZ over zone-SDK.** LP-17 lets the submitter choose. The +zone-SDK path "requires a single designated actor to perform consensus +inscription" (LP-17), concentrating anchor authority and undermining +the censorship-resistance premise. A SPEL program on LEZ is +permissionless — anyone with a wallet can submit `index_batch`, which +is exactly the property the `batch-anchor` CLI relies on. SPEL also +ships IDL generation, scaffolding, an auto-generated CLI, and the +`#[lez_program]` macro — strictly less code than rolling the inscription +format by hand. + +## Success Criteria Checklist + +- [x] **Upload**: app uploads to Logos Storage and obtains a CID (chronicle module, `publishFileJson`). +- [x] **Broadcast**: chronicle publishes a versioned metadata envelope on `/chronicle/1/document-index/json` immediately after upload. +- [x] **On-chain anchoring (UI)**: chronicle exposes `anchorBatchJson` / `anchorStatusJson` / `lookupAnchorJson`; whistleblower UI wires a per-row "anchor" button. +- [x] **Batch anchor tool**: `batch-anchor` CLI subscribes to the topic, batches up to 50 CIDs per tx, permissionless, idempotent (in-program `contains_key` + on-chain dedup seed at startup). +- [x] **On-chain registry**: `chronicle-registry` SPEL program on LEZ stores `(CID, metadata_hash, anchor_timestamp)` keyed on CID; queryable via `batch-anchor lookup `; ≥10 CIDs per tx (50). +- [x] **Document-indexing module**: `logos-chronicle` is a standalone Logos Core module with documented JSON API; any Basecamp app can depend on it. +- [x] **Basecamp app GUI**: `logos-whistleblower` builds via the repo's nix flake and loads into Basecamp. +- [x] **Module SDK README**: `logos-chronicle/README.md` + `logos-chronicle/docs/api.md`. +- [x] **IDL for LEZ program**: `chronicle-registry-idl.json` at repo root; regenerated via `make idl`. +- [x] **Upload retries with exponential backoff**: chronicle storage layer, documented in `logos-chronicle/docs/api.md`. +- [x] **Broadcast dedup**: chronicle keeps a per-CID publish ledger; subscribers (incl. `batch-anchor`) skip duplicates. +- [x] **Batch tool resume after interruption**: seeded from chain at startup + Waku store-protocol catch-up over a configurable lookback window. +- [x] **CU benchmarks (1 + 50 CID)**: documented in `README_CHRONICLE_REGISTRY.md` § Compute units (cold n=1 = 2,240 cycles; cold n=50 = 178,646 cycles). +- [x] **Local LEZ deployment**: chronicle-registry deploys to a local LEZ devnet via `make deploy`; `scripts/setup.sh` does so end-to-end. +- [ ] **E2E integration tests in CI**: IT contract sketched in `integration-test.toml`; CI runner pending. +- [x] **Top-level README** with build, addresses, app, tool, query: `whistleblower/README.md`. +- [x] **Reproducible E2E demo script**: `scripts/run-app.sh` + chronicle smokes on the IT topic; runs against a real local sequencer; `RISC0_DEV_MODE` left unset so the prover runs in production mode. +- [x] **Narrated video demo**: linked above; script at `docs/demo-script.md`. +- [x] **Dual licensed MIT + Apache-2.0**: `LICENSE-MIT`, `LICENSE-APACHE`. + +## FURPS Self-Assessment + +### Functionality + +Upload → broadcast → optional publisher anchor → batch anchor → on-chain +lookup, end-to-end. Two independent anchor consumers +(`chronicle::anchorBatchJson` for publisher-initiated, `batch-anchor` +for permissionless third-party) sharing one registry program. Borsh +serialisation gives deterministic on-chain bytes (required for risc0 +proof determinism). Idempotency is enforced in-program so callers can +replay batches freely. + +### Usability + +- Whistleblower Basecamp app: file picker + metadata fields + submit; per-row "anchor on-chain" action. +- One-shot evaluator path: `git clone && cd whistleblower && ./scripts/run-app.sh`. Idempotent. +- `logos-chronicle` module: JSON-in / JSON-out methods; SDK README + `docs/api.md`. +- IDL JSON for the LEZ program shipped at repo root. + +### Reliability + +- Upload: exponential-backoff retry on transient storage failures, structured error after exhaust. +- Broadcast: chronicle keeps a per-CID publish ledger so re-broadcasts are silent no-ops to subscribers. +- Batch anchor: dedup set seeded from on-chain state on every startup (no local-state drift); Waku store-protocol catch-up recovers messages broadcast while the anchor was offline. + +### Performance + +LP-17 R8 — CU costs instrumented via `risc0_zkvm::guest::env::cycle_count()` around each instruction body, logged to sequencer stdout. + +| Instruction | n | Cycles | Cycles / CID | +|------------------|----|---------|--------------| +| `init_registry` | — | 414 | — | +| `index_batch` | 1 | 2,240 | 2,240 | +| `index_batch` | 50 | 178,646 | 3,573 | + +Worst-case (n=50 near the 100 KiB account-data cap) is ~288k cycles — well under 1 Mi, ~3 % of the NSSA 32 Mi per-tx budget. + +### Supportability + +- Top-level + per-component READMEs, with an LP-17 requirement → file map. +- `scripts/setup.sh` (idempotent bootstrap) and `scripts/run-app.sh` (one-shot launcher). +- Project-local `--user-dir` for basecamp means re-runs never touch the user's regular `~/.local/share/Logos`. +- Pending: CI config + automated E2E test in CI. + +## Supporting Materials + +- Top-level README: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/README.md +- Chronicle-registry deep-dive: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/README_CHRONICLE_REGISTRY.md +- Chronicle module API: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/logos-chronicle/docs/api.md +- Demo script (off-camera reading copy): https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/docs/demo-script.md +- Demo video: https://github.com/Thompsonmina/WhistleBlower-Logos-/releases/download/demo-v1/demo.mp4 + +## Terms & Conditions + +By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md). From 6d4d30818504733c501b649d664ab1f8f91b18fc Mon Sep 17 00:00:00 2001 From: Thompsonmina Date: Tue, 12 May 2026 17:03:27 +0100 Subject: [PATCH 3/4] retrigger validation (linked repo now has CI + demo.sh + .idl.json) From 8e83abc14bad5a6e728cd0dcffc45d5f00b2fe31 Mon Sep 17 00:00:00 2001 From: Thompson Date: Fri, 15 May 2026 00:58:48 +0100 Subject: [PATCH 4/4] polish documenting a bit --- solutions/LP-0017.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/solutions/LP-0017.md b/solutions/LP-0017.md index d21ba84..2caa4bd 100644 --- a/solutions/LP-0017.md +++ b/solutions/LP-0017.md @@ -53,10 +53,9 @@ messages broadcast while it was offline, subscribes to the live relay, and flushes the buffer on either size (50) or time (30 s) — whichever comes first. -**Why LEZ over zone-SDK.** LP-17 lets the submitter choose. The -zone-SDK path "requires a single designated actor to perform consensus -inscription" (LP-17), concentrating anchor authority and undermining -the censorship-resistance premise. A SPEL program on LEZ is +**Why LEZ over zone-SDK.** The zone-SDK path "requires a single designated actor to perform consensus +inscription" concentrating anchor authority and undermining +the censorship-resistance premise of the problem. A SPEL program on LEZ is permissionless — anyone with a wallet can submit `index_batch`, which is exactly the property the `batch-anchor` CLI relies on. SPEL also ships IDL generation, scaffolding, an auto-generated CLI, and the @@ -79,10 +78,10 @@ format by hand. - [x] **Batch tool resume after interruption**: seeded from chain at startup + Waku store-protocol catch-up over a configurable lookback window. - [x] **CU benchmarks (1 + 50 CID)**: documented in `README_CHRONICLE_REGISTRY.md` § Compute units (cold n=1 = 2,240 cycles; cold n=50 = 178,646 cycles). - [x] **Local LEZ deployment**: chronicle-registry deploys to a local LEZ devnet via `make deploy`; `scripts/setup.sh` does so end-to-end. -- [ ] **E2E integration tests in CI**: IT contract sketched in `integration-test.toml`; CI runner pending. +- [ ] **E2E integration tests in CI**: IT contract sketched in `integration-test.toml`; chronicle smoke test on the IT topic; that runs against a real local sequencer; `RISC0_DEV_MODE` left unset so the prover runs in production mode CI runner that runs lez and logoscore environment pending. - [x] **Top-level README** with build, addresses, app, tool, query: `whistleblower/README.md`. -- [x] **Reproducible E2E demo script**: `scripts/run-app.sh` + chronicle smokes on the IT topic; runs against a real local sequencer; `RISC0_DEV_MODE` left unset so the prover runs in production mode. -- [x] **Narrated video demo**: linked above; script at `docs/demo-script.md`. +- [x] **Reproducible E2E demo script**: `scripts/run-app.sh` + . +- [x] **Narrated video demo**: linked above;. - [x] **Dual licensed MIT + Apache-2.0**: `LICENSE-MIT`, `LICENSE-APACHE`. ## FURPS Self-Assessment