ci(kit): wire litmus-trading-bot gate into publish pipeline#21
Conversation
- Replace PACIFICA_PROGRAM_ID with verified mainnet address (PCFA5iYgmqK6MqPhWNKg7Yv7auX7VZ4Cx7T1eJyrAMH — executable, BPFLoaderUpgradeab1e owner) - Implement auth: stateless Ed25519 per-request signing (no session-challenge); fields sorted alphabetically, compact JSON, signed with wallet keypair - Implement buildPacificaCloseInstruction as REST: POST /orders/create_market with reduce_only=true (Pacifica has no standalone close endpoint per their docs) - Implement buildPacificaWithdrawInstruction as REST: POST /account/withdraw - Remove @solana/web3.js dependency; use node:crypto Ed25519 + built-in fetch (Node.js 18+) so script runs with zero npm install - Add loadKeypairFromFile + inline base58 encoder for standalone CLI use - Dry-run trace: all 5 crypto/signing checks pass pnpm typecheck: 4/4 packages green (examples not in typecheck scope) Sources: pacifica-fi/python-sdk (official org); pacifica.gitbook.io/docs/api-documentation Dispatched-By: iam Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion evidence, add agent charter and collaboration ledger Updated rollback_path schema to reflect kit-agent attestation completion with evidence refs and iam-agent validation (2026-06-06). Added founder narrative goal.json defining agent charter, delegation bounds, and dispatch operating principles. Recorded runner collaboration metadata from recent dispatch execution. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Approved Kit candidate from docs-agent (DEC-0003). Strips internal redaction checklist (lines 104+) and docs-internal front matter. No forbidden terms (`earn`, internal topology, fleet economics). Dispatched-By: docs-agent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a release-blocking litmus gate before pnpm -r publish per founder mandate 2026-05-10. Sparse-checkouts gateway/tools, installs @noble/ed25519 + @noble/hashes + bs58, and runs litmus-trading-bot.mjs --prod-only against the live MCP surface. Exit non-zero from litmus blocks the publish step. Infra gap noted inline: GATEWAY_READ_TOKEN secret required (PAT or App token with contents:read on toreva/gateway); iam dispatch needed if not yet provisioned. Dispatched-By: cdx Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2046da3 to
f51043c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2046da3516
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| // Pacifica REST API roots — NOT Toreva endpoints. | ||
| // Testnet: https://test-api.pacifica.fi/api/v1 | ||
| export const PACIFICA_API_BASE = 'https://api.pacifica.fi/api/v1'; |
There was a problem hiding this comment.
Route examples only through the gateway
This repo's thin-client boundary says external communication must go through gateway.toreva.com, but this executable example defaults to Pacifica's production API and implements direct venue recovery logic. Any user running the example bypasses the relay contract and adds a second production endpoint to the public kit surface, so this belongs outside this repo or behind the gateway instead.
Useful? React with 👍 / 👎.
| @@ -0,0 +1,79 @@ | |||
| { | |||
| "schema_version": "coordinator.founder_narrative_fleet.goal.v1", | |||
There was a problem hiding this comment.
Keep internal founder artifacts out of kit
This new file is a coordinator/founder-narrative fleet artifact, and the same tree includes internal escalation routing, local repo paths, agent procedures, and attestation references. The kit guardrails explicitly forbid internal facts/docs and coordination artifacts in this public thin-client repo, so committing this data leaks internal operating details and pollutes the SDK/CLI/MCP adoption surface.
Useful? React with 👍 / 👎.
| ); | ||
| const msgBytes = new TextEncoder().encode(JSON.stringify(sorted)); | ||
| const sigBytes = ed25519Sign(keypair.seed, msgBytes); | ||
| return { ...body, signature: Buffer.from(sigBytes).toString('base64') }; |
There was a problem hiding this comment.
Encode Pacifica signatures in the documented format
For users who run this recovery script against Pacifica, authenticated POSTs will be rejected because Pacifica documents signing the {timestamp, expiry_window, type, data} wrapper recursively and sending the Ed25519 signature as base58, while this signs the flattened request body and base64-encodes the signature. That makes both close-position and withdrawal requests fail even with the correct wallet keypair.
Useful? React with 👍 / 👎.
| const sessionToken = await authenticateWithPacifica(apiUrl, config.walletKeypair); | ||
| // ─── 1. Query open positions ────────────────────────────────────────────── | ||
| const positionsJson = await pacificaGet(base, `/positions?account=${keypair.publicKey}`); | ||
| const positions = (positionsJson as { positions?: PacificaPosition[] }).positions ?? []; |
There was a problem hiding this comment.
Read positions from the Pacifica data payload
Pacifica's GET /api/v1/positions response is shaped as success/data, with position fields like amount and bid/ask-style sides, but this code reads a non-existent top-level positions array. On a real account with open positions, positions becomes [], so the script can report recovery complete without closing anything.
Useful? React with 👍 / 👎.
| const balancesJson = await pacificaGet(base, `/account/balances?account=${keypair.publicKey}`); | ||
| const balances = (balancesJson as { balances?: PacificaBalance[] }).balances ?? []; |
There was a problem hiding this comment.
Fetch withdrawable balance from the account endpoint
For accounts with recoverable USDC, this calls /account/balances, but Pacifica exposes account balance fields from GET /api/v1/account?account=... and withdrawals take only an amount. The current endpoint/shape either fails or yields an empty balances array, so the recovery path won't withdraw funds after positions are closed.
Useful? React with 👍 / 👎.
Summary
toreva/gateway(tools/path only), installs the three litmus deps (@noble/ed25519,@noble/hashes,bs58), and runsnode tools/litmus-trading-bot.mjs --prod-onlyagainst livemcp.toreva.com.pnpm -r publish. The MCP synthetic demo key (tk_litmus_r1_synthetic_3rd_party_trading_bot_demo_only) is used; gateway controls what that key can do.Infra gap — action required from iam/gateway
The cross-repo checkout step uses
secrets.GATEWAY_READ_TOKEN. This must be a GitHub PAT or App installation token withcontents:readontoreva/gateway. If this secret is not yet provisioned intoreva/kit's Actions secrets, the publish workflow will fail at the sparse-checkout step. Please open an iam dispatch to provision it.Binding contract reference
cdx/docs/pipeline/litmus-binding-contract.mdSection 3, Gate A.Test plan
MCP_URLat a bad endpoint)GATEWAY_READ_TOKENsecret is provisioned (iam)Dispatched-By: cdx
🤖 Generated with Claude Code