diff --git a/README.md b/README.md index 8ed6772..d7e16c0 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,9 @@ Across the whole program, roughly **30% happy-path, 70% breaking/poking.** | Artifact | Location | |---|---| | Test catalog | `catalog/` in this repo | +| v3 lifecycle reference | `reference/v3-lifecycle.md` | +| v3 QA harness setup | `reference/v3-qa-harness.md` | +| Contracts v3 presentation | `docs/presentations/contracts-v3-pr.html` | | Charter definitions | `charters/` in this repo | | Cycle plans & reports | `cycles/` in this repo | | Session notes (charter outputs) | `cycles//session-notes/` | diff --git a/catalog/README.md b/catalog/README.md index a5d3569..25faef4 100644 --- a/catalog/README.md +++ b/catalog/README.md @@ -6,6 +6,7 @@ The catalog is the master list of all known manual tests, organized by component | Path | Contents | |---|---| +| `../reference/` | v3 lifecycle reference and QA harness setup (context, not test cases) | | `track-a.md` | All Track A (smoke) tests in a single runnable checklist | | `track-b/` | Track B (deep validation) tests, one file per component | | `regression-watch.md` | Ephemeral list of known open issues to re-check next cycle | diff --git a/pr-contracts-v3-presentation (1).html b/docs/presentations/contracts-v3-pr.html similarity index 100% rename from pr-contracts-v3-presentation (1).html rename to docs/presentations/contracts-v3-pr.html diff --git a/reference/README.md b/reference/README.md new file mode 100644 index 0000000..4c43eef --- /dev/null +++ b/reference/README.md @@ -0,0 +1,12 @@ +# Reference + +Stable, searchable context for QA — not executable test cases (those live in `catalog/`). + +| Document | Purpose | +|----------|---------| +| [v3-lifecycle.md](v3-lifecycle.md) | Contracts v3 mental model, epoch states, service behavior, QA focus lanes, ops checklist | +| [v3-qa-harness.md](v3-qa-harness.md) | How to stand up compose vs `cartesi run`, preflight checklist, demo command path | + +**Presentation deck:** [docs/presentations/contracts-v3-pr.html](../docs/presentations/contracts-v3-pr.html) + +**Narrative:** [foreclose.md](../foreclose.md) — why the emergency exit exists. diff --git a/reference/v3-lifecycle.md b/reference/v3-lifecycle.md new file mode 100644 index 0000000..a05797c --- /dev/null +++ b/reference/v3-lifecycle.md @@ -0,0 +1,252 @@ +# Contracts v3 — Lifecycle Reference for QA + +Condensed reference for the Rollups Node contracts v3 integration (`feature/bump-contracts-3.0`). Source material: [Contracts v3 PR presentation](../docs/presentations/contracts-v3-pr.html). For the operator narrative on *why* foreclosure exists, see [foreclose.md](../foreclose.md). + +**Audience:** QA testers, cycle leads, and anyone writing catalog entries or charters for the v3 release. + +--- + +## Version pins (update each cycle) + +| Artifact | v3 target (as of branch review) | +|----------|----------------------------------| +| `rollups-contracts` | `2.2.0` → `3.0.0-alpha.6` | +| `dave` | `2.1.1` → `3.0.0-alpha.3` | +| Node branch | `feature/bump-contracts-3.0` (vs `origin/next/2.0`) | +| Generated bindings | `pkg/contracts/` refreshed | + +Confirm runtime image tags in `compose.local.yaml` before executing tests. Mismatched contract suite + node binary + DB schema is the highest-risk deployment mistake. + +--- + +## What changed (one paragraph) + +Contracts v3 is not only a binding bump. Claims now move through **staging** before acceptance; each application has a **withdrawal config** and a **guardian** who can **foreclose**; after foreclosure the node enters a **second lifecycle** (prove accounts-drive root → withdraw accounts). The node became a **v3 lifecycle observer** — it must reconcile L1 events (staging, foreclosure, drive-prove, withdrawals) into explicit DB state, not only submit claims. + +--- + +## Mental model: before vs now + +### Application state + +| Before (v2-alpha) | Now (v3) | +|-------------------|----------| +| Single `ApplicationState`: `ENABLED`, `DISABLED`, `FAILED`, `INOPERABLE` | **`enabled`** (operator intent) + **`status`** (system health) | +| Foreclosure hard to model | **`status=FORECLOSED`** with durable **`foreclose_block`** on L1 | +| No post-foreclosure observation model | EVM Reader keeps scanning drive-prove and withdrawal events | + +**`status` values:** `OK`, `FAILED`, `INOPERABLE`, `FORECLOSED` + +**Key distinction for QA:** `FORECLOSED` is a **normal emergency path**, not corruption. `INOPERABLE` means local mismatch or corruption. A healthy foreclosed app is typically `enabled=true`, `status=FORECLOSED`, `foreclose_block > 0`. + +### Claim finality + +| Before | Now | +|--------|-----| +| Authority/Quorum: mostly submit → accept | **SUBMITTED → STAGED → ACCEPTED** | +| No local staging model | `CLAIM_STAGED` epoch status; `staged_at_block` required | +| No withdrawal table/API | `Withdrawal` events stored; JSON-RPC read methods | + +--- + +## Consensus paths: Authority, Quorum, PRT + +### Authority + +Submit and stage happen **in the same transaction**. `acceptClaim` is a **separate transaction** after `claimStagingPeriod` blocks elapse. + +``` +CLAIM_COMPUTED → CLAIM_SUBMITTED → CLAIM_STAGED → (wait staging period) → CLAIM_ACCEPTED +``` + +Early `acceptClaim` (before staging period) must revert on-chain. If the claimer was offline and returns, it should log the rejection and recover without infinite retries. + +**Catalog:** [FOR-001](../catalog/track-b/foreclose.md), [break-the-claimer](../charters/break-the-claimer.md) + +### Quorum + +A submitted claim is **not** always staged by our transaction. The node must watch events and `getClaim` state until majority voting stages one claim, then `acceptClaim` later. + +Honest vote divergence must **not** produce false `INOPERABLE`. + +**Catalog:** [QUO-001](../catalog/track-b/quorum.md), [QUO-002](../catalog/track-b/quorum.md) + +### PRT (Dave tournaments) + +PRT **skips `CLAIM_STAGED`**. Dave tournaments can move `CLAIM_COMPUTED` → `CLAIM_ACCEPTED` directly. After foreclosure, PRT skips new tournament work and reports pre-foreclosure drain progress. + +**Cycle scope:** PRT-specific paths are currently marked out of scope in several catalog files and charters. Decide explicitly in each cycle `plan.md` whether PRT is in or deferred. + +--- + +## Epoch status machine + +```mermaid +stateDiagram-v2 + direction LR + [*] --> OPEN + OPEN --> CLAIM_COMPUTED + CLAIM_COMPUTED --> CLAIM_SUBMITTED + CLAIM_SUBMITTED --> CLAIM_STAGED: Authority or winning Quorum vote + CLAIM_STAGED --> CLAIM_ACCEPTED: acceptClaim after staging period + CLAIM_SUBMITTED --> CLAIM_FORECLOSED: foreclose before acceptance possible + CLAIM_STAGED --> CLAIM_FORECLOSED: foreclose during staged window + CLAIM_ACCEPTED --> [*]: normal path complete + CLAIM_FORECLOSED --> [*]: terminal +``` + +**DB rules:** triggers reject invalid transitions. `CLAIM_STAGED` is valid for Authority and Quorum only (not PRT). + +**Foreclosure terminalizes** any non-accepted pre-foreclosure claim work as `CLAIM_FORECLOSED`. Previously accepted history must be preserved. + +**Catalog:** [FOR-002](../catalog/track-b/foreclose.md) through [FOR-004](../catalog/track-b/foreclose.md) + +--- + +## Post-foreclosure service behavior + +Do **not** disable foreclosed apps automatically if you still need post-foreclosure observation. + +| Service | Normal work | Foreclosed app | +|---------|-------------|----------------| +| **EVM Reader** | Scans inputs, outputs, epochs, L1 state | Records foreclosure; scans drive-prove and withdrawal events | +| **Advancer** | Runs while `enabled && status=OK && foreclose_block=0` | Keeps machine only while pre-foreclosure inputs are undrained | +| **Validator** | Computes proofs for processed epochs | Skips epochs that cannot become accepted after foreclosure block | +| **Claimer** | Submit, stage, accept Authority/Quorum claims | Read-only reconciliation; marks impossible claims `CLAIM_FORECLOSED` | +| **PRT** | Dave tournament work | Skips new tournaments; reports pre-foreclosure drain | + +**EVM Reader scan order:** detect foreclosure **first**, then build scan plan (pre-foreclosure inputs → output execution → post-foreclosure drive-prove/withdrawals). Cursors (`last_foreclose_check_block`, etc.) advance strictly monotonically. + +--- + +## Emergency withdrawal sequence + +After foreclosure, normal claim submission stops. Recovery is permissionless (except guardian foreclose): + +1. **Guardian** calls `foreclose()` — app becomes `FORECLOSED`; `foreclose_block` recorded. +2. **Anyone** calls `proveAccountsDriveMerkleRoot(root, proof)` — once per app. +3. **Anyone** calls `withdraw(account, accountProof)` — gas payer can differ from recipient. +4. EVM Reader stores `Withdrawal` events; JSON-RPC and CLI expose them. + +Proof files come from `cartesi-rollups-machine-tool` (replay snapshot → `prove accounts-drive`). + +**Catalog:** [FOR-006](../catalog/track-b/foreclose.md) through [FOR-012](../catalog/track-b/foreclose.md), [MTL-001](../catalog/track-b/machine-tool.md), [MTL-002](../catalog/track-b/machine-tool.md), [SMK-005](../catalog/track-a.md) + +--- + +## API and CLI surface (what QA should verify) + +### Application JSON (JSON-RPC / reads) + +Old single `state` field replaced by: + +- `enabled`, `status` +- `claim_staging_period`, `withdrawal_config` +- Foreclosure markers: `foreclose_block`, `accounts_drive_proved_block`, root, transactions, cursors + +**Catalog:** [ILC-010](../catalog/track-b/internal-cli.md) + +### New JSON-RPC methods + +- `cartesi_listWithdrawals` +- `cartesi_getWithdrawal` + +Verify operator CLI `read withdrawals` and JSON-RPC return consistent rows (FOR-012). + +### New operator CLI commands + +``` +cartesi-rollups-cli foreclose +cartesi-rollups-cli prove-drive-root --proof-file drive-root-proof.json +cartesi-rollups-cli withdraw --proof-file account-proof.json +cartesi-rollups-cli read withdrawals [account-index] +``` + +Deploy support: `deploy application --claim-staging-period`, `--withdrawal-config`, `--withdrawal-config-file`; `deploy quorum` for v3 Quorum. + +**Catalog:** [ILC-007](../catalog/track-b/internal-cli.md) through [ILC-010](../catalog/track-b/internal-cli.md) + +--- + +## QA focus lanes + +Test **lifecycle correctness**, not only command success. Upstream integration tests cover staging, quorum, foreclosure, replay, and withdrawal on Anvil — manual QA still matters for operator-facing tools, timing on real networks, and error clarity. + +| Lane | What to test | Expected signal | +|------|--------------|-----------------| +| **Staging** | Authority: submit stages immediately; accept waits for period | `CLAIM_COMPUTED → SUBMITTED → STAGED → ACCEPTED` | +| **Quorum** | Majority stages; honest vote divergence classified correctly | No false `INOPERABLE` for pending honest divergence | +| **Foreclosure** | Foreclose before, during, and after claim work | App `FORECLOSED`; impossible claims → `CLAIM_FORECLOSED` | +| **Withdrawals** | Prove drive root, withdraw accounts, restart scanner | Rows persist once; cursors advance; RPC reads match | +| **Ops paths** | Bad signer, bad proof, bad/partial config | Clear errors; no hidden partial state | + +These lanes map directly to the [cycle plan template](../templates/cycle-plan-template.md) QA Focus Lanes table. + +--- + +## Known risk points (where bugs hurt most) + +| Risk | What goes wrong | Mitigation to verify | +|------|-----------------|----------------------| +| **Chain/DB divergence** | Missed `ClaimStaged`, `ClaimAccepted`, `Foreclosure`, or `Withdrawal` event | Counters, event scans, cursors, reconciliation reads | +| **Bad withdrawal config** | Wrong guardian, drive layout, or output builder blocks recovery | All-or-nothing config validation; tool output checks | +| **Gas spending loops** | Repeated `acceptClaim` failures burn gas forever | `CARTESI_CLAIMER_MAX_ACCEPT_ATTEMPTS` (default 5); app → `FAILED` | +| **PRT assumptions** | PRT never uses `CLAIM_STAGED`; no new tournaments after foreclosure | Consensus-aware filters; DB trigger rules | + +--- + +## Ops checklist (before v3 deploy) + +### Configuration + +- [ ] Update factory addresses: InputBox, AuthorityFactory, QuorumFactory, ApplicationFactory, SelfHosted, DaveAppFactory +- [ ] Set `CARTESI_CLAIMER_MAX_ACCEPT_ATTEMPTS` if default `5` is wrong for the network +- [ ] Confirm guardian wallets and withdrawal config for apps that need foreclosure +- [ ] Confirm snapshot policy for apps that may need withdrawal proofs + +### Data and rollout + +- [ ] Migration `000001` changed — **do not reuse a v2-alpha DB** without an explicit migration plan +- [ ] JSON-RPC clients updated for `enabled` + `status` (not old single `state`) +- [ ] Monitor `FORECLOSED`, `FAILED`, `INOPERABLE`, and claim staging states **separately** +- [ ] Guardian and gas-payer accounts funded for emergency flows + +### Highest-risk mistake + +Mixing **old contracts**, **old factory addresses**, or **old DB shape** with the new node binary. + +--- + +## Catalog map (v3-heavy areas) + +| Topic | Primary catalog file | +|-------|----------------------| +| Staging + foreclosure + emergency withdrawal | [catalog/track-b/foreclose.md](../catalog/track-b/foreclose.md) | +| Quorum staging/divergence | [catalog/track-b/quorum.md](../catalog/track-b/quorum.md) | +| Operator CLI v3 | [catalog/track-b/internal-cli.md](../catalog/track-b/internal-cli.md) | +| Machine tool proofs | [catalog/track-b/machine-tool.md](../catalog/track-b/machine-tool.md) | +| Release smoke (includes emergency path) | [catalog/track-a.md](../catalog/track-a.md) | +| JSON-RPC boundaries | [catalog/track-b/jsonrpc-api.md](../catalog/track-b/jsonrpc-api.md) | + +--- + +## Upstream integration tests (do not duplicate manually) + +Before adding catalog entries, check whether CI already covers the mechanics: + +- `test/integration/*foreclose*.go` +- `test/integration/withdrawal_lifecycle_test.go` +- `test/integration/echo_quorum_test.go` +- `internal/repository/repotest/` + +Manual value remains: real testnet timing, operator UX, cross-surface parity (CLI vs JSON-RPC), and partial-failure recovery. + +--- + +## Related artifacts + +| Artifact | Purpose | +|----------|---------| +| [v3-qa-harness.md](v3-qa-harness.md) | How to stand up the compose stack for v3 testing | +| [foreclose.md](../foreclose.md) | Narrative explanation of the emergency exit | +| [Contracts v3 PR presentation](../docs/presentations/contracts-v3-pr.html) | Full slide deck with sequence diagrams | diff --git a/reference/v3-qa-harness.md b/reference/v3-qa-harness.md new file mode 100644 index 0000000..5e8e743 --- /dev/null +++ b/reference/v3-qa-harness.md @@ -0,0 +1,361 @@ +# Contracts v3 — QA Harness Setup + +How to stand up an environment capable of running v3 lifecycle tests (staging, foreclosure, emergency withdrawal, operator CLI, machine tool). For *what* to test, see [v3-lifecycle.md](v3-lifecycle.md) and the [catalog](../catalog/). + +This repo does **not** ship a test application. Use an app from the Cartesi CLI templates or the rollups-node repo (see below). + +--- + +## Two harness modes + +| Mode | Good for | Cannot do | +|------|----------|-----------| +| **`cartesi run`** + a scaffolded app | CLI misuse, JSON-RPC/inspect boundaries, basic claimer auth scenarios | Emergency withdrawal, `cartesi-rollups-cli`, per-service restart, quorum deploy | +| **Compose** (Mugen-Builders `compose.local.yaml`) | Full v3 lifecycle, FOR/ILC/MTL catalog, SMK-005, operator-day-two | Quick iteration on a single monolithic stack | + +**Rule of thumb:** if the test mentions `cartesi-rollups-cli`, `cartesi-rollups-machine-tool`, `foreclose`, `prove-drive-root`, `withdraw`, or quorum deploy — use **compose**. + +--- + +## Choosing a test application + +Pick the app based on what you need to exercise — not every catalog entry uses the same template. + +| Need | Suggested app | Source | +|------|---------------|--------| +| Fast local smoke (inputs, notices, basic claimer) | Any minimal JS/Python template | `cartesi create -t javascript` (or `python`) | +| Emergency withdrawal + foreclosure (SMK-005, FOR-006–012) | **`erc20-withdrawal-dapp`** | rollups-node repo / presentation demo path | +| Quorum lifecycle (QUO-*) | App deployed against a v3 Quorum consensus | compose + `deploy quorum` | + +### `erc20-withdrawal-dapp` (full v3 path) + +Use for foreclosure and emergency withdrawal catalog work. It exercises: + +- Deposits and normal voucher flow +- Accounts-drive layout required for emergency withdrawal proofs +- Output builder integration for post-foreclosure payouts + +### Lightweight template (quick devnet) + +For CLI, JSON-RPC, and inspect tests that do not need emergency withdrawal: + +```sh +cartesi create -t javascript +cd +cartesi build +cartesi run --epoch-length 10 -p +``` + +Replace ``, ``, and payload format with whatever your template defines. + +--- + +## Tooling: three different CLIs + +Do not assume one install gives you everything. These are separate binaries with different run contexts. + +| Tool | Purpose | Where it runs | +|------|---------|---------------| +| **`cartesi`** | Developer workflow: `create`, `build`, `run`, `send`, `doctor` | **Host** — install via Cartesi CLI package | +| **`cartesi-rollups-cli`** | Operator workflow: `deploy`, `foreclose`, `prove-drive-root`, `withdraw`, `read …`, `app …` | **Inside the advancer container** when using compose — **not** on the host and **not** available with `cartesi run` | +| **`cartesi-rollups-machine-tool`** | `replay`, `prove accounts-drive` — produces proof JSON for emergency withdrawal | **Host** — build from the [rollups-node](https://github.com/cartesi/rollups-node) repo (`make build`) at the **same version** as the node under test; needs DB/env config (see rollups-node `make env`) | + +Prefix every operator CLI invocation in compose: + +```sh +export COMPOSE_FILE=compose.local.yaml +export EXEC="docker compose -f $COMPOSE_FILE exec advancer cartesi-rollups-cli" + +# Examples +$EXEC app list +$EXEC read epochs +$EXEC foreclose +``` + +Optional host tools: **`cast`** (Foundry) for direct L1 calls when not going through the operator CLI. + +--- + +## Prerequisites + +Record versions in every session note. + +### Host + +```sh +cartesi --version +docker --version +docker compose version +cartesi-rollups-machine-tool --help # after rollups-node build; skip if not running MTL/FOR emergency path +``` + +| Requirement | Notes | +|-------------|-------| +| **Cartesi CLI (`cartesi`)** | On the host; used to scaffold apps and `cartesi build` | +| **Docker Desktop** | Running before compose or `cartesi run` | +| **`cartesi-rollups-machine-tool`** | Required for MTL-* and emergency proof generation; build from rollups-node matching the node image under test | +| **Foundry `cast`** (optional) | Direct L1 transactions when debugging outside operator CLI | + +### Compose stack (provides `cartesi-rollups-cli`) + +| Requirement | Notes | +|-------------|-------| +| **Mugen-Builders `compose.local.yaml`** | Self-hosted node; see [cartesi-deploy skill](../.agents/skills/cartesi-deploy/SKILL.md) | +| **Node runtime image** | Must match v3 contract suite (verify tag in compose file) | +| **Contracts v3 suite** | `rollups-contracts 3.0.0-alpha.6` per [v3-lifecycle.md](v3-lifecycle.md) | +| **v3 factory addresses** | InputBox, AuthorityFactory, QuorumFactory, ApplicationFactory, SelfHosted, DaveAppFactory | +| **Funded deployer key** | In `.env` for compose / Anvil or testnet | +| **Guardian key** | Must match `withdrawal_config` guardian address (foreclose) | +| **Gas payer** | For `prove-drive-root` and `withdraw` (can differ from recipient) | + +After `docker compose up`, confirm operator CLI is reachable: + +```sh +docker compose -f compose.local.yaml exec advancer cartesi-rollups-cli --help +``` + +--- + +## Compose setup (canonical v3 harness) + +### 1. Build the application machine image + +```sh +cd +cartesi build +``` + +Confirm snapshot exists: + +```sh +ls .cartesi/image/ +``` + +### 2. Obtain and configure Mugen-Builders deployment + +Follow the [cartesi-deploy skill](../.agents/skills/cartesi-deploy/SKILL.md) for full detail. Summary: + +1. Clone or download [deployment-setup-v2.0](https://github.com/Mugen-Builders/deployment-setup-v2.0) +2. Copy `compose.local.yaml` and configure `.env` for your chain +3. **Verify runtime image tag** matches the v3 contract suite under test +4. Point factory addresses at the **v3** deployment (InputBox, AuthorityFactory, QuorumFactory, ApplicationFactory, SelfHosted, DaveAppFactory) + +### 3. Start services + +```sh +docker compose -f compose.local.yaml up -d +``` + +Confirm all services healthy: advancer, validator, claimer, evm-reader, jsonrpc-api, postgres. + +Set the operator CLI helper (use in all following steps): + +```sh +export COMPOSE_FILE=compose.local.yaml +export EXEC="docker compose -f $COMPOSE_FILE exec advancer cartesi-rollups-cli" +``` + +### 4. Deploy application with v3 flags + +```sh +$EXEC deploy application \ + --claim-staging-period \ + --withdrawal-config-file +``` + +Verify partial/invalid withdrawal config is rejected before any on-chain tx (ILC-008). + +For quorum tests: + +```sh +$EXEC deploy quorum ... +``` + +### 5. Register and confirm v3 fields + +```sh +$EXEC contract +$EXEC read epochs +``` + +Expect `enabled`, `status`, `claim_staging_period`, `withdrawal_config`, foreclosure markers — not the old single `state` field (ILC-010). + +--- + +## Preflight checklist (run before charters or v3 catalog blocks) + +Complete in ~5–10 minutes. Stop and fix before proceeding if any step fails. + +### Host and toolchain + +- [ ] `docker info` succeeds +- [ ] `cartesi doctor` all green (when using `cartesi run`) +- [ ] `docker compose -f compose.local.yaml exec advancer cartesi-rollups-cli --help` succeeds (compose path) +- [ ] No zombie compose state: `docker ps` and `cartesi status` agree +- [ ] If prior session ended badly: `docker compose -p down` and clean restart + +### Stack health (compose) + +- [ ] All node services running +- [ ] JSON-RPC responds: + +```sh +curl -s -X POST http://localhost:/rpc \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"cartesi_getVersion","params":[],"id":1}' +``` + +- [ ] Application registered with v3 fields visible via `$EXEC contract ` + +### Minimal roundtrip + +- [ ] Send one advance input (`cartesi send` on host, or `$EXEC send` inside advancer) +- [ ] Input appears in `cartesi_listInputs` / `read inputs` +- [ ] After epoch close: claim progresses through staging states (Authority) or submitted → staged (Quorum) +- [ ] At least one notice or expected output for the app template + +### Charter-specific gates + +| Charter / lane | Extra preflight | +|----------------|-----------------| +| break-the-claimer | Compose with isolatable `claimer` service; short `claim-staging-period` for timing tests | +| stress-evm-reader | Configurable RPC/WS; ability to swap endpoints | +| misuse-the-cli | **Clean slate** — no stack running (or document intentional dirty state) | +| operator-day-two | Compose + funded testnet; guardian key ready | +| Foreclosure / withdrawal (FOR-*, SMK-005) | `erc20-withdrawal-dapp` (or equivalent); guardian + gas payer funded | + +--- + +## End-to-end v3 demo path (smoke reference) + +Canonical sequence from the contracts v3 presentation. Use as SMK-005 / FOR happy-path rehearsal. + +Requires compose running and `EXEC` set (see compose setup §3). Machine-tool commands run on the **host** with rollups-node `make env` (or equivalent DB connection). + +```sh +# Host: build operator + machine-tool binaries (rollups-node checkout) +make build +eval $(make env) + +# Operator CLI — inside advancer container +$EXEC deploy quorum ... +$EXEC deploy application \ + --claim-staging-period \ + --withdrawal-config-file + +# Normal lifecycle — observe staging +$EXEC read epochs +# Watch: CLAIM_SUBMITTED → CLAIM_STAGED → CLAIM_ACCEPTED + +# Emergency path +$EXEC foreclose # guardian signer + +# Machine tool — host (needs DB/env from eval $(make env)) +cartesi-rollups-machine-tool replay \ + --template \ + --application \ + --to-epoch \ + --store snapshots/accepted-epoch- + +cartesi-rollups-machine-tool prove accounts-drive \ + --snapshot snapshots/accepted-epoch- \ + --account \ + --accounts-drive-start-index \ + --out-drive-root-proof drive-root-proof.json \ + --out-withdraw-proof account-proof.json + +# Operator CLI again — proof files must be visible inside advancer or copied in +$EXEC prove-drive-root --proof-file drive-root-proof.json +$EXEC withdraw --proof-file account-proof.json +$EXEC read withdrawals +``` + +**What to watch:** + +1. Application shows `enabled`, `status`, foreclosure markers after foreclose +2. Epochs move through staged states before acceptance +3. Foreclosure stops normal claims but **not** L1 observation +4. Withdrawal rows appear only after drive root is proved +5. Second withdrawal for same account fails (single-use) + +--- + +## Quick devnet harness (`cartesi run`) + +For fast iteration on tests that do not need emergency withdrawal or the operator CLI: + +```sh +cartesi create -t javascript # or python, etc. +cd +cartesi build +cartesi run --epoch-length 10 -p +``` + +| Service | URL pattern | +|---------|----------------| +| Proxy | `http://127.0.0.1:` | +| Anvil RPC | `http://127.0.0.1:/anvil` | +| Inspect | `http://127.0.0.1:/inspect/` | +| JSON-RPC | `http://127.0.0.1:/rpc` | + +Send inputs with `cartesi send` (payload format depends on your app) and confirm processing via JSON-RPC or inspect routes. + +**Limitation:** all services run in one `rollups_node` container. Restarting only the claimer requires compose. + +--- + +## Which catalog areas need which harness + +| Catalog area | Harness | Notes | +|--------------|---------|-------| +| `track-a` SMK-001–004 (devnet) | `cartesi run` or compose | Any scaffolded template | +| `track-a` SMK-005–006 | Compose + testnet | Withdrawal dapp + emergency path | +| `foreclose.md` FOR-* | Compose + withdrawal dapp | Timing-sensitive; real block progression | +| `internal-cli.md` ILC-* | Compose | `$EXEC` inside advancer; not on host | +| `machine-tool.md` MTL-* | Compose + rollups-node build on host | DB access via `make env`; proofs fed back to `$EXEC` | +| `quorum.md` QUO-* | Compose + multi-validator quorum deploy | Testnet | +| `jsonrpc-api.md` JRP-* | Either | Lightweight template sufficient for many entries | +| `cli.md`, `misuse-the-cli` charter | `cartesi run` or compose | Prefer clean slate for misuse | + +--- + +## Teardown + +```sh +docker compose -p down +``` + +For `cartesi run` stacks: + +```sh +docker compose -p down +``` + +For v3 alpha: prefer a **fresh database** over reusing a v2-alpha DB against the new migration. See [v3-lifecycle.md — Ops checklist](v3-lifecycle.md#ops-checklist-before-v3-deploy). + +--- + +## Troubleshooting + +| Symptom | Likely cause | Action | +|---------|--------------|--------| +| `cartesi run` prints URL then fails at compose | No machine snapshot | Run `cartesi build` first | +| `cartesi status` says down but `docker ps` shows containers | Partial compose rollback after failed run | `docker compose down`; full restart | +| Internal CLI not found on host | `cartesi-rollups-cli` is not a host binary | Run via `$EXEC …` inside advancer, or build rollups-node for local dev | +| `cartesi-rollups-cli: command not found` in advancer | Stack not up or wrong service | `docker compose ps`; exec into `advancer`, not `rollups_node` from `cartesi run` | +| Foreclose succeeds but no withdrawal rows | Drive root not proved yet | Run prove → withdraw sequence | +| `enabled`/`status` missing in API | Old node or wrong contract suite | Verify image tag and bindings version | +| Tests pass on Anvil, fail on testnet | Staging period / block timing | Increase waits; use shorter period in dev | + +For deeper diagnosis, use the [cartesi-debug skill](../.agents/skills/cartesi-debug/SKILL.md). + +--- + +## Related artifacts + +| Artifact | Purpose | +|----------|---------| +| [v3-lifecycle.md](v3-lifecycle.md) | Mental model, epoch states, QA focus lanes | +| [catalog/track-b/foreclose.md](../catalog/track-b/foreclose.md) | Executable foreclosure tests | +| [catalog/track-a.md](../catalog/track-a.md) | Release smoke including SMK-005 | +| [charters/README.md](../charters/README.md) | Exploratory session guide |