gentle-pi 4.2.0 → 4.4.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 (334) hide show
  1. package/README.md +340 -138
  2. package/assets/agents/gentle-ai-explore.md +1 -0
  3. package/assets/agents/gentle-ai-verify.md +6 -4
  4. package/assets/agents/gentle-ai-worker.md +7 -1
  5. package/assets/design-canvas/canvas.css +648 -0
  6. package/assets/design-canvas/canvas.js +1497 -0
  7. package/assets/design-canvas/index.html +88 -0
  8. package/assets/design-canvas/inspector.js +290 -0
  9. package/assets/orchestrator-delegation-reference.md +163 -0
  10. package/assets/orchestrator-delegation.md +25 -176
  11. package/assets/orchestrator-tracking.md +1 -1
  12. package/assets/orchestrator-verification.md +14 -8
  13. package/assets/orchestrator-writer.md +5 -1
  14. package/assets/orchestrator.md +11 -11
  15. package/bin/engram-guard +1 -1
  16. package/bin/gentle-shell.mjs +237 -139
  17. package/contracts/review-provider-contract-mirror/provider-contract.lock.json +8 -7
  18. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/README.md +7 -0
  19. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/manifest.json +11 -2
  20. package/contracts/review-provider-contract-mirror/v1.4.0/bundle/routing/pi.md +92 -0
  21. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/generated/provider-capabilities.baseline.json +8 -1
  22. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/generated/provider-roles.baseline.json +1 -1
  23. package/docs/assets/diagrams/agent-orchestration.svg +54 -15
  24. package/docs/assets/diagrams/gentleman-workflow.svg +69 -11
  25. package/docs/assets/diagrams/measured-routing.svg +49 -0
  26. package/docs/assets/diagrams/native-review.svg +52 -12
  27. package/docs/assets/diagrams/odd-workflow.svg +128 -66
  28. package/docs/assets/diagrams/permission-modes.svg +51 -0
  29. package/docs/assets/features/audio-notifications.png +0 -0
  30. package/docs/assets/features/command-palette.png +0 -0
  31. package/docs/bundled-install.md +65 -30
  32. package/docs/delegated-verification.md +16 -8
  33. package/docs/gentle-agents-activity.md +16 -6
  34. package/docs/gentle-music.md +61 -0
  35. package/docs/gentle-shell-uninstall.md +8 -1
  36. package/docs/gentle-shell.md +80 -9
  37. package/docs/install-wizard.md +37 -6
  38. package/docs/permission-modes.md +8 -3
  39. package/docs/readme-reference.md +120 -28
  40. package/docs/session-profile-format.md +26 -0
  41. package/docs/voice.md +259 -0
  42. package/docs/yolo-mode.md +38 -10
  43. package/extensions/ask-user-choice.ts +4 -1
  44. package/extensions/codegraph-tools.ts +68 -6
  45. package/extensions/gentle-agents.ts +270 -48
  46. package/extensions/gentle-ai.ts +490 -113
  47. package/extensions/gentle-design.ts +158 -0
  48. package/extensions/gentle-herdr-activity.ts +2 -3
  49. package/extensions/gentle-music.ts +289 -0
  50. package/extensions/gentle-shell.ts +359 -85
  51. package/extensions/gentle-todo.ts +43 -9
  52. package/extensions/gentle-voice.ts +11 -0
  53. package/extensions/quiet-tools.ts +1 -1
  54. package/extensions/session-scratch.ts +384 -0
  55. package/extensions/skill-registry.ts +63 -8
  56. package/extensions/startup-banner.ts +2 -3
  57. package/lib/agent-home.ts +8 -3
  58. package/lib/agent-profiles.ts +26 -0
  59. package/lib/agents-config.ts +35 -0
  60. package/lib/agents-protocol.ts +60 -1
  61. package/lib/agents-runner.ts +107 -9
  62. package/lib/agents-session-transport.ts +101 -6
  63. package/lib/agents-view.ts +3 -1
  64. package/lib/agents-widget.ts +14 -1
  65. package/lib/auto-permission-memory.ts +48 -18
  66. package/lib/auto-permission-runtime.ts +21 -6
  67. package/lib/bounded-writer-admission.ts +51 -0
  68. package/lib/clipboard-image.ts +147 -0
  69. package/lib/command-palette-catalog.ts +2 -4
  70. package/lib/commit-slice-signal.ts +100 -0
  71. package/lib/context-backstop.ts +120 -0
  72. package/lib/delivered-test-lint.ts +80 -0
  73. package/lib/design-canvas-server.ts +947 -0
  74. package/lib/design-comments.ts +437 -0
  75. package/lib/design-handoffs.ts +313 -0
  76. package/lib/design-open-browser.ts +58 -0
  77. package/lib/design-sources.ts +120 -0
  78. package/lib/destructive-command-guard.ts +120 -9
  79. package/lib/external-editor.ts +31 -0
  80. package/lib/gauge-theme.ts +146 -0
  81. package/lib/gentle-ai-binary.ts +28 -7
  82. package/lib/gentle-design.ts +513 -0
  83. package/lib/gentle-shell-bundled.ts +146 -36
  84. package/lib/gentle-shell-import-pi.ts +233 -0
  85. package/lib/gentle-shell-launcher.ts +154 -15
  86. package/lib/gentle-shell-startup-update.ts +61 -9
  87. package/lib/gentle-shell-uninstall.ts +51 -2
  88. package/lib/herdr-activity.ts +24 -0
  89. package/lib/image-attachments.ts +150 -0
  90. package/lib/inprocess-reviewer.ts +33 -2
  91. package/lib/nan-provider.ts +3 -0
  92. package/lib/native-review-cli.ts +20 -5
  93. package/lib/notification-audio-native.ts +149 -13
  94. package/lib/notification-audio.ts +4 -0
  95. package/lib/notification-pulse-worker.ts +82 -18
  96. package/lib/notification-service.ts +5 -1
  97. package/lib/orchestrator-discovery.ts +5 -1
  98. package/lib/orchestrator-presence.ts +87 -8
  99. package/lib/orchestrator-scope.ts +31 -3
  100. package/lib/orchestrator-state.ts +11 -3
  101. package/lib/permission-mode-policy.ts +2 -2
  102. package/lib/provider-contract-bundle.ts +99 -53
  103. package/lib/review-candidate-view-owner.ts +29 -19
  104. package/lib/review-candidate-view.ts +36 -2
  105. package/lib/review-host-relay.ts +11 -2
  106. package/lib/review-reminder-receipt.ts +24 -1
  107. package/lib/review-risk-assessment.ts +43 -38
  108. package/lib/review-session-standing-permission.ts +3 -1
  109. package/lib/session-profile-append-controller.ts +713 -0
  110. package/lib/session-profile-disk-reader.ts +182 -0
  111. package/lib/session-profile-freeze.ts +30 -1
  112. package/lib/session-profile-persistence.ts +15 -7
  113. package/lib/session-scratch.ts +523 -0
  114. package/lib/session-worktree-registry.ts +7 -0
  115. package/lib/shell-bar.ts +29 -28
  116. package/lib/shell-changes-view.ts +80 -13
  117. package/lib/shell-changes.ts +81 -5
  118. package/lib/shell-gauge.ts +49 -6
  119. package/lib/shell-prompt.ts +4 -4
  120. package/lib/shell-sidebar-layout.ts +26 -6
  121. package/lib/shell-todo.ts +24 -5
  122. package/lib/shell-usage-view.ts +5 -1
  123. package/lib/shell-usage.ts +7 -7
  124. package/lib/verifier-admission.ts +30 -0
  125. package/lib/vim-editor-adapter.ts +11 -8
  126. package/lib/voice-artifacts.ts +188 -0
  127. package/lib/voice-command.ts +576 -0
  128. package/lib/voice-install.ts +455 -0
  129. package/lib/voice-platform.ts +99 -0
  130. package/lib/voice-push-to-talk.ts +262 -0
  131. package/lib/voice-session.ts +460 -0
  132. package/lib/voice-settings.ts +50 -0
  133. package/lib/voice-ui.ts +158 -0
  134. package/lib/yolo-session-policy.ts +58 -22
  135. package/lib/yolo-temp-scratch.ts +69 -0
  136. package/package.json +1 -2
  137. package/runtime/gentle-ai-binary.mjs +28 -7
  138. package/runtime/gentle-shell-bundled.mjs +145 -35
  139. package/runtime/gentle-shell-import-pi.mjs +234 -0
  140. package/runtime/gentle-shell-launcher.mjs +152 -13
  141. package/runtime/gentle-shell-startup-update.mjs +61 -9
  142. package/runtime/gentle-shell-uninstall.mjs +51 -2
  143. package/runtime/native-review-cli.mjs +19 -4
  144. package/runtime/review-risk-assessment.mjs +43 -38
  145. package/scripts/build-runtime-modules.mjs +1 -0
  146. package/scripts/bundled-engram-migration.mjs +119 -0
  147. package/scripts/gentle-ai-installer.mjs +10 -10
  148. package/scripts/installer-downloads.mjs +7 -7
  149. package/scripts/installer-preflight.mjs +5 -3
  150. package/scripts/installer-server.mjs +14 -4
  151. package/scripts/installer-windows.mjs +37 -7
  152. package/scripts/main-channel.mjs +94 -19
  153. package/scripts/pi-update.mjs +34 -6
  154. package/scripts/run-test-suite.mjs +5 -0
  155. package/scripts/verify-package-files.mjs +43 -13
  156. package/scripts/voice-worker.cjs +476 -0
  157. package/skills/design/SKILL.md +110 -0
  158. package/skills/gentle-ai/SKILL.md +3 -3
  159. package/skills/work-unit-commits/SKILL.md +5 -3
  160. package/tests/agent-profiles.test.ts +24 -0
  161. package/tests/agent-risk-escalation.test.ts +37 -10
  162. package/tests/agents-config.test.ts +61 -0
  163. package/tests/agents-fake-child.ts +8 -1
  164. package/tests/agents-protocol.test.ts +32 -0
  165. package/tests/agents-runner.test.ts +485 -7
  166. package/tests/agents-session-transport.test.ts +53 -3
  167. package/tests/ask-user-choice.test.ts +30 -0
  168. package/tests/auto-mode.test.ts +17 -0
  169. package/tests/auto-permission-memory-diagnostics.test.ts +56 -0
  170. package/tests/auto-permission-runtime.test.ts +85 -1
  171. package/tests/autonomous-guard.test.ts +142 -0
  172. package/tests/bounded-writer-admission.test.ts +11 -3
  173. package/tests/bundled-install.test.ts +3 -3
  174. package/tests/card-content-policy.test.ts +19 -9
  175. package/tests/child-safety.test.ts +39 -0
  176. package/tests/clipboard-image.test.ts +114 -0
  177. package/tests/codegraph-tools.test.ts +123 -2
  178. package/tests/command-palette.test.ts +15 -5
  179. package/tests/commit-slice-signal.test.ts +162 -0
  180. package/tests/context-backstop.test.ts +225 -0
  181. package/tests/delegate-for-reason-contract.test.ts +92 -24
  182. package/tests/delivered-test-lint.test.ts +105 -0
  183. package/tests/design-canvas-assets.test.ts +710 -0
  184. package/tests/design-canvas-server.test.ts +1096 -0
  185. package/tests/design-comments.test.ts +201 -0
  186. package/tests/design-handoffs.test.ts +282 -0
  187. package/tests/design-open-browser.test.ts +70 -0
  188. package/tests/design-sources.test.ts +132 -0
  189. package/tests/destructive-command-guard.test.ts +85 -1
  190. package/tests/engram-safety.test.ts +132 -57
  191. package/tests/external-editor.test.ts +84 -0
  192. package/tests/fixtures/primary-session-prompt/gentleman.golden.md +143 -0
  193. package/tests/fixtures/provider-contract-bundle/v1.4.0/README.md +29 -0
  194. package/tests/fixtures/provider-contract-bundle/v1.4.0/manifest.json +83 -0
  195. package/tests/fixtures/provider-contract-bundle/v1.4.0/orchestration/pi.md +70 -0
  196. package/tests/fixtures/provider-contract-bundle/v1.4.0/routing/pi.md +92 -0
  197. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/lens.schema.json +16 -0
  198. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/refuter.schema.json +1 -0
  199. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/targeted-validator.schema.json +1 -0
  200. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/lens.json +1 -0
  201. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/refuter.json +1 -0
  202. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/targeted-validator.json +1 -0
  203. package/tests/gauge-theme.test.ts +120 -0
  204. package/tests/gentle-agents.test.ts +645 -21
  205. package/tests/gentle-ai-binary.test.ts +1 -1
  206. package/tests/gentle-ai-child-guards.test.ts +61 -0
  207. package/tests/gentle-ai-doctor-herdr.test.ts +94 -0
  208. package/tests/gentle-ai-installer.test.ts +51 -51
  209. package/tests/gentle-ai.test.ts +292 -13
  210. package/tests/gentle-design.test.ts +1313 -0
  211. package/tests/gentle-music.test.ts +335 -0
  212. package/tests/gentle-shell-bin.test.ts +163 -0
  213. package/tests/gentle-shell-bundled.test.ts +392 -176
  214. package/tests/gentle-shell-import-pi.test.ts +262 -0
  215. package/tests/gentle-shell-launcher.test.ts +107 -2
  216. package/tests/gentle-shell-startup-update.test.ts +77 -1
  217. package/tests/gentle-shell-uninstall.test.ts +89 -0
  218. package/tests/gentle-shell.test.ts +225 -17
  219. package/tests/gentle-todo.test.ts +190 -0
  220. package/tests/headless-delivery-question.test.ts +58 -0
  221. package/tests/herdr-activity.test.ts +34 -1
  222. package/tests/image-attachments.test.ts +119 -0
  223. package/tests/image-paste-chips.test.ts +236 -0
  224. package/tests/inprocess-reviewer.test.ts +55 -2
  225. package/tests/installer-bundles.test.ts +12 -6
  226. package/tests/installer-posix-bootstrap.test.ts +8 -8
  227. package/tests/installer-preflight.test.ts +16 -0
  228. package/tests/installer-server.test.ts +10 -2
  229. package/tests/installer-windows-bootstrap.test.ts +94 -7
  230. package/tests/installer-windows-diagnostics.test.ts +111 -0
  231. package/tests/main-channel-upgrade.test.ts +232 -2
  232. package/tests/main-channel.test.ts +140 -21
  233. package/tests/nan-provider.test.ts +36 -0
  234. package/tests/native-review-capability-contract.test.ts +17 -4
  235. package/tests/native-review-parity.test.ts +23 -2
  236. package/tests/no-self-pause-contract.test.ts +5 -2
  237. package/tests/notification-audio-native.test.ts +128 -9
  238. package/tests/notification-customize.test.ts +17 -5
  239. package/tests/odd-integration.test.ts +5 -1
  240. package/tests/odd-routing-canonical-ratchet.test.ts +128 -162
  241. package/tests/odd-routing-contract.test.ts +115 -30
  242. package/tests/orchestrator-budget.test.ts +22 -8
  243. package/tests/orchestrator-discovery.test.ts +29 -0
  244. package/tests/orchestrator-presence.test.ts +100 -2
  245. package/tests/orchestrator-rdd-ownership.test.ts +3 -1
  246. package/tests/orchestrator-scope.test.ts +80 -0
  247. package/tests/orchestrator-state.test.ts +29 -0
  248. package/tests/orchestrator-status-publication-contract.test.ts +12 -8
  249. package/tests/package-files.test.ts +34 -0
  250. package/tests/package-manifest.test.ts +24 -20
  251. package/tests/permission-mode-policy.test.ts +10 -1
  252. package/tests/pi-update-launcher.test.ts +21 -2
  253. package/tests/pi-update.test.ts +99 -4
  254. package/tests/primary-session-prompt.test.ts +101 -0
  255. package/tests/provider-contract-bundle.test.ts +118 -0
  256. package/tests/provider-contract-mirror.test.ts +24 -0
  257. package/tests/quiet-tool-rendering.test.ts +23 -0
  258. package/tests/rdd-aware-verification-contract.test.ts +29 -11
  259. package/tests/rdd-status-line.test.ts +79 -0
  260. package/tests/review-agent-end-preflight.test.ts +6 -0
  261. package/tests/review-candidate-view.test.ts +49 -0
  262. package/tests/review-contract-prompt.test.ts +5 -2
  263. package/tests/review-controller-native-routing.test.ts +14 -1
  264. package/tests/review-controller.test.ts +1 -1
  265. package/tests/review-host-relay-routing.test.ts +147 -3
  266. package/tests/review-host-relay.test.ts +9 -2
  267. package/tests/review-json-arguments.test.ts +20 -3
  268. package/tests/review-loadout-rdd-off-sdk.test.ts +258 -0
  269. package/tests/review-owner-identity.test.ts +132 -0
  270. package/tests/review-relay-transport-agent.test.ts +26 -0
  271. package/tests/review-reminder-receipt.test.ts +31 -1
  272. package/tests/review-risk-assessment.test.ts +163 -76
  273. package/tests/review-session-standing-permission-controller.test.ts +14 -1
  274. package/tests/review-session-standing-permission.test.ts +27 -1
  275. package/tests/run-test-suite.test.ts +15 -0
  276. package/tests/runtime-harness.mjs +16 -6
  277. package/tests/session-changes-shell.test.ts +1 -1
  278. package/tests/session-changes.test.ts +2 -1
  279. package/tests/session-profile-append-controller-fork.test.ts +458 -0
  280. package/tests/session-profile-append-controller-pi.test.ts +290 -0
  281. package/tests/session-profile-append-controller.test.ts +731 -0
  282. package/tests/session-profile-disk-reader-pi.test.ts +183 -0
  283. package/tests/session-profile-disk-reader.test.ts +311 -0
  284. package/tests/session-profile-freeze.test.ts +23 -0
  285. package/tests/session-scratch.test.ts +1011 -0
  286. package/tests/session-subject-routing-contract.test.ts +2 -1
  287. package/tests/session-worktree-registry.test.ts +13 -1
  288. package/tests/shell-bar.test.ts +21 -2
  289. package/tests/shell-changes-view.test.ts +137 -1
  290. package/tests/shell-changes.test.ts +148 -1
  291. package/tests/shell-gauge.test.ts +42 -0
  292. package/tests/shell-prompt.test.ts +3 -3
  293. package/tests/shell-render-cache.test.ts +134 -1
  294. package/tests/shell-sidebar-layout.test.ts +50 -0
  295. package/tests/short-check-routing-contract.test.ts +1 -1
  296. package/tests/skill-collision-prefixes.test.ts +3 -1
  297. package/tests/skill-registry-watcher.test.ts +17 -5
  298. package/tests/skill-registry.test.ts +47 -3
  299. package/tests/small-task-inline-contract.test.ts +37 -0
  300. package/tests/standalone-config-home.test.ts +324 -0
  301. package/tests/startup-banner.test.ts +5 -4
  302. package/tests/startup-home-repo.test.ts +34 -0
  303. package/tests/support/orchestrator-modules.ts +1 -0
  304. package/tests/task-size-routing-contract.test.ts +70 -10
  305. package/tests/test-scratch-contract.test.ts +102 -0
  306. package/tests/test-strength-contract.test.ts +36 -1
  307. package/tests/tool-batching-contract.test.ts +64 -0
  308. package/tests/verification-proportionality.test.ts +46 -0
  309. package/tests/verifier-admission.test.ts +154 -0
  310. package/tests/verify-agent-contract.test.ts +8 -8
  311. package/tests/voice-command.test.ts +773 -0
  312. package/tests/voice-install.test.ts +323 -0
  313. package/tests/voice-platform.test.ts +176 -0
  314. package/tests/voice-push-to-talk.test.ts +444 -0
  315. package/tests/voice-session.test.ts +434 -0
  316. package/tests/voice-settings.test.ts +49 -0
  317. package/tests/voice-ui.test.ts +97 -0
  318. package/tests/voice-worker.test.ts +445 -0
  319. package/tests/weak-model-economy-prompt.test.ts +32 -0
  320. package/tests/windows-hidden-processes.test.ts +30 -2
  321. package/tests/writer-edit-surface-scope.test.ts +3 -0
  322. package/tests/writer-feature-document-admission.test.ts +156 -0
  323. package/tests/yolo-customize.test.ts +5 -1
  324. package/tests/yolo-mode.test.ts +19 -1
  325. package/tests/yolo-session-policy-capture.test.ts +104 -0
  326. package/tests/yolo-temp-scratch.test.ts +71 -0
  327. package/scripts/mirror-odd-routing.mjs +0 -242
  328. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/orchestration/pi.md +0 -0
  329. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/lens.schema.json +0 -0
  330. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/refuter.schema.json +0 -0
  331. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/targeted-validator.schema.json +0 -0
  332. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/lens.json +0 -0
  333. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/refuter.json +0 -0
  334. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/targeted-validator.json +0 -0
