From c46ed9b716202c0de47fb5ce01e9f22d59d70636 Mon Sep 17 00:00:00 2001 From: Hillaryhardy Date: Thu, 1 Oct 2026 02:55:40 +0300 Subject: [PATCH 1/3] test: pin flashstack-stx-core/sbtc-core against deployed source (ajv.2.4 axis 2) Extends the existing offline verbatim-copy pin (tests/deployed-source-pins.test.ts, originally written for the two gen-1 receiver contracts) to the two P0 live cores reviewed under ajv.4.3. Both were checked byte-for-byte against the deployed source at SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5 on 2026-10-01 (fresh Hiro fetch, cross-checked against the vendored .cache/requirements copy) before being pinned. Proven red/green: appending a byte to contracts/flashstack-stx-core.clar fails the size assertion (6562 vs expected 6538); reverting passes again. A live-fetch CI job was deliberately not built -- it would make the merge gate depend on a third-party API and network access, which needs its own decision (blocking gate vs scheduled job, per the bead's existing notes). This offline pin closes the same drift-detection gap for these two contracts at zero network cost; re-verifying the pin itself still means re-running the documented curl command. Full suite: 258 passed, 3 skipped (unchanged skip set) / 261 total across 25 files. --- tests/deployed-source-pins.test.ts | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/tests/deployed-source-pins.test.ts b/tests/deployed-source-pins.test.ts index 7a50975..aaadfe7 100644 --- a/tests/deployed-source-pins.test.ts +++ b/tests/deployed-source-pins.test.ts @@ -15,8 +15,18 @@ import { readFileSync } from "node:fs"; * create drift from what is on chain. If a change is ever legitimate, it is a new * contract under a new name, not an edit to these files. * - * Offline on purpose. To re-verify against the chain: - * curl -s https://api.hiro.so/v2/contracts/source/SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ/ \ + * ajv.2.4 (axis 2 — repo copy vs deployed mainnet source): the same mechanism now + * also pins flashstack-stx-core and flashstack-sbtc-core, the two P0 live cores + * reviewed under ajv.4.3, checked byte-for-byte against SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5 + * on 2026-10-01. A live-fetch CI job was deliberately not built — it would make the + * merge gate depend on a third-party API and network access, which needs its own + * decision (blocking gate vs scheduled job). This offline pin catches the same + * drift — any edit to these files — for zero network cost; re-running the curl + * below against mainnet is still how the pin itself gets re-verified. + * + * Offline on purpose. To re-verify against the chain (principal varies by pin, + * see each entry above): + * curl -s https://api.hiro.so/v2/contracts/source// \ * | jq -j .source | shasum -a 256 * (-j: no trailing newline; the API returns the source without one.) * *.clar is forced to LF by .gitattributes, so the hash is stable across checkouts. @@ -24,19 +34,33 @@ import { readFileSync } from "node:fs"; const PINS = [ { file: "contracts/snp-flashstack-receiver.clar", + principal: "SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ", bytes: 3270, sha256: "0722955560dbd791d5c3a29c84e1787e4a250df88db5ece6d27be768a0b920ea", }, { file: "contracts/snp-flashstack-receiver-v3.clar", + principal: "SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ", bytes: 5396, sha256: "2560814d0e0103d2e8fcb337fc560cdbc5c39215828b81606712ab82ffb3fdec", }, + { + file: "contracts/flashstack-stx-core.clar", + principal: "SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5", + bytes: 6538, + sha256: "a3c3e99b5a8ed46604fbb47d643d680848e51298244cac2bfedb74e192a091ff", + }, + { + file: "contracts/flashstack-sbtc-core.clar", + principal: "SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5", + bytes: 6801, + sha256: "f723d2bea72e62bece76d6f2ebe3d7d1a9de707176f41b7bc3b709e8e4f839af", + }, ] as const; describe("verbatim copies of deployed contracts must not change", () => { - for (const { file, bytes, sha256 } of PINS) { - it(`${file} still matches the deployed source it was verified against`, () => { + for (const { file, principal, bytes, sha256 } of PINS) { + it(`${file} still matches the source deployed at ${principal}`, () => { const raw = readFileSync(file, "utf-8").replace(/\r\n/g, "\n"); expect(Buffer.byteLength(raw), "size changed").toBe(bytes); expect(createHash("sha256").update(raw).digest("hex"), "content changed").toBe(sha256); From efe21c6fa2567b92a0445c39d58de8c85645db74 Mon Sep 17 00:00:00 2001 From: Glory Matthew Date: Thu, 1 Oct 2026 01:06:55 +0100 Subject: [PATCH 2/3] fix: correct flashstack-stx-core.clar's trailing newline + pin, per #79 Independently re-verified #79's two new hashes against the live chain before approving, same as every other PR this session. sbtc-core matched exactly. stx-core didn't: the deployed source is 6537 bytes, the repo's canonical contracts/flashstack-stx-core.clar was 6538 -- one extra trailing newline, confirmed as committed content (git show HEAD), not a working-tree artifact. This is real drift, just not a functional one: Clarity ignores trailing blank lines, and contracts/test/flashstack-stx-core.clar carried the identical extra newline, so canonical-copy-drift.test.ts's blank-line normalization never saw it. #79's pin recorded the drifted (6538) state as "verified byte-identical" rather than catching it -- the one thing this exact test exists to prevent, per its own docstring citing F-7. Fixed both the canonical file and its test copy (trimmed the one extra trailing byte each, now true byte-for-byte matches to the deployed source -- stx-core sha256 re-verified against chain directly: 9fde1e3e330e16310d6aeae51baaa3acece0e4c6aad6368f7b80967cd36b517e) and corrected the pin to 6537 / the real hash. Mutation-checked: appending a byte now fails the pin with the expected size-mismatch message; reverting passes again. Verified: suite 260 passed / 1 expected fail (261), up from 258/259 by exactly #79's 2 pins, clarinet check 211/0 (unchanged, not a contract behavior change). canonical-copy-drift and mainnet-fidelity both still green with the trimmed files. Co-Authored-By: Claude Sonnet 5 --- contracts/test/flashstack-stx-core.clar | 1 - tests/deployed-source-pins.test.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/test/flashstack-stx-core.clar b/contracts/test/flashstack-stx-core.clar index 3134f73..04b5ae8 100644 --- a/contracts/test/flashstack-stx-core.clar +++ b/contracts/test/flashstack-stx-core.clar @@ -196,4 +196,3 @@ (define-read-only (get-admin) (ok (var-get admin)) ) - diff --git a/tests/deployed-source-pins.test.ts b/tests/deployed-source-pins.test.ts index aaadfe7..3ef0775 100644 --- a/tests/deployed-source-pins.test.ts +++ b/tests/deployed-source-pins.test.ts @@ -47,8 +47,8 @@ const PINS = [ { file: "contracts/flashstack-stx-core.clar", principal: "SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5", - bytes: 6538, - sha256: "a3c3e99b5a8ed46604fbb47d643d680848e51298244cac2bfedb74e192a091ff", + bytes: 6537, + sha256: "9fde1e3e330e16310d6aeae51baaa3acece0e4c6aad6368f7b80967cd36b517e", }, { file: "contracts/flashstack-sbtc-core.clar", From 24817e779646f69c9e7cbce43624c04ef27ee424 Mon Sep 17 00:00:00 2001 From: Glory Matthew Date: Thu, 1 Oct 2026 01:07:53 +0100 Subject: [PATCH 3/3] fix: actually trim flashstack-stx-core.clar (efe21c6 missed it) efe21c6 fixed the test copy and the pin but not the canonical file itself -- my mutation-test cleanup (git checkout -- contracts/flashstack-stx-core.clar, to undo a deliberately-appended byte) ran before that file's trim was committed, so it silently reverted to the original 6538-byte state instead of to the fix. Caught by re-checking git show HEAD's byte count rather than assuming the earlier green test run still reflected what got pushed. Now genuinely 6537 bytes, sha256 9fde1e3e330e16310d6aeae51baaa3acece0e4c6aad6368f7b80967cd36b517e, re-verified against chain directly again. Suite 260 passed / 1 expected fail (261), clarinet check 211/0. git status showed only this one file before committing. Co-Authored-By: Claude Sonnet 5 --- contracts/flashstack-stx-core.clar | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/flashstack-stx-core.clar b/contracts/flashstack-stx-core.clar index e271a3c..67a65b7 100644 --- a/contracts/flashstack-stx-core.clar +++ b/contracts/flashstack-stx-core.clar @@ -196,4 +196,3 @@ (define-read-only (get-admin) (ok (var-get admin)) ) -