Skip to content

Commit 2e8aef1

Browse files
V48 Gate 3 (specification-implementation): era-pin superseded V43–V47 route-realization proofs so Gate Quality is green
Gate Quality failed at `pnpm --filter @bitcode/protocol test` (the sole failing step in both CI runs): 16 V43–V47 canonical proof suites asserted `false !== true`. Cause: those proofs read the historical singular-route source in place (`uapi/app/deposit/*`, `uapi/app/read/*`) and assert on its literal content, but V48 Gate 3 (f51a7b2) pluralized the routes and MOVED those files to `uapi/app/deposits/` and `uapi/app/reads/` (old paths are redirect-only shims), so every `readSource` came back empty. The standalone `.mjs` gate checkers are already pointer-gated (era-pinned) in the workflow, but the protocol test suite runs `node --test test/*.test.js` unconditionally, so this class was never pinned. The proofs are NOT re-pointed at the plural routes: Gate 3 also rewrote those files, so their historical content predicates would not match, and the frozen proofs exist to attest their own era (the `.bitcode/` artifacts + promoted spec families keep the historical route names). Instead they are era-pinned: - New `packages/protocol/test/era-pinned-superseded-routes.js` — a `node:test` `test` shim that skips every registered test WITH A REASON when the current plural realization is present (`uapi/app/deposits/DepositPageClient.tsx` exists), and is `node:test` unchanged otherwise (so the proofs still run on the promoted V47 canon, where the singular realization stands). - The 16 superseded proof files import `test` from that shim instead of `node:test` (one import-line change each; no body changes). - V48 notes checker-posture paragraph updated to record the protocol-suite pin. Verified: `pnpm --filter @bitcode/protocol test` → 237 tests, 199 pass, 0 fail, 38 skipped (exit 0); protocol typecheck 0. Skips render with the era-pin reason. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 0c758de commit 2e8aef1

18 files changed

Lines changed: 86 additions & 17 deletions

BITCODE_SPEC_V48_NOTES.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,20 @@ become MASTER-DETAIL:
563563

564564
Checker posture: all gate checkers literal-matching the old routes are
565565
era-pinned (V43–V47) and do not run at the current pointer; frozen `.bitcode/`
566-
era artifacts and promoted spec families keep the historical route names.
566+
era artifacts and promoted spec families keep the historical route names. The
567+
standalone `.mjs` gate checkers are pointer-gated in the workflow; the
568+
`@bitcode/protocol` **test suite** (`node --test test/*.test.js`, run
569+
unconditionally by Gate Quality) was NOT — its V43–V47 route-realization proofs
570+
read the historical singular-route source in place and moved to `false !== true`
571+
once the pluralization moved the files to `uapi/app/deposits|reads`. Those 16
572+
superseded proof files import `test` from
573+
`packages/protocol/test/era-pinned-superseded-routes.js` (a `node:test` shim)
574+
instead of `node:test`: it skips every test WITH A REASON when the current
575+
plural realization is present (`uapi/app/deposits/DepositPageClient.tsx` exists)
576+
and runs them unchanged on the promoted V47 canon where the singular
577+
realization still stands. The proofs are NOT re-pointed at the plural routes —
578+
Gate 3 rewrote those files, so their historical content predicates would not
579+
match, and the frozen proofs attest their own era.
567580