@@ -1,74 +1,136 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="960" height="760" viewBox="0 0 960 760" role="img" aria-labelledby="odd-title odd-desc">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1000" height="500" viewBox="0 0 1000 500" role="img" aria-labelledby="odd-title odd-desc">
2
2
  <title id="odd-title">Organic Driven Development workflow</title>
3
3
  <desc id="odd-desc">One feature moves through the seven ODD protocol steps. Authorize, explore, resolve uncertainty, then classify: small understood work stays light with no durable artifacts, while substantial work is tracked in one feature document before the first write. Both paths implement task by task and close with verified proof. The same feature document carries progress across sessions so work resumes instead of restarting.</desc>
4
4
  <defs>
5
- <linearGradient id="odd-bg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#100c15"/><stop offset="1" stop-color="#21101f"/></linearGradient>
6
- <marker id="odd-arrow" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10" viewBox="0 0 10 10" refX="10" refY="5" orient="auto"><path d="M0 0 10 5 0 10z" fill="#f095c8"/></marker>
5
+ <linearGradient id="odd-bg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#0f0b13"/><stop offset="1" stop-color="#1a0e19"/></linearGradient>
6
+ <radialGradient id="odd-glow" cx="0.12" cy="0" r="0.7"><stop stop-color="#f095c8" stop-opacity="0.16"/><stop offset="1" stop-color="#f095c8" stop-opacity="0"/></radialGradient>
7
+ <linearGradient id="odd-card" x1="0" y1="0" x2="0" y2="1"><stop stop-color="#1d1520"/><stop offset="1" stop-color="#151017"/></linearGradient>
8
+ <linearGradient id="odd-accent" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#3a1932"/><stop offset="1" stop-color="#1e1020"/></linearGradient>
9
+ <pattern id="odd-dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="1" fill="#ffffff" fill-opacity="0.045"/></pattern>
10
+ <filter id="odd-shine" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur stdDeviation="10"/></filter>
11
+ <marker id="odd-arrow" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" viewBox="0 0 8 8" refX="7" refY="4" orient="auto"><path d="M0 0.5 7 4 0 7.5z" fill="#f095c8"/></marker>
7
12
  </defs>
