gentle-pi 2.4.0 → 2.6.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 (227) hide show
  1. package/README.md +292 -25
  2. package/assets/agents/gentle-ai-worker.md +13 -0
  3. package/assets/agents/jd-fix-agent.md +18 -0
  4. package/assets/agents/jd-judge-a.md +1 -1
  5. package/assets/agents/jd-judge-b.md +1 -1
  6. package/assets/agents/sdd-apply.md +7 -5
  7. package/assets/agents/sdd-archive.md +5 -3
  8. package/assets/agents/sdd-design.md +4 -0
  9. package/assets/agents/sdd-explore.md +4 -0
  10. package/assets/agents/sdd-init.md +4 -0
  11. package/assets/agents/sdd-onboard.md +4 -0
  12. package/assets/agents/sdd-proposal.md +4 -0
  13. package/assets/agents/sdd-remediate.md +37 -0
  14. package/assets/agents/sdd-research.md +26 -3
  15. package/assets/agents/sdd-spec.md +4 -0
  16. package/assets/agents/sdd-status.md +9 -75
  17. package/assets/agents/sdd-sync.md +4 -0
  18. package/assets/agents/sdd-tasks.md +4 -0
  19. package/assets/agents/sdd-verify.md +5 -3
  20. package/assets/chains/sdd-full.chain.md +4 -0
  21. package/assets/chains/sdd-plan.chain.md +4 -0
  22. package/assets/chains/sdd-verify.chain.md +4 -0
  23. package/assets/migrations/managed-assets-v2.5.0.json +7 -0
  24. package/assets/orchestrator-delegation.md +39 -11
  25. package/assets/orchestrator.md +5 -5
  26. package/assets/sdd-orchestrator-workflow.md +54 -21
  27. package/assets/support/sdd-status-contract.md +34 -90
  28. package/contracts/telemetry/runtime-aggregate-v1.schema.json +65 -0
  29. package/docs/delegated-verification.md +25 -0
  30. package/docs/telemetry.md +94 -0
  31. package/docs/windows-startup-console-visibility.md +18 -0
  32. package/extensions/ask-user-choice.ts +159 -25
  33. package/extensions/codegraph-tools.ts +95 -5
  34. package/extensions/gentle-agents.ts +1337 -0
  35. package/extensions/gentle-ai.ts +2916 -386
  36. package/extensions/gentle-shell.ts +650 -0
  37. package/extensions/gentle-todo.ts +234 -0
  38. package/extensions/quiet-tools.ts +2 -1
  39. package/extensions/runtime-metrics.ts +130 -0
  40. package/extensions/sdd-init.ts +2 -2
  41. package/extensions/startup-banner.ts +52 -75
  42. package/lib/agent-profiles.ts +550 -0
  43. package/lib/agents-completion-delivery.ts +72 -0
  44. package/lib/agents-config.ts +315 -0
  45. package/lib/agents-history.ts +88 -0
  46. package/lib/agents-messaging.ts +187 -0
  47. package/lib/agents-protocol.ts +501 -0
  48. package/lib/agents-runner.ts +1012 -0
  49. package/lib/agents-thread-view.ts +57 -0
  50. package/lib/agents-transcript.ts +87 -0
  51. package/lib/agents-view-layout.ts +40 -0
  52. package/lib/agents-view.ts +914 -0
  53. package/lib/agents-widget.ts +241 -0
  54. package/lib/gentle-ai-binary.ts +3 -1
  55. package/lib/gentle-ai-renderer.ts +143 -25
  56. package/lib/native-choice-list.ts +194 -0
  57. package/lib/native-fullscreen-interaction.ts +47 -0
  58. package/lib/native-pointer-region.ts +164 -0
  59. package/lib/native-review-cli.ts +371 -13
  60. package/lib/orchestrator-presence.ts +337 -0
  61. package/lib/profiles-orchestrator.ts +203 -0
  62. package/lib/review-candidate-view-owner.ts +427 -0
  63. package/lib/review-candidate-view.ts +150 -48
  64. package/lib/review-consent-component.ts +247 -0
  65. package/lib/review-consent-ui.ts +110 -0
  66. package/lib/review-host-relay.ts +28 -0
  67. package/lib/review-integration-v2.ts +243 -11
  68. package/lib/review-last-event-controller.ts +8 -4
  69. package/lib/review-relay-contract.ts +11 -0
  70. package/lib/review-reminder-receipt.ts +74 -0
  71. package/lib/review-repository.ts +2 -2
  72. package/lib/review-risk-assessment.ts +339 -0
  73. package/lib/review-session-standing-permission-ipc.ts +309 -0
  74. package/lib/review-session-standing-permission.ts +240 -0
  75. package/lib/runtime-metrics-children.ts +199 -0
  76. package/lib/runtime-metrics-delivery.ts +68 -0
  77. package/lib/runtime-metrics-native.ts +166 -0
  78. package/lib/runtime-metrics-pi-identity.ts +113 -0
  79. package/lib/runtime-metrics-policy.ts +51 -0
  80. package/lib/runtime-metrics.ts +255 -0
  81. package/lib/sdd-preflight.ts +362 -81
  82. package/lib/sdd-research-capabilities.ts +228 -0
  83. package/lib/sdd-status.ts +29 -7
  84. package/lib/session-worktree-registry.ts +118 -0
  85. package/lib/shell-bar.ts +184 -0
  86. package/lib/shell-card.ts +133 -0
  87. package/lib/shell-changes-view.ts +530 -0
  88. package/lib/shell-changes.ts +290 -0
  89. package/lib/shell-gauge.ts +40 -0
  90. package/lib/shell-prompt.ts +115 -0
  91. package/lib/shell-sidebar-banner.ts +11 -0
  92. package/lib/shell-sidebar-layout.ts +213 -0
  93. package/lib/shell-sidebar.ts +41 -0
  94. package/lib/shell-todo.ts +297 -0
  95. package/lib/shell-usage-view.ts +76 -0
  96. package/lib/shell-usage.ts +246 -0
  97. package/lib/telemetry-trigger.ts +153 -0
  98. package/package.json +8 -5
  99. package/runtime/gentle-ai-binary.mjs +3 -1
  100. package/runtime/native-review-cli.mjs +370 -12
  101. package/runtime/review-integration-v2.mjs +243 -11
  102. package/runtime/review-relay-contract.mjs +11 -0
  103. package/runtime/review-risk-assessment.mjs +340 -0
  104. package/runtime/telemetry-trigger.mjs +154 -0
  105. package/scripts/build-runtime-modules.mjs +11 -1
  106. package/scripts/check-types.mjs +125 -0
  107. package/scripts/gentle-ai-installer.mjs +10 -10
  108. package/scripts/install-gentle-ai.mjs +12 -0
  109. package/scripts/install-tui-mode-setting.mjs +114 -0
  110. package/scripts/test-packed-runner.mjs +38 -2
  111. package/scripts/types-baseline.json +99 -0
  112. package/scripts/verify-package-files.mjs +8 -2
  113. package/skills/_shared/review-ledger-contract.md +20 -2
  114. package/skills/issue-creation/SKILL.md +3 -3
  115. package/skills/judgment-day/SKILL.md +17 -3
  116. package/skills/judgment-day/references/prompts-and-formats.md +14 -3
  117. package/tests/agent-profiles.test.ts +722 -0
  118. package/tests/agents-completion-delivery.test.ts +94 -0
  119. package/tests/agents-config.test.ts +205 -0
  120. package/tests/agents-fake-child.ts +66 -0
  121. package/tests/agents-grouping.test.ts +179 -0
  122. package/tests/agents-history.test.ts +54 -0
  123. package/tests/agents-integration.test.ts +100 -0
  124. package/tests/agents-messaging.test.ts +94 -0
  125. package/tests/agents-protocol.test.ts +198 -0
  126. package/tests/agents-queries.test.ts +190 -0
  127. package/tests/agents-responsive.test.ts +43 -0
  128. package/tests/agents-runner-process.test.ts +111 -0
  129. package/tests/agents-runner.test.ts +959 -0
  130. package/tests/agents-thread-view.test.ts +45 -0
  131. package/tests/agents-transcript.test.ts +30 -0
  132. package/tests/agents-view.test.ts +685 -0
  133. package/tests/agents-widget.test.ts +141 -0
  134. package/tests/artifact-language.test.ts +25 -2
  135. package/tests/ask-user-choice.test.ts +325 -5
  136. package/tests/asset-installation-runtime.test.ts +108 -0
  137. package/tests/autonomous-guard.test.ts +116 -1
  138. package/tests/codegraph-tools.test.ts +112 -2
  139. package/tests/delegated-key-learnings-contract.test.ts +1 -1
  140. package/tests/devbinary/native-review-parity.devtest.ts +110 -0
  141. package/tests/feature-request-form.test.ts +67 -0
  142. package/tests/fixtures/agents-messaging-child.mjs +5 -0
  143. package/tests/fixtures/agents-process-child.mjs +23 -0
  144. package/tests/fixtures/runtime-metrics-native-batches.json +6 -0
  145. package/tests/gentle-agents.test.ts +2168 -0
  146. package/tests/gentle-ai-binary.test.ts +7 -2
  147. package/tests/gentle-ai-installer.test.ts +47 -47
  148. package/tests/gentle-ai-renderer.test.ts +103 -0
  149. package/tests/gentle-ai.test.ts +971 -15
  150. package/tests/gentle-card-text.ts +35 -0
  151. package/tests/gentle-shell.test.ts +818 -0
  152. package/tests/gentle-todo.test.ts +226 -0
  153. package/tests/install-tui-mode-setting.test.ts +324 -0
  154. package/tests/issue-creation-skill.test.ts +22 -0
  155. package/tests/model-routing-authority.test.ts +12 -0
  156. package/tests/native-choice-list.test.ts +202 -0
  157. package/tests/native-fullscreen-interaction.test.ts +125 -0
  158. package/tests/native-pointer-region.test.ts +245 -0
  159. package/tests/native-review-capability-contract.test.ts +27 -1
  160. package/tests/native-review-cli.test.ts +317 -3
  161. package/tests/native-review-consent.test.ts +91 -0
  162. package/tests/native-review-parity-runtime.test.ts +8 -2
  163. package/tests/native-review-parity.test.ts +43 -29
  164. package/tests/native-sdd-attempt-authority.test.ts +7 -2
  165. package/tests/orchestrator-budget.test.ts +69 -0
  166. package/tests/orchestrator-presence.test.ts +389 -0
  167. package/tests/orchestrator-rdd-ownership.test.ts +9 -0
  168. package/tests/package-manifest.test.ts +243 -7
  169. package/tests/profiles-orchestrator.test.ts +208 -0
  170. package/tests/quiet-tool-rendering.test.ts +97 -37
  171. package/tests/rdd-aware-verification-contract.test.ts +226 -0
  172. package/tests/rdd-status-line.test.ts +286 -0
  173. package/tests/review-agent-end-preflight.test.ts +332 -24
  174. package/tests/review-candidate-view.test.ts +751 -7
  175. package/tests/review-consent-ui.test.ts +352 -0
  176. package/tests/review-contract-prompt.test.ts +17 -0
  177. package/tests/review-controller-native-recovery.test.ts +29 -4
  178. package/tests/review-controller-native-routing.test.ts +884 -7
  179. package/tests/review-controller-workspace-root.test.ts +45 -2
  180. package/tests/review-controller.test.ts +26 -1
  181. package/tests/review-host-relay-restart-parity.test.ts +142 -1
  182. package/tests/review-host-relay-routing.test.ts +384 -8
  183. package/tests/review-host-relay.test.ts +29 -0
  184. package/tests/review-integration-v2-forward.test.ts +44 -0
  185. package/tests/review-integration-v2.test.ts +276 -0
  186. package/tests/review-last-event-closure.test.ts +112 -3
  187. package/tests/review-ledger-contract.test.ts +61 -6
  188. package/tests/review-relay-contract.test.ts +26 -0
  189. package/tests/review-reminder-receipt.test.ts +62 -0
  190. package/tests/review-repository.test.ts +28 -1
  191. package/tests/review-risk-assessment.test.ts +626 -0
  192. package/tests/review-session-standing-permission-controller.test.ts +656 -0
  193. package/tests/review-session-standing-permission-ipc.test.ts +233 -0
  194. package/tests/review-session-standing-permission-runtime.test.ts +212 -0
  195. package/tests/review-session-standing-permission.test.ts +156 -0
  196. package/tests/runtime-harness.mjs +447 -39
  197. package/tests/runtime-metrics-children.test.ts +206 -0
  198. package/tests/runtime-metrics-delivery.test.ts +85 -0
  199. package/tests/runtime-metrics-extension.test.ts +187 -0
  200. package/tests/runtime-metrics-native.test.ts +209 -0
  201. package/tests/runtime-metrics-pi-identity.test.ts +113 -0
  202. package/tests/runtime-metrics-policy.test.ts +62 -0
  203. package/tests/runtime-metrics.test.ts +184 -0
  204. package/tests/sdd-agent-tools.test.ts +10 -1
  205. package/tests/sdd-execution-routing-contract.test.ts +28 -0
  206. package/tests/sdd-managed-runtime-settlement.test.ts +331 -0
  207. package/tests/sdd-native-managed-uptake.test.ts +253 -0
  208. package/tests/sdd-planning-routing-contract.test.ts +45 -0
  209. package/tests/sdd-preflight.test.ts +252 -8
  210. package/tests/sdd-research-capabilities.test.ts +256 -0
  211. package/tests/sdd-research-live.test.ts +241 -0
  212. package/tests/sdd-selection-transport.test.ts +504 -0
  213. package/tests/sdd-status.test.ts +51 -0
  214. package/tests/session-worktree-registry.test.ts +135 -0
  215. package/tests/shell-bar.test.ts +176 -0
  216. package/tests/shell-card.test.ts +139 -0
  217. package/tests/shell-changes-view.test.ts +609 -0
  218. package/tests/shell-changes.test.ts +350 -0
  219. package/tests/shell-prompt.test.ts +140 -0
  220. package/tests/shell-sidebar-banner.test.ts +23 -0
  221. package/tests/shell-sidebar-layout.test.ts +387 -0
  222. package/tests/shell-sidebar.test.ts +50 -0
  223. package/tests/shell-todo.test.ts +259 -0
  224. package/tests/shell-usage-view.test.ts +62 -0
  225. package/tests/shell-usage.test.ts +197 -0
  226. package/tests/startup-banner.test.ts +126 -0
  227. package/tests/telemetry-trigger.test.ts +351 -0
