gentle-pi 2.2.0 → 2.3.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 (130) hide show
  1. package/README.md +51 -80
  2. package/assets/agents/review-readability.md +0 -2
  3. package/assets/agents/review-reliability.md +0 -2
  4. package/assets/agents/review-resilience.md +0 -2
  5. package/assets/agents/review-risk.md +0 -2
  6. package/assets/agents/sdd-apply.md +5 -3
  7. package/assets/agents/sdd-proposal.md +2 -0
  8. package/assets/agents/sdd-research.md +54 -0
  9. package/assets/agents/sdd-status.md +4 -4
  10. package/assets/agents/sdd-tasks.md +2 -3
  11. package/assets/agents/sdd-verify.md +21 -1
  12. package/assets/chains/sdd-full.chain.md +1 -1
  13. package/assets/chains/sdd-verify.chain.md +1 -1
  14. package/assets/orchestrator-delegation.md +54 -248
  15. package/assets/orchestrator-memory.md +2 -0
  16. package/assets/orchestrator.md +22 -38
  17. package/assets/sdd-orchestrator-workflow.md +30 -37
  18. package/assets/support/sdd-status-contract.md +7 -7
  19. package/contracts/review-integration/v1/schemas/transition-execution.schema.json +42 -0
  20. package/contracts/review-integration/v2/schemas/last-event-closure.schema.json +66 -0
  21. package/contracts/review-integration/v2/schemas/opencode-provider-role.schema.json +14 -0
  22. package/docs/native-authority-architecture.md +9 -11
  23. package/docs/review-integration.md +27 -373
  24. package/extensions/ask-user-choice.ts +151 -0
  25. package/extensions/gentle-ai.ts +1778 -3673
  26. package/extensions/quiet-tools.ts +515 -32
  27. package/extensions/sdd-init.ts +4 -8
  28. package/lib/gentle-ai-renderer.ts +70 -0
  29. package/lib/model-routing-authority.ts +133 -0
  30. package/lib/native-review-cli.ts +372 -940
  31. package/lib/opaque-pi-reviewer-adapter.ts +284 -0
  32. package/lib/review-candidate-view.ts +341 -132
  33. package/lib/review-host-relay.ts +210 -68
  34. package/lib/review-integration-v2.ts +839 -307
  35. package/lib/review-last-event-controller.ts +35 -0
  36. package/lib/sdd-preflight.ts +177 -66
  37. package/lib/sdd-status.ts +66 -111
  38. package/lib/terminal-theme.ts +1 -1
  39. package/package.json +83 -82
  40. package/runtime/gentle-ai-binary.mjs +1 -1
  41. package/runtime/native-review-cli.mjs +322 -890
  42. package/runtime/review-integration-v2.mjs +789 -257
  43. package/runtime/review-relay-contract.mjs +1 -1
  44. package/scripts/{build-git-commit-transaction-runner.mjs → build-runtime-modules.mjs} +4 -5
  45. package/scripts/gentle-ai-installer.mjs +75 -22
  46. package/scripts/maintainer/provider-relay-matrix.mjs +195 -11
  47. package/scripts/test-packed-runner.mjs +4 -7
  48. package/scripts/verify-package-files.mjs +12 -13
  49. package/skills/_shared/review-ledger-contract.md +8 -14
  50. package/skills/chained-pr/SKILL.md +3 -0
  51. package/skills/cognitive-doc-design/SKILL.md +1 -1
  52. package/skills/comment-writer/SKILL.md +1 -1
  53. package/skills/gentle-ai/SKILL.md +7 -74
  54. package/skills/judgment-day/SKILL.md +5 -7
  55. package/skills/rdd-defect-workflow/SKILL.md +3 -3
  56. package/skills/release/SKILL.md +3 -3
  57. package/skills/skill-registry/SKILL.md +1 -1
  58. package/skills/work-unit-commits/SKILL.md +3 -1
  59. package/tests/artifact-language.test.ts +24 -11
  60. package/tests/ask-user-choice.test.ts +264 -0
  61. package/tests/codegraph-tools.test.ts +3 -3
  62. package/tests/crosslane/cross-lane.mjs +15 -1168
  63. package/tests/delegated-key-learnings-contract.test.ts +8 -6
  64. package/tests/devbinary/native-review-parity.devtest.ts +167 -250
  65. package/tests/devbinary/pi-host-relay.devtest.ts +867 -0
  66. package/tests/fixtures/devbinary/last-event-capture-correction-plan.captured.json +10 -0
  67. package/tests/fixtures/devbinary/last-event-capture-refuter-approved.captured.json +20 -0
  68. package/tests/fixtures/devbinary/last-event-capture-refuter-correction-required.captured.json +26 -0
  69. package/tests/fixtures/devbinary/last-event-capture-result-approved.captured.json +8 -0
  70. package/tests/fixtures/devbinary/last-event-capture-result-correction-required.captured.json +26 -0
  71. package/tests/fixtures/devbinary/last-event-capture-validation-approved.captured.json +8 -0
  72. package/tests/fixtures/devbinary/last-event-closure.provenance.md +13 -0
  73. package/tests/fixtures/devbinary/review-acknowledged-v1.captured.json +9 -0
  74. package/tests/fixtures/devbinary/review-acknowledged.provenance.md +31 -0
  75. package/tests/fixtures/devbinary/start-v3-zero-lens-closed.captured.json +21 -0
  76. package/tests/fixtures/native-review-cli/v2.5.0-rc.1/PROVENANCE.txt +15 -0
  77. package/tests/gentle-ai-binary.test.ts +83 -13
  78. package/tests/gentle-ai-dev-binary.test.ts +51 -228
  79. package/tests/gentle-ai-installer.test.ts +137 -47
  80. package/tests/gentle-ai.test.ts +820 -131
  81. package/tests/gentle-theme.test.ts +133 -0
  82. package/tests/maintainer/provider-relay.maintest.ts +340 -4
  83. package/tests/model-routing-authority.test.ts +257 -0
  84. package/tests/native-review-capability-contract.test.ts +28 -1
  85. package/tests/native-review-cli.test.ts +586 -962
  86. package/tests/native-review-consent.test.ts +150 -66
  87. package/tests/native-review-parity-runtime.test.ts +80 -359
  88. package/tests/native-review-parity.test.ts +674 -925
  89. package/tests/opaque-pi-reviewer-adapter.test.ts +266 -0
  90. package/tests/orchestrator-budget.test.ts +132 -88
  91. package/tests/orchestrator-rdd-ownership.test.ts +103 -0
  92. package/tests/package-manifest.test.ts +37 -35
  93. package/tests/provider-defect-handoff.test.ts +15 -118
  94. package/tests/quiet-tool-rendering.test.ts +1055 -28
  95. package/tests/review-authority-recovery-docs.test.ts +1 -2
  96. package/tests/review-candidate-view.test.ts +409 -3
  97. package/tests/review-compact-contract.test.ts +4 -30
  98. package/tests/review-controller-lock-status.test.ts +2 -2
  99. package/tests/review-controller-native-recovery.test.ts +363 -1450
  100. package/tests/review-controller-native-routing.test.ts +1251 -5642
  101. package/tests/review-controller-retired-ops.test.ts +1 -1
  102. package/tests/review-controller-workspace-root.test.ts +222 -71
  103. package/tests/review-controller.test.ts +26 -816
  104. package/tests/review-corrected-finalize-binding.test.ts +112 -153
  105. package/tests/review-dispatch-hydration-gap.test.ts +1 -53
  106. package/tests/review-gate.test.ts +0 -45
  107. package/tests/review-host-relay-restart-parity.test.ts +360 -0
  108. package/tests/review-host-relay-routing.test.ts +117 -82
  109. package/tests/review-host-relay.test.ts +242 -8
  110. package/tests/review-integration-v2-forward.test.ts +576 -553
  111. package/tests/review-integration-v2.test.ts +239 -165
  112. package/tests/review-last-event-closure.test.ts +408 -0
  113. package/tests/review-ledger-contract.test.ts +97 -35
  114. package/tests/review-recovered-lineage-routing.test.ts +0 -47
  115. package/tests/review-relay-transport-agent.test.ts +119 -46
  116. package/tests/review-snapshot.test.ts +3 -2
  117. package/tests/runtime-harness.mjs +361 -196
  118. package/tests/sdd-agent-tools.test.ts +36 -0
  119. package/tests/sdd-preflight.test.ts +81 -15
  120. package/tests/sdd-status.test.ts +109 -110
  121. package/tests/skill-collision-prefixes.test.ts +5 -8
  122. package/tests/writer-edit-surface-scope.test.ts +230 -0
  123. package/themes/Gentleman-Cute.json +94 -0
  124. package/themes/Gentleman-Sexy.json +92 -0
  125. package/lib/git-commit-transaction.ts +0 -861
  126. package/runtime/git-commit-transaction.mjs +0 -862
  127. package/scripts/run-git-commit-transaction.mjs +0 -35
  128. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status-engram.json +0 -139
  129. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status.json +0 -200
  130. package/tests/git-commit-transaction.test.ts +0 -530
@@ -0,0 +1,103 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import test from "node:test";
5
+
6
+ const ROOT = join(import.meta.dirname, "..");
7
+ const ASSETS = join(ROOT, "assets");
8
+ const BOUNDARY =
9
+ "Gentle AI dynamically supplies runtime-specific RDD instructions via generated Pi APPEND_SYSTEM composition. Follow only those exact native instructions; if absent or unsupported, this package does not invent or fall back.";
10
+
11
+ function read(relativePath: string): string {
12
+ return readFileSync(join(ROOT, relativePath), "utf8");
13
+ }
14
+
15
+ const core = read("assets/orchestrator.md");
16
+ const delegation = read("assets/orchestrator-delegation.md");
17
+ const staticPrompts = `${core}\n${delegation}`;
18
+
19
+ test("static prompts omit stale native RDD lifecycle mirrors", () => {
20
+ for (const marker of [
21
+ "Authority-First Terminal Procedure",
22
+ "reconcile-terminal-mirrors",
23
+ "Native Bounded Review Orchestration",
24
+ "Continue after a stop reason code",
25
+ "gentle-ai review status",
26
+ "next_transition",
27
+ "start -> finalize -> validate",
28
+ "review.capture-result",
29
+ "review.validate",
30
+ "reviewGate.result",
31
+ ]) {
32
+ assert.ok(!staticPrompts.includes(marker), `stale RDD marker remains: ${marker}`);
33
+ }
34
+ });
35
+
36
+ test("lossless blocking prompts route every closed single-select envelope through the native closed tool", () => {
37
+ for (const clause of [
38
+ "For every strictly closed single-select envelope",
39
+ "ask_user_choice",
40
+ "envelope-owned canonical option token as opaque `value`",
41
+ "returns exactly one `value`",
42
+ "externally owned open/free-text questionnaire",
43
+ "never for a closed domain",
44
+ "exact captured provider-owned choice invocation",
45
+ ]) {
46
+ assert.ok(delegation.includes(clause), `lossless prompt is missing: ${clause}`);
47
+ }
48
+ });
49
+
50
+ test("static prompts declare one dynamic Gentle AI RDD ownership boundary", () => {
51
+ assert.equal(staticPrompts.split(BOUNDARY).length - 1, 1, "expected one dynamic RDD ownership boundary");
52
+ assert.ok(core.includes(BOUNDARY), "the Pi parent prompt owns the single boundary");
53
+ assert.ok(!delegation.includes(BOUNDARY), "generic delegation detail must not gain RDD text");
54
+ });
55
+
56
+ test("rendered parent prompt keeps the RDD boundary while omitting lifecycle mirrors", async () => {
57
+ const { __testing } = await import("../extensions/gentle-ai.ts");
58
+ const rendered = __testing.getOrchestratorPrompt();
59
+ assert.ok(rendered.includes(BOUNDARY));
60
+ for (const marker of ["Authority-First Terminal Procedure", "reconcile-terminal-mirrors", "next_transition"]) {
61
+ assert.ok(!rendered.includes(marker), `rendered parent prompt leaked: ${marker}`);
62
+ }
63
+ assert.ok(Buffer.byteLength(rendered, "utf8") <= 8192, "the rendered parent prompt must stay below the reduced 8 KiB budget");
64
+ });
65
+
66
+ test("static prompts retain normal SDD and delegated-work guidance", () => {
67
+ for (const heading of ["## SDD Workflow (lazy-loaded)", "## Memory Contract"]) {
68
+ assert.ok(core.includes(heading), `core lost ${heading}`);
69
+ }
70
+ for (const heading of [
71
+ "### Delegation Rules",
72
+ "#### Background Subagent Policy",
73
+ "#### Allowed edit surfaces (MANDATORY)",
74
+ "### 3. SDD (optional)",
75
+ ]) {
76
+ assert.ok(delegation.includes(heading), `delegation lost ${heading}`);
77
+ }
78
+ });
79
+
80
+ test("always-on parent prompt requires a narrow writer edit surface before launch", () => {
81
+ assert.match(core, /Before launching (?:a )?bounded writer/i);
82
+ assert.match(core, /`gentle-ai-worker`/);
83
+ assert.match(core, /`worker`/);
84
+ assert.match(core, /## Allowed edit surfaces/);
85
+ assert.match(core, /repository-relative/i);
86
+ assert.match(core, /never `\.`|never a bare repository root/i);
87
+ assert.match(core, /do not ask the human to author paths or globs/i);
88
+ });
89
+
90
+ test("review integration documents the opaque Pi adapter and Go-owned authority boundary", () => {
91
+ const docs = read("docs/review-integration.md");
92
+ for (const marker of [
93
+ "Buffer → Buffer/error",
94
+ "exact Go-issued materialize/submission tokens",
95
+ "typed Pi transport refusal fails closed",
96
+ "Go owns worktree, lineage, candidate freeze, lens selection, correction, validator, approval burn, and review semantics",
97
+ "Delivery commands remain ordinary repository-policy operations.",
98
+ "package has no durable receipt or policy authority",
99
+ "static assets intentionally omit lifecycle instructions",
100
+ ]) {
101
+ assert.ok(docs.includes(marker), `review integration doc is missing: ${marker}`);
102
+ }
103
+ });
@@ -114,10 +114,10 @@ test("package verification names the native review runtime boundary and packaged
114
114
  const manifest = readPackageJson();
115
115
 
116
116
  assert.ok(manifest.files?.includes("lib/"), "the published package must include the native review runtime module directory");
117
- assert.ok(manifest.files?.includes("runtime/"), "the published package must include the generated JavaScript transaction runtime");
117
+ assert.ok(manifest.files?.includes("runtime/"), "the published package must include generated JavaScript runtime modules");
118
118
  assert.match(verifier, /"lib\/native-review-cli\.ts"/, "package verification must require the native review adapter from the packaged runtime");
119
- assert.match(verifier, /"runtime\/git-commit-transaction\.mjs"/, "package verification must require the installed JavaScript transaction runtime");
120
- assert.match(verifier, /build-git-commit-transaction-runner\.mjs.*--check/s, "package verification must reject generated-runtime drift");
119
+ assert.match(verifier, /"runtime\/native-review-cli\.mjs"/, "package verification must require the generated native review adapter");
120
+ assert.match(verifier, /build-runtime-modules\.mjs.*--check/s, "package verification must reject generated-runtime drift");
121
121
  assert.match(verifier, /"tests\/fixtures\/native-review-cli\/v2\.1\.3\/start\.json"/, "package verification must retain the pinned native decoder fixture");
122
122
  assert.match(
123
123
  readFileSync(join(PACKAGE_ROOT, "extensions", "gentle-ai.ts"), "utf8"),
@@ -187,36 +187,31 @@ test("npm publication is bound to the exact package tag and triggering commit",
187
187
  assert.doesNotMatch(releaseSkill, /--ref "\$\{tag\}"|-f dist-tag=/);
188
188
  });
189
189
 
190
- test("publication gate is isolated from graph-v1 authority storage", () => {
190
+ test("Pi delivery relay is absent from the packaged extension", () => {
191
191
  const extension = readFileSync(join(PACKAGE_ROOT, "extensions", "gentle-ai.ts"), "utf8");
192
- const gate = readFileSync(join(PACKAGE_ROOT, "lib", "review-publication-gate.ts"), "utf8");
193
- const transaction = readFileSync(join(PACKAGE_ROOT, "lib", "review-transaction.ts"), "utf8");
194
192
 
195
- assert.match(extension, /from "\.\.\/lib\/review-publication-gate\.ts"/);
196
- assert.match(transaction, /from "\.\/review-publication-gate\.ts"/);
197
- assert.doesNotMatch(gate, /review-(?:transaction|object-store|graph-schema|lock|snapshot)/);
198
- assert.doesNotMatch(transaction, /export function evaluateReleaseFastPathV1|export function resolveConfiguredPushDestinationV1/);
193
+ assert.doesNotMatch(extension, /review-publication-gate/);
199
194
  });
200
195
 
201
- test("installed commit transaction runner loads JavaScript only and has deterministic build checks", () => {
196
+ test("generated runtime modules and packed-package checks are deterministic", () => {
202
197
  const packageJson = readPackageJson();
203
- const runner = readFileSync(join(PACKAGE_ROOT, "scripts", "run-git-commit-transaction.mjs"), "utf8");
198
+ const generator = readFileSync(join(PACKAGE_ROOT, "scripts", "build-runtime-modules.mjs"), "utf8");
204
199
  const packedRunner = readFileSync(join(PACKAGE_ROOT, "scripts", "test-packed-runner.mjs"), "utf8");
205
200
  const ci = readFileSync(join(PACKAGE_ROOT, ".github", "workflows", "ci.yml"), "utf8");
206
- assert.equal(packageJson.scripts?.["build:transaction-runner"], "node scripts/build-git-commit-transaction-runner.mjs --write");
207
- assert.equal(packageJson.scripts?.["check:transaction-runner"], "node scripts/build-git-commit-transaction-runner.mjs --check");
208
- assert.equal(packageJson.scripts?.["test:packed-runner"], "node scripts/test-packed-runner.mjs");
209
- assert.match(packageJson.scripts?.prepublishOnly ?? "", /pnpm run test:packed-runner/);
210
- assert.match(ci, /pnpm run test:packed-runner/);
201
+ assert.equal(packageJson.scripts?.["build:runtime-modules"], "node scripts/build-runtime-modules.mjs --write");
202
+ assert.equal(packageJson.scripts?.["check:runtime-modules"], "node scripts/build-runtime-modules.mjs --check");
203
+ assert.equal(packageJson.scripts?.["test:packed-package"], "node scripts/test-packed-runner.mjs");
204
+ assert.match(packageJson.scripts?.prepublishOnly ?? "", /pnpm run test:packed-package/);
205
+ assert.match(ci, /pnpm run check:runtime-modules/);
206
+ assert.match(ci, /pnpm run test:packed-package/);
207
+ assert.match(generator, /Generated by scripts\/build-runtime-modules\.mjs/);
211
208
  assert.match(packedRunner, /\["install"[^\]]*"--ignore-scripts=false"/s, "packed install must explicitly enable postinstall");
212
209
  assert.doesNotMatch(packedRunner, /\["install"[^\]]*"--ignore-scripts"(?!\=false)/s);
213
210
  assert.match(packedRunner, /execFileSync\("where\.exe", \["npm"\]/);
214
211
  assert.match(packedRunner, /could not resolve npm-cli\.js without a command shell/);
215
212
  assert.doesNotMatch(packedRunner, /ComSpec|cmd\.exe/);
216
213
  assert.match(packedRunner, /review", "capabilities", "--contract", "gentle-ai\.review-integration\/v2"/);
217
- assert.match(runner, /\.\.\/runtime\/git-commit-transaction\.mjs/);
218
- assert.doesNotMatch(runner, /\.ts["']/);
219
- assert.doesNotMatch(runner, /experimental-strip-types/);
214
+ assert.doesNotMatch(packedRunner, /git-commit-transaction|transaction runner/i);
220
215
  });
221
216
 
222
217
  test("package manifest ships and runs the checked-in package-local Gentle AI installer", () => {
@@ -266,20 +261,20 @@ test("package manifest installs pi-pretty through a wrapper without bundling nat
266
261
  );
267
262
  });
268
263
 
269
- test("package verification binds the published Gentle AI v2.4.0 runtime pin", () => {
264
+ test("package verification binds the published Gentle AI v2.5.0 runtime pin", () => {
270
265
  const installer = readFileSync(join(PACKAGE_ROOT, "scripts", "gentle-ai-installer.mjs"), "utf8");
271
266
  const binary = readFileSync(join(PACKAGE_ROOT, "lib", "gentle-ai-binary.ts"), "utf8");
272
267
  const verifier = readFileSync(join(PACKAGE_ROOT, "scripts", "verify-package-files.mjs"), "utf8");
273
268
 
274
- assert.match(installer, /INSTALLER_VERSION = "2\.4\.0"/);
269
+ assert.match(installer, /INSTALLER_VERSION = "2\.5\.0"/);
275
270
  assert.match(installer, /GENTLE_AI_WINDOWS_SOURCE_PACKAGE.*GENTLE_AI_WINDOWS_SOURCE_MODULE/);
276
- assert.match(installer, /GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:XKkcy\+t76cyUKQnRwL1UnqHbhh8o416I8HQ1UsdvWSI="/);
271
+ assert.match(installer, /GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:0nvTLJFAf9ruBDwTvi\+aDrWt\/dt\/GKvUP2cFVB6c2DI="/);
277
272
  assert.match(installer, /GOTOOLCHAIN: "local"/);
278
273
  assert.match(installer, /GOSUMDB: "sum\.golang\.org"/);
279
274
  assert.match(binary, /GENTLE_AI_VERSION = INSTALLER_VERSION/);
280
275
  assert.match(binary, /GO_SUMDB_SOURCE_BUILD/);
281
276
  assert.match(binary, /GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM/);
282
- assert.match(verifier, /v2\.4\.0/);
277
+ assert.match(verifier, /v2\.5\.0/);
283
278
  });
284
279
 
285
280
 
@@ -981,6 +976,10 @@ test("gentle-ai-worker packages the exact scoped writer contract", () => {
981
976
  const contextContract = readMarkdownSection(source, "Context contract");
982
977
  assert.match(contextContract, /pre-existing untracked targets explicitly listed by the parent/);
983
978
  assert.match(contextContract, /new files required by the delegated task/);
979
+ assert.match(contextContract, /derived candidate set the human can approve or narrow/);
980
+ assert.match(contextContract, /never an open request for the human to author paths or globs/);
981
+ assert.match(interactionContract, /closed set the human can approve, decline, or select from/);
982
+ assert.match(interactionContract, /never ask the human to author paths, globs, identifiers, or commands as free text/);
984
983
 
985
984
  const implementationRules = readMarkdownSection(source, "Implementation rules");
986
985
  assert.match(implementationRules, /`blocked` only for a non-human technical blocker/);
@@ -1129,7 +1128,7 @@ test("bounded implementation routing uses the same explicit fallback in both pol
1129
1128
  );
1130
1129
  });
1131
1130
 
1132
- test("orchestrator routes generic roles without reusing SDD or review agents", () => {
1131
+ test("orchestrator routes generic roles without static RDD lens routing", () => {
1133
1132
  for (const file of ["orchestrator.md", "orchestrator-delegation.md"]) {
1134
1133
  const routing = readFileSync(join(PACKAGE_ROOT, "assets", file), "utf8");
1135
1134
  assert.match(routing, /generic non-SDD exploration[\s\S]*`gentle-ai-explore`/);
@@ -1139,12 +1138,16 @@ test("orchestrator routes generic roles without reusing SDD or review agents", (
1139
1138
  );
1140
1139
  assert.match(routing, /generic non-SDD (?:technical )?verification[\s\S]*`gentle-ai-verify`/);
1141
1140
  assert.match(routing, /SDD roles stay inside SDD|Use `sdd-explore` and `sdd-verify` only inside SDD/);
1142
- assert.match(routing, /review lenses inside reviews|Use review lenses only inside explicit review transactions/);
1143
- assert.match(routing, /(?:truly local )?read-only check(?:ing)? of (?:known )?1-3 known files|1-3-file read-only check/);
1141
+ assert.match(routing, /(?:truly local )?read-only check(?:ing)? of (?:known )?1[-–]3 known files|1[-–]3-file read-only check/);
1144
1142
  assert.match(routing, /(?:verification that |verification commands →).*executes? or delegates?|executing\/delegating verification commands/);
1145
1143
  assert.match(routing, /missing(?: or |\/)unusable[\s\S]*native `Agent`[\s\S]*(?:the )?same read-only/);
1146
1144
  assert.match(routing, /report (?:the )?fallback/);
1145
+ assert.doesNotMatch(routing, /review lenses? (?:inside|only inside)|review lens routing/i);
1147
1146
  }
1147
+
1148
+ const core = readFileSync(join(PACKAGE_ROOT, "assets", "orchestrator.md"), "utf8");
1149
+ assert.match(core, /Gentle AI dynamically supplies runtime-specific RDD instructions/);
1150
+ assert.match(core, /this package does not invent or fall back/);
1148
1151
  });
1149
1152
 
1150
1153
  test("pi-pretty wrapper uses real package path resolution for pnpm symlink installs", () => {
@@ -1160,9 +1163,9 @@ test("pi-pretty wrapper uses real package path resolution for pnpm symlink insta
1160
1163
  assert.match(wrapper, /quietToolsEnabled/);
1161
1164
  });
1162
1165
 
1163
- test("v2.2.0 release package and runtime stop before publication", () => {
1166
+ test("v2.3.0 release package and runtime stop before publication", () => {
1164
1167
  const packageJson = readPackageJson();
1165
- assert.equal(packageJson.version, "2.2.0", "the release manifest must remain explicitly pinned to v2.2.0");
1168
+ assert.equal(packageJson.version, "2.3.0", "the release manifest must remain explicitly pinned to v2.3.0");
1166
1169
  assert.equal(
1167
1170
  packageJson.scripts?.test,
1168
1171
  "node --experimental-strip-types --test tests/*.test.ts && pnpm run check:provider-contract && pnpm run test:harness",
@@ -1192,17 +1195,16 @@ test("bounded review keeps the Judgment Day skill contract at canon metadata ver
1192
1195
  assert.doesNotMatch(frontmatter, /^ version: "1\.4"$/m);
1193
1196
  });
1194
1197
 
1195
- test("README documents bounded review transactions and the honest installed permission boundary", () => {
1198
+ test("README documents dynamic Gentle AI RDD ownership and the installed permission boundary", () => {
1196
1199
  const readme = readFileSync(join(PACKAGE_ROOT, "README.md"), "utf8");
1197
1200
  for (const clause of [
1198
- "New ordinary review uses compact `gentle_review` `start -> finalize -> validate`.",
1199
- "Native compact gate validation is read-only.",
1200
- "Release from protected `main` may bypass receipt validation only when the tag targets the current immutable `origin/main` SHA, required CI for that exact SHA is successful, the remote head is rechecked before tag push, and no fresh risk evidence exists; otherwise release fails closed through native receipt validation.",
1201
+ "Gentle AI dynamically supplies runtime-specific RDD instructions",
1202
+ "does not define an RDD lifecycle",
1201
1203
  "Dangerous-command safety remains independent and authoritative.",
1202
- "Adversarial review roles (the refuter and the targeted validator) are never Pi-authored",
1203
1204
  "package-managed isolated installation",
1204
1205
  "Project and user overrides may shadow a package asset",
1205
1206
  ]) {
1206
- assert.ok(readme.includes(clause), `README missing review v2 clause: ${clause}`);
1207
+ assert.ok(readme.includes(clause), `README missing dynamic RDD clause: ${clause}`);
1207
1208
  }
1209
+ assert.doesNotMatch(readme, /New ordinary review uses compact `gentle_review` `start -> finalize -> validate`\./);
1208
1210
  });
@@ -46,13 +46,6 @@ const DELEGATION_CHOICE1_ORDER = [
46
46
  "execute the shared candidate-scoped continuation below",
47
47
  ] as const;
48
48
 
49
- const SDD_CHOICE1_ORDER = [
50
- "Complete a definitive lookup across open and closed issues",
51
- "Derive the evidence channel only from the installed build string",
52
- "If the installed build predates the relevant published fix",
53
- "perform no further GitHub mutation and no blind retry",
54
- ] as const;
55
-
56
49
  // ---------------------------------------------------------------------------
57
50
  // 1 — assets/orchestrator-delegation.md structural presence
58
51
  // ---------------------------------------------------------------------------
@@ -101,6 +94,12 @@ test("orchestrator-delegation.md states the admissibility-before-relay rule", ()
101
94
  assert.match(DELEGATION, /The test is what produced the failure, not what the work was doing when it happened/i);
102
95
  });
103
96
 
97
+ test("orchestrator-delegation.md excludes local consent lifecycle outcomes from provider-defect reporting", () => {
98
+ assert.match(DELEGATION, /`consent-binding-expired` and `consent-binding-already-consumed` are local lifecycle outcomes, not Gentle AI provider defects/i);
99
+ assert.match(DELEGATION, /An unknown consent binding is reportable only when independent evidence proves a fresh, same-session, unconsumed binding was lost/i);
100
+ assert.match(DELEGATION, /Never infer that evidence from the old combined stale-binding message/i);
101
+ });
102
+
104
103
  test("orchestrator-delegation.md states the never-offer-to-repair rule", () => {
105
104
  assert.match(
106
105
  DELEGATION,
@@ -231,125 +230,23 @@ test("orchestrator-delegation.md does NOT reference the rc.3 canon", () => {
231
230
  });
232
231
 
233
232
  // ---------------------------------------------------------------------------
234
- // 3 — assets/sdd-orchestrator-workflow.md structural presence
233
+ // 3 — SDD points to the single complete handoff contract
235
234
  // ---------------------------------------------------------------------------
236
235
 
237
- test("sdd-orchestrator-workflow.md carries the provider defect handoff section", () => {
236
+ test("sdd-orchestrator-workflow.md points provider defects to the complete delegation contract", () => {
238
237
  assert.match(SDD_WORKFLOW, /## Provider Defect Handoff/);
239
- });
240
-
241
- test("sdd-orchestrator-workflow.md references v2.4.0-rc.8 and the consent/v3 envelope", () => {
242
- assert.match(SDD_WORKFLOW, /v2\.4\.0-rc\.8/);
243
- assert.match(SDD_WORKFLOW, /gentle-ai\.review-integration\.consent\/v3/);
244
- });
245
-
246
- test("sdd-orchestrator-workflow.md lists all three semantic choice tokens in order", () => {
247
- for (const token of CHOICE_TOKENS) {
248
- assert.ok(
249
- SDD_WORKFLOW.includes(`\`${token}\``),
250
- `sdd-orchestrator-workflow.md missing semantic choice token: ${token}`,
251
- );
252
- }
253
-
254
- const positions = CHOICE_TOKENS.map((token) => SDD_WORKFLOW.indexOf(`\`${token}\``));
255
- for (const pos of positions) {
256
- assert.notEqual(pos, -1, "a choice token is missing; ordering assertion is meaningless");
257
- }
258
- assert.ok(
259
- positions[0] < positions[1],
260
- `report_and_continue must appear before continue_without_reporting in sdd-orchestrator-workflow.md; got positions ${positions}`,
261
- );
262
- assert.ok(
263
- positions[1] < positions[2],
264
- `continue_without_reporting must appear before stop_here in sdd-orchestrator-workflow.md; got positions ${positions}`,
265
- );
266
- });
267
-
268
- test("sdd-orchestrator-workflow.md preserves the rc.8 choice-1 ordering on the concise surface", () => {
269
- assertChoice1Order(SDD_WORKFLOW, SDD_CHOICE1_ORDER, "sdd-orchestrator-workflow.md");
270
- });
271
-
272
- test("sdd-orchestrator-workflow.md references the full contract in orchestrator-delegation.md", () => {
273
238
  assert.match(
274
239
  SDD_WORKFLOW,
275
240
  /The full contract lives in `assets\/orchestrator-delegation\.md` under `#### Gentle AI Provider Defect Handoff \(MANDATORY\)`/i,
276
241
  );
277
- // The pointer must resolve: the named heading has to exist on the delegation surface.
278
242
  assert.match(DELEGATION, /^#### Gentle AI Provider Defect Handoff \(MANDATORY\)$/m);
243
+ assert.doesNotMatch(SDD_WORKFLOW, /`report_and_continue`|`continue_without_reporting`|`stop_here`/);
279
244
  });
280
245
 
281
- test("sdd-orchestrator-workflow.md states the rc.8 concise rules", () => {
282
- // admissibility
283
- assert.match(SDD_WORKFLOW, /Classify admissibility before relaying/i);
284
- // never-repair
285
- assert.match(
286
- SDD_WORKFLOW,
287
- /Never offer to switch to, inspect, modify, or directly repair the Gentle AI repository/i,
288
- );
289
- // consent
290
- assert.match(SDD_WORKFLOW, /Ask the user first, in the active conversation language, for explicit consent to report the apparent defect/i);
291
- // privacy
292
- assert.match(SDD_WORKFLOW, /Privacy scrub immediately before the first GitHub operation/i);
293
- // definitive lookup
294
- assert.match(SDD_WORKFLOW, /Complete a definitive lookup across open and closed issues in `Gentleman-Programming\/gentle-ai`/i);
295
- // evidence channel
296
- assert.match(SDD_WORKFLOW, /recognized prerelease tags are `-rc\.` and `-main\.`; every other build is stable/i);
297
- assert.match(SDD_WORKFLOW, /never recommend switching channels/i);
298
- // outdated + regression
299
- assert.match(SDD_WORKFLOW, /If the installed build predates the relevant published fix, recommend installing it and reproducing/i);
300
- assert.match(SDD_WORKFLOW, /treat it as a possible regression/i);
301
- assert.match(SDD_WORKFLOW, /never reopen automatically/i);
302
- // confirmed creation
303
- assert.match(SDD_WORKFLOW, /Confirmed creation requires the GitHub create operation to confirm a newly-created issue identity\/URL/i);
304
- // uncertainty continuation
305
- assert.match(SDD_WORKFLOW, /perform no further GitHub mutation and no blind retry/i);
306
- assert.match(SDD_WORKFLOW, /execute the exact captured provider-owned decline invocation exactly once, validate it, re-enter native negotiated STATUS, and resume the already-held consumer continuation/i);
307
- // exact decline
308
- assert.match(SDD_WORKFLOW, /Both continue choices execute that exact captured decline invocation exactly once/i);
309
- assert.match(SDD_WORKFLOW, /never synthesize the decline command, target, token, or consumer continuation from prose/i);
310
- // scope/mode
311
- assert.match(SDD_WORKFLOW, /Do not invoke `gentle-ai review mode disable` at clone or global scope within this handoff/i);
312
- assert.match(SDD_WORKFLOW, /Do not turn RDD off or on within this handoff/i);
313
- // resume
314
- assert.match(SDD_WORKFLOW, /Resume after an installed published fix or an explicit maintainer-authorized, documented native recovery or reset/i);
315
- assert.match(SDD_WORKFLOW, /Never resume against unpublished code/i);
316
- });
317
-
318
- test("sdd-orchestrator-workflow.md does NOT carry the gentle-report label discipline", () => {
319
- assert.equal(
320
- SDD_WORKFLOW.includes("gentle-report"),
321
- false,
322
- "sdd-orchestrator-workflow.md must not reference the removed gentle-report label",
323
- );
324
- });
325
-
326
- test("sdd-orchestrator-workflow.md does NOT make published fixes the sole resumption route", () => {
327
- assert.equal(
328
- SDD_WORKFLOW.includes("Resume only after an installed published fix"),
329
- false,
330
- "sdd-orchestrator-workflow.md must not state the prohibited sole-resumption route",
331
- );
332
- });
333
-
334
- test("sdd-orchestrator-workflow.md does NOT retain the rc.3 hard-stop that withholds the decline invocation", () => {
335
- assert.equal(
336
- SDD_WORKFLOW.includes("Any report ambiguity or failure is a hard stop: preserve all consumer state and do not execute the decline invocation"),
337
- false,
338
- "sdd-orchestrator-workflow.md must not retain the rc.3 hard-stop wedge",
339
- );
340
- });
341
-
342
- test("both handoff surfaces invoke `gentle-ai review mode disable` exactly once", () => {
343
- // The delegation surface carries the contract inside the canon block, so its
344
- // section is bounded by the following `####` canon heading, not by `## `.
345
- const surfaces = [
346
- ["orchestrator-delegation.md", DELEGATION, /#### Gentle AI Provider Defect Handoff[\s\S]*?(?=\n#### SDD Edit-Authority|$)/],
347
- ["sdd-orchestrator-workflow.md", SDD_WORKFLOW, /## Provider Defect Handoff[\s\S]*?(?=\n## |$)/],
348
- ] as const;
349
- for (const [name, asset, sectionPattern] of surfaces) {
350
- const section = asset.match(sectionPattern)?.[0] ?? "";
351
- assert.ok(section.length > 0, `${name}: provider defect handoff section not found`);
352
- const n = countOccurrences(section, "gentle-ai review mode disable");
353
- assert.equal(n, 1, `${name} must invoke "gentle-ai review mode disable" exactly once; got ${n}`);
354
- }
246
+ test("the complete delegation handoff invokes `gentle-ai review mode disable` exactly once", () => {
247
+ const section = DELEGATION.match(
248
+ /#### Gentle AI Provider Defect Handoff[\s\S]*?(?=\n#### SDD Edit-Authority|$)/,
249
+ )?.[0] ?? "";
250
+ assert.ok(section.length > 0, "orchestrator-delegation.md: provider defect handoff section not found");
251
+ assert.equal(countOccurrences(section, "gentle-ai review mode disable"), 1);
355
252
  });