Files
charleswiltgen__axiom/scripts/cursor-output.test.ts
T
Charles Wiltgen 73bcab39b0 fix(scripts): regenerate Codex on version bump and close the version-parity class
set-version.js regenerated the Cursor variant but never Codex, so
axiom-codex/.codex-plugin/plugin.json kept the PREVIOUS version through a
version bump — invisibly. Gate 12f compares skills/ and agents/ mtimes against
that manifest and a pure version bump touches neither, while the version-parity
gate (check 8) covered Cursor's manifest but not Codex's. Confirmed by reverting
the manifest to the prior version and watching Phase 1 pass green.

Root package.json had the identical hole: written by set-version.js, but read by
pre-deploy only for the `pi` manifest block, never into the parity map. Also
confirmed empirically. `pi install` resolves against that file.

- set-version.js now runs build-cursor.ts AND build-codex.ts
- --tag preflight absolves axiom-codex/ output via a new codex-output.js,
  mirroring cursor-output.js (regression the fix itself introduced: the
  preflight would have refused on ~350 files the same run had just written)
- check 8 reads every version carrier from one table; parse wrapped in
  try/catch because build-codex rmSync's and rebuilds in place with no staging
- version-parity.test.ts fails if a carrier is added without a matching read
- methodology-leak.test.ts keeps behavioral-test methodology out of
  .claude/rules/skill-development.md, which the harness appends to every
  skill-file read and therefore reaches a test's GREEN arm but never its control

Parity gate now reports 9 files, up from 7. Unit suite 488/488 (was 478).
Reviewed with code-reviewer; the root package.json hole was its finding.
2026-09-05 10:49:43 -07:00

42 lines
1.6 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { isCursorGeneratedPath } from "./cursor-output.js";
test("recognises every path the Cursor build regenerates", () => {
for (const generated of [
"axiom-cursor/README.md",
"axiom-cursor/.cursor-plugin/plugin.json",
"axiom-cursor/skills/axiom-swiftui/SKILL.md",
"axiom-cursor/reports/inventory-sha256.json",
"axiom-cursor/scripts/cursor-hook-adapter.py",
".cursor-plugin/marketplace.json",
]) {
assert.equal(isCursorGeneratedPath(generated), true, generated);
}
});
test("does not absolve unrelated working-tree changes", () => {
// The point of the --tag preflight is refusing to tag a dirty tree. Widening it
// for generated output must not turn it into a blanket pass.
for (const unrelated of [
"scripts/set-version.js",
"docs/start/cursor-install.md",
"CURSOR-MARKETPLACE-SUBMISSION.md",
".claude-plugin/plugins/axiom/agents/build-fixer.md",
// Not Cursor output, so false here is correct. Since 2026-09-05 it IS
// regenerated by set-version, but that is `isCodexGeneratedPath`'s job —
// the --tag preflight composes the two predicates. See codex-output.test.ts.
"axiom-codex/skills/axiom-swiftui/SKILL.md",
"axiom-cursor-notes.md",
".cursor-plugin/other.json",
"",
]) {
assert.equal(isCursorGeneratedPath(unrelated), false, unrelated);
}
});
test("normalises Windows separators", () => {
assert.equal(isCursorGeneratedPath("axiom-cursor\\README.md"), true);
assert.equal(isCursorGeneratedPath(".cursor-plugin\\marketplace.json"), true);
});