@@ -36,7 +36,7 @@ const WINDOWS_SYSTEM_ROOT = "C:\\Windows";
36
36
  // version check below) derives from this constant instead of repeating the
37
37
  // literal, so a pin bump cannot leave a stale copy behind. See
38
38
  // scripts/install-gentle-ai.mjs for the incident that motivated this.
39
- export const INSTALLER_VERSION = "2.6.0";
39
+ export const INSTALLER_VERSION = "2.8.0";
40
40
  export const RELEASE_BASE_URL = `https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${INSTALLER_VERSION}/`;
41
41
  export const GENTLE_AI_INSTALL_METHOD = Object.freeze({
42
42
  SIGNED_RELEASE_ASSET: "signed-release-asset",
@@ -45,10 +45,10 @@ export const GENTLE_AI_INSTALL_METHOD = Object.freeze({
45
45
  export const GENTLE_AI_WINDOWS_SOURCE_PACKAGE_PATH = "github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai";
46
46
  export const GENTLE_AI_WINDOWS_SOURCE_MODULE = "github.com/gentleman-programming/gentle-ai/v2";
47
47
  export const GENTLE_AI_WINDOWS_SOURCE_TAG = `v${INSTALLER_VERSION}`;
48
- // `go mod download -json github.com/gentleman-programming/gentle-ai/v2@v2.6.0`
48
+ // `go mod download -json github.com/gentleman-programming/gentle-ai/v2@v2.8.0`
49
49
  // with GOSUMDB=sum.golang.org reports this exact module SumDB checksum, and the
50
- // tag resolves to commit c24a724a, the published v2.6.0 release head.
51
- export const GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:scGoZYnPHh4oCVqlcfQAOSpm22Ii5lmB0kBbiBKvNZk=";
50
+ // tag resolves to commit 890ca948, the published v2.8.0 release head.
51
+ export const GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:QNdrYDxq/Bi08o9PCk0jc4r5YObLdFmRCLXjKMqsze8=";
52
52
  export const GENTLE_AI_WINDOWS_SOURCE_PACKAGE = `${GENTLE_AI_WINDOWS_SOURCE_PACKAGE_PATH}@${GENTLE_AI_WINDOWS_SOURCE_TAG}`;
53
53
  export const GENTLE_AI_WINDOWS_MINIMUM_GO_VERSION = "1.25.10";
54
54
  export const GENTLE_AI_GO_TOOLCHAIN_UNAVAILABLE_CODE = "GENTLE_AI_GO_TOOLCHAIN_UNAVAILABLE";
@@ -67,7 +67,7 @@ export class GentleAiInstallerError extends Error {
67
67
  // Sentinel used while a re-pinned gentle-ai release is not yet published. A
68
68
  // sentinel digest can never match a real SHA-256, so installation fails closed,
69
69
  // and verify-package-files.mjs refuses to pack/publish while any digest below
70
- // still holds it. The v2.6.0 digests are pinned from the published release:
70
+ // still holds it. The v2.8.0 digests are pinned from the published release:
71
71
  // archive sha256 values verified against the minisign-signed checksums.txt and
72
72
  // freshly computed hashes; binary sha256 values computed from the extracted
73
73
  // executables.
@@ -109,15 +109,15 @@ async function downloadPinnedGentleAiAsset(asset, destination, options) {
109
109
  }
110
110
 
111
111
  // Windows is absent from signed release archives on purpose. gentle-ai stopped
112
- // distributing unsigned Windows builds in c4b764d0, so v2.6.0 publishes signed
112
+ // distributing unsigned Windows builds in c4b764d0, so v2.8.0 publishes signed
113
113
  // Darwin/Linux archives only. Windows x64/arm64 uses the separately verified
114
114
  // exact-tag Go SumDB source-build path below; restore archive rows only when
115
115
  // upstream ships signed Windows assets.
116
116
  export const GENTLE_AI_RELEASE_ASSETS = Object.freeze({
117
- "darwin/amd64": asset("gentle-ai_2.6.0_darwin_amd64.tar.gz", "e09389a4fa2de6a1999cf44bb7850d1f8bc166f330010b64c20aaab32bc68cb7", "a142e166a7638b1d9920ec01be2417a0257c52074395ed829bf5b989199b3f03", "gentle-ai"),
118
- "darwin/arm64": asset("gentle-ai_2.6.0_darwin_arm64.tar.gz", "9999842e0ccb769101d51454b714f599535c551cde73411a1f72936ff635c13e", "ddc9ffb6aa64268f8de8ffe80056b58b97e3cf480dea849c38d97d7c2b2618f4", "gentle-ai"),
119
- "linux/amd64": asset("gentle-ai_2.6.0_linux_amd64.tar.gz", "1dbf4e4ebc2b0d0e0f3f003a77ca2cf0fedc7b4d3e5f85939abeb877694630f0", "37e4ef32e869fa181b77346be160dfef35ff6fa40f26723d6dcd705ffb6d385d", "gentle-ai"),
120
- "linux/arm64": asset("gentle-ai_2.6.0_linux_arm64.tar.gz", "9fc43679476486fb234c302c91f8e15fd7d878e43de1104c2ebdddd68baaa95b", "7ff61e615fe861fd1175bb9750b4c15c23dcdfeaa4a7ed0a96d5ec2bdf39e72f", "gentle-ai"),
117
+ "darwin/amd64": asset("gentle-ai_2.8.0_darwin_amd64.tar.gz", "9c735e51916c31135926e62b21ac990216d810907a73894f68ec47bb0648d22d", "3880084f118533102a02eb0656a709db9817d330f82de8f533868667e0ac449d", "gentle-ai"),
118
+ "darwin/arm64": asset("gentle-ai_2.8.0_darwin_arm64.tar.gz", "b62d01aadba484e79869e11878d47e81cd692ebce93a5de454d0889db65fac54", "fed81b2b3dbec02ab5f06ce73364b43d28c532231813a01e2015d585f08cbb2e", "gentle-ai"),
119
+ "linux/amd64": asset("gentle-ai_2.8.0_linux_amd64.tar.gz", "56378fd47cfee127d5982398e79248194d3c7624d268efda9823a6b061a018b7", "df19c4ac20cfdfc0cc0c98c75cda42106340ca9966009f5dfb61575c1ada27c8", "gentle-ai"),
120
+ "linux/arm64": asset("gentle-ai_2.8.0_linux_arm64.tar.gz", "41726bffee269206e5fe96d7bd900164d01f478d8916bdfba446a7991903dfc1", "a93fff44ea583546d37ce833cc2a0f14afec118ae4209c305cafcadb91f67bac", "gentle-ai"),
121
121
  });
122
122
 
123
123
  // A pinned asset is either a signed archive or, for a prerelease pin only,
@@ -4,6 +4,7 @@
4
4
  // v2.1.11 while writing v2.2.0 to disk, which is the one moment an operator
5
5
  // most needs the number to be true.
6
6
  import { INSTALLER_VERSION, installGentleAi } from "./gentle-ai-installer.mjs";
7
+ import { installTuiModeSetting } from "./install-tui-mode-setting.mjs";
7
8
 
8
9
  if (process.env.GENTLE_PI_SKIP_GENTLE_AI_INSTALL === "1") {
9
10
  console.warn("GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1: skipped package-local Gentle AI installation; native review operations will fail with package-local-binary-missing until gentle-pi is reinstalled.");
@@ -16,3 +17,14 @@ if (process.env.GENTLE_PI_SKIP_GENTLE_AI_INSTALL === "1") {
16
17
  process.exitCode = 1;
17
18
  }
18
19
  }
20
+
21
+ // A native failure never changes settings; the explicit native-only skip does.
22
+ if (!process.exitCode) {
23
+ try {
24
+ const result = await installTuiModeSetting();
25
+ if (result.changed) console.log("gentle-pi enabled fullscreen in global Pi settings; /settings can switch back to regular.");
26
+ } catch (error) {
27
+ console.error(`gentle-pi could not enable fullscreen: ${error instanceof Error ? error.message : String(error)}`);
28
+ process.exitCode = 1;
29
+ }
30
+ }
@@ -0,0 +1,114 @@
1
+ import { closeSync, constants, fchmodSync, fsyncSync, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, renameSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { randomUUID } from "node:crypto";
6
+ import { setTimeout as delay } from "node:timers/promises";
7
+
8
+ function inspect(path) {
9
+ try { return lstatSync(path); }
10
+ catch (error) { if (error.code === "ENOENT") return undefined; throw error; }
11
+ }
12
+
13
+ function sameFile(left, right) {
14
+ return left && right && left.dev === right.dev && left.ino === right.ino;
15
+ }
16
+
17
+ function assertDirectories(paths) {
18
+ for (const path of paths) {
19
+ const stat = inspect(path);
20
+ if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync(path) !== path) {
21
+ throw new Error(`Unsafe fullscreen settings installation path: ${path}`);
22
+ }
23
+ }
24
+ }
25
+
26
+ function readSettings(path) {
27
+ const before = inspect(path);
28
+ if (!before) return { stat: undefined, text: undefined, value: {} };
29
+ if (!before.isFile() || before.isSymbolicLink()) throw new Error("settings.json must be a regular, non-symlink file");
30
+ const fd = openSync(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
31
+ try {
32
+ if (!sameFile(before, fstatSync(fd))) throw new Error("settings.json changed while opening");
33
+ const text = readFileSync(fd, "utf8");
34
+ const value = JSON.parse(text.replace(/^\uFEFF/, ""));
35
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("settings.json must contain a JSON object");
36
+ return { stat: before, text, value };
37
+ } finally { closeSync(fd); }
38
+ }
39
+
40
+ // Pi uses proper-lockfile with realpath:false: its cooperative lock is the
41
+ // settings.json.lock directory. Do not steal stale locks. Keep the synchronous
42
+ // critical section below shorter than proper-lockfile's default stale window.
43
+ async function acquireLock(path) {
44
+ for (let attempt = 0; attempt < 10; attempt++) {
45
+ try {
46
+ mkdirSync(path, { mode: 0o700 });
47
+ return inspect(path);
48
+ } catch (error) {
49
+ if (error.code !== "EEXIST") throw error;
50
+ if (attempt === 9) throw new Error("Fullscreen settings lock is busy; retry installation when other settings writers finish");
51
+ await delay(20);
52
+ }
53
+ }
54
+ }
55
+
56
+ /** Only physically owned global Pi npm or exact Git installs may mutate Pi settings.
57
+ * Atomic rename protects readers from partial JSON, not arbitrary writers or
58
+ * malicious same-user ancestor swaps. No lifecycle cwd or store symlink grants ownership.
59
+ */
60
+ export async function installTuiModeSetting(options = {}) {
61
+ const env = options.env ?? process.env;
62
+ const requestedHome = resolve(env.GENTLE_PI_AGENT_HOME || env.PI_CODING_AGENT_DIR || join(options.home ?? homedir(), ".pi", "agent"));
63
+ const packageRoot = resolve(options.packageRoot ?? dirname(dirname(fileURLToPath(import.meta.url))));
64
+ let home;
65
+ try { home = realpathSync(requestedHome); }
66
+ catch (error) { if (error.code === "ENOENT") return { changed: false, recognized: false }; throw error; }
67
+ const installations = [
68
+ {
69
+ packageRoot: join(home, "npm", "node_modules", "gentle-pi"),
70
+ paths: [home, join(home, "npm"), join(home, "npm", "node_modules"), join(home, "npm", "node_modules", "gentle-pi")],
71
+ },
72
+ {
73
+ packageRoot: join(home, "git", "github.com", "Gentleman-Programming", "gentle-pi"),
74
+ paths: [home, join(home, "git"), join(home, "git", "github.com"), join(home, "git", "github.com", "Gentleman-Programming"), join(home, "git", "github.com", "Gentleman-Programming", "gentle-pi")],
75
+ },
76
+ ];
77
+ // Canonical agent-home aliases (including macOS /var) are supported.
78
+ // pnpm's physical store, npm links, and Git aliases are not owned global installs.
79
+ const installation = installations.find(({ packageRoot: expected }) => realpathSync(packageRoot) === expected);
80
+ if (!installation) return { changed: false, recognized: false };
81
+ assertDirectories(installation.paths);
82
+ const settingsPath = join(home, "settings.json");
83
+ const lockPath = `${settingsPath}.lock`;
84
+ const lock = await acquireLock(lockPath);
85
+ const started = Date.now();
86
+ let staging;
87
+ try {
88
+ assertDirectories(installation.paths);
89
+ const original = readSettings(settingsPath);
90
+ if (original.value.tuiMode === "fullscreen") return { changed: false, recognized: true };
91
+ staging = join(home, `.settings-fullscreen-${randomUUID()}.tmp`);
92
+ const fd = openSync(staging, "wx", original.stat ? original.stat.mode & 0o777 : 0o600);
93
+ try {
94
+ if (original.stat) fchmodSync(fd, original.stat.mode & 0o777);
95
+ writeFileSync(fd, `${JSON.stringify({ ...original.value, tuiMode: "fullscreen" }, null, 2)}\n`, "utf8");
96
+ fsyncSync(fd);
97
+ } finally { closeSync(fd); }
98
+ assertDirectories(installation.paths);
99
+ const latest = readSettings(settingsPath);
100
+ if (latest.text !== original.text || (original.stat ? !sameFile(original.stat, latest.stat) : latest.stat !== undefined)) {
101
+ throw new Error("settings.json changed concurrently; retry installation");
102
+ }
103
+ if (!sameFile(lock, inspect(lockPath)) || Date.now() - started >= 5000) throw new Error("Fullscreen settings lock ownership expired; retry installation");
104
+ renameSync(staging, settingsPath);
105
+ staging = undefined;
106
+ return { changed: true, recognized: true };
107
+ } finally {
108
+ // Only clean our own artifacts while the original parent remains canonical.
109
+ if (realpathSync(home) === home) {
110
+ if (staging) unlinkSync(staging);
111
+ if (sameFile(lock, inspect(lockPath))) rmdirSync(lockPath);
112
+ }
113
+ }
114
+ }
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import assert from "node:assert/strict";
3
4
  import { execFileSync } from "node:child_process";
4
5
  import { createHash } from "node:crypto";
5
6
  import { existsSync, mkdtempSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
@@ -11,6 +12,10 @@ const root = fileURLToPath(new URL("..", import.meta.url));
11
12
  const temporary = mkdtempSync(join(tmpdir(), "gentle-pi-packed-runner-"));
12
13
  const packDirectory = join(temporary, "pack");
13
14
  const installDirectory = join(temporary, "install");
15
+ // Every child inherits only disposable Pi homes, never the operator's settings.
16
+ const agentHome = join(temporary, "agent");
17
+ const piAgentHome = join(temporary, "pi-agent");
18
+ const isolatedEnv = { ...process.env, GENTLE_PI_AGENT_HOME: agentHome, PI_CODING_AGENT_DIR: piAgentHome };
14
19
 
15
20
  function windowsNpmInvocation() {
16
21
  const candidates = [];
@@ -31,12 +36,16 @@ function windowsNpmInvocation() {
31
36
 
32
37
  function runNpm(arguments_, options) {
33
38
  const invocation = process.platform === "win32" ? windowsNpmInvocation() : { file: "npm", prefix: [] };
34
- return execFileSync(invocation.file, [...invocation.prefix, ...arguments_], options);
39
+ return execFileSync(invocation.file, [...invocation.prefix, ...arguments_], { ...options, env: isolatedEnv });
35
40
  }
36
41
 
37
42
  try {
38
43
  mkdirSync(packDirectory);
39
44
  mkdirSync(installDirectory);
45
+ mkdirSync(agentHome);
46
+ mkdirSync(piAgentHome);
47
+ const originalSettings = '{ "tuiMode": "regular", "theme": "packed-fixture" }\n';
48
+ writeFileSync(join(agentHome, "settings.json"), originalSettings);
40
49
  const packed = JSON.parse(runNpm(["pack", "--ignore-scripts", "--json", "--pack-destination", packDirectory], {
41
50
  cwd: root,
42
51
  encoding: "utf8",
@@ -49,13 +58,40 @@ try {
49
58
  cwd: installDirectory,
50
59
  stdio: "inherit",
51
60
  });
61
+ // This is an ordinary npm consumer, not Pi's managed global npm directory.
62
+ assert.equal(readFileSync(join(agentHome, "settings.json"), "utf8"), originalSettings);
63
+ assert.deepEqual(readdirSync(agentHome), ["settings.json"]);
64
+ assert.deepEqual(readdirSync(piAgentHome), []);
65
+ assert.equal(existsSync(join(installDirectory, ".pi", "settings.json")), false);
52
66
  const packageRoot = join(installDirectory, "node_modules", "gentle-pi");
67
+ assert.ok(existsSync(join(packageRoot, "scripts", "install-tui-mode-setting.mjs")));
68
+ const { nativeReviewAbandonAuthorization } = await import(pathToFileURL(join(packageRoot, "runtime", "native-review-cli.mjs")).href);
69
+ const abandonAuthorization = nativeReviewAbandonAuthorization({
70
+ lineage: "review-abc",
71
+ expectedRevision: "revision-9",
72
+ snapshotIdentity: "snapshot-1",
73
+ capturedLensResults: ["00-risk.json", "01-refuter.json"],
74
+ findingsPresent: true,
75
+ actor: "maintainer",
76
+ reason: "operator_disposition",
77
+ });
78
+ assert.equal(abandonAuthorization, [
79
+ "gentle-ai.review-abandon-authorization/v2",
80
+ "lineage=review-abc",
81
+ "revision=revision-9",
82
+ "snapshot_identity=snapshot-1",
83
+ "reason=operator_disposition",
84
+ "captured_lens_results=00-risk.json,01-refuter.json",
85
+ "findings_present=true",
86
+ "actor=maintainer",
87
+ ].join("\n"));
88
+ assert.ok(!abandonAuthorization.includes("evidence_records_present"));
53
89
  // Accept prerelease pins too: a stable-only pattern here was a second,
54
90
  // silent pin that refused the first prerelease version directory.
55
91
  const versions = readdirSync(join(packageRoot, ".gentle-ai"), { withFileTypes: true }).filter((entry) => entry.isDirectory() && /^v\d+\.\d+\.\d+(?:-[0-9A-Za-z][0-9A-Za-z.]*)?$/.test(entry.name));
56
92
  if (versions.length !== 1) throw new Error("packed install did not contain exactly one package-local Gentle AI version");
57
93
  const executable = join(packageRoot, ".gentle-ai", versions[0].name, process.platform === "win32" ? "gentle-ai.exe" : "gentle-ai");
58
- const capabilities = JSON.parse(execFileSync(executable, ["review", "capabilities", "--contract", "gentle-ai.review-integration/v2"], { cwd: installDirectory, encoding: "utf8" }));
94
+ const capabilities = JSON.parse(execFileSync(executable, ["review", "capabilities", "--contract", "gentle-ai.review-integration/v2"], { cwd: installDirectory, encoding: "utf8", env: isolatedEnv }));
59
95
  // Decode with the PACKED consumer's own decoder rather than comparing the
60
96
  // schema string against a list hand-copied into this script. The copy was a
61
97
  // second, silent pin: it accepted only `capabilities/v2`, so the moment the
@@ -0,0 +1,99 @@
1
+ {
2
+ "note": "Recorded TypeScript diagnostics. Regenerate with `node scripts/check-types.mjs --update` after fixing or deliberately accepting diagnostics. This file may only shrink without a review decision.",
3
+ "total": 205,
4
+ "byFileAndCode": {
5
+ "extensions/codegraph-tools.ts TS2339": 1,
6
+ "extensions/codegraph-tools.ts TS2345": 1,
7
+ "extensions/gentle-agents.ts TS2322": 3,
8
+ "extensions/gentle-ai.ts TS2322": 5,
9
+ "extensions/gentle-ai.ts TS2339": 11,
10
+ "extensions/gentle-ai.ts TS2345": 15,
11
+ "extensions/gentle-ai.ts TS2365": 1,
12
+ "extensions/gentle-ai.ts TS2488": 2,
13
+ "extensions/gentle-ai.ts TS2554": 1,
14
+ "extensions/gentle-ai.ts TS2740": 1,
15
+ "extensions/gentle-shell.ts TS2556": 1,
16
+ "extensions/quiet-tools.ts TS2339": 1,
17
+ "extensions/quiet-tools.ts TS2352": 2,
18
+ "lib/agents-messaging.ts TS2322": 1,
19
+ "lib/native-review-cli.ts TS2304": 6,
20
+ "lib/native-review-cli.ts TS2339": 1,
21
+ "lib/native-review-cli.ts TS2345": 1,
22
+ "lib/review-candidate-view.ts TS2353": 2,
23
+ "lib/review-compact-contract.ts TS2322": 2,
24
+ "lib/review-compact-contract.ts TS2365": 1,
25
+ "lib/review-integration-v2.ts TS2322": 2,
26
+ "lib/review-integration-v2.ts TS2352": 2,
27
+ "lib/review-publication-gate.ts TS2365": 2,
28
+ "lib/review-transaction.ts TS2322": 1,
29
+ "lib/review-transaction.ts TS2345": 1,
30
+ "lib/runtime-metrics-children.ts TS2345": 2,
31
+ "lib/sdd-preflight.ts TS2352": 1,
32
+ "lib/sdd-preflight.ts TS2365": 1,
33
+ "lib/shell-sidebar-layout.ts TS2341": 1,
34
+ "tests/agents-queries.test.ts TS2322": 1,
35
+ "tests/agents-queries.test.ts TS2345": 3,
36
+ "tests/agents-runner-process.test.ts TS2322": 1,
37
+ "tests/devbinary/native-review-parity.devtest.ts TS2339": 1,
38
+ "tests/devbinary/pi-host-relay.devtest.ts TS2339": 3,
39
+ "tests/gentle-agents.test.ts TS2339": 1,
40
+ "tests/gentle-agents.test.ts TS2352": 2,
41
+ "tests/gentle-ai-binary.test.ts TS2339": 2,
42
+ "tests/gentle-ai-installer.test.ts TS2339": 7,
43
+ "tests/gentle-ai-installer.test.ts TS2556": 1,
44
+ "tests/gentle-ai-renderer.test.ts TS2345": 6,
45
+ "tests/gentle-ai.test.ts TS2339": 1,
46
+ "tests/gentle-ai.test.ts TS2352": 8,
47
+ "tests/gentle-ai.test.ts TS2353": 1,
48
+ "tests/gentle-shell.test.ts TS2352": 1,
49
+ "tests/gentle-shell.test.ts TS2540": 1,
50
+ "tests/gentle-shell.test.ts TS2554": 1,
51
+ "tests/maintainer/provider-relay.maintest.ts TS2339": 17,
52
+ "tests/maintainer/provider-relay.maintest.ts TS2345": 1,
53
+ "tests/maintainer/provider-relay.maintest.ts TS2540": 2,
54
+ "tests/native-binary-gate.test.ts TS2339": 2,
55
+ "tests/native-review-consent.test.ts TS2554": 1,
56
+ "tests/native-review-parity-runtime.test.ts TS2339": 1,
57
+ "tests/quiet-tool-rendering.test.ts TS2339": 1,
58
+ "tests/quiet-tool-rendering.test.ts TS2345": 1,
59
+ "tests/review-agent-end-preflight.test.ts TS2339": 2,
60
+ "tests/review-agent-end-preflight.test.ts TS2345": 1,
61
+ "tests/review-candidate-view.test.ts TS2353": 4,
62
+ "tests/review-candidate-view.test.ts TS2540": 2,
63
+ "tests/review-candidate-view.test.ts TS2554": 2,
64
+ "tests/review-controller-native-recovery.test.ts TS2345": 1,
65
+ "tests/review-controller-native-routing.test.ts TS2339": 2,
66
+ "tests/review-controller-workspace-root.test.ts TS2322": 2,
67
+ "tests/review-correction-lifecycle.test.ts TS2339": 4,
68
+ "tests/review-gate.test.ts TS2322": 5,
69
+ "tests/review-gate.test.ts TS2345": 4,
70
+ "tests/review-gate.test.ts TS2740": 1,
71
+ "tests/review-graph-schema.test.ts TS2352": 2,
72
+ "tests/review-host-relay-routing.test.ts TS2345": 1,
73
+ "tests/review-host-relay-routing.test.ts TS2739": 1,
74
+ "tests/review-integration-v2-forward.test.ts TS2322": 1,
75
+ "tests/review-last-event-closure.test.ts TS2322": 1,
76
+ "tests/review-policy-judgment-day.test.ts TS2345": 1,
77
+ "tests/review-policy-ordinary.test.ts TS2345": 1,
78
+ "tests/review-policy-ordinary.test.ts TS2554": 1,
79
+ "tests/review-risk-assessment.test.ts TS2345": 1,
80
+ "tests/review-risk-assessment.test.ts TS2352": 1,
81
+ "tests/review-session-standing-permission-controller.test.ts TS2339": 1,
82
+ "tests/review-session-standing-permission-controller.test.ts TS2345": 1,
83
+ "tests/review-session-standing-permission-controller.test.ts TS2352": 1,
84
+ "tests/review-session-standing-permission-ipc.test.ts TS2322": 4,
85
+ "tests/review-test-fixtures.ts TS2739": 1,
86
+ "tests/review-transaction.test.ts TS2339": 1,
87
+ "tests/runtime-metrics-extension.test.ts TS2345": 1,
88
+ "tests/sdd-preflight.test.ts TS2352": 1,
89
+ "tests/sdd-preflight.test.ts TS2554": 2,
90
+ "tests/sdd-research-capabilities.test.ts TS2339": 1,
91
+ "tests/sdd-research-capabilities.test.ts TS2698": 1,
92
+ "tests/sdd-research-live.test.ts TS2322": 1,
93
+ "tests/shell-sidebar-layout.test.ts TS2339": 1,
94
+ "tests/shell-sidebar-layout.test.ts TS2345": 1,
95
+ "tests/shell-usage-view.test.ts TS2322": 1,
96
+ "tests/skill-registry.test.ts TS2345": 5,
97
+ "tests/writer-edit-surface-scope.test.ts TS2352": 1
98
+ }
99
+ }
@@ -30,6 +30,7 @@ const requiredPaths = [
30
30
  "assets/agents/sdd-init.md",
31
31
  "assets/agents/sdd-onboard.md",
32
32
  "assets/agents/sdd-proposal.md",
33
+ "assets/agents/sdd-remediate.md",
33
34
  "assets/agents/sdd-research.md",
34
35
  "assets/agents/sdd-spec.md",
35
36
  "assets/agents/sdd-status.md",
@@ -46,6 +47,7 @@ const requiredPaths = [
46
47
  "assets/support/sdd-status-contract.md",
47
48
  "assets/support/strict-tdd.md",
48
49
  "assets/support/strict-tdd-verify.md",
50
+ "docs/delegated-verification.md",
49
51
  "docs/native-authority-architecture.md",
50
52
  "docs/skill-style-guide.md",
51
53
  "docs/review-integration.md",
@@ -59,10 +61,13 @@ const requiredPaths = [
59
61
  "lib/review-integration-v2.ts",
60
62
  "lib/review-relay-contract.ts",
61
63
  "lib/sdd-preflight.ts",
64
+ "lib/telemetry-trigger.ts",
62
65
  "runtime/gentle-ai-binary.mjs",
63
66
  "runtime/native-review-cli.mjs",
64
67
  "runtime/review-integration-v2.mjs",
68
+ "runtime/review-risk-assessment.mjs",
65
69
  "runtime/review-relay-contract.mjs",
70
+ "runtime/telemetry-trigger.mjs",
66
71
  "scripts/check-provider-contract.mjs",
67
72
  "scripts/gentle-ai-installer.mjs",
68
73
  "scripts/install-gentle-ai.mjs",
@@ -176,6 +181,7 @@ const contractHashes = {
176
181
  "contracts/review-integration/v2/schemas/repair.schema.json": "98a85fd45a8ae7f6211ffeeb3f9c478fa1dd1c17f385751f15f2111e6c3ab167",
177
182
  "contracts/review-integration/v2/schemas/start.schema.json": "2991e3fcca672d9257d61b6a336fb34e58b15a8e03f8a09a7adf892cae6a8085",
178
183
  "contracts/review-integration/v2/schemas/status.schema.json": "c4dcc736cfc6300560a3c4262d2d982368529d5c49d58d499552a3b0beef9212",
184
+ "contracts/telemetry/runtime-aggregate-v1.schema.json": "26be905d39fe8274e049e1270553695b7540a3b24571d42eb7d96c5a7deb48b5",
179
185
  "docs/review-integration.md": "95a3df92785bc4d9f3b99e702aaf817ae0440bd16c83218d2c3f2aca67c280fb",
180
186
  };
181
187
 
@@ -334,7 +340,7 @@ async function main() {
334
340
  });
335
341
 
336
342
  if (driftedContracts.length > 0) {
337
- console.error("gentle-pi packaged review-integration/v1 and review-integration/v2 contract bytes drifted from the pinned v2.6.0 runtime's vendored Gentle AI contract artifacts:");
343
+ console.error("gentle-pi packaged review-integration/v1 and review-integration/v2 contract bytes drifted from the pinned v2.8.0 runtime's vendored Gentle AI contract artifacts:");
338
344
  for (const drift of driftedContracts) console.error(`- ${drift.relativePath}: expected ${drift.expected}, got ${drift.actual}`);
339
345
  process.exit(1);
340
346
  }
@@ -379,7 +385,7 @@ async function main() {
379
385
  process.exit(1);
380
386
  }
381
387
 
382
- console.log(`gentle-pi package resource check passed (${requiredPaths.length} files; ${Object.keys(contractHashes).length} exact byte-pinned contract artifacts for the v2.6.0 runtime).`);
388
+ console.log(`gentle-pi package resource check passed (${requiredPaths.length} files; ${Object.keys(contractHashes).length} exact byte-pinned contract artifacts for the v2.8.0 runtime).`);
383
389
  }
384
390
 
385
391
  const isMainModule = process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href;
@@ -20,7 +20,9 @@ Risk routing is deterministic:
20
20
 
21
21
  Generated files matching `testdata/golden/**` remain in snapshot identity but do not count as authored risk lines. Ordinary tests, fixtures, and snapshots are never broadly excluded. The correction budget is frozen as `min(200, ceil(original_changed_lines / 2))`.
22
22
 
23
- Before status/START, consult effective review mode. `off` creates no authority or authorization and yields organic `disabled/unmanaged`, never approval. Ordinary START declares `--consent relay`; low risk stays silent. A medium/high `consent/v2` result always returns the complete raw provider envelope plus an opaque in-memory candidate binding to the parent, then stops without UI or provider follow-up. The parent localizes and presents it losslessly while preserving tokens, commands, target IDs, and invocations. One explicit `answer-consent` call accepts only that binding and `granted|declined`, consumes it before provider mutation, and rechecks repository/target/projection/lineage/answer binding. Ambiguity reconciles through STATUS, never replay. Grant is exact-candidate-only. Decline creates no lineage, authority, actor/candidate binding, latch, or pending authorization; the next candidate asks again. Old Pi clone latch files are inert.
23
+ Before status/START, consult effective review mode. `off` creates no authority or authorization and yields organic `disabled/unmanaged`, never approval. Ordinary START declares `--consent relay`; low risk stays silent. A medium/high `consent/v3` result carries the complete raw two-choice provider envelope plus an opaque in-memory candidate binding. In an eligible interactive parent Pi session, the host displays both provider labels and effects unchanged plus one clearly separate host-owned action: **Run this review and allow reviews for this Pi session**. The first two actions stay candidate-only. Direct human selection of the third action executes that fresh envelope's exact existing `granted` invocation through `answer-consent`, then grants only future fresh validated envelopes for the same live SessionManager object, exact nonempty session ID, and canonical Git worktree root. Every envelope is consumed once before provider mutation and rechecks repository, target, projection, lineage, answer binding, and live session identity; ambiguity reconciles through STATUS and never replays.
24
+
25
+ The host grant lives only in a schema-checked `globalThis[Symbol.for(...)]` WeakMap registry. Reload preserves the SessionManager and reconnects the grant; quit, new, resume, fork, explicit revoke, or process restart removes it. `/tree` retains it. Child-agent processes, headless/RPC/unsupported UI, explicit cross-repository `workspaceRoot`, model prose, and tool arguments cannot offer, create, or consume it. It grants no provider mode, verdict, cost forecast, acknowledgement, maintenance, delivery, or cross-repository authority. If host UI is cancelled, fails, or cannot prove current Git/session identity, the original unresolved provider envelope is returned unchanged. If that envelope reaches the parent, localize and present its original two choices losslessly; never append the host action to the decoded provider contract. Decline creates no lineage, authority, standing grant, latch, or pending authorization; the next candidate asks again. Old Pi clone latch files are inert, and Pi writes no asked latch.
24
26
 
25
27
  Reviewer, refuter, and validator verdicts are admitted natively, never Pi-authored. `finalize` follows the provider's negotiated `next_transition` and supplies only the negotiated collection answers: a lens `review.capture-result` collect input rendered with `--agent=pi --materialize=true` is satisfied by the gentle-pi host relay, which prints the exact Go-materialized opaque prompt, launches a fresh locked-down print-mode `pi` subprocess in an empty scratch directory with every discovery surface disabled, and submits the untouched raw output bytes through the provider-owned submission form. The adversarial roles do not go through that relay: `review.capture-refuter` and `review.capture-validation` collect inputs render as self-contained authority-advancing vectors (binding tokens plus `--agent=pi --execute=true`, no submission descriptor); executing the exact rendered invocation makes Go materialize the role prompt, spawn its own locked-down `pi` process, and admit the raw verdict. Native Go owns validation, canonicalization, missing lens/finding ID assignment, persistence, and hashing, and performs only the legal transition from the current compact state. The five states are `reviewing`, `correction_required`, `validating`, `approved`, and `escalated`.
26
28
 
@@ -77,7 +79,7 @@ Dangerous-command confirmation/safety and destructive-review-maintenance consent
77
79
 
78
80
  ## Judgment Day
79
81
 
80
- Judgment Day starts only when explicitly requested and replaces ordinary review for that lineage.
82
+ Judgment Day is independent: it neither enables nor replaces ordinary review; a separately requested ordinary review remains independent.
81
83
 
82
84
  Judgment Day starts with exactly two blind judges and zero refuters.
83
85
 
@@ -85,4 +87,20 @@ Judgment Day alone may iterate discovery and scoped re-judgment, for at most two
85
87
 
86
88
  Findings surviving round two escalate; no third-round transition exists.
87
89
 
90
+ A standalone `jd-fix-agent` dispatch requires no graph-v1 or native review lineage and is accepted only with this exact Markdown shape. The correction batch contains only one round (`1 of 2` or `2 of 2`) and one lowercase SHA-256. The exact frozen finding rows are one JSON object per line, use only the canonical row fields, and exactly match the authorized IDs.
91
+
92
+ ```markdown
93
+ ## Judgment Day activation
94
+ User explicitly requested Judgment Day.
95
+ ## Exact authorized severe IDs
96
+ - `JD-A-001`
97
+ ## Judgment Day correction batch
98
+ Round: 1 of 2.
99
+ Frozen ledger SHA-256: `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`
100
+ ## Exact frozen finding rows
101
+ {"id":"JD-A-001","lens":"judgment-day","location":"path/to/authorized-file.ts:1","severity":"CRITICAL","status_at_freeze":"open","evidence_class":"deterministic","evidence_claim":"Concrete user-impact claim supported by the frozen location."}
102
+ ## Allowed edit surfaces
103
+ path/to/authorized-file.ts
104
+ ```
105
+
88
106
  Judgment Day stays mutable on graph-v1. Its reducer, replay, object-store, lock, snapshot, and graph receipt-validation dependencies remain live even though ordinary authority is native.
@@ -46,7 +46,7 @@ LABEL_ARGS+=(--label "$LABEL") # Repeat only for each permitted discovered label
46
46
  gh issue list --repo "$TARGET" --state all --search "$QUERY" --limit 1000
47
47
  ```
48
48
 
49
- If results are saturated or completeness is uncertain, narrow the read-only search or stop. Comment on a confirmed duplicate instead of creating one. Before commenting on a confirmed duplicate, perform the same privacy scan/redaction on the exact comment body as for publication.
49
+ The agent must complete the duplicate search proactively and retain evidence of its result. If results are saturated or completeness is uncertain, narrow the read-only search or stop. Comment on a confirmed duplicate instead of creating one. Before commenting on a confirmed duplicate, perform the same privacy scan/redaction on the exact comment body as for publication.
50
50
  2. Select one repository-provided form only when its declared purpose matches. If multiple forms match and policy does not distinguish them, stop and request that decision.
51
51
  3. For a YAML form, read its schema and establish controls in declared order. Support only `input`, `textarea`, `dropdown`, and `checkboxes`. Markdown controls are non-answer guidance: honor their visible instructions when collecting and materializing adjacent answers, but do not render them as response sections. Fail closed before mutation on malformed, unsupported, missing, or ambiguous required structure or answers. A malformed schema, or missing or ambiguous required answers, fail closed: do not open a browser or mutate. A browser handoff is available only when the user explicitly requests browser completion or a syntactically valid selected form cannot safely/faithfully be represented by the automated path; otherwise report why automation is unsafe and stop.
52
52
 
@@ -54,7 +54,7 @@ LABEL_ARGS+=(--label "$LABEL") # Repeat only for each permitted discovered label
54
54
  | --- | --- |
55
55
  | `input` / `textarea` | Preserve the visible label. Require an answer when `validations.required` is true; otherwise render `_No response_`. |
56
56
  | `dropdown` | Preserve visible labels and options. Require exact selected option text; single-select has one selection, and multi-select preserves selections in declared options order. A required dropdown needs at least one valid selection; an optional dropdown with no selection renders `_No response_`. |
57
- | `checkboxes` | Preserve the visible label and every option as `- [x]` or `- [ ]` in declared order. Enforce individually required checkboxes and require explicit first-person affirmation for first-person option text. |
57
+ | `checkboxes` | Preserve the visible label and every option as `- [x]` or `- [ ]` in declared order. Enforce individually required checkboxes. For agent-verifiable operational options, proactively complete the action and mark it only with retained evidence; the agent may explicitly attest only its own evidence-backed work and must not attribute its actions to the user. Personal facts, consent, legal declarations, and other first-person user assertions require explicit user affirmation; require explicit first-person affirmation for such user declarations. Do not blanket-check checkboxes: a request to publish does not affirm any checkbox. |
58
58
 
59
59
  For each answer, render `### <visible label>` followed by its materialized value. For `textarea.attributes.render`, fence the answer with the declared language and a fence long enough for its content. Never invent answers, selections, confirmations, or labels.
60
60
 
@@ -62,7 +62,7 @@ A Markdown template may be completed only from known evidence into the same priv
62
62
 
63
63
  ## Review And Publication
64
64
 
65
- Before the single create attempt, review the target, title, selected form or permitted fallback, exact body, and permitted labels. Perform a privacy scan immediately before publication: replace private project names, usernames, hostnames, home paths, credentials, and private network addresses with useful placeholders without removing reproduction structure.
65
+ Before the single create attempt, review the target, title, selected form or permitted fallback, exact body, and permitted labels. The agent must complete the privacy scan/redaction of the exact body immediately before publication and retain evidence of it: replace private project names, usernames, hostnames, home paths, credentials, and private network addresses with useful placeholders without removing reproduction structure.
66
66
 
67
67
  Create one owner-only temporary directory outside the repository for both private files; restrict it to the current user and clean up both files on every exit/outcome:
68
68
 
@@ -11,12 +11,10 @@ metadata:
11
11
 
12
12
  Load this skill only when the user explicitly requests Judgment Day, Judgement Day, dual/adversarial review, or an equivalent trigger. Resolve one exact target before starting.
13
13
 
14
- Judgment Day is a standalone developer tool: judges run whenever asked, on any runtime, and need no review transaction, runtime identity, or delivery-receipt machinery to start. It neither enables nor replaces an ordinary 4R lifecycle; a separately requested ordinary review remains independent.
14
+ Judgment Day is a standalone developer tool: judges run whenever asked, on any runtime, and need no review transaction, runtime identity, or delivery-receipt machinery to start. Judgment Day is independent: it neither enables nor replaces ordinary review; a separately requested ordinary review remains independent.
15
15
 
16
16
  Judgment Day starts only when explicitly requested. It does not start, configure, or consume ordinary review for that lineage.
17
17
 
18
- Historical compatibility note (obsolete): Judgment Day starts only when explicitly requested and replaces ordinary review for that lineage. Current behavior is the independent lifecycle above.
19
-
20
18
  ## Transaction Rules
21
19
 
22
20
  Judgment Day starts with exactly two blind judges and zero refuters.
@@ -57,6 +55,22 @@ WARNING and SUGGESTION candidates become one-time informational rows and never s
57
55
 
58
56
  ## Fix Boundary
59
57
 
58
+ A standalone `jd-fix-agent` dispatch requires no graph-v1 or native review lineage and is accepted only as one standalone agent with this exact Markdown shape. The `## Judgment Day activation` section contains only `User explicitly requested Judgment Day.`. The parent replaces the example ID, frozen ledger hash, row data, and surface with controller-authorized values. The correction batch contains only one round (`1 of 2` or `2 of 2`) and one lowercase SHA-256. The exact frozen finding rows are one JSON object per line, use only the canonical row fields, and exactly match the authorized IDs.
59
+
60
+ ```markdown
61
+ ## Judgment Day activation
62
+ User explicitly requested Judgment Day.
63
+ ## Exact authorized severe IDs
64
+ - `JD-A-001`
65
+ ## Judgment Day correction batch
66
+ Round: 1 of 2.
67
+ Frozen ledger SHA-256: `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`
68
+ ## Exact frozen finding rows
69
+ {"id":"JD-A-001","lens":"judgment-day","location":"path/to/authorized-file.ts:1","severity":"CRITICAL","status_at_freeze":"open","evidence_class":"deterministic","evidence_claim":"Concrete user-impact claim supported by the frozen location."}
70
+ ## Allowed edit surfaces
71
+ path/to/authorized-file.ts
72
+ ```
73
+
60
74
  Fix only the exact controller-authorized severe IDs in the one supplied batch.
61
75
 
62
76
  Do not add findings, alter frozen claims, authorize transitions, deliver, publish, or start another actor.
@@ -11,7 +11,7 @@ You are one of two blind Judgment Day judges. Stay read-only and work independen
11
11
  ## Skills to load before work
12
12
  {matching SKILL.md paths}
13
13
 
14
- Judgment Day starts only when explicitly requested and replaces ordinary review for that lineage.
14
+ Judgment Day is independent: it neither enables nor replaces ordinary review; a separately requested ordinary review remains independent.
15
15
 
16
16
  Judgment Day starts with exactly two blind judges and zero refuters.
17
17
 
@@ -55,10 +55,21 @@ Do not put `summary`, `skill_resolution`, prose, or orchestration metadata insid
55
55
  ## Fix Agent Prompt
56
56
 
57
57
  ```markdown
58
- You are a surgical Judgment Day fix agent.
58
+ You are a surgical Judgment Day fix agent. This standalone dispatch requires no graph-v1 or native review lineage.
59
59
 
60
+ Use this exact runtime-accepted dispatch shape. The `## Judgment Day activation` section contains only `User explicitly requested Judgment Day.`. The parent replaces the example ID, frozen ledger hash, row data, and surface with controller-authorized values. The correction batch contains only one round (`1 of 2` or `2 of 2`) and one lowercase SHA-256. The exact frozen finding rows are one JSON object per line, use only the canonical row fields, and exactly match the authorized IDs.
61
+
62
+ ## Judgment Day activation
63
+ User explicitly requested Judgment Day.
60
64
  ## Exact authorized severe IDs
61
- {frozen IDs and exact rows}
65
+ - `JD-A-001`
66
+ ## Judgment Day correction batch
67
+ Round: 1 of 2.
68
+ Frozen ledger SHA-256: `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`
69
+ ## Exact frozen finding rows
70
+ {"id":"JD-A-001","lens":"judgment-day","location":"path/to/authorized-file.ts:1","severity":"CRITICAL","status_at_freeze":"open","evidence_class":"deterministic","evidence_claim":"Concrete user-impact claim supported by the frozen location."}
71
+ ## Allowed edit surfaces
72
+ path/to/authorized-file.ts
62
73
 
63
74
  ## Skills to load before work
64
75
  {matching SKILL.md paths}