8
- <rect width="960" height="760" rx="20" fill="url(#odd-bg)"/>
9
- <text x="40" y="65" fill="#fff7f1" font-family="Arial, Helvetica, sans-serif" font-size="44" font-weight="700">Explore, track, implement.</text>
10
- <text x="40" y="120" fill="#d7a0b8" font-family="Arial, Helvetica, sans-serif" font-size="44" font-weight="700">Resume without ceremony.</text>
11
- <g fill="#1c1420" stroke="#d7a0b8" stroke-width="2">
12
- <rect x="40" y="170" width="196" height="120" rx="16"/>
13
- <rect x="268" y="170" width="196" height="120" rx="16"/>
14
- <rect x="496" y="170" width="196" height="120" rx="16"/>
15
- <rect x="724" y="170" width="196" height="120" rx="16"/>
16
- <rect x="724" y="330" width="196" height="120" rx="16" fill="#2a1426" stroke="#f095c8" stroke-width="3"/>
17
- <rect x="610" y="490" width="196" height="120" rx="16"/>
18
- <rect x="268" y="490" width="196" height="120" rx="16"/>
19
- </g>
20
- <rect x="496" y="330" width="196" height="120" rx="16" fill="#18121b" stroke="#d7a0b8" stroke-width="2" stroke-dasharray="6 6"/>
21
- <g fill="none" stroke="#f095c8" stroke-width="3" stroke-linecap="round" marker-end="url(#odd-arrow)">
22
- <path d="M236 230H268"/>
23
- <path d="M464 230H496"/>
24
- <path d="M692 230H724"/>
25
- <path d="M822 290V330"/>
26
- <path d="M822 290V310H594V330"/>
27
- <path d="M708 470V490"/>
28
- <path d="M610 550H464"/>
29
- </g>
30
- <g fill="none" stroke="#f095c8" stroke-width="3" stroke-linecap="round">
31
- <path d="M594 450V470H708"/>
32
- <path d="M822 450V470H708"/>
33
- </g>
34
- <g font-family="Arial, Helvetica, sans-serif" font-size="20" fill="#d7a0b8" opacity="0.85">
35
- <text x="56" y="198">01</text>
36
- <text x="284" y="198">02</text>
37
- <text x="512" y="198">03</text>
38
- <text x="740" y="198">04</text>
39
- <text x="740" y="358">05</text>
40
- <text x="626" y="518">06</text>
41
- <text x="284" y="518">07</text>
42
- </g>
43
- <g font-family="Arial, Helvetica, sans-serif" text-anchor="middle">
44
- <g fill="#fff7f1" font-size="30" font-weight="700">
45
- <text x="138" y="222">Authorize</text>
46
- <text x="366" y="222">Explore</text>
47
- <text x="594" y="222">Resolve</text>
48
- <text x="822" y="222">Classify</text>
49
- <text x="822" y="382">Track</text>
50
- <text x="594" y="382">Stay light</text>
51
- <text x="708" y="542">Implement</text>
52
- <text x="366" y="542">Close</text>
13
+
14
+ <!-- canvas -->
15
+ <rect width="1000" height="500" rx="24" fill="url(#odd-bg)"/>
16
+ <rect width="1000" height="500" rx="24" fill="url(#odd-dots)"/>
17
+ <rect width="1000" height="500" rx="24" fill="url(#odd-glow)"/>
18
+ <rect x="0.5" y="0.5" width="999" height="499" rx="23.5" fill="none" stroke="#f095c8" stroke-opacity="0.16"/>
19
+
20
+ <g font-family="ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Roboto, 'Helvetica Neue', Arial, sans-serif">
21
+
22
+ <!-- eyebrow -->
23
+ <text x="36" y="52" fill="#f095c8" font-size="12.5" font-weight="700" letter-spacing="2.6">ORGANIC DRIVEN DEVELOPMENT</text>
24
+ <text x="964" y="52" fill="#8e7987" font-size="13" text-anchor="end">small work stays light · substantial work gets tracked</text>
25
+
26
+ <!-- phase brackets -->
27
+ <g fill="#8e7987" font-size="11" font-weight="700" letter-spacing="2" text-anchor="middle">
28
+ <text x="220" y="94">UNDERSTAND</text>
29
+ <text x="552" y="94">DECIDE</text>
30
+ <text x="844" y="94">DELIVER</text>
53
31
  </g>
54
- <g fill="#d7a0b8" font-size="22">
55
- <text x="138" y="262">read-only</text>
56
- <text x="366" y="262">code and needs</text>
57
- <text x="594" y="262">uncertainty</text>
58
- <text x="822" y="262">substantial?</text>
59
- <text x="822" y="422">one document</text>
60
- <text x="594" y="422">small work</text>
61
- <text x="708" y="582">task by task</text>
62
- <text x="366" y="582">verified proof</text>
32
+ <g fill="none" stroke="#f095c8" stroke-opacity="0.28" stroke-width="1">
33
+ <path d="M36 110V104H404V110"/>
34
+ <path d="M420 110V104H684V110"/>
35
+ <path d="M724 110V104H964V110"/>
63
36
  </g>
