Skip to content

ci(kit): wire litmus-trading-bot gate into publish pipeline#21

Merged
gapview01 merged 6 commits into
mainfrom
daemon/kit/wire-litmus-gate-into-publish-2026-07-02
Jul 2, 2026
Merged

ci(kit): wire litmus-trading-bot gate into publish pipeline#21
gapview01 merged 6 commits into
mainfrom
daemon/kit/wire-litmus-gate-into-publish-2026-07-02

Conversation

@gapview01

Copy link
Copy Markdown
Member

Summary

  • Implements founder mandate 2026-05-10: litmus-trading-bot must be a release-blocking gate before any kit SDK version publishes.
  • Sparse-checkouts toreva/gateway (tools/ path only), installs the three litmus deps (@noble/ed25519, @noble/hashes, bs58), and runs node tools/litmus-trading-bot.mjs --prod-only against live mcp.toreva.com.
  • Any non-zero exit from litmus blocks 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 with contents:read on toreva/gateway. If this secret is not yet provisioned in toreva/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.md Section 3, Gate A.

Test plan

  • Merge and tag a release — confirm litmus step runs before publish step
  • Verify litmus exit 0 on healthy MCP surface allows publish to proceed
  • Verify litmus exit 1 on broken MCP surface blocks publish (can test by temporarily pointing MCP_URL at a bad endpoint)
  • Confirm GATEWAY_READ_TOKEN secret is provisioned (iam)

Dispatched-By: cdx
🤖 Generated with Claude Code

gapview01 and others added 6 commits July 2, 2026 16:14
- 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>
@gapview01
gapview01 force-pushed the daemon/kit/wire-litmus-gate-into-publish-2026-07-02 branch from 2046da3 to f51043c Compare July 2, 2026 06:14
@gapview01
gapview01 merged commit 7e8e244 into main Jul 2, 2026
2 checks passed
@gapview01
gapview01 deleted the daemon/kit/wire-litmus-gate-into-publish-2026-07-02 branch July 2, 2026 06:15

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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') };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 ?? [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +121 to +122
const balancesJson = await pacificaGet(base, `/account/balances?account=${keypair.publicKey}`);
const balances = (balancesJson as { balances?: PacificaBalance[] }).balances ?? [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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