mirror of
https://github.com/CharlesWiltgen/Axiom.git
synced 2026-09-20 19:58:20 +08:00
73bcab39b0
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.
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { isCodexGeneratedPath } from "./codex-output.js";
|
|
import { isCursorGeneratedPath } from "./cursor-output.js";
|
|
|
|
test("recognises every path the Codex build regenerates", () => {
|
|
for (const generated of [
|
|
"axiom-codex/README.md",
|
|
"axiom-codex/.codex-plugin/plugin.json",
|
|
"axiom-codex/skills/axiom-swiftui/SKILL.md",
|
|
"axiom-codex/skills/axiom-media/skills/music-library.md",
|
|
"axiom-codex/hooks/user-prompt-submit.py",
|
|
]) {
|
|
assert.equal(isCodexGeneratedPath(generated), true, generated);
|
|
}
|
|
});
|
|
|
|
test("does not absolve unrelated working-tree changes", () => {
|
|
// The --tag preflight exists to refuse tagging 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/codex-install.md",
|
|
".claude-plugin/plugins/axiom/agents/build-fixer.md",
|
|
"axiom-codex-notes.md",
|
|
// build-codex.ts does NOT write the Codex marketplace manifest — it is
|
|
// version-free and hand-maintained (see .claude/rules/version-management.md).
|
|
".agents/plugins/marketplace.json",
|
|
"",
|
|
]) {
|
|
assert.equal(isCodexGeneratedPath(unrelated), false, unrelated);
|
|
}
|
|
});
|
|
|
|
test("normalises Windows separators", () => {
|
|
assert.equal(isCodexGeneratedPath("axiom-codex\\README.md"), true);
|
|
});
|
|
|
|
test("the two generated-output predicates are disjoint", () => {
|
|
// set-version's --tag preflight ORs these. If they ever overlapped, a path
|
|
// could be absolved by the wrong owner and the narrowing intent would rot.
|
|
for (const p of [
|
|
"axiom-cursor/.cursor-plugin/plugin.json",
|
|
".cursor-plugin/marketplace.json",
|
|
"axiom-codex/.codex-plugin/plugin.json",
|
|
"axiom-codex/skills/axiom-media/SKILL.md",
|
|
]) {
|
|
assert.equal(
|
|
isCursorGeneratedPath(p) && isCodexGeneratedPath(p),
|
|
false,
|
|
`${p} claimed by both predicates`,
|
|
);
|
|
}
|
|
});
|