64
- </g>
65
- <g font-family="Arial, Helvetica, sans-serif" font-size="22" fill="#d7a0b8">
66
- <text x="708" y="302" text-anchor="middle">small</text>
67
- <text x="838" y="316" text-anchor="start">substantial</text>
68
- </g>
69
- <rect x="40" y="650" width="880" height="90" rx="16" fill="#18121b" stroke="#d7a0b8" stroke-width="2" stroke-dasharray="8 7"/>
70
- <g font-family="Arial, Helvetica, sans-serif" text-anchor="middle">
71
- <text x="480" y="686" fill="#fff7f1" font-size="34" font-weight="700">Resume where you stopped</text>
72
- <text x="480" y="722" fill="#d7a0b8" font-size="26">One feature document, mirrored in Engram across sessions.</text>
37
+
38
+ <!-- flow lines -->
39
+ <g fill="none" stroke="#f095c8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" marker-end="url(#odd-arrow)">
40
+ <path d="M148 250H162"/>
41
+ <path d="M276 250H290"/>
42
+ <path d="M404 250H418"/>
43
+ <path d="M532 250H544Q552 250 552 242V200Q552 192 560 192H570"/>
44
+ <path d="M532 250H544Q552 250 552 258V300Q552 308 560 308H570"/>
45
+ <path d="M684 192H696Q704 192 704 200V242Q704 250 712 250H722"/>
46
+ <path d="M684 308H696Q704 308 704 300V258Q704 250 712 250H722"/>
47
+ <path d="M836 250H850"/>
48
+ </g>
49
+ <path d="M628 386V410" fill="none" stroke="#f095c8" stroke-opacity="0.45" stroke-width="1.5" stroke-dasharray="2 5" stroke-linecap="round"/>
50
+
51
+ <!-- branch labels -->
52
+ <g fill="#c99bb4" font-size="12" font-weight="600" letter-spacing="0.6" text-anchor="middle">
53
+ <text x="628" y="134">small</text>
54
+ <text x="628" y="378">substantial</text>
55
+ </g>
56
+
57
+ <!-- accent glows -->
58
+ <g fill="#f095c8" opacity="0.22" filter="url(#odd-shine)">
59
+ <rect x="430" y="204" width="92" height="92" rx="16"/>
60
+ <rect x="582" y="270" width="92" height="76" rx="16"/>
61
+ </g>
62
+
63
+ <!-- cards -->
64
+ <g stroke-width="1">
65
+ <rect x="36" y="194" width="112" height="112" rx="14" fill="url(#odd-card)" stroke="#f095c8" stroke-opacity="0.22"/>
66
+ <rect x="164" y="194" width="112" height="112" rx="14" fill="url(#odd-card)" stroke="#f095c8" stroke-opacity="0.22"/>
67
+ <rect x="292" y="194" width="112" height="112" rx="14" fill="url(#odd-card)" stroke="#f095c8" stroke-opacity="0.22"/>
68
+ <rect x="420" y="194" width="112" height="112" rx="14" fill="url(#odd-accent)" stroke="#f095c8" stroke-width="1.5"/>
69
+ <rect x="572" y="144" width="112" height="96" rx="14" fill="#130e15" stroke="#d7a0b8" stroke-opacity="0.55" stroke-dasharray="5 5"/>
70
+ <rect x="572" y="260" width="112" height="96" rx="14" fill="url(#odd-accent)" stroke="#f095c8" stroke-width="1.5"/>
71
+ <rect x="724" y="194" width="112" height="112" rx="14" fill="url(#odd-card)" stroke="#f095c8" stroke-opacity="0.22"/>
72
+ <rect x="852" y="194" width="112" height="112" rx="14" fill="url(#odd-card)" stroke="#f095c8" stroke-opacity="0.45"/>
73
+ </g>
74
+
75
+ <!-- step numbers -->
76
+ <g fill="#f095c8" fill-opacity="0.13">
77
+ <rect x="48" y="206" width="30" height="18" rx="9"/>
78
+ <rect x="176" y="206" width="30" height="18" rx="9"/>
79
+ <rect x="304" y="206" width="30" height="18" rx="9"/>
80
+ <rect x="432" y="206" width="30" height="18" rx="9" fill-opacity="0.26"/>
81
+ <rect x="584" y="272" width="30" height="18" rx="9" fill-opacity="0.26"/>
82
+ <rect x="736" y="206" width="30" height="18" rx="9"/>
83
+ <rect x="864" y="206" width="30" height="18" rx="9"/>
84
+ </g>
85
+ <g fill="#f5b8da" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="700" text-anchor="middle">
86
+ <text x="63" y="219">01</text>
87
+ <text x="191" y="219">02</text>
88
+ <text x="319" y="219">03</text>
89
+ <text x="447" y="219">04</text>
90
+ <text x="599" y="285">05</text>
91
+ <text x="751" y="219">06</text>
92
+ <text x="879" y="219">07</text>
93
+ </g>
94
+
95
+ <!-- icons (24px grid) -->
96
+ <g fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
97
+ <g transform="translate(116 203) scale(0.8)"><path d="M12 3 19 6v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z"/><path d="M9 12l2 2 4-4"/></g>
98
+ <g transform="translate(244 203) scale(0.8)"><circle cx="11" cy="11" r="6"/><path d="M15.5 15.5 20 20"/></g>
99
+ <g transform="translate(372 203) scale(0.8)"><path d="M4 5h16v11h-9l-4 4v-4H4z"/><path d="M10 9.2a2 2 0 1 1 2.6 1.9c-.4.2-.6.5-.6.9"/><path d="M12 13.6v.1"/></g>
100
+ <g transform="translate(500 203) scale(0.8)"><path d="M12 3l9 9-9 9-9-9z"/><path d="M12 8v5M12 16v.1"/></g>
101
+ <g transform="translate(652 153) scale(0.8)"><path d="M20 4C12 4 6 10 6 18"/><path d="M6 18c8 0 14-6 14-14"/><path d="M4 20l2-2M9 15l6-6"/></g>
102
+ <g transform="translate(652 269) scale(0.8)"><path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5M10 13h6M10 17h6"/></g>
103
+ <g transform="translate(804 203) scale(0.8)"><path d="M9 8l-4 4 4 4M15 8l4 4-4 4"/></g>
104
+ <g transform="translate(932 203) scale(0.8)"><circle cx="12" cy="12" r="9"/><path d="M8 12.5l3 2.5 5-5.5"/></g>
105
+ </g>
106
+
107
+ <!-- titles -->
108
+ <g fill="#fbeff5" font-size="17" font-weight="650">
109
+ <text x="48" y="266">Authorize</text>
110
+ <text x="176" y="266">Explore</text>
111
+ <text x="304" y="266">Resolve</text>
112
+ <text x="432" y="266">Classify</text>
113
+ <text x="584" y="202">Stay light</text>
114
+ <text x="584" y="318">Track</text>
115
+ <text x="736" y="266">Implement</text>
116
+ <text x="864" y="266">Close</text>
117
+ </g>
118
+ <g fill="#a8939f" font-size="12.5">
119
+ <text x="48" y="288">read-only</text>
120
+ <text x="176" y="288">code and needs</text>
121
+ <text x="304" y="288">uncertainty</text>
122
+ <text x="432" y="288">substantial?</text>
123
+ <text x="584" y="222">small work</text>
124
+ <text x="584" y="338">one document</text>
125
+ <text x="736" y="288">task by task</text>
126
+ <text x="864" y="288">verified proof</text>
127
+ </g>
128
+
129
+ <!-- resume band -->
130
+ <rect x="36" y="410" width="928" height="56" rx="14" fill="#f095c8" fill-opacity="0.06" stroke="#f095c8" stroke-opacity="0.22"/>
131
+ <g fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" transform="translate(56 426) scale(1)">
132
+ <path d="M20 12a8 8 0 1 1-2.3-5.6"/><path d="M20 4v5h-5"/>
133
+ </g>
134
+ <text x="92" y="443" font-size="15.5"><tspan fill="#fbeff5" font-weight="650">Resume where you stopped</tspan><tspan fill="#a8939f" dx="10">One feature document, mirrored in Engram across sessions.</tspan></text>
73
135
  </g>
74
136
  </svg>
@@ -0,0 +1,51 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1000" height="400" viewBox="0 0 1000 400" role="img" aria-labelledby="modes-title modes-desc">
2
+ <title id="modes-title">Permission modes</title>
3
+ <desc id="modes-desc">Three permission modes. Normal keeps the standard prompts. Auto checks eligible actions with an independent inference using the current session model; ordinary checks are tool-free, an eligible script check can inspect at most two complete files, and unavailable or stale decisions do not run the action. YOLO gives standing permission for ordinary already-scoped work while destructive actions still ask. In every mode, explicit restrictions, destructive guards, and independent consent remain, and none of the modes is a sandbox.</desc>
4
+ <defs>
5
+ <linearGradient id="modes-bg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#0f0b13"/><stop offset="1" stop-color="#1a0e19"/></linearGradient>
6
+ <radialGradient id="modes-glow" cx="0.12" cy="0" r="0.7"><stop stop-color="#f095c8" stop-opacity="0.16"/><stop offset="1" stop-color="#f095c8" stop-opacity="0"/></radialGradient>
7
+ <linearGradient id="modes-card" x1="0" y1="0" x2="0" y2="1"><stop stop-color="#1d1520"/><stop offset="1" stop-color="#151017"/></linearGradient>
8
+ <linearGradient id="modes-accent" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#3a1932"/><stop offset="1" stop-color="#1e1020"/></linearGradient>
9
+ <linearGradient id="modes-bar" x1="0" y1="0" x2="1" y2="0"><stop stop-color="#c46b9e"/><stop offset="1" stop-color="#f095c8"/></linearGradient>
10
+ <pattern id="modes-dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="1" fill="#ffffff" fill-opacity="0.045"/></pattern>
11
+ <filter id="modes-shine" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur stdDeviation="10"/></filter>
12
+ <marker id="modes-arrow" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" viewBox="0 0 8 8" refX="7" refY="4" orient="auto"><path d="M0 0.5 7 4 0 7.5z" fill="#f095c8"/></marker>
13
+ <marker id="modes-arrow-soft" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" viewBox="0 0 8 8" refX="7" refY="4" orient="auto"><path d="M0 0.5 7 4 0 7.5z" fill="#d7a0b8"/></marker>
14
+ </defs>
15
+ <rect width="1000" height="400" rx="24" fill="url(#modes-bg)"/>
16
+ <rect width="1000" height="400" rx="24" fill="url(#modes-dots)"/>
17
+ <rect width="1000" height="400" rx="24" fill="url(#modes-glow)"/>
18
+ <rect x="0.5" y="0.5" width="999" height="399" rx="23.5" fill="none" stroke="#f095c8" stroke-opacity="0.16"/>
19
+ <g font-family="ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Roboto, 'Helvetica Neue', Arial, sans-serif">
20
+ <text x="36" y="52" fill="#f095c8" font-size="12.5" font-weight="700" letter-spacing="2.6">PERMISSION MODES</text>
21
+ <text x="964" y="52" fill="#8e7987" font-size="13" text-anchor="end">/gentle:mode · /gentle:yolo</text>
22
+ <path d="M36 96H956" stroke="#f095c8" stroke-opacity="0.35" stroke-width="1.5" marker-end="url(#modes-arrow)"/>
23
+ <text x="36" y="86" fill="#8e7987" font-size="11" font-weight="700" letter-spacing="0.4" text-anchor="start">more questions</text>
24
+ <text x="964" y="86" fill="#8e7987" font-size="11" font-weight="700" letter-spacing="0.4" text-anchor="end">fewer questions</text>
25
+ <rect x="36" y="120" width="288" height="160" rx="14" fill="url(#modes-card)" stroke="#f095c8" stroke-opacity="0.22"/>
26
+ <g transform="translate(292 129) scale(0.8)" fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></g>
27
+ <text x="48" y="200" fill="#fbeff5" font-size="20" font-weight="650">Normal</text>
28
+ <text x="48" y="222" fill="#a8939f" font-size="12.5">standard prompts</text>
29
+ <text x="48" y="240" fill="#a8939f" font-size="12.5">the default</text>
30
+ <rect x="48" y="132" width="145" height="18" rx="9" fill="#f095c8" fill-opacity="0.13"/>
31
+ <text x="120.4" y="145" fill="#f5b8da" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="700" text-anchor="middle">/gentle:mode normal</text>
32
+ <rect x="356" y="120" width="288" height="160" rx="14" fill="url(#modes-card)" stroke="#f095c8" stroke-opacity="0.22"/>
33
+ <g transform="translate(612 129) scale(0.8)" fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></g>
34
+ <text x="368" y="200" fill="#fbeff5" font-size="20" font-weight="650">Auto</text>
35
+ <text x="368" y="222" fill="#a8939f" font-size="12.5">an independent check decides</text>
36
+ <text x="368" y="240" fill="#a8939f" font-size="12.5">unavailable or stale: does not run</text>
37
+ <rect x="368" y="132" width="130" height="18" rx="9" fill="#f095c8" fill-opacity="0.13"/>
38
+ <text x="433.2" y="145" fill="#f5b8da" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="700" text-anchor="middle">/gentle:mode auto</text>
39
+ <rect x="686" y="130" width="268" height="140" rx="16" fill="#f095c8" opacity="0.22" filter="url(#modes-shine)"/>
40
+ <rect x="676" y="120" width="288" height="160" rx="14" fill="url(#modes-accent)" stroke="#f095c8" stroke-width="1.5"/>
41
+ <g transform="translate(932 129) scale(0.8)" fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M13 3 5 14h6l-1 7 8-11h-6z"/></g>
42
+ <text x="688" y="200" fill="#fbeff5" font-size="20" font-weight="650">YOLO</text>
43
+ <text x="688" y="222" fill="#a8939f" font-size="12.5">standing permission for scoped work</text>
44
+ <text x="688" y="240" fill="#a8939f" font-size="12.5">destructive actions still ask</text>
45
+ <rect x="688" y="132" width="145" height="18" rx="9" fill="#f095c8" fill-opacity="0.13"/>
46
+ <text x="760.4" y="145" fill="#f5b8da" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" font-weight="700" text-anchor="middle">/gentle:yolo enable</text>
47
+ <rect x="36" y="308" width="928" height="56" rx="14" fill="#f095c8" fill-opacity="0.06" stroke="#f095c8" stroke-opacity="0.22"/>
48
+ <g transform="translate(56 324.0) scale(1)" fill="none" stroke="#f095c8" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 19 6v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z"/><path d="M9 12l2 2 4-4"/></g>
49
+ <text x="92" y="341.5" font-size="15.5"><tspan fill="#fbeff5" font-weight="650">In every mode</tspan><tspan fill="#a8939f" dx="10">explicit restrictions, destructive guards, and independent consent remain. Not a sandbox.</tspan></text>
50
+ </g>
51
+ </svg>
@@ -13,7 +13,7 @@ The building blocks live in `scripts/bundled-install.mjs`. The web installer and
13
13
  | `~/.gentle-shell/npm/{prefix,cache}/`, `~/.gentle-shell/npm/npmrc` | npm's global prefix, cache and global config. The global config file is never written. |
