Skip to content

M0: repeatable live-server money-loop smoke (pnpm smoke) in CI - #98

Open
Xiaoher-C wants to merge 4 commits into
mainfrom
feat/m0-smoke-v2
Open

M0: repeatable live-server money-loop smoke (pnpm smoke) in CI#98
Xiaoher-C wants to merge 4 commits into
mainfrom
feat/m0-smoke-v2

Conversation

@Xiaoher-C

Copy link
Copy Markdown
Owner

Summary

M0 substrate hardening (workstream WS-A). Permanent successor to the 2026-06-07 throwaway smoke (docs/verification/e2e-smoke-2026-06-07.md) — 17 steps / 96 assertions in ~0.3s against a real in-process server on fresh temp DBs:

  • Full rental funnel (a)-(i): grants → card publish → session+escrow → 402 negative → thread spend → settle split → double-end 409 → receipt co-sign + tamper 400 → public /o/
  • GAP#1 regression: voucher-funded refunds restore the VOUCHER (balance untouched) + balance-funded path + expired-voucher fallback, asserted via direct credit-DB inspection
  • GAP#2 regression: /o/:share_token AND persisted outcome_json carry no thread free-text (authed read as positive control)
  • Ledger conservation invariant (sum of balances + in-flight escrow + voucher remaining == mints)
  • Unauth fuzz: 7 session mutation routes × {no-auth, garbage-sig, signed-stranger} → 401/403
  • CI: pnpm smoke job + scripts/ typecheck (tsconfig.scripts.json)
  • Fixed a pre-existing ~25% flake: base64url last-char tamper flip carries only 2 significant bits and often decoded to identical signature bytes → flip first char instead

Notes

Test plan

  • pnpm smoke — 17 steps green, 3 consecutive runs, exit-code paths verified
  • Full backend suite green; tsc -p tsconfig.scripts.json clean

Merge order: #97 → this → relay-dispatch.

Xiaoher-C and others added 4 commits June 11, 2026 22:53
Permanent port of the 2026-06-07 throwaway smoke methodology
(docs/verification/e2e-smoke-2026-06-07.md) into scripts/e2e-smoke.ts:

- boots createRegistryServer({registryDb, creditDb}) in-process on port 0
  with fresh temp SQLite DBs (mkdtemp + AGENTBNB_DIR), never ~/.agentbnb
- drives the full renter funnel (a)-(i) over real HTTP with the repo's
  own Ed25519 crypto (generateKeyPair/signRequest/signEscrowReceipt)
- GAP#1 regression: voucher-funded escrow refunds restore the VOUCHER
  (balance NOT credited), plus the expired-voucher balance fallback
- GAP#2 regression: public /o/:share_token payload AND persisted
  outcome_json carry no thread title/description free text; authed
  outcome keeps detail as a positive control
- ledger conservation invariant: balances + in-flight escrow + voucher
  remaining == bootstrap + issued vouchers + provider bonuses
- unauthenticated fuzz: all 7 session mutation routes reject no-auth,
  garbage-signature, and signed-stranger calls with 401/403
- one PASS/FAIL line per step, watchdog at 90s, exit 0 only when green,
  teardown closes the server and removes the temp dir

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Works on a clean checkout: pnpm install builds better-sqlite3 and the
preceding skill-inspector build step satisfies the server import graph.
No .tmp-smoke dependency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tic tamper

- Self-guard every POST /api/sessions behind guardSessionCreate(): budget 8
  of the 10/min per-IP RATE_LIMIT_CREATE the route-hardening branch adds to
  session-routes.ts, failing fast with a clear message instead of flaking
  into 429s. Header comment documents the interplay; production limit
  untouched.
- Watchdog no longer process.exit(1)s past the .finally() (which leaked
  TEMP_ROOT and open server/DB handles): it now sets watchdogFired + logs,
  and Promise.race hands control to the shared finally, which always runs
  registered teardowns + rmSync and exits (watchdogFired || anyFailed ? 1 : 0).
- funnel-g-tampered-receipt-400 flaked ~25% of runs: the last base64url char
  of a 64-byte Ed25519 signature carries only 2 significant bits, so the
  'A'<->'B' flip often decoded to identical bytes and the tampered receipt
  verified (observed 201). Flip the first char (6 significant bits) instead.
- Document why each credit_transactions.reason is in/out of sumMinted in the
  ledger-conservation invariant, and note the 403-before-409 contract on the
  settled-session unauth fuzz.
scripts/*.ts sat outside tsconfig.json's include, so e2e-smoke.ts was never
typechecked in CI. Add tsconfig.scripts.json (extends the root config,
noEmit, rootDir .) and run 'npx tsc -p tsconfig.scripts.json' right after
the existing Typecheck step.
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