kijito-tools 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +6 -0
  3. package/README.md +220 -0
  4. package/bin/cli.js +34 -0
  5. package/install.sh +161 -0
  6. package/package.json +50 -0
  7. package/providers/_shared/wake-core.mjs +358 -0
  8. package/providers/claude/CLAUDE.md.snippet +31 -0
  9. package/providers/claude/install.sh +186 -0
  10. package/providers/claude/scripts/arm-session.sh +66 -0
  11. package/providers/claude/scripts/claude-armed.sh +101 -0
  12. package/providers/claude/scripts/heartbeat-watchdog.sh +209 -0
  13. package/providers/claude/scripts/inbox-selftest.sh +277 -0
  14. package/providers/claude/scripts/kijito-persona-lib.sh +94 -0
  15. package/providers/claude/scripts/kijito-qa-pass.sh +12 -0
  16. package/providers/claude/scripts/lifecycle-lib.sh +167 -0
  17. package/providers/claude/scripts/myctx.sh +46 -0
  18. package/providers/claude/scripts/self-clear.sh +134 -0
  19. package/providers/claude/scripts/session-autosend.sh +85 -0
  20. package/providers/claude/scripts/session-catchup-hint.sh +330 -0
  21. package/providers/claude/scripts/statusline-context.sh +67 -0
  22. package/providers/claude/skills/kijito-qa-memory/SKILL.md +110 -0
  23. package/providers/claude/skills/kijito-recall/SKILL.md +53 -0
  24. package/providers/claude/skills/kijito-start/SKILL.md +122 -0
  25. package/providers/claude/wiring/README.md +93 -0
  26. package/providers/claude/wiring/kijito-heartbeat@.service +21 -0
  27. package/providers/codex/README.md +75 -0
  28. package/providers/codex/codex-kijito-parity-plan.md +265 -0
  29. package/providers/codex/docs-codex-setup.md +64 -0
  30. package/providers/codex/install.mjs +184 -0
  31. package/providers/codex/n0-capability-probe-protocol.md +472 -0
  32. package/providers/codex/n0-harness/README.md +57 -0
  33. package/providers/codex/n0-harness/cli.mjs +58 -0
  34. package/providers/codex/n0-harness/evidence-manifest.mjs +77 -0
  35. package/providers/codex/n0-harness/fixture.mjs +279 -0
  36. package/providers/codex/n0-harness/lib.mjs +141 -0
  37. package/providers/codex/n0-harness/manifest.mjs +36 -0
  38. package/providers/codex/n0-harness/oracle.mjs +464 -0
  39. package/providers/codex/n0-harness/parser.mjs +200 -0
  40. package/providers/codex/n0-harness/prompt.mjs +43 -0
  41. package/providers/codex/n0-harness/snapshot.mjs +120 -0
  42. package/providers/codex/n0-harness/specimen.mjs +37 -0
  43. package/providers/codex/notify/kijito-notify-count.mjs +117 -0
  44. package/providers/codex/notify/kijito-notify-count.test.mjs +76 -0
  45. package/providers/codex/plans/gate4-battery-log.md +184 -0
  46. package/providers/codex/plans/gate4-battery-protocol.md +43 -0
  47. package/providers/codex/plans/hive-user-first-plan-QA.md +34 -0
  48. package/providers/codex/plans/hive-user-first-plan.md +247 -0
  49. package/providers/codex/release-manifest.json +53 -0
  50. package/providers/codex/same-chat-continuation-plan-gate.md +235 -0
  51. package/providers/codex/same-chat-continuation-plan.md +458 -0
  52. package/providers/codex/skills/kijito-qa-memory/SKILL.md +193 -0
  53. package/providers/codex/skills/kijito-qa-memory/agents/openai.yaml +4 -0
  54. package/providers/codex/skills/kijito-recall/SKILL.md +53 -0
  55. package/providers/codex/skills/kijito-start/SKILL.md +173 -0
  56. package/providers/codex/skills/kijito-start/agents/openai.yaml +4 -0
  57. package/providers/codex/test/n0-cli-refusal.test.mjs +31 -0
  58. package/providers/codex/test/n0-counterexample-matrix.test.mjs +118 -0
  59. package/providers/codex/test/n0-guard-census-core.mjs +1372 -0
  60. package/providers/codex/test/n0-guard-census.json +35479 -0
  61. package/providers/codex/test/n0-guard-census.mjs +31 -0
  62. package/providers/codex/test/n0-guard-census.test.mjs +374 -0
  63. package/providers/codex/test/n0-guard-counterexamples.mjs +1068 -0
  64. package/providers/codex/test/n0-guard-independent-projection.mjs +70 -0
  65. package/providers/codex/test/n0-guard-independent-projection.test.mjs +53 -0
  66. package/providers/codex/test/n0-guard-manifest-author.mjs +424 -0
  67. package/providers/codex/test/n0-guard-mutation-operators.test.mjs +244 -0
  68. package/providers/codex/test/n0-guard-mutation-runner.mjs +599 -0
  69. package/providers/codex/test/n0-guard-remainder-classes.test.mjs +314 -0
  70. package/providers/codex/test/n0-guard-sanitizer-pairs.test.mjs +68 -0
  71. package/providers/codex/test/n0-guard-shared-context-predicates.test.mjs +84 -0
  72. package/providers/codex/test/n0-harness.test.mjs +553 -0
  73. package/providers/codex/test/n0-notable-regressions.test.mjs +70 -0
  74. package/providers/codex/test/n0-subject-boundary.mjs +97 -0
  75. package/providers/codex/test/n0-subject-boundary.test.mjs +72 -0
  76. package/providers/codex/test/same-chat-plan-preflight.sh +167 -0
  77. package/providers/codex/tools/refresh-manifest.mjs +81 -0
  78. package/providers/codex/wake-helper/TRANSPORT-NOTES.md +25 -0
  79. package/providers/codex/wake-helper/integration.test.mjs +285 -0
  80. package/providers/codex/wake-helper/kijito-wake-helper.mjs +488 -0
  81. package/providers/codex/wake-helper/kijito-wake-helper.test.mjs +128 -0
  82. package/providers/codex/wake-helper/mock-daemon.mjs +64 -0
  83. package/providers/codex/wake-helper/status-probe.mjs +45 -0
  84. package/providers/codex/wake-helper/ws-uds.mjs +153 -0
  85. package/providers/monitor/.github/workflows/publish-npm.yml +38 -0
  86. package/providers/monitor/.github/workflows/publish-pypi.yml +30 -0
  87. package/providers/monitor/CHANGELOG.md +465 -0
  88. package/providers/monitor/IMPORT-PROVENANCE.md +68 -0
  89. package/providers/monitor/LICENSE +202 -0
  90. package/providers/monitor/NOTICE +7 -0
  91. package/providers/monitor/OPAQUE-OUTPUT-ENFORCEMENT.md +45 -0
  92. package/providers/monitor/README.md +571 -0
  93. package/providers/monitor/RELEASING.md +125 -0
  94. package/providers/monitor/arm-hive-monitor.sh +13 -0
  95. package/providers/monitor/bin/cli.js +43 -0
  96. package/providers/monitor/com.kijito.inbox-monitor.plist.template +59 -0
  97. package/providers/monitor/docs/DESIGN.md +984 -0
  98. package/providers/monitor/kijito-inbox-monitor@.service.template +95 -0
  99. package/providers/monitor/kijito_inbox_monitor.py +3666 -0
  100. package/providers/monitor/package.json +35 -0
  101. package/providers/monitor/pyproject.toml +42 -0
  102. package/providers/monitor/scripts/mutation-check.py +399 -0
  103. package/providers/monitor/scripts/prepublish-gate.sh +284 -0
  104. package/providers/monitor/test_kijito_monitor.py +5609 -0
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { analyzeGuardGraph, mergeManifest, validateManifest } from "./n0-guard-census-core.mjs";
6
+ import { counterexampleUniverse } from "./n0-guard-counterexamples.mjs";
7
+ import { independentProjection } from "./n0-guard-independent-projection.mjs";
8
+
9
+ const here = path.dirname(fileURLToPath(import.meta.url));
10
+ const sourceRoot = path.resolve(here, "../n0-harness");
11
+ const manifestPath = path.join(here, "n0-guard-census.json");
12
+ const graph = analyzeGuardGraph(sourceRoot);
13
+ const projection = independentProjection(sourceRoot);
14
+ const counterexamples = counterexampleUniverse();
15
+
16
+ if (process.argv.includes("--generate")) {
17
+ const prior = fs.existsSync(manifestPath) ? JSON.parse(fs.readFileSync(manifestPath, "utf8")) : null;
18
+ fs.writeFileSync(manifestPath, `${JSON.stringify(mergeManifest(graph, prior, projection, counterexamples), null, 2)}\n`);
19
+ process.stdout.write(`${JSON.stringify(graph.counts)}\n`);
20
+ } else if (process.argv.includes("--check-structure")) {
21
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
22
+ validateManifest(graph, manifest, { requirePairs: false, projection, counterexamples });
23
+ process.stdout.write(`N0_GUARD_CENSUS_STRUCTURE_GREEN ${JSON.stringify(graph.counts)}\n`);
24
+ } else if (process.argv.includes("--check")) {
25
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
26
+ validateManifest(graph, manifest, { requirePairs: true, projection, counterexamples });
27
+ process.stdout.write(`N0_GUARD_CENSUS_GREEN ${JSON.stringify(graph.counts)} independent=${projection.aggregate}\n`);
28
+ } else {
29
+ process.stderr.write("usage: n0-guard-census.mjs --generate|--check-structure|--check\n");
30
+ process.exitCode = 64;
31
+ }
@@ -0,0 +1,374 @@
1
+ import assert from "node:assert/strict";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import { analyzeGuardGraph, mergeManifest, validateManifest } from "./n0-guard-census-core.mjs";
7
+ import { assertDiscriminatingPair, assertRedundantDispositionSingle } from "./n0-guard-mutation-runner.mjs";
8
+
9
+ function fixture(source) {
10
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "n0-census-self."));
11
+ fs.writeFileSync(path.join(root, "fixture.mjs"), source);
12
+ return root;
13
+ }
14
+
15
+ function errorCode(fn, code) {
16
+ assert.throws(fn, (error) => error?.code === code, `expected ${code}`);
17
+ }
18
+
19
+ function ownNormal(entry) {
20
+ entry.mutation = entry.kind.includes("atom")
21
+ ? { operator: "force-owned-condition", value: false }
22
+ : { operator: "bypass-rejection" };
23
+ entry.witness = { partition: "acceptFlipSet", id: "named", rejectCode: "BAD", acceptCode: "GREEN" };
24
+ entry.acceptFlipSet = [{ id: "named", rejectCode: "BAD", acceptCode: "GREEN" }];
25
+ entry.rejectDeltaSet = [];
26
+ entry.positiveRegressionSet = [];
27
+ entry.ownershipRecord = { kind: "normal-ownership" };
28
+ }
29
+
30
+ function fullyOwn(manifest) {
31
+ for (const entry of manifest.entries) {
32
+ if (entry.kind === "success-constructor") {
33
+ entry.ownershipRecord = { kind: "owned-success", reason: "test" };
34
+ } else if (["unresolved-call", "outcome-candidate"].includes(entry.kind)) {
35
+ entry.classification = { kind: entry.kind === "unresolved-call" ? "non-predicate" : "non-outcome", reason: "test" };
36
+ } else {
37
+ ownNormal(entry);
38
+ }
39
+ }
40
+ manifest.floors.ownershipCounts = { rejectPreservingOwnership: 0, mixedOwnership: 0 };
41
+ manifest.floors.ownershipGrowthReasons = {};
42
+ manifest.floors.sharedContextPredicateAtoms = 0;
43
+ manifest.floors.sameCodeShadowEntries = 0;
44
+ manifest.floors.successPathCalls = 0;
45
+ manifest.floors.delegatedOutcomeCalls = 0;
46
+ manifest.floors.compoundDispositionMembers = 0;
47
+ manifest.compounds = [];
48
+ return manifest;
49
+ }
50
+
51
+ test("AST census ignores sink-like data while owning multiline executable sinks", () => {
52
+ const root = fixture(`
53
+ const a = "fail( data";
54
+ const b = \`verdict("RED" data\`;
55
+ const c = /fail\\(/;
56
+ function fail() { throw new Error("x"); }
57
+ function verdict(status) { return status; }
58
+ export function probe(value) {
59
+ if (!value) fail(
60
+ "MULTILINE",
61
+ "real"
62
+ );
63
+ return verdict("N0_TEST_CAPABLE");
64
+ }
65
+ `);
66
+ try {
67
+ const graph = analyzeGuardGraph(root);
68
+ assert.equal(graph.entries.filter((entry) => entry.kind === "rejection-site" && entry.spelling === "fail").length, 1);
69
+ assert.equal(graph.counts["success-constructor"], 1);
70
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
71
+ });
72
+
73
+ test("manifest ownership fails closed for missing, duplicate, stale, and unmatched nodes", () => {
74
+ const root = fixture(`function fail() { throw new Error("x"); } function verdict(s){return s;} export function p(x){if(!x) fail("X"); return verdict("N0_TEST_CAPABLE");}`);
75
+ try {
76
+ const graph = analyzeGuardGraph(root);
77
+ const base = mergeManifest(graph);
78
+ assert.equal(validateManifest(graph, base, { requirePairs: false, requireBaseline: false }), true);
79
+ const missing = structuredClone(base); missing.entries.pop();
80
+ errorCode(() => validateManifest(graph, missing, { requirePairs: false, requireBaseline: false }), "CENSUS_UNOWNED_NODE");
81
+ const duplicate = structuredClone(base); duplicate.entries.push(structuredClone(duplicate.entries[0]));
82
+ errorCode(() => validateManifest(graph, duplicate, { requirePairs: false, requireBaseline: false }), "CENSUS_DUPLICATE_OWNER");
83
+ const stale = structuredClone(base); stale.entries[0].sourceHash = "0".repeat(64);
84
+ errorCode(() => validateManifest(graph, stale, { requirePairs: false, requireBaseline: false }), "CENSUS_STALE_ANCHOR");
85
+ const unmatched = structuredClone(base); unmatched.entries.push({ ...structuredClone(unmatched.entries[0]), id: "ghost" });
86
+ errorCode(() => validateManifest(graph, unmatched, { requirePairs: false, requireBaseline: false }), "CENSUS_UNMATCHED_OWNER");
87
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
88
+ });
89
+
90
+ test("predicate helpers and every rejecting-helper call site are separate nodes", () => {
91
+ const root = fixture(`
92
+ function fail() { throw new Error("x"); }
93
+ function verdict(s){ return s; }
94
+ function valid(x) { return typeof x === "string" && x.length > 2 && /^[a-z]+$/.test(x); }
95
+ function requireValid(x) { if (!valid(x)) fail("BAD"); }
96
+ export function p(a,b) { requireValid(a); requireValid(b); return verdict("N0_TEST_CAPABLE"); }
97
+ export function q(a,b) { if (a && b) requireValid(a); return verdict("N0_TEST_CAPABLE"); }
98
+ `);
99
+ try {
100
+ const graph = analyzeGuardGraph(root);
101
+ assert.equal(graph.entries.filter((entry) => entry.kind === "predicate-atom" && entry.predicate === "valid").length, 3);
102
+ assert.equal(graph.entries.filter((entry) => entry.kind === "rejecting-helper-call" && entry.helper === "requireValid").length, 3);
103
+ assert.equal(graph.entries.filter((entry) => entry.kind === "guard-atom" && entry.ownerSinkLine === 7).length, 2);
104
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
105
+ });
106
+
107
+ test("N-term guard requires every atomic owner and exactly one success constructor", () => {
108
+ const root = fixture(`function fail(){throw new Error("x");} function verdict(s){return s;} export function p(a,b,c){if(a||b||c) fail("BAD"); return verdict("N0_TEST_CAPABLE");}`);
109
+ try {
110
+ const graph = analyzeGuardGraph(root);
111
+ assert.equal(graph.entries.filter((entry) => entry.kind === "guard-atom").length, 3);
112
+ const nMinusOne = mergeManifest(graph);
113
+ const atom = nMinusOne.entries.find((entry) => entry.kind === "guard-atom");
114
+ nMinusOne.entries = nMinusOne.entries.filter((entry) => entry.id !== atom.id);
115
+ errorCode(() => validateManifest(graph, nMinusOne, { requirePairs: false, requireBaseline: false }), "CENSUS_UNOWNED_NODE");
116
+ const nMinusOnePairs = fullyOwn(mergeManifest(graph));
117
+ const missingPair = nMinusOnePairs.entries.find((entry) => entry.kind === "guard-atom");
118
+ missingPair.mutation = null;
119
+ missingPair.witness = null;
120
+ missingPair.acceptFlipSet = null;
121
+ missingPair.rejectDeltaSet = null;
122
+ missingPair.positiveRegressionSet = null;
123
+ missingPair.ownershipRecord = null;
124
+ errorCode(() => validateManifest(graph, nMinusOnePairs, { requirePairs: true, requireBaseline: false }), "CENSUS_PAIR_MISSING");
125
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
126
+ });
127
+
128
+ test("named two-sided pairs reject unrelated attribution and strengthening mutants", () => {
129
+ const entry = {
130
+ id: "fixture:guard",
131
+ witness: { partition: "acceptFlipSet", id: "named-counterexample", rejectCode: "EXACT_RED", acceptCode: "EXACT_GREEN" },
132
+ };
133
+ errorCode(() => assertDiscriminatingPair(entry,
134
+ { accepted: false, code: "UNRELATED_TEST_FAILURE" },
135
+ { accepted: true, code: "EXACT_GREEN" }), "MUTATION_PRISTINE_PAIR");
136
+ errorCode(() => assertDiscriminatingPair(entry,
137
+ { accepted: false, code: "EXACT_RED" },
138
+ { accepted: false, code: "EXACT_RED" }), "MUTATION_NOT_DISCRIMINATED");
139
+ });
140
+
141
+ test("redundancy disposition singles must preserve the full matrix, not only their witness", () => {
142
+ const entry = {
143
+ id: "fixture:disposed",
144
+ disposition: { witness: { id: "named", rejectCode: "BAD" } },
145
+ };
146
+ const pristine = {
147
+ named: { accepted: false, code: "BAD" },
148
+ independentlyDiscriminated: { accepted: false, code: "OTHER_BAD" },
149
+ };
150
+ assert.equal(assertRedundantDispositionSingle(entry, pristine, structuredClone(pristine)), undefined);
151
+ const changed = structuredClone(pristine);
152
+ changed.independentlyDiscriminated = { accepted: true, code: "GREEN" };
153
+ errorCode(() => assertRedundantDispositionSingle(entry, pristine, changed),
154
+ "MUTATION_DISPOSITION_SINGLE");
155
+ });
156
+
157
+ test("bare throw, process termination, dynamic negative verdicts, and second success are visible", () => {
158
+ const root = fixture(`
159
+ function verdict(s){return s;}
160
+ export function p(x){
161
+ if(x===1) throw new Error("x");
162
+ if(x===2) process.exit(1);
163
+ if(x===3) process.exitCode=1;
164
+ if(x===4) return verdict("RED");
165
+ if(x===5) return verdict("N0_TEST_CAPABLE");
166
+ return verdict("N0_TEST_CAPABLE");
167
+ }
168
+ `);
169
+ try {
170
+ const graph = analyzeGuardGraph(root);
171
+ assert.equal(graph.counts["termination-site"], 1);
172
+ assert.equal(graph.counts["exit-status-site"], 1);
173
+ assert.equal(graph.counts["success-constructor"], 2);
174
+ const manifest = mergeManifest(graph);
175
+ errorCode(() => validateManifest(graph, manifest, { requirePairs: false, requireBaseline: false }), "CENSUS_SUCCESS_COUNT");
176
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
177
+ });
178
+
179
+ test("relative import escape, missing imports, and dynamic imports fail closed", () => {
180
+ for (const [source, code] of [
181
+ ['import "../outside.mjs"; export const x = 1;', "CENSUS_IMPORT_ESCAPE"],
182
+ ['import "./missing.mjs"; export const x = 1;', "CENSUS_IMPORT_MISSING"],
183
+ ['export async function x(){ return import("node:fs"); }', "CENSUS_DYNAMIC_IMPORT"],
184
+ ]) {
185
+ const root = fixture(source);
186
+ try { errorCode(() => analyzeGuardGraph(root), code); }
187
+ finally { fs.rmSync(root, { recursive: true, force: true }); }
188
+ }
189
+ });
190
+
191
+ test("rejecting function aliases fail closed before a manifest can be generated", () => {
192
+ const root = fixture(`
193
+ function fail(){ throw new Error("x"); }
194
+ const alias = fail;
195
+ export function p(x){ if(!x) alias("BAD"); return { status: "N0_TEST_CAPABLE" }; }
196
+ `);
197
+ try { errorCode(() => analyzeGuardGraph(root), "CENSUS_REJECT_ALIAS"); }
198
+ finally { fs.rmSync(root, { recursive: true, force: true }); }
199
+ });
200
+
201
+ test("predicate aliases and optional calls fail closed before proof enumeration", () => {
202
+ for (const [source, code] of [
203
+ [`
204
+ function fail(){ throw new Error("x"); }
205
+ function valid(x){ return typeof x === "string"; }
206
+ const alias = valid;
207
+ export function p(x){ if(!valid(x)) fail("BAD"); if(!alias(x)) fail("BAD_ALIAS"); return {status:"N0_TEST_CAPABLE"}; }
208
+ `, "CENSUS_PREDICATE_ALIAS"],
209
+ [`
210
+ function fail(){ throw new Error("x"); }
211
+ function valid(x){ return typeof x === "string"; }
212
+ export function p(x){ if(!valid?.(x)) fail("BAD"); return {status:"N0_TEST_CAPABLE"}; }
213
+ `, "CENSUS_PREDICATE_DYNAMIC_CALL"],
214
+ ]) {
215
+ const root = fixture(source);
216
+ try { errorCode(() => analyzeGuardGraph(root), code); }
217
+ finally { fs.rmSync(root, { recursive: true, force: true }); }
218
+ }
219
+ });
220
+
221
+ test("hoisted conjuncts preserve atomic granularity and delegated predicates resolve transitively", () => {
222
+ const inline = fixture(`
223
+ function fail(){throw new Error("x");}
224
+ function leaf(x){return x > 0;}
225
+ function delegated(x){return leaf(x);}
226
+ export function p(a,b){if(a && delegated(b)) fail("BAD"); return {status:"N0_TEST_CAPABLE"};}
227
+ `);
228
+ const hoisted = fixture(`
229
+ function fail(){throw new Error("x");}
230
+ function leaf(x){return x > 0;}
231
+ function delegated(x){return leaf(x);}
232
+ export function p(a,b){const bad = a && delegated(b); if(bad) fail("BAD"); return {status:"N0_TEST_CAPABLE"};}
233
+ `);
234
+ try {
235
+ const a = analyzeGuardGraph(inline);
236
+ const b = analyzeGuardGraph(hoisted);
237
+ assert.equal(a.counts["guard-atom"], 2);
238
+ assert.equal(b.counts["guard-atom"], 2);
239
+ assert.ok(b.entries.some((entry) => entry.kind === "predicate-atom" && entry.predicate === "delegated"));
240
+ assert.ok(b.entries.some((entry) => entry.kind === "predicate-atom" && entry.predicate === "leaf"));
241
+ } finally {
242
+ fs.rmSync(inline, { recursive: true, force: true });
243
+ fs.rmSync(hoisted, { recursive: true, force: true });
244
+ }
245
+ });
246
+
247
+ test("computed exits, sink-like calls, and variable-held verdict objects cannot disappear", () => {
248
+ const root = fixture(`
249
+ import assert from "node:assert";
250
+ export function p(x){
251
+ if(x===1) process["exit"](1);
252
+ if(x===2) process.kill(process.pid, "SIGTERM");
253
+ if(x===3) Promise.reject(new Error("x"));
254
+ if(x===4) assert(false);
255
+ const red = {status:"RED"};
256
+ if(x===5) return red;
257
+ const green = {status:"N0_TEST_CAPABLE"};
258
+ return green;
259
+ }
260
+ `);
261
+ try {
262
+ const graph = analyzeGuardGraph(root);
263
+ assert.equal(graph.counts["termination-site"], 1);
264
+ assert.ok(graph.entries.some((entry) => entry.kind === "rejection-site" && entry.spelling === "process.kill"));
265
+ assert.ok(graph.entries.some((entry) => entry.kind === "rejection-site" && entry.spelling === "Promise.reject"));
266
+ assert.ok(graph.entries.some((entry) => entry.kind === "rejection-site" && entry.spelling === "assert"));
267
+ assert.ok(graph.entries.some((entry) => entry.kind === "rejection-site" && entry.spelling === "object:RED"));
268
+ assert.equal(graph.counts["success-constructor"], 1);
269
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
270
+ });
271
+
272
+ test("a second variable-held success and new closed-world calls fail the owning gates", () => {
273
+ const root = fixture(`
274
+ function fail(){throw new Error("x");}
275
+ const object = { dynamic(){ return false; } };
276
+ export function p(x){
277
+ if(object["dynamic"]()) fail("BAD");
278
+ const one = {status:"N0_TEST_CAPABLE"};
279
+ if(x) return one;
280
+ const two = {status:"N0_TEST_CAPABLE"};
281
+ return two;
282
+ }
283
+ `);
284
+ try {
285
+ const graph = analyzeGuardGraph(root);
286
+ assert.equal(graph.counts["success-constructor"], 2);
287
+ assert.ok(graph.entries.some((entry) => entry.kind === "unresolved-call" && entry.callee === "object.dynamic"));
288
+ const manifest = mergeManifest(graph);
289
+ errorCode(() => validateManifest(graph, manifest, { requirePairs: false, requireBaseline: false }), "CENSUS_SUCCESS_COUNT");
290
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
291
+ });
292
+
293
+ test("count and redundancy-disposition ratchets fail in the dangerous direction", () => {
294
+ const root = fixture(`function fail(){throw new Error("x");} export function p(x){if(!x) fail("BAD"); return {status:"N0_TEST_CAPABLE"};}`);
295
+ try {
296
+ const graph = analyzeGuardGraph(root);
297
+ const count = mergeManifest(graph);
298
+ count.floors.counts["guard-atom"] += 1;
299
+ errorCode(() => validateManifest(graph, count, { requirePairs: false, requireBaseline: false }), "CENSUS_COUNT_REGRESSION");
300
+ const disposition = mergeManifest(graph);
301
+ const target = disposition.entries.find((entry) => entry.kind === "guard-atom");
302
+ const cover = disposition.entries.find((entry) => entry.kind === "rejection-site");
303
+ target.disposition = {
304
+ kind: "not-independently-discriminated",
305
+ witness: { id: "named", rejectCode: "BAD", acceptCode: "GREEN" },
306
+ coveredBy: [cover.id],
307
+ };
308
+ errorCode(() => validateManifest(graph, disposition, { requirePairs: false, requireBaseline: false }), "CENSUS_DISPOSITION_GROWTH");
309
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
310
+ });
311
+
312
+ test("manifest regeneration preserves a floor when the last node of a kind disappears", () => {
313
+ const root = fixture(`export function p(x){if(x) process.exit(1); return {status:"N0_TEST_CAPABLE"};}`);
314
+ try {
315
+ const priorGraph = analyzeGuardGraph(root);
316
+ const prior = mergeManifest(priorGraph);
317
+ assert.equal(prior.floors.counts["termination-site"], 1);
318
+ fs.writeFileSync(path.join(root, "fixture.mjs"),
319
+ `export function p(){return {status:"N0_TEST_CAPABLE"};}`);
320
+ const currentGraph = analyzeGuardGraph(root);
321
+ assert.equal(currentGraph.counts["termination-site"] ?? 0, 0);
322
+ const regenerated = mergeManifest(currentGraph, prior);
323
+ assert.equal(regenerated.floors.counts["termination-site"], 1);
324
+ errorCode(() => validateManifest(currentGraph, regenerated, {
325
+ requirePairs: false,
326
+ requireBaseline: false,
327
+ }), "CENSUS_COUNT_REGRESSION");
328
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
329
+ });
330
+
331
+ test("manifest rejects arbitrary mutation operators before execution", () => {
332
+ const root = fixture(`function fail(){throw new Error("x");} export function p(x){if(!x) fail("BAD"); return {status:"N0_TEST_CAPABLE"};}`);
333
+ try {
334
+ const graph = analyzeGuardGraph(root);
335
+ const manifest = mergeManifest(graph);
336
+ const target = manifest.entries.find((entry) => entry.kind === "guard-atom");
337
+ target.mutation = { operator: "substitute-reviewed-expression", expression: "({})" };
338
+ errorCode(() => validateManifest(graph, manifest, { requirePairs: false, requireBaseline: false }), "CENSUS_MUTATION_OPERATOR");
339
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
340
+ });
341
+
342
+ test("manifest rejects empty, mismatched, and positive-regressing ownership partitions", () => {
343
+ const root = fixture(`function fail(){throw new Error("x");} export function p(x){if(!x) fail("BAD"); return {status:"N0_TEST_CAPABLE"};}`);
344
+ try {
345
+ const graph = analyzeGuardGraph(root);
346
+ const complete = fullyOwn(mergeManifest(graph));
347
+ assert.equal(validateManifest(graph, complete, { requirePairs: true, requireBaseline: false }), true);
348
+ const target = complete.entries.find((entry) => entry.kind === "guard-atom");
349
+
350
+ const empty = structuredClone(complete);
351
+ empty.entries.find((entry) => entry.id === target.id).acceptFlipSet = [];
352
+ errorCode(() => validateManifest(graph, empty, { requirePairs: true, requireBaseline: false }), "CENSUS_MUTATION_OWNERSHIP");
353
+
354
+ const wrongWitness = structuredClone(complete);
355
+ wrongWitness.entries.find((entry) => entry.id === target.id).witness.acceptCode = "OTHER_GREEN";
356
+ errorCode(() => validateManifest(graph, wrongWitness, { requirePairs: true, requireBaseline: false }), "CENSUS_MUTATION_WITNESS");
357
+
358
+ const mixed = structuredClone(complete);
359
+ mixed.entries.find((entry) => entry.id === target.id).rejectDeltaSet = [{
360
+ id: "other",
361
+ before: { accepted: false, code: "BEFORE" },
362
+ after: { accepted: false, code: "AFTER" },
363
+ }];
364
+ errorCode(() => validateManifest(graph, mixed, { requirePairs: true, requireBaseline: false }), "CENSUS_MUTATION_OWNERSHIP");
365
+
366
+ const regressing = structuredClone(complete);
367
+ regressing.entries.find((entry) => entry.id === target.id).positiveRegressionSet = [{
368
+ id: "positive",
369
+ before: { accepted: true, code: "GREEN" },
370
+ after: { accepted: false, code: "RED" },
371
+ }];
372
+ errorCode(() => validateManifest(graph, regressing, { requirePairs: true, requireBaseline: false }), "CENSUS_MUTATION_OWNERSHIP");
373
+ } finally { fs.rmSync(root, { recursive: true, force: true }); }
374
+ });