568581
### Deposit/Read product-surface presentation laws (Garrett, 2026-07-04)
569582

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Era-pin for superseded product-route realization proofs.
3+
*
4+
* V48 Gate 3 pluralized the product routes (`/deposit` -> `/deposits`,
5+
* `/read` -> `/reads`) and MOVED the client + route-model files into
6+
* `uapi/app/deposits/` and `uapi/app/reads/` (the old paths are redirect-only
7+
* shims). The V43-V47 canonical proofs read the historical singular-route
8+
* source in place and assert on its literal content, so once the pluralized
9+
* realization lands they are validating a superseded era against source that
10+
* has legitimately moved forward.
11+
*
12+
* Rather than mutate the frozen historical proofs to chase the current routes
13+
* (they exist to attest their own era, and the `.bitcode/` artifacts + promoted
14+
* spec families keep the historical route names), these proofs are ERA-PINNED:
15+
* a superseded proof file imports `test` from here instead of `node:test`, and
16+
* every test it registers is skipped WITH A REASON once the current (plural)
17+
* realization is present. On the promoted V47 canon — where the singular
18+
* realization still exists — `SUPERSEDED` is false and the proofs run normally.
19+
*
20+
* This mirrors the `.mjs` gate checkers' era-pinning (pointer-gated in the
21+
* workflow); the difference is that the protocol test suite runs
22+
* `node --test test/*.test.js` unconditionally, so the pin lives at the import.
23+
*/
24+
25+
import nodeTest from 'node:test';
26+
import { existsSync } from 'node:fs';
27+
import path from 'node:path';
28+
import { fileURLToPath } from 'node:url';
29+
30+
const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../..');
31+
32+
/** True once the V48 plural-route realization is present in the working tree. */
33+
export const SUPERSEDED = existsSync(
34+
path.join(REPO_ROOT, 'uapi/app/deposits/DepositPageClient.tsx'),
35+
);
36+
37+
const SKIP_REASON =
38+
'era-pinned: superseded by V48 Gate 3 route pluralization (/deposit->/deposits, /read->/reads)';
39+
40+
/**
41+
* A `node:test` `test` shim. When the realization is superseded it registers
42+
* every test as skipped (carrying the reason); otherwise it is `node:test`'s
43+
* `test` unchanged. Handles the `(name)`, `(name, fn)`, and
44+
* `(name, options, fn)` call signatures.
45+
*/
46+
function eraPinnedTest(name, options, fn) {
47+
if (!SUPERSEDED) return nodeTest(name, options, fn);
48+
if (typeof options === 'function') {
49+
fn = options;
50+
options = {};
51+
}
52+
return nodeTest(name, { ...(options || {}), skip: SKIP_REASON }, fn || (() => {}));
53+
}
54+
55+
export default eraPinnedTest;
56+
export { eraPinnedTest as test };

packages/protocol/test/v43-cross-route-rehearsal-telemetry-repair.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import test from 'node:test';
2+
import test from './era-pinned-superseded-routes.js';
33

44
import {
55
V43_CROSS_ROUTE_REHEARSAL_ARTIFACT_PATH,

packages/protocol/test/v44-depositor-earnings-supply-opportunities.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import test from 'node:test';
2+
import test from './era-pinned-superseded-routes.js';
33

44
import {
55
V44_DEPOSITOR_DEMAND_OPPORTUNITY_STATE_IDS,

packages/protocol/test/v44-organization-policy-wallet-authority.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import { test } from 'node:test';
2+
import { test } from './era-pinned-superseded-routes.js';
33
import {
44
V44_ORGANIZATION_POLICY_ACTION_IDS,
55
V44_ORGANIZATION_POLICY_OBJECT_IDS,

packages/protocol/test/v44-reading-budget-quote-policy.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import test from 'node:test';
2+
import test from './era-pinned-superseded-routes.js';
33

44
import {
55
V44_READING_BUDGET_QUOTE_FORBIDDEN_PAYLOAD_IDS,

packages/protocol/test/v45-proof-family-artifacts.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import assert from 'node:assert/strict';
22
import path from 'node:path';
33
import { fileURLToPath } from 'node:url';
4-
import { test } from 'node:test';
4+
import { test } from './era-pinned-superseded-routes.js';
55

66
import {
77
V45_PROOF_FAMILY_ARTIFACT_PATHS,

packages/protocol/test/v45-source-safe-e2e-rehearsal.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import { test } from 'node:test';
2+
import { test } from './era-pinned-superseded-routes.js';
33

44
import {
55
V45_SOURCE_SAFE_E2E_REHEARSAL_ARTIFACT_PATH,

packages/protocol/test/v46-local-interface-comprehension-rehearsal.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import { test } from 'node:test';
2+
import { test } from './era-pinned-superseded-routes.js';
33
import {
44
V46_LOCAL_INTERFACE_COMPREHENSION_REHEARSAL_ARTIFACT_PATH,
55
V46_LOCAL_INTERFACE_COMPREHENSION_REHEARSAL_ROWS,

packages/protocol/test/v46-product-route-comprehension-readback.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert/strict';
2-
import { test } from 'node:test';
2+
import { test } from './era-pinned-superseded-routes.js';
33
import {
44
V46_PRODUCT_ROUTE_CAPABILITY_IDS,
55
V46_PRODUCT_ROUTE_COMPREHENSION_READBACK_ARTIFACT_PATH,

0 commit comments

Comments
 (0)