Skip to content

Develop - #173

Closed
Levi-Ojukwu wants to merge 26 commits into
mainfrom
develop
Closed

Levi-Ojukwu wants to merge 26 commits into
mainfrom
develop

Conversation

@Levi-Ojukwu

Copy link
Copy Markdown
Contributor

What this does

Checklist

  • npm run check:contracts, npm run build and npm test pass
  • Schema changes come with a new, forward-only migration (existing migrations untouched)
  • No secrets: no .env files, keys, seeds or tokens, in code, tests, fixtures or logs
  • Anything that can submit a transaction still defaults to dry-run
  • docs/api.md updated if a request or response shape changed
  • .env.example updated if config changed

How this was tested

mhikel66 and others added 26 commits October 17, 2026 02:52
…y-trade verification

- Resilience (fixes #148): Add per-dependency bulkheads, timeouts, signal propagation, and graceful shutdown across HTTP, database, and background processes.
- Schema Hardening (fixes #149): Add Postgres status enums, numeric/format CHECK constraints, missing foreign keys with deliberate cascading rules, and pre-migration audit script.
- Trace Auditing (fixes #150): Implement end-to-end reasoning trace auditing against the on-chain registry, automatic relinking of missed events, and admin inspection endpoints.
- Copy-Trade Verification (fixes #151): Enforce on-chain verification of copy trades against contract Trade events, prevent hash reuse, and add indexer/cron reconciliation.

Closes #148, #149, #150, #151
feat: harden resilience, schema constraints, trace audits, and copy-trade verification
- deterministic seed dataset with local IPFS, raw-event export and anonymised snapshots
- checksummed backups, restore script and post-restore chain reconciliation
- env/file/Vault secret loading with hot rotation and JWT grace
- digest-pinned CD with migration lint and post-deploy checks

closes #147
closes #146
closes #145
closes #144
…Redis prefix) (#135)

- ensureContainers(): TEST_DATABASE_URL/TEST_REDIS_URL or Testcontainers
  postgres:16-alpine + redis:7-alpine; skips cleanly without Docker
- global setup migrates od_template once; each file clones it
- truncateAll, typed factories, per-file Redis key prefix
- test:integration / test:all scripts; setupTestEnv defaults REDIS_URL
Durable queue row per reasoning trace that should be published to
reasoning-registry: exact payload, status, attempts/backoff, submitted tx
and trace id, confirmation time. The migration backfills pinned-but-
unpublished MARKET_CREATION traces (commented as a data migration); trade
traces can't be backfilled because their direction isn't recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d confirm via indexer (#131)

- enqueueTracePublication replaces pinAndPublishTrace in runMarketMakerCycle
  (step 7) and executeTrade (step 5); trade traces are no longer fire-and-
  forget or skipped when the market isn't on-chain yet.
- src/jobs/trace-publication.worker.ts: claims due rows with FOR UPDATE
  SKIP LOCKED, pins, waits for onChainMarketId (voided -> FAILED), checks the
  trace link and the registry's market_trace_at index before publishing so a
  hash is never published twice, retries with capped exponential backoff,
  parks AgentNotRegistered/EmptyAction/EmptyCid as FAILED, and never confirms
  in dry-run. Runs every TRACE_PUBLISH_CRON (default 30 s).
- Indexer TracePublished now sets verified and confirms the queue row.
- Action strings come from src/lib/trace-actions.ts.
- New env: TRACE_PUBLISH_ENABLED, TRACE_PUBLISH_CRON,
  TRACE_PUBLISH_MAX_ATTEMPTS, TRACE_CONFIRM_TIMEOUT_MS (validated).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d actions (#131)

13 worker tests (pending market, backoff vs permanent errors, pin retry,
missing Pinata config, already-linked and on-chain duplicates, SUBMITTED
re-check, dry-run, voided market, max attempts, claim loop, idempotent
enqueue) plus an indexer assertion that TracePublished sets verified and
confirms the queue row. docs/architecture.md gains the lifecycle; docs/api.md
fixes the REASONING_PUBLISHED action example and defines verified;
docs/contract-requests.md notes the buy vs buy_yes/buy_no mismatch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IdempotencyKey model with a unique (scope, method, route, key) and an
index on expiresAt. Forward-only migration generated with prisma migrate
diff so it matches the schema exactly (CI's drift check).

Refs #123
idempotent() implements draft-ietf-httpapi-idempotency-key-header on
Postgres: ON CONFLICT DO NOTHING claim, replay with Idempotent-Replayed,
422 IDEMPOTENCY_KEY_MISMATCH, 409 IDEMPOTENCY_IN_PROGRESS + Retry-After,
and conditional stale-lock takeover. Keys are scoped by user, method and
route template. 2xx/4xx are stored (64 KB cap, header allowlist,
sensitive fields redacted); 5xx releases the key.

- required on POST /markets/generate (a retry returns the same jobId and
  starts no second cycle) and POST /trade/copy
- optional on PATCH /trade/copy/:id/confirm, PUT /traces/access/allowance,
  POST /traces/verify and POST /traces/:id/unlock
- /auth/* excluded (single-use handshake; /auth/verify returns a JWT)
- CORS allows Idempotency-Key, exposes Idempotent-Replayed and Retry-After
- hourly cron purges expired keys in batches of 5 000

Refs #123
A concurrent recordPayment with the same txHash passed the pre-check and
lost the unique race on PaymentEvent.txHash inside $transaction (P2002),
which surfaced as 500 INTERNAL_ERROR. Catch P2002, re-read the winning
payment, and return its subscription for the same user or 409
PAYMENT_ALREADY_USED otherwise, with or without an Idempotency-Key.

Refs #123
14 tests (in-memory store + real routes): replay, mismatch, in-flight
409, stale-lock takeover, 5xx not stored, 4xx replayed, per-user and
per-route scope, header/secret redaction and size cap, optional/invalid
keys, purge, required key on /trade/copy, /markets/generate replay
starting one cycle, CORS, and the recordPayment P2002 race.
docs/api.md gains an Idempotency section.

Closes #123
feat(api): Idempotency-Key support on state-changing endpoints (+ recordPayment P2002 race fix)
test: integration tier against real Postgres + Redis (Testcontainers): infra + auth/payments/isolation suites (#135)
feat(traces): durable trace publication queue — wait for on-chain market, retry, confirm via indexer (#131)
…-144

feat: add seeded snapshots, backups, secret rotation and CD
feat(health): add livez, dependency-aware readyz and admin status
ci: lint new migrations for lock safety (partial, #104)
feat: propagate request and job correlation ids through logs, agent logs and errors
@github-actions

Copy link
Copy Markdown

👋 Thanks for the contribution! This repository only accepts contributor pull requests into the develop branch. PRs raised against main cannot be merged, so this one has been closed automatically.

Please re-open your PR with base: develop (rebase your branch onto develop first if needed). See the note at the bottom of the issue you're working on.

@github-actions github-actions Bot closed this Oct 17, 2026
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.

9 participants