Skip to content

test: real-chain e2e validation against Paseo Next v2 - #2

Merged
EnderOfWorlds007 merged 3 commits into
mainfrom
feat/e2e-chain-validation
Aug 18, 2026
Merged

test: real-chain e2e validation against Paseo Next v2#2
EnderOfWorlds007 merged 3 commits into
mainfrom
feat/e2e-chain-validation

Conversation

@EnderOfWorlds007

Copy link
Copy Markdown
Collaborator

Adds an end-to-end suite that deploys to Paseo Next v2 for real and verifies what actually landed on-chain.

Why not just assert exit 0

The README documents the failure mode: a bad CAR deploys successfully and then serves 404s. A test asserting on the exit code passes straight through the bug we most need to catch. So the suite round-trips the on-chain contenthash back to the bytes that were staged:

  1. Fixture carries a run-unique marker (git SHA + run number), so a stale result can't satisfy the comparison.
  2. Expected CID computed locally — ipfs add -Q --cid-version=1 --raw-leaves --pin=false.
  3. Deploy, then scrape Verified on-chain: <contenthash>.
  4. Fetch the manifest via bulletin-deploy's public API (fetchManifestRoundtrip + parseManifest), which polls the gateway within a budget.
  5. Assert files["index.html"].cid and .size match the staged fixture exactly.

It also asserts the archive shape — a default deploy contains exactly index.html — which is a permanent regression guard on the default changed in #1. A second case covers --fallback.

Session isolation (subtle, please don't simplify it away)

The deploy runs under a throwaway HOME. When a login session exists, bulletin-deploy transfers the registered name to the signed-in account — so a local run by a signed-in developer would move decentralize-ci.dot to their personal account and permanently break CI's overwrite path. IPFS_PATH is resolved from the real environment before HOME is overridden, because a fresh HOME also hides the IPFS repo.

Not a required check

workflow_dispatch + nightly only. Two finalized chain transactions against a public RPC, ~3 minutes wall time. Unit Tests stays the sole required check; npm test is unchanged and stays hermetic, so no PR run can reach the chain.

Dependencies

e2e/BOOTSTRAP.md is a dependency register and recovery runbook, and e2e/bootstrap.sh is a read-only preflight (--fix for local remediation, --register explicit and confirmation-gated). Notable entries: decentralize-ci.dot is owned by bulletin-deploy's shared default worker, and the deploy costs 0 PAS only because that worker holds ProofOfPersonhoodFull — if that ever lapses the suite needs a funded account. CI needs ipfs init, not just the binary.

Design: docs-internal/superpowers/specs/2026-08-10-e2e-chain-validation-design.md.

Verified

  • npm run typecheck clean; npm test still exactly 51 tests, e2e not collected; npm run build clean.
  • npm run test:e2e run for real: 2 passed, two real Paseo deploys, no unhandled errors.

Spec for a Paseo Next v2 deploy test that round-trips the on-chain
contenthash back to the exact bytes staged, rather than asserting exit 0 —
a bad CAR deploys successfully and then serves 404s.

Records the findings from the spike that shaped it: the default worker
signs with no session and pays 0 PAS, CI needs 'ipfs init' and not just
the binary, the contenthash addresses the CAR rather than a browsable
directory, and the .paseo.li name URL serves the host shell rather than
the deployed content.
Adds e2e/BOOTSTRAP.md (what the e2e suite depends on, how to check it, how
to recover it) and e2e/bootstrap.sh (idempotent, check-only-by-default
preflight; --fix for local ipfs init; --register gated behind confirmation
for the one real deploy that reclaims decentralize-ci.dot). Does not
implement the e2e tests themselves.
Deploys a run-unique fixture to decentralize-ci.dot and asserts the
deployed manifest's per-file CID and size match the bytes that were
staged. Exit 0 is not the assertion: a bad CAR deploys successfully and
then serves 404s, so the test round-trips the on-chain contenthash back
through bulletin-deploy's public manifest API instead.

Also guards the archive shape — the default deploy must contain exactly
index.html, with --fallback covered as a separate case.

The deploy runs under a throwaway HOME so no login session is visible to
the child. Without it, a local run by a signed-in developer would
transfer decentralize-ci.dot to their own account and permanently break
CI's overwrite path. IPFS_PATH is resolved from the real environment
first, since a fresh HOME also hides the IPFS repo.

The deploy is spawned asynchronously rather than with spawnSync: an
80-second synchronous block starves vitest's reporter RPC, which
surfaced as a 'Timeout calling onTaskUpdate' unhandled error and vitest's
own warning that results might be false positives.

Kept out of 'npm test' via a separate vitest config, so no PR run can
reach the chain. The workflow is workflow_dispatch plus nightly only,
never a required check.
@EnderOfWorlds007
EnderOfWorlds007 merged commit 48948d6 into main Aug 18, 2026
4 checks passed
@EnderOfWorlds007
EnderOfWorlds007 deleted the feat/e2e-chain-validation branch August 18, 2026 15:54
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