Skip to content

docs(spec): section 26 prover loop spawn, four controls, kill switch (#3265) - #627

Merged
MichaelTaylor3d merged 1 commit into
developfrom
spec/3265-prover-loop-controls
Sep 27, 2026
Merged

MichaelTaylor3d merged 1 commit into
developfrom
spec/3265-prover-loop-controls

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

What

Adds SPEC.md §26 — Reward prover loop: the spawn, the four controls, and the kill switch (DIG-Network/dig_ecosystem#3265), plus a one-sentence cross-reference in §5. Docs only: no source, no dependency, no version change.

Written against tip 69c793a7 and the published dig-rewards-coin 0.8.0 / dig-rpc-protocol 0.12.0 sources. Every clause either cites the code that already satisfies it or is marked (target) and listed in §26.14 with the ticket that lands it.

The locked shape, in one paragraph

Spawn from serve_with_shutdown right after the claim spawn, through a decide → spawn_if → from_config seam mirrored from rewards_claim/driver.rs (shape only — the claim config's default_enabled() == true is explicitly the trap, §26.3 cl. 6). Config is <state_dir>/rewards-prover.json with exactly three keys: enabled (default false, under a const _: () = assert! so the default cannot flip silently), mode (dryRun default | live), standard_fee_mojos (default 0 = refuse; above 0.1 XCH = refuse, never clamp). The node never writes the file. Spawn prints ONE warn line with the §6.3-derived figures (24 bundles/day, 192 actions/day, FeeBudget::daily_limit_for(fee), 0.24 XCH/day = 87.6 XCH/year at 0.01 XCH, 192 removals/day → ~1.3 days, 96 churns/day → ~2.6 days) per funded distributor. Dry-run is a DryRunChainPort decorator that logs and never calls the inner writes, runs the scheduler against a scratch bound store, and is log-only (0.12.0 cannot carry a mode). The kill switch is two tokio tasks on one watch channel: a switch task that ticks heartbeat_tick, re-reads enabled + <state_dir>/rewards-prover.STOP every 60 s and flips the sender; a cycle task that select!s the receiver against the cycle so a wedged cycle is dropped immediately — no RPC method. Stopped is durable until process restart. A cycle whose seam is absent faults (CycleOutcome, never advances last_cycle_completed_at); while the inventory is undetermined dig.getRewardProverStatus answers Half::NotConsulted; money counters are chain-derived, never local. Live mode is refused until PROVER_LIVE_MODE_RELEASED is flipped by a one-line PR citing the composed-system gate, which follows #3292, #3421, #3422, #3423.

Hard truth the section states

At this tip a spawned loop faults ChainSourceUnavailable on every cycle (chain_port.rs:77-97). The controls are verifiable now; distribution is not. The section orders the port work AFTER the controls and makes "spawns, reports Idle, distributes nothing" unrepresentable (§26.9 cl. 9).

Decider questions (for the orchestrator, not settled here)

  1. Undetermined inventory on the wire — Half::NotConsulted (locked, node-side only) vs a whole-call error vs a new wire field (protocol lane).
  2. Dry-run write bounds — scratch in-memory store seeded from the live store (locked) vs advancing the live bounds.
  3. PROVER_LIVE_MODE_RELEASED tripwire — a code constant flipped only by the gate verdict (locked).
  4. First cycle immediately at spawn (locked; the claim loop waits one cadence) — changes the periodicity test from 0→1→2 to 1→2→3.

Verification

  • git ls-files --eol SPEC.md → LF in/out; 15 new headings; 21 (target) markers; cross-reference at §5 line 1095.
  • No cargo invoked (docs only).

Refs: DIG-Network/dig_ecosystem#3265, #3274, #3261, #3292, #3421, #3422, #3423.

🤖 Generated with Claude Code

…l switch (dig_ecosystem#3265)

Normative SPEC.md section 26 locking the shape of the PR that spawns the reward
prover loop, before any implementer touches it:

- the spawn site (server.rs after spawn_claim_driver_from_config) and the
  three-function seam mirrored from rewards_claim/driver.rs, with the closed
  ProverDriverRefusal set
- rewards-prover.json: exactly three keys, every default stated (enabled=false
  under a compile-time assertion, mode=dryRun, standard_fee_mojos=0 refuses),
  a refused-not-clamped fee maximum, a corrupt marker that is never default()
- control 2: the spawn-time line and its exact figures (24 bundles/day, 192
  actions/day, FeeBudget::daily_limit_for, 0.24 XCH/day = 87.6 XCH/year at
  0.01 XCH, 192 removals/day -> ~1.3 days, 96 churns/day -> ~2.6 days), and
  the arithmetically false 96/1.3 pairing named so it is never printed
- control 3: DryRunChainPort contract, dry-run write bounds never touch the
  live store, log-only visibility stated as a 0.12.0 wire limitation
- control 4: two tasks one watch channel, sentinel file + config re-read every
  60 s, the wedged-reachability argument and its spawn_blocking precondition,
  Stopped is durable and one-way, no RPC method
- cycle honesty: CycleOutcome so a cycle that cannot see never completes,
  absent seams fault ChainSourceUnavailable, NotConsulted while the inventory
  is undetermined, chain-derived counters never local (dig_ecosystem#3274)
- the required periodicity/kill-switch test shapes and the composed-system
  gate that alone releases PROVER_LIVE_MODE_RELEASED
- sequencing: controls first, then #3292, #3421, #3422, #3423, gate, release

Docs only. No source, no dependency, no version change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@MichaelTaylor3d MichaelTaylor3d changed the title docs(spec): section 26 reward prover loop - spawn, four controls, kill switch (dig_ecosystem#3265) docs(spec): section 26 prover loop spawn, four controls, kill switch (#3265) Sep 27, 2026
@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review September 27, 2026 11:36
@MichaelTaylor3d
MichaelTaylor3d merged commit 2e08447 into develop Sep 27, 2026
9 of 10 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the spec/3265-prover-loop-controls branch September 27, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant