Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7864ed9
Add a working plan for a medium-scale testnet simulation.
AdamSpitz Sep 11, 2026
6d29d92
Define v1 realistic campaign schema
AdamSpitz Sep 11, 2026
2504edf
Add deterministic campaign planner
AdamSpitz Sep 11, 2026
94aa986
Separate campaign chain environments
AdamSpitz Sep 11, 2026
6a12e4b
Add resumable campaign execution engine
AdamSpitz Sep 11, 2026
13dadc9
Make campaign behavior cause-aware
AdamSpitz Sep 11, 2026
96a0700
Add campaign reconciliation engine
AdamSpitz Sep 11, 2026
d5672cc
Bind campaign reconciliation to indexer events
AdamSpitz Sep 11, 2026
729d18b
Add campaign runtime binding artifact
AdamSpitz Sep 11, 2026
241bb55
Add campaign SDK reconciliation checks
AdamSpitz Sep 11, 2026
c7f2d6a
Exercise campaign reconciliation against the local stack
AdamSpitz Sep 11, 2026
c2c0b27
Bind campaign execution to contract writes.
AdamSpitz Sep 11, 2026
bc1c225
Fund generated campaign wallets before local execution.
AdamSpitz Sep 11, 2026
4673931
Fix campaign reconcile after the local 100-user run.
AdamSpitz Sep 11, 2026
a25820c
File a TODO for unmixing local and testnet generated env.
AdamSpitz Sep 11, 2026
fafc61e
Keep localhost and testnet generated env profiles from mixing.
AdamSpitz Sep 11, 2026
4bb8102
Record local campaign UI inspection on chain 31337.
AdamSpitz Sep 11, 2026
f5e16bb
Add a read-only remote canary preflight for the 10-user campaign.
AdamSpitz Sep 11, 2026
d99d16b
Temporarily disable CreatorAssuranceVeto indexer (not yet deployed to…
AdamSpitz Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
.env.secrets
.env.render
.env.cloudflare
.generated-env/
services/implication-attester/.env
ui/.env
integration-tests/.env.local
Expand Down
20 changes: 20 additions & 0 deletions CONTINUITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2147,3 +2147,23 @@ not more protocol surface.

Removed the item from `focus.md`. Spec status is closed. Deferred: indexed
beneficiary lookup and bulk/bot UX.

## 2026-09-11 — Campaign reconciliation talks to the local stack

Item 6 of the medium-realistic campaign: indexer adapter paginates with `fetchEventsComplete` and collapses alternative proving events so ordinary vs retroactive funding is one write. `npm run gen:campaign:reconcile -- --probe` reads live chain/indexer heads. Without `--probe` it reconciles from plan + execution + runtime-bindings. A live adapter test exercises raw lookup plus an SDK belief fold against Ponder. Campaign execution adapter is still required before mined campaign txs exist to close item 6.

## 2026-09-11 — Local campaign wallet provisioning

Item 7 of the medium-realistic campaign: `campaignProvisioning.ts` funds generated wallets before `gen:campaign:execute`. Local mode transfers ETH from the Hardhat funder and payment tokens (mint fallback). Remote stays transfer-only and refuses Hardhat keys. `--skip-provision` exists for already-funded reruns. Live smoke on the local stack wrote `execution/funding-ledger.json` for all 100 slots. Full 100-user execute/reconcile/UI inspection is still open.

## 2026-09-11 — Full local 100-user campaign execute + reconcile

Ran `gen:campaign:execute --mode local --concurrency 4 --skip-provision`: 1932 mined, 0 failed, ~196s. First reconcile mismatched all fund-project and note SDK folds. Fixes: derived funding checks now use `campaignFundProjectCost()` (0.01 token per buy, matching the adapter) instead of planner persona amounts; note lookups lowercase the bound contract address. Re-reconcile: 1932/1932 verified, indexer lag 0.

## 2026-09-11 — Local campaign CauseStarter UI inspection

Plan item 7 closed. Restarted a 6-day-old `causestarter:dev` so Vite baked `VITE_CHAIN_ID=31337` instead of Base Sepolia. Schools and open-source boards, a bridge statement, and a funded project (eip155:31337) render from the local indexer. Notes page needs a connected wallet. Empty `VITE_DEFAULT_ALIGNMENT_TRUST_ROOT` shows the “no starter vouching network” banner. Details: `fake-data-generation/campaigns/medium-realistic-v1-local-run.md`. Next: remote canary preflight (plan item 8).

## 2026-09-11 — Remote canary preflight (no mutation)

Plan item 8 closed. `campaignCanary.ts` + `npm run gen:campaign:canary-preflight` slice the medium-realistic plan to 10 users (plus extra actors required by prerequisites), estimate ETH/token needs and paced duration, probe chain bytecode and indexer lag, and write `reports/remote-canary-preflight.{json,md}`. Shared-lab health, official implication path, `verifier-testnet.sh`, and the budget/window remain `needs-adam`. Does not send transactions. Next: item 9 only after Adam approves that proposal.
12 changes: 12 additions & 0 deletions fake-data-generation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ This directory is **four jobs**, not one “generate fake data” switch:

The rest of this README is the **generative simulation** (jobs 1, 2, 4): randomly generated users and on-chain actions. Job 3 is the JSON + attester loop, not `runSimulation`.

The medium realistic campaign has a separate planning-only command: `npm run gen:campaign:plan`. It deterministically writes the selected statement catalog, unprovisioned wallet slots, persona/cause/project assignments, complete prerequisite-linked action graph, and gas/payment-token estimate under `output/campaigns/medium-realistic-v1/`. Its actions carry persona- and cause-aware intent: belief values and changes, project outcome text, outcome-backed alignments, skewed funding amounts (including deliberately unfunded projects), and shared-cause trust reasons for delegation/revocation histories. A later provisioning step binds public addresses to those slots; planning neither creates private keys nor connects to a chain.

Campaign execution uses the explicit environment boundary in `campaignEnvironment.ts`. Local mode is pinned to Hardhat chain 31337 and may use the legacy deploy/Hardhat-wallet/free-mint conveniences. Remote mode requires a committed deployment env manifest, an explicit non-Hardhat chain ID, existing bytecode at every required address, generated campaign wallets, and transfer-only payment-token provisioning. Deployment and provisioning adapters are validated against those policies before they can run; remote execution must also carry a separate mutation-confirmation flag when it is added. The existing `gen:tiny`/`gen:small`/`gen:medium`/`gen:large` commands remain local-only legacy simulation paths and are not remote campaign commands.

Remote canary prep is `npm run gen:campaign:canary-preflight`. It is read-only: chain/bytecode + indexer lag, a 10-user slice of the planned graph, native/token budget and duration estimates, and secrets/retention notes. It writes `reports/remote-canary-preflight.json` and `.md` for Adam's approval and never sets `--confirm-remote-mutation`. Do not run remote execute until that proposal is approved.

The reusable runner in `campaignExecutor.ts` consumes a frozen action plan through a chain adapter. It atomically persists planned/submitted/mined/failed state and transaction hashes, resumes submitted transactions by receipt lookup, respects action prerequisites, and enforces bounded concurrency, pacing, classified retries, a transaction cap, and a native-token budget. [`campaignActionAdapter.ts`](./campaignActionAdapter.ts) is the contract-binding layer: it maps each planned action type onto SDK writes, classifies RPC vs revert failures, and updates public runtime bindings (no private keys). `npm run gen:campaign:execute` runs that adapter locally after environment preflight and funds generated wallets (ETH plus payment tokens, minting locally when transfer fails). Remote mode still requires `--confirm-remote-mutation` and stays transfer-only. Pass `--skip-provision` only when wallets are already funded. Generated wallet secrets stay under `output/campaigns/secrets/` (gitignored via `output/`). The funding ledger is `execution/funding-ledger.json`.

Each local `fund-project` write currently spends `CAMPAIGN_FUND_PROJECT_TOKEN` (`0.01` of the 6-decimal payment token), not the planner’s persona-sized `amount`. Reconciliation’s SDK funding check uses that same unit cost. Note folds are looked up as `<contract.toLowerCase()>:<id>`.

`campaignReconciler.ts` provides the matching transaction-to-indexer boundary. `campaignIndexerAdapter.ts` binds every campaign action type to its real raw Ponder event(s), reads chain/indexer heads, and delegates derived truth to `campaignSdkDerivedChecks.ts`. Those binding-aware SDK checks verify final folded beliefs, implications, cause refs, projects and cumulative funding, alignments, and note ownership; repeated writes compare with the campaign's final intended state. The reusable reconciler detects omissions, duplicates, and derived-state mismatches, polls through a bounded settling window, records chain-head lag and indexing latency, and atomically writes machine-readable JSON plus a concise operator summary. `campaignRuntimeBindings.ts` defines the public, execution-produced handoff from planned IDs to wallet addresses, statement/roster CIDs, project contracts, and on-chain note IDs; it validates plan identity and coverage and persists atomically without wallet secrets. `npm run gen:campaign:reconcile -- --probe` talks to the live local chain and Ponder `/status` heads. The same command without `--probe` loads planned actions, execution state, and runtime bindings, then writes the reconciliation JSON/summary through the real indexer adapter and SDK folds. Raw lookups paginate with `fetchEventsComplete` and treat ordinary vs retroactive funding events as one proving write. A live adapter test runs when `http://localhost:42069` is reachable. Full 100-user local execution provisions wallets beyond the funded Hardhat accounts before submitting writes; a dry adapter test covers binding updates without a live chain.

## Overview

The generative testing suite consists of:
Expand Down
Loading
Loading