Skip to content

Package proof tests

A proof in matrix-work-harness is a top-to-bottom integration test demonstrating that a feature works end to end against a real Host (and, where relevant, a real cloud endpoint). Proofs live in projects/matrix-3/scripts/prove-*.ts and are run on demand — typically before declaring a feature done, before tagging a release, or as part of investigating a regression.

This page covers what a proof is, when to write one, and the conventions across the existing scripts.

Existing proofs

projects/matrix-3/scripts/
├── prove-fresh-device-link.ts          # full Device-Link enrollment via hivecast login
├── prove-namespace-routed-gateway.ts   # gateway routes namespaced subjects correctly
├── prove-sdk-worker-container.ts       # SDK runs inside a worker-cell container
├── prove-local-production-e2e.mjs      # local-production deployment loop
└── proof-flowpad-cli-control.ts        # flowpad responds to CLI control ops

Each is a standalone script. Run with tsx:

bash
cd projects/matrix-3
pnpm exec tsx scripts/prove-fresh-device-link.ts \
  --route-key proof-$(date -u +%Y%m%d-%H%M) \
  --cloud https://hivecast.ai

When proofs are required

The project root CLAUDE.md calls out two:

  • Fresh device-link proof before claiming Device-Link work is done:

    bash
    node projects/matrix-3/scripts/prove-fresh-device-link.ts \
      --route-key codex-proof-$(date -u +%Y%m%d-%H%M) \
      --cloud https://hivecast.ai
  • Run a small in-place check first, then the focused package test/build for the touched boundary, and only then the full proof. Don't run broad regression suites after each line edit.

In general:

  • After a non-trivial change to install/start/stop/link flow → run the device-link proof.
  • After a change to gateway routing or namespace handling → prove-namespace-routed-gateway.ts.
  • After a change to worker-cell behaviour → prove-sdk-worker-container.ts.
  • After a deployment-pipeline change → prove-local-production-e2e.mjs.

What a proof looks like

A proof script does what a real user would do, and asserts that the system reaches the expected state. The shape:

ts
// projects/matrix-3/scripts/prove-x.ts
import { spawn } from 'node:child_process';
import * as fs from 'node:fs';
import * as path from 'node:path';

async function main() {
  const args = parseArgs(process.argv.slice(2));

  // 1. Set up — temp home, build artifacts, fresh state.
  const home = fs.mkdtempSync('/tmp/proof-x-');

  try {
    // 2. Run the actual flow.
    await spawnSync('hivecast', ['install', '--home', home]);
    await spawnSync('hivecast', ['start', '--home', home]);
    await spawnSync('hivecast', ['login', '--device', '--home', home, '--cloud', args.cloud]);

    // 3. Assert success.
    const link = JSON.parse(fs.readFileSync(path.join(home, 'credentials/hivecast-link.json'), 'utf8'));
    if (!link.hostId) throw new Error('hostId missing after link');
    if (!link.deviceSlug) throw new Error('deviceSlug missing after link');

    // 4. Output the proof.
    console.log('PROOF OK', { home, hostId: link.hostId, deviceSlug: link.deviceSlug });
  } finally {
    // 5. Tear down — stop host, clean home.
    await spawnSync('hivecast', ['stop', '--home', home]);
    fs.rmSync(home, { recursive: true, force: true });
  }
}

main().catch((err) => { console.error('PROOF FAILED', err); process.exit(1); });

Real proofs are richer (more steps, more assertions), but the skeleton is consistent.

Conventions

  • Script lives at projects/matrix-3/scripts/prove-<thing>.ts. Use the prove- prefix; the proof- files in scripts are pre-existing variants. New proofs should use prove-.
  • Idempotent setup. Use a fresh temp home per run. Do not assume any pre-existing state.
  • Honest exit codes. 0 on success, 1 on failure. Print clear final status.
  • Verbose intermediate output. Proofs are diagnostic tools; print every step. The final PROOF OK / PROOF FAILED line is what humans grep for.
  • Cleanup in finally. Even on failure, stop the Host and remove the temp directory.
  • No CI-only assumptions. Proofs run on a developer's laptop too. If they need credentials, accept them via flags (--cloud, --route-key, --api-key-ref).

What proofs are NOT

  • Not a substitute for unit tests. Proofs catch integration regressions. Unit tests catch logic bugs. Both are needed.
  • Not run on every commit. Proofs are slow (minutes per script, real network round-trips). They are pre-merge gates for the feature they cover, not blanket gates.
  • Not a replacement for hivecast doctor. Doctor diagnoses a running install; proofs verify the install/start flow actually works.

Adding a new proof

When you add a feature that crosses package boundaries, write a proof:

  1. Create projects/matrix-3/scripts/prove-<feature>.ts.
  2. Drive the feature end to end through real CLI commands.
  3. Assert observable state: HTTP responses, files in <host-home>/, NATS subject reachability, system.<actor>.<op> results.
  4. Document the proof in your feature's workstream doc. Any agent picking up follow-up work runs the proof to verify the baseline.
  5. Add to a per-feature CI gate when the feature is stable.

See also

  • Runtime smoke testscreateDaemonHarness for the in-process equivalent.
  • Browser tests — Playwright proofs covering UI flows.
  • The proof scripts themselves: projects/matrix-3/scripts/prove-*.ts.

Source: projects/matrix-3/scripts/prove-fresh-device-link.ts, projects/matrix-3/scripts/prove-namespace-routed-gateway.ts, projects/matrix-3/scripts/prove-sdk-worker-container.ts, projects/matrix-3/scripts/prove-local-production-e2e.mjs.