14
14
  | `~/.gentle-shell/runtime/pnpm-11.1.1/package/` | Our pnpm, from the verified registry tarball. |
15
15
  | `~/.gentle-shell/runtime/go/1.25.14/go/` | Our Go, only when asked (`acquireGo` layout). |
16
- | `~/.gentle-shell/runtime/engram-3.4.0/engram` | Our Engram, from the verified GitHub release archive ([Isolation from the user's Gentle AI](#isolation-from-the-users-gentle-ai)). |
16
+ | `~/.gentle-shell/runtime/engram-3.5.2/engram` | Our Engram, from the verified GitHub release archive ([Isolation from the user's Gentle AI](#isolation-from-the-users-gentle-ai)). |
17
17
  | `~/.gentle-shell/gentle-ai/` | Gentle AI's state, managed assets, backups and telemetry state (`GENTLE_AI_HOME`). |
18
18
  | `~/.gentle-shell/config/gentle-ai/` | gentle-pi's config home in a bundled install (derived, never exported to Pi): profiles, preferences, persona, background subagents. |
19
19
  | `~/.gentle-shell/pnpm/{store,cache,state,config}/` | Every folder pnpm writes. |
@@ -24,6 +24,25 @@ The building blocks live in `scripts/bundled-install.mjs`. The web installer and
24
24
 
25
25
  On Windows the same layout lives under a private folder. The module tries `%LOCALAPPDATA%\gentle-shell` first. It falls back to `%USERPROFILE%\.gentle-shell-bundle` only when an untrusted owner or ACL rejects the first folder, the same rule the bootstrap uses for its tools. The folder is claimed with the bootstrap's protected DACL and marked with `.gentle-shell-bundle` (`ensureWindowsPrivateFolder`). `current` is a pointer file holding the version id. The launcher is `bin\gentle-shell.cmd`, and `tmp\` holds TEMP and TMP for pnpm's children. The agent home stays at `%USERPROFILE%\.gentle-shell\agent`.
26
26
 
27
+ ### Windows prerequisite failure diagnostics
28
+
29
+ `windowsProcessCheck` still throws exactly `Windows prerequisite process failed`
30
+ (`process-failed` classification). Its standard Error cause preserves status,
31
+ signal and selected process-error fields plus bounded stdout/stderr. A sanitized
32
+ `cause.stack` also carries these fields for existing evidence consumers, without
33
+ local callsites, raw spawn errors, commands, argv or environment snapshots.
34
+ Process-error messages use only a sanitized native error code or fixed fallback,
35
+ never raw spawn text that could include a private bare executable name.
36
+ Limits are UTF-16 code units: streams1024 each, error message256, name/code/errno
37
+ text64, signal32 and cause stack8192; numeric status/errno remain numeric.
38
+ Path/SID, encoded ACL/opaque and control-bearing lines are suppressed; credential
39
+ markers, including underscore-separated environment names such as `GITHUB_TOKEN`
40
+ and `API_KEY`, suppress the entire field including continuation lines. This conservative
41
+ filter may discard useful output and is not a general-purpose secret parser.
42
+ Nothing prints automatically. CMD/BAT rejection, neutral cwd, shell=false,
43
+ 15-second SIGKILL/1MiB capture and all ACL/provenance checks remain unchanged.
44
+ Elapsed time alone does not establish timeout or diagnose the historical CI failure.
45
+
27
46
  ## Ownership rules
28
47
 
29
48
  - **Runtimes.** Each one is downloaded through `verifiedDownload` (the existing pins and hashes), written to a staging folder and run once to check its version. It is then marked with `.gentle-shell-runtime` and published with one rename. A marked runtime is reused. An unmarked folder is never replaced. Renaming is safe here because the extracted trees hold only regular files and folders, never links. The pnpm tarball's executable bits (`bin/pnpm.mjs`, `dist/node-gyp-bin/node-gyp`) are kept, for the owner only.
@@ -229,56 +248,72 @@ Dropped: inherited npm and pnpm settings, `NODE_OPTIONS`, `NODE_PATH`, and the w
229
248
 
230
249
  ### Engram startup safety
231
250
 
232
- A bundled Shell decides, before setup and again right before Pi starts, whether memory may open the shared Engram store. When it may not, Shell keeps working without memory and **points `ENGRAM_BIN` at its own guard**, so no provider, whichever Pi route loaded it, can open, create or migrate a store it cannot vouch for. The core pin is **3.4.0**, acquired through the existing size- and checksum-verified path.
251
+ A bundled Shell shares the global Engram server, like other agents' hooks: it reuses a verified server already listening on the default endpoint and, when nothing listens, starts one itself with its verified bundled core. It decides before setup and again right before Pi starts. When memory may not be used, Shell keeps working without memory and **points `ENGRAM_BIN` at its own guard**, so no provider, whichever Pi route loaded it, can open, create or migrate a store directly. The core pin is **3.5.2**, acquired through the existing size- and checksum-verified path.
233
252
 
234
253
  #### Decision
235
254
 
236
255
  | Evidence (default `~/.engram`, default endpoint `127.0.0.1:7437`) | Memory | `ENGRAM_BIN` / `ENGRAM_URL` |
237
256
  |---|---|---|
238
- | No data directory, nothing listening, verified bundled core | Allowed; this launch provisions a fresh store | Bundled core |
239
- | Same, but the bundled core is missing or unverified | Disabled | Guard (never an `engram` from `PATH`) |
240
- | Running server answers the exact `GET /compatibility` ready contract | Allowed; reuse that server | Guard + `ENGRAM_URL=http://127.0.0.1:7437` |
241
- | Shell's own store (provenance below), nothing listening | Allowed | Bundled core |
242
- | Shell's own store, server listening with `/health` `instance_id` = recorded id **and** `version` = the exact bundled core version | Allowed | Bundled core |
243
- | Anything else: foreign or unreadable data, provenance mismatch, a different server, timeout, 401/404, malformed answers | Disabled | Guard |
244
- | Explicit `ENGRAM_BIN`, `ENGRAM_URL`, `ENGRAM_PORT`, `ENGRAM_DATA_DIR`, `ENGRAM_DATABASE_URL`, or an invalid `ENGRAM_STARTUP_POLICY` | Disabled, never probed | Explicit `ENGRAM_BIN`/`ENGRAM_URL` kept; `ENGRAM_URL` alone gets the verified core (or the guard) as `ENGRAM_BIN`; otherwise guard |
245
-
246
- Classification never runs an Engram executable (`instance-id`, `version`, `serve`), never opens SQLite, and never infers compatibility from a version string. It reads file metadata, the `.instance-id` file, the raw database header, and makes bounded (1 s) read-only `GET /compatibility` and `GET /health` requests to the default endpoint on a direct loopback socket, without proxy, redirects or credentials. `gentle-shell --version` and a Pi version or help flag (`--version`, `-v`, `--help`, `-h` where Pi reads it as a flag: before Pi's own `--` and not as another option's value, so a prompt or option value containing `-v` does not count) never probe, ensure the companion, print memory notices or touch provenance.
257
+ | Running server answers the exact `GET /compatibility` ready contract | Allowed; reuse that server unchanged | Guard + `ENGRAM_URL=http://127.0.0.1:7437` |
258
+ | Nothing listening, verified bundled core | Allowed once the server Shell starts (below) answers ready; otherwise disabled for that launch | Guard + `ENGRAM_URL=http://127.0.0.1:7437` |
259
+ | Nothing listening, but `engram.db`'s header `user_version` is newer than the bundled core's schema | Disabled; no server is started | Guard |
260
+ | Nothing listening, but the bundled core is missing or unverified | Disabled | Guard (never an `engram` from `PATH`) |
261
+ | Anything else listening: a different service, timeout, 401/404, an older server, malformed answers | Disabled; the listener is never stopped or replaced | Guard |
262
+ | Explicit `ENGRAM_BIN`, `ENGRAM_URL`, `ENGRAM_PORT`, `ENGRAM_SOCKET`, `ENGRAM_DATA_DIR`, `ENGRAM_DATABASE_URL`, `ENGRAM_SERVER_MODE`, or an invalid `ENGRAM_STARTUP_POLICY` | Disabled, never probed or started | Explicit `ENGRAM_BIN`/`ENGRAM_URL` kept; `ENGRAM_URL` alone gets the verified core (or the guard) as `ENGRAM_BIN`; otherwise guard |
247
263
 
248
- #### The guard
264
+ An existing store at `~/.engram` does not disable memory by itself, whoever created it (an earlier Shell or the global Engram CLI): the server owns the store, and Shell only talks to a server that proves itself through `/compatibility`. The one exception is the header tripwire: when `engram.db` is a regular, unlinked file whose first 100 bytes are a valid SQLite header (magic, page size, bytes 18/19 each 1 or 2) and whose `user_version` (bytes 60-63) is **greater** than the bundled core's schema (`1`, verified from `v3.5.2:internal/store/store.go`), a newer Engram migrated the store, so Shell does not start its older core on it. Start that newer Engram's server yourself; Shell then reuses it. A pin without a verified schema entry treats any readable header as newer. Equal or lower (including a stale `0` before a WAL checkpoint) is no signal either way.
249
265
 
250
- `bin/engram-guard` is a POSIX `sh` script, run directly (no shell needed by the caller). It ignores its arguments, prints `ENGRAM_STARTUP_NOTICE` (as data, never executed) to stderr and exits 78. It never runs Engram and never reads or writes Engram data. gentle-engram 0.4.1 reaches local data only by running `ENGRAM_BIN` (`instance-id` first, before any health probe or spawn), so the guard stops it before any store access; 0.4.2 also honors `ENGRAM_STARTUP_POLICY=disabled`. Pi, its subagents and the agent's shell all inherit the same environment.
266
+ Classification never runs an Engram executable, never opens SQLite, and never infers compatibility from a version string. It reads the raw database header and makes bounded (1 s) read-only `GET /compatibility` and `GET /health` requests to the default endpoint on a direct loopback socket, without proxy, redirects or credentials. `gentle-shell --version` and a Pi version or help flag (`--version`, `-v`, `--help`, `-h` where Pi reads it as a flag: before Pi's own `--` and not as another option's value, so a prompt or option value containing `-v` does not count) never probe, start a server, ensure the companion or print memory notices. A Pi subcommand (`gentle-shell list`, `install`, ...) and `gentle-shell setup` never start a server either.
251
267
 
252
- - **Explicit selections bypass the guard.** An `ENGRAM_BIN` or `ENGRAM_URL` you set is never replaced or removed (with only `ENGRAM_URL`, `ENGRAM_BIN` is still the verified core, or the guard without one, never a `PATH` engram); memory is still marked disabled through the policy, which only 0.4.2+ honors.
253
- - **Windows.** The guard has no `.exe`; spawning it fails (for example `ENOENT` or `EINVAL`), which still fails closed, but no notice is printed.
268
+ #### Starting the shared server
254
269
 
255
- #### Provenance (Shell's own store)
270
+ Only the final pre-Pi decision starts a server. Shell runs the verified bundled core as plain `engram serve`, with Engram's own default port and data directory, **detached** (its own process group, `stdio` ignored, unreferenced, `windowsHide` on Windows, working directory the home folder), so it outlives Pi like a server other agents' hooks start. Its environment is the user's minus every `ENGRAM_*` setting and `GH_TOKEN`/`GITHUB_TOKEN`, plus `ENGRAM_NO_UPDATE_CHECK=1`. For `TMPDIR`/`TMP`/`TEMP` whose final path component is session scratch (`gp` or `ga` followed by exactly six alphanumeric characters), POSIX drops the setting. Windows instead explicitly replaces it with its original absolute ancestor outside consecutive scratch components: omitting `TEMP` can cause Node to inherit the parent's scratch again. When any Windows scratch setting is replaced and `TEMP` is absent, Shell also sets `TEMP` to that stable ancestor. Existing custom temp settings retain their own values, even when they name different roots. Windows path separators and case-insensitive environment keys are supported. An unsafe relative scratch path disables this startup attempt before spawning; Shell never guesses a root or creates a temp folder. Unrelated variables remain unchanged. Pi keeps the user's environment. Shell then polls `GET /compatibility` for up to 10 seconds. A ready answer allows memory through the reuse URL; otherwise (the core fails to start, exits, or never answers ready) memory is disabled for that launch with a notice, and Shell still starts Pi. Concurrent launches converge: when the child exits (for example because another launch won the bind), Shell keeps polling for a short grace, and a ready `/compatibility` from the winner counts as started. Shell never stops a server it started or found; it keeps running for every client until you stop it.
256
271
 
257
- When the final pre-Pi decision is "fresh" (no data directory, nothing listening, verified bundled core, no explicit selection), Shell provisions the store identity itself **before** Pi starts: it runs the verified bundled core's `instance-id` (15 s timeout) with the environment Pi will use, except that this one invocation gets `ENGRAM_NO_UPDATE_CHECK=1` and no `GH_TOKEN`/`GITHUB_TOKEN`. In Engram 3.4.0 that command only creates the data directory, `.instance-id.lock` and `.instance-id`; it skips orphan migration and opens no database. Shell then reads the `.instance-id` **file** (regular, not a link, a valid id equal to the command's output, in the same default directory it classified as absent) and immediately writes `<prefix>/config/engram-provenance.json` (mode 0600): the canonical data directory, that instance id, and the sha256 of the bundled core. If any step fails (the command fails or times out, the identity is invalid, or the record cannot be written), memory is disabled for that launch behind the guard; Pi never starts with memory allowed without a written record. Shell never records a store it did not provision, so a store that appears later at the default directory is never adopted.
272
+ #### The guard
258
273
 
259
- A later launch treats the store as Shell's own only when all hold:
274
+ `bin/engram-guard` is a POSIX `sh` script, run directly (no shell needed by the caller). It ignores its arguments, prints `ENGRAM_STARTUP_NOTICE` (as data, never executed) to stderr and exits 78. It never runs Engram and never reads or writes Engram data. gentle-engram 0.4.1 reaches local data only by running `ENGRAM_BIN` (`instance-id` first, before any health probe or spawn), so the guard stops it before any store access; 0.4.2 also honors `ENGRAM_STARTUP_POLICY=disabled`, and with `ENGRAM_URL` it talks to the shared server over HTTP. Pi, its subagents and the agent's shell all inherit the same environment.
260
275
 
261
- 1. The data directory, its `.instance-id` and the current bundled core digest equal the record. A Shell upgrade that changes the core binary therefore disables memory: forward upgrades are not allowed by version.
262
- 2. The directory still holds only identity files (the session has not created a database yet), or `engram.db` is a regular, unlinked file whose first 100 bytes are a valid SQLite header (magic, page size, bytes 18/19 each 1 or 2) and whose `user_version` (bytes 60-63) is **not greater** than the bundled core's schema (`1`, verified from `v3.4.0:internal/store/store.go`). A greater value means a newer Engram migrated the shared store. Equal or lower (including a stale `0` before a WAL checkpoint) is no signal either way. A pin without a verified schema entry disables this path.
263
- 3. If a server listens, its `/health` reports the recorded instance and exactly the bundled core version.
276
+ - **Explicit selections bypass the guard.** An `ENGRAM_BIN` or `ENGRAM_URL` you set is never replaced or removed (with only `ENGRAM_URL`, `ENGRAM_BIN` is still the verified core, or the guard without one, never a `PATH` engram); memory is still marked disabled through the policy, which only 0.4.2+ honors. An `ENGRAM_SERVER_MODE` you set is passed through untouched; Shell never selects one.
277
+ - **Windows.** The guard has no `.exe`; spawning it fails (for example `ENOENT` or `EINVAL`), which still fails closed, but no notice is printed.
264
278
 
265
279
  #### Compatible reuse and authorization
266
280
 
267
- `GET /compatibility` (published in Engram 3.4.0 through PR #1792; 3.3.2 answers 404) must return `status: "ready"`, `active_reuse_authorized: true`, `capability: "startup-verified-store-v1"`, `revision: 1`, `source: "active"`, 32-hex `instance_id` and `runtime_id`, and no `offline_automatic_opening_authorized: true`. The endpoint uses the server's `requireAuth`: open when the **server** has no `ENGRAM_HTTP_TOKEN`, otherwise it needs `Authorization: Bearer <token>`. Shell owns no such secret and sends none, so a token-protected server answers 401 and stays unknown (disabled).
281
+ `GET /compatibility` (published in Engram 3.4.0 through PR #1792; 3.3.2 answers 404) must return `status: "ready"`, `active_reuse_authorized: true`, `capability: "startup-verified-store-v1"`, `revision: 1`, `source: "active"`, 32-hex `instance_id` and `runtime_id`, and no `offline_automatic_opening_authorized: true`. Engram 3.5.2's plain `serve` answers exactly this. The endpoint uses the server's `requireAuth`: open when the **server** has no `ENGRAM_HTTP_TOKEN`, otherwise it needs `Authorization: Bearer <token>`. Shell owns no such secret and sends none, so a token-protected server answers 401 and stays unknown (disabled). The server Shell starts never inherits `ENGRAM_HTTP_TOKEN`.
268
282
 
269
283
  #### Recovery and setup
270
284
 
271
- When the running server's `/health` reports a valid 32-hex `instance_id` and a canonical numeric `x.y.z` version (optional `v` prefix, no leading zeros, at most four digits per component) older than 3.4.0, and `/compatibility` does not answer ready, the notice names that version and asks to back up the data, update **that server** to 3.4.0 or later with its own installation method, and restart it. The version only selects this wording: memory stays disabled, and any other version string is never shown. Otherwise, when disabled, Shell explains that it **could not verify safe store or server reuse**. Matching versions or updating alone do not prove compatibility. Reuse requires the verified active `/compatibility` contract or matching Shell-provisioned store identity under the rules above. Back up existing data before manual changes; do not delete the store, fabricate provenance, or bypass the safety check. Shell rechecks on every launch and remains usable without memory. It performs no migration, deletion, or process termination.
285
+ When the running server's `/health` reports a valid 32-hex `instance_id` and a canonical numeric `x.y.z` version (optional `v` prefix, no leading zeros, at most four digits per component) older than 3.4.0, and `/compatibility` does not answer ready, the notice names that version and asks to back up the data, update **that server** to 3.4.0 or later with its own installation method, and restart it. The version only selects this wording: memory stays disabled, and any other version string is never shown. Otherwise, when disabled, Shell explains that it **could not verify safe server reuse**. Matching versions or updating alone do not prove compatibility. Back up existing data before manual changes; do not delete the store or bypass the safety check. Shell rechecks on every launch and remains usable without memory. Ordinary startup performs no migration, deletion, or process termination.
272
286
 
273
287
  Engram 3.3.2 does not expose `/compatibility`, so reinstalling that version cannot authorize reuse of an existing global store. [Engram 3.4.0](https://github.com/Gentleman-Programming/engram/releases/tag/v3.4.0) includes the endpoint from PR #1792. Back up the existing store before updating its server through its own installation method, then restart that server and Shell. Updating Shell's bundled binary does not replace an already-running global server. Reuse still requires a valid ready response, not just the version number; a token-protected server cannot provide it to Shell's unauthenticated probe. Do not disable authentication to bypass this policy or use an unpublished build.
274
288
 
275
- The memory decision never skips or fails setup: `gentle-shell setup` always publishes the verified core, runs Gentle AI and pins the companion, as before. Gentle AI 4.0.0 `install --agent pi` runs no `engram setup` for Pi, and `pi-engram init` only edits settings, so neither opens a store. Setup reclassifies after publishing the core, and the decision only selects the Engram environment its children and the launched Pi receive. On a new machine the wizard publishes the runtime without Engram, so the first `gentle-shell setup` publishes the core and the following launch is the fresh one that records provenance. Setup and every launch pin `npm:gentle-engram@0.4.2` through Pi's own `install` command (configuration only) and verify the declaration plus `engram.startupPolicy: 1`; a failed check is reported and Shell still starts, protected by the guard. `setup --dry-run` installs nothing.
289
+ The memory decision never skips or fails setup: `gentle-shell setup` always publishes the verified core, runs Gentle AI and pins the companion, as before. Gentle AI 4.0.0 `install --agent pi` runs no `engram setup` for Pi, and `pi-engram init` only edits settings, so neither opens a store. Setup reclassifies after publishing the core, and the decision only selects the Engram environment its children and the launched Pi receive. On a new machine the wizard publishes the runtime without Engram, so the first `gentle-shell setup` publishes the core and the following launch starts the shared server. Setup and every launch pin `npm:gentle-engram@0.4.2` through Pi's own `install` command (configuration only) and verify the declaration plus `engram.startupPolicy: 1`; a failed check is reported and Shell still starts, protected by the guard. `setup --dry-run` installs nothing.
290
+
291
+ #### Explicit recovery after a core upgrade
292
+
293
+ Earlier Shell releases provisioned `~/.engram` themselves and recorded `<prefix>/config/engram-provenance.json`; ordinary startup no longer reads that record. To migrate such a **Shell-provisioned store** with the bundled core explicitly, stop every Engram client and server using the directory, retain a complete backup (including WAL and configuration), then run:
294
+
295
+ ```sh
296
+ gentle-shell memory migrate --confirm-quiescent
297
+ ```
298
+
299
+ **Release dependency:** this requires a published bundled core advertising `migrate-copy`. The pinned Engram 3.5.2 implements it; Engram 3.4.0 did not. Shell checks help in an isolated home and refuses without invoking an unknown migration command or changing the source/provenance. Do not substitute an unpublished binary, edit hashes, or assume equal schema versions authorize recovery.
300
+
301
+ When supported, the provider copies the complete directory to a new sibling and validates/migrates only that copy. Shell checks the provider's directory and identity evidence, renames the original to the reported `backup_dir`, promotes the copy, and atomically replaces its core-bound provenance. Success prints one JSON record with `status: "migrated"`, `instance_id`, and `backup_dir`. Keep that backup until you have verified your records in Shell. Provider failures preserve the original and provenance; any incomplete copy is identified and retained, never promoted. Explicit foreign data locations or endpoints are not adopted by this command.
302
+
303
+ The confirmation is an operator assertion, not a process lock: source hashes detect observed changes but do not establish that every writer has stopped. Never run recovery while another integration is using the store.
304
+
305
+ #### Recovering an interrupted migration
306
+
307
+ A marker at `<prefix>/config/engram-migration.json` blocks memory before probes or starting a server. It records the `source`, `output`, `backup` paths and `originalProvenance`. **Keep clients stopped and do not simply remove this marker.** Preserve all paths while inspecting them.
308
+
309
+ To roll back an interrupted promotion, first verify the paths and recorded instance identity. If `backup` exists, it is the original directory: retain any current `source` under a separate quarantine name, then restore `backup` to `source`. If no backup exists, do not replace the original source with the incomplete output. Restore `originalProvenance` atomically to `<prefix>/config/engram-provenance.json`, preserving the old core hash exactly. Only after source identity and provenance are reconciled may the marker be removed. Retain the migration output for diagnosis. If these facts cannot be established, leave the marker and request recovery assistance rather than guessing.
310
+
311
+ No automatic retry, store deletion, or server termination is performed.
276
312
 
277
313
  #### Known limits
278
314
 
279
- - **Shared-store residuals.** Provenance proves Shell's core created the store, not that no other Engram opened it since. A different Engram that changed the store without raising `user_version` (for example same-schema repairs) is not detected without reading the database, and changes still only in the WAL are not visible in the header.
280
- - **Concurrent creation.** Another client that uses Shell's freshly provisioned directory (same `.instance-id`) during or after the session is not distinguishable from Shell's own core, beyond the header check. A held identity lock makes provisioning time out and disables memory for that launch.
281
- - **Failed provisioning.** If the identity was created but the record could not be written, later launches see an unrecorded store and keep memory disabled; the notice explains how to recover.
315
+ - **Shared-store residuals.** The header tripwire only sees a newer schema recorded in `engram.db`'s header. A different Engram that changed the store without raising `user_version`, or changes still only in the WAL, are not detected without reading the database; the server that opens the store owns its migrations.
316
+ - **A detached server keeps running.** The server Shell starts is not tied to Pi's lifetime, by design (it is shared). Stop it like any Engram server when you no longer want it; Shell starts it again on the next launch if nothing listens.
282
317
  - **Older or other integrations.** gentle-engram versions before 0.4.1, and integrations that do not reach data through `ENGRAM_BIN` (for example an MCP launcher running `engram` from `PATH`), are not covered by the guard.
283
318
  - **Non-bundled installs** keep their previous behavior.
284
319
 
@@ -289,7 +324,7 @@ S9. Everything Gentle AI and gentle-pi keep lives in the prefix, except Engram's
289
324
  | Process | Gets |
290
325
  |---|---|
291
326
  | `gentle-shell setup` (the pinned `gentle-ai install --agent pi`) | `GENTLE_AI_HOME=<prefix>/gentle-ai`, `GENTLE_AI_PI_CONFIG_DIR=<prefix>/config/gentle-ai`, `GENTLE_AI_ENGRAM_BIN=<prefix>/runtime/engram-<v>/engram`, `GENTLE_AI_NO_SELF_UPDATE=1` and `GENTLE_PI_CONFIG_HOME=<prefix>/config`. |
292
- | Pi and its subagents | `GENTLE_SHELL_PREFIX=<prefix>` and the memory startup policy; `ENGRAM_BIN` is the verified `<prefix>/runtime/engram-<v>/engram` when memory is allowed locally, otherwise the Shell guard (plus `ENGRAM_URL` for verified reuse). An explicit `ENGRAM_BIN` or `ENGRAM_URL` is kept as is ([Engram startup safety](#engram-startup-safety)). No `GENTLE_AI_*` variable, and `GENTLE_PI_CONFIG_HOME` is left as the user has it. |
327
+ | Pi and its subagents | `GENTLE_SHELL_PREFIX=<prefix>` and the memory startup policy; `ENGRAM_BIN` is the Shell guard, plus `ENGRAM_URL=http://127.0.0.1:7437` when the shared server is verified. An explicit `ENGRAM_BIN` or `ENGRAM_URL` is kept as is ([Engram startup safety](#engram-startup-safety)). No `GENTLE_AI_*` variable, and `GENTLE_PI_CONFIG_HOME` is left as the user has it. |
293
328
  | gentle-pi's own `gentle-ai` runs (review, telemetry trigger, runtime metrics) | The same five variables as setup. |
294
329
  | The agent's shell | Pi's environment: the user's own plus the Pi row above. |
295
330
 
@@ -299,10 +334,10 @@ S9. Everything Gentle AI and gentle-pi keep lives in the prefix, except Engram's
299
334
  - **Aligned with Gentle AI 4.0.0.** Gentle AI 4.0.0 reads `GENTLE_PI_CONFIG_HOME` as the parent of its own `gentle-ai` folder: `piBackgroundPolicyPath` in `internal/cli/pi_background.go` writes `<GENTLE_PI_CONFIG_HOME>/gentle-ai/background-subagents.json`, else `~/.pi/gentle-ai/...`. So the config home is `<prefix>/config/gentle-ai`, and only the Gentle AI processes Gentle Shell starts also get `GENTLE_PI_CONFIG_HOME=<prefix>/config`. The policy 4.0.0 writes during setup then lands in the bundled config home, and a release with gentle-ai#5462 writes the same folder through `GENTLE_AI_PI_CONFIG_DIR`. In 4.0.0 only `install`, `sync` and their dry runs read it (the background-policy projection); review and telemetry runs do not, and get it only so every Gentle AI process Gentle Shell starts agrees.
300
335
  - **Gentle AI's variables never reach Pi.** Pi's bash tool would pass them to a `gentle-ai` the user runs in the agent's shell, and that run would then use the prefix. Instead, `gentleAiIsolationEnv` (`lib/gentle-ai-binary.ts`) adds them to each `gentle-ai` that a bundled gentle-pi starts itself (the central `gentleAiProcessEnvironment`, the review relay, the runtime metrics send and the telemetry trigger), and the launcher adds them to setup. `GENTLE_AI_ENGRAM_BIN` is set only when our Engram is published.
301
336
  - **Engram.** `ensureEngram` (`scripts/bundled-install.mjs`) publishes the pinned Engram release under `runtime/engram-<v>/`. The archive is checked against its pinned size and sha256 from the release's `checksums.txt`. Only the `engram` (or `engram.exe`) regular file is written. `engram version` must print `engram <v>` from the staging folder before the folder is published. `ensureRuntime({ engram: true })` includes it. `gentle-shell setup` in a bundled install ensures it before it runs Gentle AI, and stops if it cannot, whatever the memory decision ([Engram startup safety](#engram-startup-safety)). `gentle-shell upgrade` and `--rollback` pass `engram: true` to the release's own `ensureRuntime`. With `GENTLE_AI_ENGRAM_BIN`, Gentle AI uses that binary as is: no brew, download, `go install`, `PATH` or registry change, and no `go` or `brew` dependency probes.
302
- - **gentle-engram.** The gentle-engram Pi extension finds Engram only through `ENGRAM_BIN`, read once when it loads, and otherwise runs `engram` from `PATH`. So Pi gets `ENGRAM_BIN` (the core or the guard), and no `PATH` entry is added. An `ENGRAM_BIN` the user set is kept. The agent's shell inherits `ENGRAM_BIN` too, so an Engram MCP launcher started there through `ENGRAM_BIN` uses the same core or guard.
337
+ - **gentle-engram.** The gentle-engram Pi extension finds Engram only through `ENGRAM_BIN`, read once when it loads, and otherwise runs `engram` from `PATH`. So Pi gets `ENGRAM_BIN` (the guard; memory reaches the shared server through `ENGRAM_URL`), and no `PATH` entry is added. An `ENGRAM_BIN` the user set is kept. The agent's shell inherits `ENGRAM_BIN` too, so an Engram MCP launcher started there through `ENGRAM_BIN` uses the same guard.
303
338
  - **Personas.** Setup snapshots and restores the persona Gentle AI may rewrite: the prefix's `config/gentle-ai/persona.json`, and also the user's `~/.pi/gentle-ai/persona.json`. A Gentle AI release without the variables still writes the user's file, and restoring an unchanged file does nothing. The managed-asset record is restored only in the user's `~/.gentle-ai/state.json`; the prefix's record belongs to the pinned Gentle AI.
304
339
  - **pi-pretty and prompt history.** In bundled mode only, the pi-pretty wrapper passes `deps.sdk` with Pi's five tool factories and `getAgentDir`, so its FFF database lands in `<agent home>/pi-pretty/fff`, and prompt history keeps its store under `<agent home>/history` ([Prompt history](prompt-history.md)). Elsewhere both keep their existing locations: Pi's deps reach pi-pretty unchanged (`$HOME/.pi/agent/pi-pretty/fff`, or no store without `HOME`), and history stays under `~/.pi/agent/history`, also in the isolated home of a pnpm or npm install, so existing histories are not left behind.
305
- - **Effective with a later Gentle AI.** gentle-pi pins Gentle AI 4.1.1 today (`INSTALLER_VERSION`); the following are historical compatibility notes for Gentle AI 4.0.0, which ignores the four `GENTLE_AI_*` variables. Whether 4.1.1 includes gentle-ai#5462 is unverified here. Until gentle-pi pins a Gentle AI release that contains gentle-ai#5462:
340
+ - **Effective with a later Gentle AI.** gentle-pi pins Gentle AI 4.3.1 today (`INSTALLER_VERSION`); the following are historical compatibility notes for Gentle AI 4.0.0, which ignores the four `GENTLE_AI_*` variables. Whether 4.3.1 includes gentle-ai#5462 is unverified here. Until gentle-pi pins a Gentle AI release that contains gentle-ai#5462:
306
341
  - Setup still writes `~/.gentle-ai` and `~/.pi/gentle-ai`, with the restores above, and still acquires Engram its own way.
307
342
  - The persona goes to the user's `~/.pi/gentle-ai/persona.json` (Gentle AI 4.0.0 resolves it from the OS home) and is restored there. The prefix's `config/gentle-ai/persona.json` is not created by setup.
308
343
  - The background-subagents policy already lands in `<prefix>/config/gentle-ai/` through `GENTLE_PI_CONFIG_HOME=<prefix>/config` (see above).
@@ -1,6 +1,10 @@
1
1
  # Delegated verification
2
2
 
3
- How the Gentle Pi orchestrator decides who verifies a bounded writer's work. The always-on parent prompt renders a `Receipt-driven development: on|off|unknown` line; the verification module (`assets/orchestrator-verification.md`, Verification rule) keys the verification rule on it. This page is package-owned; `docs/review-integration.md` mirrors the Gentle AI contract and must stay byte-identical to it.
3
+ How the Gentle Pi orchestrator decides who verifies a bounded writer's work. The always-on parent prompt renders a `Receipt-driven development: on|off|unknown` line; the verification module (`assets/orchestrator-verification.md`, Verification rule) keys the verification rule on it. Because the line sits in the cached system-prompt prefix, a session keeps the first line it rendered and re-renders it only when RDD turns off or back on (which also drops or restores the review execution contract); an `unknown` to `on` flip or a deciding-source change keeps the original text, and review tools always read the live mode. While the pinned line reads `off`, the parent request also carries a lean review loadout: `gentle_review` keeps its schema but its snippet, guidelines, and description cover only `assess`, and the `gentle_review_capture`, `gentle_review_capture_group`, and `gentle_review_scope` declarations are hidden (they stay registered and active). The loadout follows the pinned line, so it changes only at the next run after RDD turns off or back on, together with the review execution contract; `on` and `unknown` keep the full registered text. This page is package-owned; `docs/review-integration.md` mirrors the Gentle AI contract and must stay byte-identical to it.
4
+
5
+ ## Background capability admission
6
+
7
+ An explicit agent `tools` declaration containing `bash_background` requires the background-subagents policy to resolve to `on` at dispatch, for both task and background launches. Otherwise the runner fails the task before spawn and reports the policy file, opt-in schema, and `/gentle:background-subagents enable|disable|status`. Fix the deciding policy explicitly; automation must not toggle it. Passing admission does not promise child background-tool support (future Slices 2–3); ordinary missing-tool reporting remains the backstop. See the [policy contract](readme-reference.md#capability-reference).
4
8
 
5
9
  ## Receipt-driven development on
6
10
 
@@ -23,7 +27,7 @@ A recorded outcome is keyed by the candidate's own target identity, never by rep
23
27
 
24
28
  ### How `assess` resolves the writer profile (gentle-pi#1175)
25
29
 
26
- The writer profile comes from the runtime-recorded model and effort of the pending mutations for the root (`writerProfileSource: runtime`). Caller `writerModelId`/`writerEffort` are only a fallback when no runtime evidence exists (`caller`); with neither, the profile is small (`fallback`). A missing model, a `mini` model token (`gemini` is not mini), or `low` effort keeps the conservative small-model bias.
30
+ The writer profile comes from the runtime-recorded model and effort of the pending mutations for the root (`writerProfileSource: runtime`). Caller `writerModelId`/`writerEffort` are only a fallback when no runtime evidence exists (`caller`); with neither, the profile is small (`fallback`). The writer profile is reported but never adds a verifier: a `mini` model or `low` effort gets the same plan as any other writer.
27
31
 
28
32
  ### What `assess` projects
29
33
 
@@ -31,18 +35,22 @@ When native reports them, `assess` projects `reviewDue`, `reviewDueReason`, `can
31
35
 
32
36
  ## Receipt-driven development off or unknown (gentle-pi#662)
33
37
 
34
- The host exposes one read-only native operation: `gentle-ai review assess --cwd <repo> [--base-ref <ref> --committed-only] --json` (gentle-ai#4295). It is decoded by `lib/review-risk-assessment.ts` and wired through `lib/native-review-cli.ts` exactly like the existing `reviewMode` STATUS reader -- a bounded subprocess with a typed decode, never a mutation. A non-zero exit, a failure envelope, or an older binary without the verb all fail closed to `high` risk.
38
+ The host exposes one read-only native operation: `gentle-ai review assess --cwd <repo> [--base-ref <ref> --committed-only] --json` (gentle-ai#4295). It is decoded by `lib/review-risk-assessment.ts` and wired through `lib/native-review-cli.ts` exactly like the existing `reviewMode` STATUS reader -- a bounded subprocess with a typed decode, never a mutation. A non-zero exit, a failure envelope, or an older binary without the verb all report native risk `unassessable`, which informs only: the plan is medium and adds no independent verifier unless the agent escalates.
35
39
 
36
40
  The `gentle_review` tool's `assess` operation (`extensions/gentle-ai.ts`) combines that assessment with the rendered `Receipt-driven development:` line to decide whether a delegated writer's change needs a separate `gentle-ai-verify` run, following this tier table:
37
41
 
38
- | Native risk tier | Verification when RDD is `off`/`unknown` |
42
+ | Tier | Verification when RDD is `off`/`unknown` |
39
43
  | --- | --- |
40
44
  | passive | structural readback by the parent; no separate verifier, no tests |
41
- | medium | writer self-verification stands; a separate `gentle-ai-verify` run is added only when the writer profile is a small model (mini or low effort) |
42
- | high | writer self-verification plus a separate `gentle-ai-verify` run, always |
43
- | unknown / assess failed | treated as high |
45
+ | medium | writer self-verification stands; no separate verifier, whatever model wrote the change |
46
+ | high | only through `escalate` naming a Task Size high-risk item: writer self-verification plus one separate `gentle-ai-verify` run |
47
+ | native high, unknown, or assess failed | informs only: writer self-verification stands; escalate when a named high-risk item applies |
48
+
49
+ The plan risk (`risk`) is high only with an escalation; otherwise a native passive stays passive and every other native tier is medium. The native tier stays visible as `nativeRisk`. The independent verifier is for concrete occasions: the plan adds it only when `escalate` names a Task Size high-risk item, never for size, a native tier alone, a failed assessment, or the model or effort that wrote the change.
50
+
51
+ With RDD off, ASSESS remains read-only even when native reports `reviewDue` or a continuation: relay those fields unchanged, but do not execute the continuation, invoke STATUS or another review lifecycle operation, or enable RDD based on assessment metadata. Continue the verification plan and applicable functional checks; the named-risk independent verifier remains required.
44
52
 
45
- This table applies in every RDD state; a closed native review never removes a verifier the tier requires. The small-model bias raises the medium tier to high for verification purposes only; an unknown RDD line never lowers a tier below `off`. The parent's own spot check (re-running one reported command before delivery) stays required in every tier.
53
+ This table applies in every RDD state; a closed native review never removes a verifier the tier requires. An unknown RDD line never lowers a tier below `off`. The parent's own spot check (re-running one reported command before delivery) stays required in every tier.
46
54
 
47
55
  A native code review is not a substitute for applicable functional checks: tests, builds, and functional verification such as browser checks for UI changes still run when applicable. Review outcomes never authorize delivery; human consent for native review and the user-owned RDD switch are unchanged.
48
56