gentle-pi 2.0.0 → 2.1.1

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.
@@ -212,7 +212,8 @@ test("installed commit transaction runner loads JavaScript only and has determin
212
212
  assert.equal(packageJson.scripts?.["test:packed-runner"], "node scripts/test-packed-runner.mjs");
213
213
  assert.match(packageJson.scripts?.prepublishOnly ?? "", /pnpm run test:packed-runner/);
214
214
  assert.match(ci, /pnpm run test:packed-runner/);
215
- assert.doesNotMatch(packedRunner, /\["install"[^\]]*"--ignore-scripts"/s);
215
+ assert.match(packedRunner, /\["install"[^\]]*"--ignore-scripts=false"/s, "packed install must explicitly enable postinstall");
216
+ assert.doesNotMatch(packedRunner, /\["install"[^\]]*"--ignore-scripts"(?!\=false)/s);
216
217
  assert.match(packedRunner, /execFileSync\("where\.exe", \["npm"\]/);
217
218
  assert.match(packedRunner, /could not resolve npm-cli\.js without a command shell/);
218
219
  assert.doesNotMatch(packedRunner, /ComSpec|cmd\.exe/);
@@ -275,7 +276,13 @@ test("package verification binds the published Gentle AI v2.2.2 runtime pin", ()
275
276
  const verifier = readFileSync(join(PACKAGE_ROOT, "scripts", "verify-package-files.mjs"), "utf8");
276
277
 
277
278
  assert.match(installer, /INSTALLER_VERSION = "2\.2\.2"/);
279
+ assert.match(installer, /GENTLE_AI_WINDOWS_SOURCE_PACKAGE.*GENTLE_AI_WINDOWS_SOURCE_MODULE/);
280
+ assert.match(installer, /GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:YZcI5dRvoHm82I2CULvgBkB2M3UQQGarYO\/u\/Nt5LSc="/);
281
+ assert.match(installer, /GOTOOLCHAIN: "local"/);
282
+ assert.match(installer, /GOSUMDB: "sum\.golang\.org"/);
278
283
  assert.match(binary, /GENTLE_AI_VERSION = "2\.2\.2"/);
284
+ assert.match(binary, /GO_SUMDB_SOURCE_BUILD/);
285
+ assert.match(binary, /GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM/);
279
286
  assert.match(verifier, /v2\.2\.2/);
280
287
  });
281
288
 
@@ -1130,9 +1137,9 @@ test("pi-pretty wrapper uses real package path resolution for pnpm symlink insta
1130
1137
  assert.match(wrapper, /quietToolsEnabled/);
1131
1138
  });
1132
1139
 
1133
- test("v2.0.0 release package and runtime stop before publication", () => {
1140
+ test("v2.1.1 release package and runtime stop before publication", () => {
1134
1141
  const packageJson = readPackageJson();
1135
- assert.equal(packageJson.version, "2.0.0", "the release manifest must remain explicitly pinned to v2.0.0");
1142
+ assert.equal(packageJson.version, "2.1.1", "the release manifest must remain explicitly pinned to v2.1.1");
1136
1143
  assert.equal(
1137
1144
  packageJson.scripts?.test,
1138
1145
  "node --experimental-strip-types --test tests/*.test.ts && pnpm run test:harness",
@@ -584,6 +584,49 @@ test("native projections reconstruct symlink, intended-untracked, and gitlink id
584
584
  assert.deepEqual(projection.gitlinks, { "vendor/dependency": gitlinkCommit });
585
585
  });
586
586
 
587
+ test("native staged projections restore the exact current index over HEAD", (t) => {
588
+ const contributorRoot = repository(t);
589
+ const baseTree = git(contributorRoot, "rev-parse", "HEAD^{tree}");
590
+ writeFileSync(join(contributorRoot, "tracked.txt"), "staged candidate\n");
591
+ git(contributorRoot, "add", "tracked.txt");
592
+ const candidateTree = git(contributorRoot, "write-tree");
593
+ const registry = new CandidateViewRegistry();
594
+
595
+ registry.restoreProjectionFromNative("staged-index-projection", contributorRoot, {
596
+ baseTree,
597
+ currentCandidateTree: candidateTree,
598
+ paths: ["tracked.txt"],
599
+ intendedUntracked: [],
600
+ projection: "staged",
601
+ });
602
+
603
+ const projection = registry.resolveProjection("staged-index-projection", contributorRoot);
604
+ assert.equal(projection.baseTree, baseTree);
605
+ assert.equal(projection.candidateTree, candidateTree);
606
+ assert.equal(projection.committedOnly, false);
607
+ });
608
+
609
+ test("native staged projections reject a workspace snapshot that differs from the current index", (t) => {
610
+ const contributorRoot = repository(t);
611
+ const baseTree = git(contributorRoot, "rev-parse", "HEAD^{tree}");
612
+ writeFileSync(join(contributorRoot, "tracked.txt"), "workspace candidate\n");
613
+ const workspace = new CandidateViewRegistry().create({ contributorRoot });
614
+ try {
615
+ assert.throws(
616
+ () => new CandidateViewRegistry().restoreProjectionFromNative("workspace-as-staged", contributorRoot, {
617
+ baseTree,
618
+ currentCandidateTree: workspace.candidateTree,
619
+ paths: ["tracked.txt"],
620
+ intendedUntracked: [],
621
+ projection: "staged",
622
+ }),
623
+ (error: unknown) => error instanceof CandidateViewError && error.reason === "projection-kind-drift",
624
+ );
625
+ } finally {
626
+ workspace.cleanup();
627
+ }
628
+ });
629
+
587
630
  test("native projections recover a committed range base from its frozen tree", (t) => {
588
631
  const contributorRoot = repository(t);
589
632
  const baseCommit = git(contributorRoot, "rev-parse", "HEAD");
@@ -75,11 +75,27 @@ function nativeStatus(cwd: string, status: string, locks: readonly unknown[]): N
75
75
  } as NativeReviewStatusResult;
76
76
  }
77
77
 
78
- function fakeNative(status: NativeReviewStatusResult, onStart?: () => void): NativeReviewCli {
78
+ function fakeNative(status: NativeReviewStatusResult, onStart?: (request: Parameters<NativeReviewCli["start"]>[0]) => void): NativeReviewCli {
79
79
  const blocking = status.locks.some((lock) => (lock as { status?: string }).status !== "released");
80
+ const tree = execFileSync("git", ["rev-parse", "HEAD^{tree}"], { cwd: status.repository, encoding: "utf8" }).trim();
81
+ const targetIdentity = `sha256:${"a".repeat(64)}`;
82
+ const projection = {
83
+ schema: "gentle-ai.review-integration.projection/v1",
84
+ kind: "current-changes",
85
+ projection: "workspace",
86
+ baseTree: tree,
87
+ initialReviewTree: tree,
88
+ currentCandidateTree: tree,
89
+ pathsDigest: targetIdentity,
90
+ paths: [],
91
+ intendedUntracked: [],
92
+ intendedUntrackedProof: targetIdentity,
93
+ initialSnapshotIdentity: targetIdentity,
94
+ currentSnapshotIdentity: targetIdentity,
95
+ };
80
96
  return {
81
- start: async () => {
82
- onStart?.();
97
+ start: async (request) => {
98
+ onStart?.(request);
83
99
  return { lineageId: "native-lineage", state: "reviewing", riskLevel: "medium", selectedLenses: ["review-reliability"], changedFiles: 1, changedLines: 2, correctionBudget: 1, action: "created", lensesRequired: true };
84
100
  },
85
101
  finalize: async () => { throw new Error("finalize must not run"); },
@@ -90,7 +106,9 @@ function fakeNative(status: NativeReviewStatusResult, onStart?: () => void): Nat
90
106
  targetStatus: async () => ({
91
107
  applicability: blocking ? "corrupted" : "unrelated",
92
108
  action: blocking ? "repair_authority" : "start",
93
- raw: { action: blocking ? "repair_authority" : "start", locks: status.locks },
109
+ targetIdentity,
110
+ projection,
111
+ raw: { action: blocking ? "repair_authority" : "start", locks: status.locks, target_identity: targetIdentity, projection: { projection: "workspace" } },
94
112
  }),
95
113
  } as unknown as NativeReviewCli;
96
114
  }
@@ -121,11 +139,11 @@ test("INSPECT treats released lock residue as non-blocking and still blocks on l
121
139
  test("START precondition ignores released lock residue and still blocks on live lock claims", async (t) => {
122
140
  const cwd = repository(t);
123
141
 
124
- let started = 0;
125
- const proceeded = await runtime(fakeNative(nativeStatus(cwd, "clean", [RELEASED_LOCK]), () => { started += 1; }))
142
+ const startRequests: Parameters<NativeReviewCli["start"]>[0][] = [];
143
+ const proceeded = await runtime(fakeNative(nativeStatus(cwd, "clean", [RELEASED_LOCK]), (request) => { startRequests.push(request); }))
126
144
  .execute("start-released", { operation: "start", input: JSON.stringify({ mode: "ordinary" }) }, undefined, undefined, context(cwd));
127
145
  const proceededDetails = proceeded.details as Record<string, unknown>;
128
- assert.equal(started, 1);
146
+ assert.deepEqual(startRequests, [{ cwd, targetIdentity: `sha256:${"a".repeat(64)}`, projection: "workspace" }]);
129
147
  assert.equal((proceededDetails.result as Record<string, unknown>).lineage_id, "native-lineage");
130
148
  assert.notEqual(proceededDetails.outcome, "native-authority-lock-present");
131
149