Skip to content

[Backend]: On-chain vs off-chain reconciliation worker for the vault ledger #105

Description

@grantfox-oss

The orchestrator keeps an off-chain view of task spend and balances (packages/orchestrator/src/vault-ledger.ts, task-results.ts, orchestrator-store.ts) alongside the authoritative on-chain state in CleverVault. These can drift: a release that succeeded on-chain but whose local write failed, a crash between the two, an RPC timeout that hid a successful settlement, or a manual on-chain action. Today nothing detects or repairs that drift, so the operator has no way to know the local ledger still matches the chain. For a payments system, silent drift is how money goes missing on the books.

Goal

Build a reconciliation worker that treats the contract as the source of truth, diffs it against the local ledger, reports drift, and (in a separate, explicit step) repairs the local records, writing an append-only audit trail of everything it changes.

Requirements and constraints

  • Pull authoritative state per task/user/asset from the vault via agent-vault-client.ts (get_task, get_account, get_user_task_infos, token_balance) and compare to the local ledger.
  • Two modes: dry-run (report a structured diff, change nothing) and repair (apply fixes). Dry-run is the default; repair must be explicitly requested.
  • Every repair writes an append-only audit entry (what changed, old value, new value, on-chain reference, timestamp). Never silently overwrite.
  • Idempotent and safe to run on a schedule; a second run with no drift makes no changes.
  • Expose results via the metrics/health surface (a reconciliation block: last run, drift count, repaired count) and optionally a GET /reconciliation endpoint.
  • Do not attempt to change on-chain state; this worker only reconciles the local view to the chain.

Edge cases

  • Local record exists for a task the chain has finalized (reconcile to completed).
  • Chain shows spend the local ledger missed (record it, audit it).
  • Partial-release drift (local spent behind chain spent).
  • A task present on-chain but absent locally, and vice versa.
  • Amounts in stroops vs display units (fixed-point correctness).

Acceptance criteria

  • Worker computes a structured drift report between local ledger and on-chain state per task/asset
  • Dry-run changes nothing; repair mode applies fixes only when explicitly enabled
  • Every repair produces an append-only audit record
  • Idempotent: a clean second run makes no changes
  • Drift/repair counts surfaced via metrics (and/or an endpoint)
  • Vitest coverage with fixture chain states vs local states for each drift class, plus an idempotency test
  • npm test passes; behavior documented in docs/

Pointers

  • packages/orchestrator/src/vault-ledger.ts, agent-vault-client.ts, task-results.ts, orchestrator-store.ts, metrics.ts, server.ts.

Notes for contributors

Comment with your diff model (what fields you compare and how you classify drift) before implementing. See CONTRIBUTING.md.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSThird CampaignCampaign: Third CampaignenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions