Skip to content

Offchain permissionless settle + regulation-safe docs#14

Merged
grimnote merged 10 commits into
mainfrom
redesign/offchain-permissionless-settle
Jul 11, 2026
Merged

Offchain permissionless settle + regulation-safe docs#14
grimnote merged 10 commits into
mainfrom
redesign/offchain-permissionless-settle

Conversation

@grimnote

Copy link
Copy Markdown
Contributor

Brings the offchain permissionless-settle redesign branch to main of the experimental protocol repo, plus regulation-safe documentation framing.

What's included

  • Permissionless settle() / offchain redesign work (drop operator staking surface, RPC routing + retry fixes, SDK/shared/CLI refactors).
  • Docs pass: README, docs/IMPLEMENTATION-STATUS.md, and per-package READMEs reframed to describe the current pre-seed demonstration as an operator-funded stablecoin self-bond rail; carrier/underwriter/insurance interfaces marked as mock R&D only.

Notes

  • Branch is 8 ahead / 6 behind main; expect a 3-way merge on GitHub.

🤖 Generated with Claude Code

grimnote and others added 9 commits June 27, 2026 14:38
Delete the on-chain `orchestration` package (OperatorRegistry,
OperatorSlashingManager, FeeManager, TaskExecutor, CCTPHandler, TaskLib,
CCTPMessageLib + interfaces/mocks/tests/scripts). `CCTPV2EscrowReceiver.settle()`
already verifies Circle's CCTP attestation and is permissionless, so the operator
stack was an access gate over an already-safe action — not a security layer.
Escrow and recourse had no compile/deploy dependency on orchestration.

- Relocate CCTPV2Forwarder (+ interface + test) into packages/escrow/contracts/receivers/
- Update CI matrices (ci/coverage/slither/aderyn), aderyn.toml, run-slither.sh,
  root package.json scripts, README, docs/IMPLEMENTATION-STATUS.md, ICore comment
- Add ADR 0001 and the redesign checklist

The off-chain operator service and SDK bridge rewire to settle() are a follow-up
(PR 2); they bind contracts by ABI/address so still build and run against existing
deployments.

forge test: escrow 145 passed, recourse 284 passed, shared builds — all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove TODO-LIGHTWEIGHT-REDESIGN.md and docs/adr/0001-drop-operator-staking.md
and the references to the ADR in docs/IMPLEMENTATION-STATUS.md. The §8 status
text (permissionless settlement) is retained.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…utor

Replace the OperatorRegistry claim + TaskExecutor.executeTask path with a direct
MessageRelayPort.settle(message, attestation) call to CCTPV2EscrowReceiver. Delete
the EthersTaskExecutorAdapter and TaskExecutorPort; add settle() + getOperatorAddress()
to the message-relay port/adapter; remove the operator-status startup check. The
job-entity 'claiming' state becomes unused (kept to preserve passing entity/repository
specs). Inbound and outbound both flow through the message-relay port.

operator: tsc clean; jest 138 passed (9 suites).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- operator-cli: delete register/stake/unbond/withdraw/status commands and their
  ABIs; rewire `relay` to call CCTPV2EscrowReceiver.settle(message, attestation);
  add real receiver ABI; reframe CLI as dev/debug/deploy tool.
- offchain-shared: drop OperatorInfo/TaskClaim/OperatorStatus types and the
  registry/executor/fee/handler addresses; keep ESCROW_RECEIVER + CCTP consts.
- sdk: clean break — remove OPERATOR_REGISTRY_ABI/TASK_EXECUTOR_ABI, the four dead
  NetworkAddresses fields, and CCTP_RELAY_TASK_TYPE; fix test stubs. coordinatorUrl
  and relayTaskId retained (coordinator kept as thin inbox).
- coordinator: no code change — round-robin SSE inbox has no deleted-contract deps
  and is the scalable dedup seam.

Builds: shared/cli/coordinator tsc clean; sdk tsup + 78 vitest passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update offchain README, operator README, operator-cli README: replace
operator-economics/staking/claim content with the permissionless settle() flow;
swap deployed-contract tables to the escrow receiver; fix mermaids and env vars.
Add `reineira` bin alias and reframe the CLI as a dev/debug/deploy tool.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Real bugs:
- Refresh operator + operator-cli .env.example: drop deleted OperatorRegistry/
  TaskExecutor/FeeManager/CCTPHandler/staking vars; add ESCROW_RECEIVER_ADDRESS
  and ESCROW_CHAIN_ID (a copied template now boots a working relayer).
- sse-coordinator-client: derive the subscription address from PRIVATE_KEY instead
  of requiring the now-undocumented OPERATOR_ADDRESS (kept as optional override).

Cleanup (remove vestigial 'claiming' state):
- Drop 'claiming' from RelayJobStatus, the DTO, getJobStatus(), and delete
  startClaiming()/startExecuting(); retries go pending_retry -> executing via
  startRetry(). Remove the dead 'insufficient stake' non-retryable error.
  Rewrite the entity + repository specs accordingly.

Hardening:
- Fail loud at startup when PRIVATE_KEY / ESCROW_RECEIVER_ADDRESS are unset.
- getOperatorAddress() no longer throws on a malformed key (warns, returns '').
- Validate ESCROW_CHAIN_ID is numeric (NaN -> default).
- Null-guard tx.wait() in relayMessage()/settle() (fall back to tx.hash).
- Fix relay.ts EscrowSettled event comment to match ABI param names.

operator: tsc clean; jest 133 passed. cli build clean. prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
From the PR #10 review (cross-checked against this branch):
- offchain/README: remove the dead @reineira-os/orchestration related-repo link
  (the receiver lives in @reineira-os/escrow now).
- sdk: remove the stale governanceToken field/address (the GOV staking token of
  the deleted OperatorRegistry); unused by any SDK module.

sdk: tsup build + 78 vitest passed. prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
From the combined review of both PRs:
- ethers-message-relay: the RPC_URL fallback in getChainConfig leaked into
  outbound relayMessage(), silently routing a relay to an unconfigured chain
  onto the escrow RPC. Seed RPC_URL as the escrow chain's entry instead and drop
  the blanket fallback, so outbound relays to unknown chains fail loudly. Cache
  escrowChainId / receiver / transmitter / operatorAddress in the constructor
  (was re-reading config per settle()).
- operator.service.executeJob: retries now route by taskType — outbound jobs
  relay to the destination, others settle — instead of always calling settle().
- Extract addressFromPrivateKey into a shared wallet.util used by both the
  relay and SSE adapters (was duplicated).
- shared: drop unused TaskResult type and the dead AUTOMATION/AGENT_CALL task hashes.
- coordinator README: replace the deleted OperatorRegistry.selectOperator() future-
  work item with relayer dedup.

operator: tsc clean; jest 133 passed. shared/cli build clean. prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reframe README + package/status docs to describe the current pre-seed
demonstration as an operator-funded stablecoin self-bond rail, and mark
carrier/underwriter/insurance interfaces as mock R&D only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…missionless-settle

# Conflicts:
#	README.md
#	packages/offchain/packages/operator-cli/src/utils/contracts.ts
#	packages/offchain/packages/operator/src/infrastructure/adapters/ethers-message-relay.adapter.ts
@grimnote
grimnote merged commit c6567c8 into main Jul 11, 2026
6 of 8 checks passed
@grimnote
grimnote deleted the redesign/offchain-permissionless-settle branch July 11, 2026 15:53
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