docs(ledger): V-13's open half closes - the hosted Safe covers chain 999 #53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| economics: | |
| name: Economic simulation gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # pnpm reads its version from `packageManager` in package.json. Passing a | |
| # `version` here as well makes the action refuse to guess between them. | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| # These simulations import each other by package name (@sent/stockback and | |
| # friends), so they need the workspace links even though they run no build. | |
| # They used to work without an install because they reached across | |
| # directories with relative paths — which is exactly the undeclared | |
| # dependency graph that refactor removed. | |
| - run: pnpm install --frozen-lockfile | |
| # Masterplan 9/10: the simulation is a mandatory validation gate. | |
| # A failure here is a BLOCKED escalation, never a tuning exercise. | |
| - name: Reproduce section 8 reference outcomes | |
| run: node --experimental-strip-types packages/economics/sim/reference.ts | |
| - name: Graduation V3 geometry proof | |
| run: node --experimental-strip-types packages/economics/sim/graduation-v3.ts | |
| - name: Stockback TWAB and conservation | |
| run: node --experimental-strip-types packages/stockback/sim/stockback.ts | |
| - name: TWAB edge cases | |
| run: node --experimental-strip-types packages/stockback/sim/twab-edges.ts | |
| - name: Market lifecycle economic gate | |
| run: node --experimental-strip-types packages/economics/sim/lifecycle.ts | |
| - name: Reorg handling | |
| run: node --experimental-strip-types services/indexer/sim/reorg.ts | |
| - name: Freshness contract | |
| run: node --experimental-strip-types packages/realtime/sim/freshness.ts | |
| - name: Attestor determinism | |
| run: node --experimental-strip-types services/stockback/sim/determinism.ts | |
| - name: Realtime gateway | |
| run: node --experimental-strip-types services/realtime/sim/gateway.ts | |
| - name: API handlers | |
| run: node --experimental-strip-types services/api/sim/handlers.ts | |
| - name: Stockback finalizer | |
| run: node --experimental-strip-types services/finalizer/sim/finalizer.ts | |
| - name: Background workers | |
| run: node --experimental-strip-types services/worker/sim/worker.ts | |
| - name: Configuration and environment | |
| run: node --experimental-strip-types packages/config/sim/env.ts | |
| - name: Display formatting | |
| run: node --experimental-strip-types apps/web/sim/format.ts | |
| - name: Chart scale | |
| run: node --experimental-strip-types apps/web/sim/chart.ts | |
| - name: Approval intents | |
| run: node --experimental-strip-types packages/sdk/sim/approve.ts | |
| # §694's last link: the handoff to the wallet. | |
| - name: Transaction handoff | |
| run: node --experimental-strip-types apps/web/sim/tx.ts | |
| # The Dockerfile copies each workspace manifest by name so the dependency | |
| # layer can be cached. A new package that nobody adds there produces an | |
| # image that installs a different graph than the repo declares, and the | |
| # failure surfaces at run time in a container rather than here. | |
| - name: Docker manifest list is complete | |
| run: | | |
| missing=0 | |
| for manifest in packages/*/package.json services/*/package.json; do | |
| if ! grep -q "COPY $manifest" infra/docker/Dockerfile; then | |
| echo "infra/docker/Dockerfile does not copy $manifest" | |
| missing=1 | |
| fi | |
| done | |
| exit $missing | |
| # The differential fixtures are committed. If TypeScript changed without | |
| # regenerating them, or a regenerated set was not committed, this fails - | |
| # which is exactly the drift 1064 forbids. | |
| - name: Differential fixtures are current | |
| run: | | |
| node --experimental-strip-types packages/economics/sim/fixtures.ts | |
| node --experimental-strip-types packages/stockback/sim/merkle-fixtures.ts | |
| node --experimental-strip-types packages/sdk/sim/intent-fixtures.ts | |
| node --experimental-strip-types packages/economics/sim/v3-fixtures.ts | |
| git diff --exit-code contracts/test/fixtures/ | |
| workspace: | |
| name: Typecheck / lint / build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| # Strict mode with noUncheckedIndexedAccess and exactOptionalPropertyTypes. | |
| # This was not wired up until Day 4's audit, which is exactly the kind of | |
| # gap an audit is for. | |
| - run: pnpm typecheck | |
| integration: | |
| name: Projection against PostgreSQL | |
| runs-on: ubuntu-latest | |
| # Every other job runs against pure functions, which left the SQL itself | |
| # entirely unexecuted: a wrong column name or a constraint that fires on the | |
| # happy path is invisible to TypeScript and surfaces in production instead. | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: sent | |
| POSTGRES_PASSWORD: sent | |
| POSTGRES_DB: sent | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U sent -d sent" | |
| --health-interval 5s | |
| --health-timeout 3s | |
| --health-retries 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Projection SQL | |
| env: | |
| DATABASE_URL: postgres://sent:sent@localhost:5432/sent | |
| run: node --experimental-strip-types tests/integration/projection.ts | |
| # The seam between the indexer's publisher and the realtime service. Both | |
| # halves had unit coverage and the join between them had none, which is | |
| # where this kind of wiring actually breaks. | |
| - name: Realtime delivery | |
| env: | |
| DATABASE_URL: postgres://sent:sent@localhost:5432/sent | |
| run: node --experimental-strip-types tests/integration/live.ts | |
| # Correctness at scale, not throughput. Nothing is asserted about timing — | |
| # a performance threshold in CI is a flaky test wearing a useful disguise. | |
| - name: Scale | |
| env: | |
| DATABASE_URL: postgres://sent:sent@localhost:5432/sent | |
| run: node --experimental-strip-types tests/load/scale.ts | |
| # "Designed to be safe under contention" and "observed to be safe under | |
| # contention" are different claims. Four workers against one queue. | |
| - name: Contention | |
| env: | |
| DATABASE_URL: postgres://sent:sent@localhost:5432/sent | |
| run: node --experimental-strip-types tests/load/concurrency.ts | |
| # The largest seam in the system: real contracts, real chain, real indexer. | |
| # Foundry supplies anvil; the artifacts come from the contracts job's own | |
| # compiler, so this indexes the same bytecode the test suite ran against. | |
| - uses: foundry-rs/foundry-toolchain@v1 | |
| - name: Build contracts | |
| run: forge build --root contracts | |
| - name: Full stack against anvil | |
| env: | |
| DATABASE_URL: postgres://sent:sent@localhost:5432/sent | |
| RPC_URL: http://127.0.0.1:8545 | |
| run: | | |
| anvil --silent & | |
| for i in $(seq 1 30); do | |
| if cast block-number --rpc-url http://127.0.0.1:8545 >/dev/null 2>&1; then break; fi | |
| sleep 1 | |
| done | |
| node --experimental-strip-types tests/e2e/stack.ts | |
| contracts: | |
| name: Foundry | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: foundry-rs/foundry-toolchain@v1 | |
| - name: Build | |
| run: forge build --root contracts | |
| # Informational only (D-008): every current hit is a test or a documented | |
| # design decision. Reviewed as part of the Day 6 quality pass. | |
| - name: Lint (non-blocking) | |
| run: forge lint --root contracts || true | |
| - name: Unit + fuzz | |
| run: forge test --root contracts -vvv | |
| - name: Invariants | |
| env: | |
| FOUNDRY_PROFILE: inv | |
| run: forge test --root contracts -vvv | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| # Replays the logs the Foundry run just captured through the production | |
| # reducer, proving the projection reproduces on-chain state (138). | |
| - name: Projection replay proof | |
| run: node --experimental-strip-types services/indexer/sim/projection.ts |