@moretea-labs/forge 1.8.1 → 1.8.2

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 (328) hide show
  1. package/AGENTS.md +5 -2
  2. package/CHANGELOG.md +20 -0
  3. package/README.en.md +24 -3
  4. package/README.md +10 -6
  5. package/README.zh-CN.md +5 -3
  6. package/THIRD_PARTY_NOTICES.md +1 -2
  7. package/adapters/chatgpt/browser-delivery-runtime.ts +5 -3
  8. package/adapters/chatgpt/provider-delivery.ts +1 -1
  9. package/adapters/chatgpt/work-conversation-binding-store.ts +20 -1
  10. package/adapters/computer/chatgpt-extension-target.ts +295 -50
  11. package/adapters/computer/chrome-extension/background.js +227 -71
  12. package/adapters/computer/chrome-extension/content.js +181 -157
  13. package/adapters/computer/chrome-extension/manifest.json +3 -1
  14. package/adapters/computer/desktop-operator-provider.ts +18 -6
  15. package/adapters/computer/interaction-target-authority.ts +39 -9
  16. package/adapters/mcp/access-mode.ts +18 -39
  17. package/adapters/mcp/auth.ts +2 -6
  18. package/adapters/mcp/instructions.ts +2 -2
  19. package/adapters/mcp/multi-repository.ts +7 -28
  20. package/adapters/mcp/runtime-gateway/context-adapter.ts +79 -40
  21. package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +7 -15
  22. package/adapters/mcp/runtime-gateway/execution-tools.ts +7 -13
  23. package/adapters/mcp/runtime-gateway/plugin-adapter.ts +16 -3
  24. package/adapters/mcp/runtime-gateway/process-tools.ts +3 -21
  25. package/adapters/mcp/runtime-gateway/router.ts +3 -5
  26. package/adapters/mcp/runtime-gateway/routing-policy.ts +17 -10
  27. package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1 -1
  28. package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +14 -9
  29. package/adapters/mcp/runtime-gateway/runtime-tools.ts +1 -5
  30. package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +36 -1
  31. package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +58 -4
  32. package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +7 -3
  33. package/adapters/mcp/runtime-gateway/work-adapter.ts +16 -16
  34. package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +0 -17
  35. package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +69 -12
  36. package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +26 -2
  37. package/adapters/mcp/server.ts +24 -3
  38. package/adapters/mcp/setup.ts +4 -10
  39. package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
  40. package/adapters/mcp/tool-mapping/legacy-tool-service.ts +672 -2935
  41. package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +1 -1
  42. package/adapters/mcp/tool-mapping/repository-tools.ts +52 -86
  43. package/adapters/mcp/toolset-names.ts +11 -42
  44. package/adapters/mcp/toolset.ts +16 -90
  45. package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
  46. package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
  47. package/adapters/mcp/transports/http-observation.ts +18 -6
  48. package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
  49. package/adapters/mcp/transports/http.ts +54 -14
  50. package/adapters/mcp/types.ts +0 -6
  51. package/assets/hooks/lib/session-state.sh +0 -38
  52. package/assets/hooks/post-bash.sh +1 -1
  53. package/assets/hooks/post-tool-observer.sh +0 -5
  54. package/assets/hooks/prompt-guard.sh +0 -55
  55. package/assets/partials/04-project-structure.partial.md +1 -1
  56. package/assets/partials/07-footer.partial.md +1 -1
  57. package/assets/partials-agents/02-operating-mode.partial.md +1 -1
  58. package/assets/partials-agents/08-deep-docs.partial.md +1 -1
  59. package/assets/reference-configs/agentic-development-flow.md +1 -1
  60. package/assets/reference-configs/external-tooling.md +0 -76
  61. package/assets/reference-configs/release-deploy.md +1 -1
  62. package/assets/templates/helpers/architecture-queue.sh +1 -1
  63. package/assets/templates/helpers/check-agent-tooling.sh +1 -327
  64. package/assets/templates/helpers/check-task-workflow.sh +1 -1
  65. package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
  66. package/assets/templates/helpers/migrate-project-template.sh +2 -2
  67. package/assets/workflow-contract.v1.json +0 -2
  68. package/docs/README.md +5 -2
  69. package/docs/architecture/CURRENT.md +114 -30
  70. package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
  71. package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +15 -2
  72. package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +4 -2
  73. package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +109 -4
  74. package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
  75. package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
  76. package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
  77. package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
  78. package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
  79. package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
  80. package/docs/architecture/domains/public-surface.md +3 -5
  81. package/docs/architecture/domains/verification.md +5 -5
  82. package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +2 -2
  83. package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
  84. package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
  85. package/docs/forge-plugin-management.md +14 -2
  86. package/docs/operations/controller-browser-plugin.md +23 -0
  87. package/docs/operations/features.md +6 -7
  88. package/docs/operations/features.zh-CN.md +1 -1
  89. package/docs/operations/github-repository.md +4 -4
  90. package/docs/operations/github-semantic-release-projection.md +20 -0
  91. package/docs/operations/homebrew.md +2 -2
  92. package/docs/operations/mcp-tool-exposure.md +13 -54
  93. package/docs/operations/runtime-performance-diagnostics.md +8 -0
  94. package/docs/operations/standalone-disaster-recovery.md +1 -1
  95. package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
  96. package/docs/tutorials/03-first-repository-task.md +2 -0
  97. package/docs/wiki/Computer-and-Plugins.md +78 -0
  98. package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
  99. package/docs/wiki/Home.md +16 -2
  100. package/docs/wiki/Implementation.md +24 -12
  101. package/docs/wiki/Installation.md +28 -32
  102. package/docs/wiki/Integrations.md +4 -0
  103. package/docs/wiki/Quick-Start.md +35 -22
  104. package/docs/wiki/Releases-and-Upgrades.md +15 -25
  105. package/docs/wiki/_Sidebar.md +5 -1
  106. package/package.json +1 -12
  107. package/packages/kernel/controller/infrastructure/controller-session-store.ts +63 -38
  108. package/packages/kernel/identity/infrastructure/activity-projection-store.ts +10 -0
  109. package/packages/kernel/scheduler/application/eligibility.ts +4 -1
  110. package/packages/kernel/scheduler/infrastructure/schedule-store.ts +13 -10
  111. package/packages/kernel/work/application/work-service.ts +1 -0
  112. package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
  113. package/packages/kernel/work/domain/state-machine.ts +9 -2
  114. package/packages/kernel/work/infrastructure/work-contract-store.ts +28 -1
  115. package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
  116. package/packages/plugin-runtime/computer/conversation-target.ts +17 -7
  117. package/scripts/assemble-template.ts +11 -72
  118. package/scripts/check-mcp-compatibility.ts +55 -74
  119. package/scripts/check-package-identity.mjs +0 -5
  120. package/scripts/check-runtime-architecture.mjs +305 -28
  121. package/scripts/init-project.sh +0 -46
  122. package/scripts/install-ios-hid-toolchain.sh +60 -0
  123. package/scripts/install-standalone-recovery.ts +1 -1
  124. package/scripts/lib/project-init-lib.sh +3 -3
  125. package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
  126. package/scripts/open-source-audit-allowlist.txt +0 -1
  127. package/scripts/run-governed-gate.ts +2 -0
  128. package/scripts/smoke-ios-physical-device.ts +38 -10
  129. package/scripts/smoke-mcp-http-runtime.ts +7 -8
  130. package/scripts/smoke-mcp-tool-surface.ts +27 -41
  131. package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +6 -3
  132. package/scripts/sync-generated-authority.mjs +0 -1
  133. package/src/cli/agent-jobs/executor-health.ts +1 -1
  134. package/src/cli/agent-jobs/integration.ts +2 -2
  135. package/src/cli/chatgpt-browser/file-policy.ts +2 -2
  136. package/src/cli/commands/doctor.ts +1 -143
  137. package/src/cli/commands/global-runtime.ts +3 -196
  138. package/src/cli/commands/init-hook.ts +6 -23
  139. package/src/cli/commands/init.ts +3 -252
  140. package/src/cli/commands/mcp.ts +0 -5
  141. package/src/cli/commands/prompt-guard-decision.ts +0 -2
  142. package/src/cli/commands/recovery.ts +2 -14
  143. package/src/cli/commands/repository.ts +17 -1
  144. package/src/cli/commands/setup-execution.ts +41 -0
  145. package/src/cli/controller/completion-orchestrator.ts +1 -1
  146. package/src/cli/controller/composite-operations.ts +1 -1
  147. package/src/cli/controller/context/instruction-context.ts +1 -1
  148. package/src/cli/controller/context/known-paths.ts +2 -2
  149. package/src/cli/controller/context/query-planning.ts +11 -4
  150. package/src/cli/controller/context/rule-resolution.ts +2 -2
  151. package/src/cli/controller/context/source-materializer.ts +2 -2
  152. package/src/cli/controller/context/structural-provider.ts +84 -0
  153. package/src/cli/controller/context/structural.ts +6 -6
  154. package/src/cli/controller/context/types.ts +8 -9
  155. package/src/cli/controller/context-pack.ts +97 -76
  156. package/src/cli/controller/operational-plan.ts +1 -1
  157. package/src/cli/controller/systemd-user.ts +4 -10
  158. package/src/cli/editing/edit-session.ts +17 -5
  159. package/src/cli/github/github.ts +4 -4
  160. package/src/cli/github/semantic-projection.ts +174 -0
  161. package/src/cli/hook/prompt-intents.ts +0 -9
  162. package/src/cli/index.ts +1 -43
  163. package/src/cli/local-bridge/connector-freshness.ts +1 -12
  164. package/src/cli/local-bridge/console-automations.ts +1 -1
  165. package/src/cli/local-bridge/console-view-models.ts +1 -1
  166. package/src/cli/local-bridge/facade-api.ts +0 -2
  167. package/src/cli/repositories/command-classifier.ts +0 -9
  168. package/src/cli/repositories/command-scope.ts +2 -2
  169. package/src/cli/repositories/locks.ts +20 -0
  170. package/src/cli/repositories/registry.ts +2 -1
  171. package/src/cli/repositories/safe-patch.ts +2 -12
  172. package/src/cli/repositories/structured-git.ts +39 -3
  173. package/src/cli/repository/inspector.ts +185 -343
  174. package/src/effects/process-runner.ts +17 -1
  175. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  176. package/src/runtime/context/semantic-navigation-contract.ts +7 -0
  177. package/src/runtime/context/semantic-navigation.ts +1 -1
  178. package/src/runtime/control-plane/cleanup-artifact-retention.ts +4 -4
  179. package/src/runtime/control-plane/execution/work-delivery-service.ts +150 -31
  180. package/src/runtime/control-plane/execution/work-handle-authority.ts +12 -4
  181. package/src/runtime/control-plane/execution/work-handle-store.ts +53 -1
  182. package/src/runtime/control-plane/execution/work-operation-service.ts +20 -10
  183. package/src/runtime/control-plane/execution/work-preparation-service.ts +108 -4
  184. package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
  185. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +28 -13
  186. package/src/runtime/control-plane/execution/work-validation-reconciler.ts +5 -1
  187. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +1 -1
  188. package/src/runtime/control-plane/facade/capability-registry.ts +2 -0
  189. package/src/runtime/control-plane/facade/work-continuation.ts +1 -1
  190. package/src/runtime/control-plane/generated-cache-retention.ts +114 -63
  191. package/src/runtime/control-plane/global-scheduler/maintenance.ts +20 -8
  192. package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -11
  193. package/src/runtime/control-plane/governance/external-effects.ts +1 -1
  194. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +1 -0
  195. package/src/runtime/control-plane/runtime-cleanup.ts +12 -93
  196. package/src/runtime/evidence/sensitive-output.ts +22 -2
  197. package/src/runtime/execution/jobs/child-reference.ts +11 -0
  198. package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
  199. package/src/runtime/execution/process-runtime/command-facade.ts +3 -3
  200. package/src/runtime/execution/process-runtime/runtime.ts +20 -16
  201. package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
  202. package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
  203. package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
  204. package/src/runtime/execution/workers/executor.ts +1 -2
  205. package/src/runtime/maintenance/cleanup.ts +41 -5
  206. package/src/runtime/plugins/action-application.ts +12 -1
  207. package/src/runtime/plugins/app-store-connect-adapter.ts +252 -4
  208. package/src/runtime/plugins/browser-adapter.ts +381 -313
  209. package/src/runtime/plugins/browser-macos-bridge.ts +114 -112
  210. package/src/runtime/plugins/browser-manifest-surface.ts +2 -1
  211. package/src/runtime/plugins/browser-registration.ts +2 -0
  212. package/src/runtime/plugins/browser-runtime.ts +26 -35
  213. package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +11 -2
  214. package/src/runtime/plugins/computer-registration.ts +76 -9
  215. package/src/runtime/plugins/github-adapter.ts +30 -3
  216. package/src/runtime/plugins/gmail-adapter.ts +166 -1
  217. package/src/runtime/plugins/google-shared.ts +10 -5
  218. package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
  219. package/src/runtime/plugins/ios-adapter.ts +45 -40
  220. package/src/runtime/plugins/ios-agent-device.ts +54 -4
  221. package/src/runtime/plugins/ios-device-ownership.ts +103 -0
  222. package/src/runtime/plugins/ios-physical-device.ts +497 -79
  223. package/src/runtime/plugins/local-system-adapter.ts +1 -99
  224. package/src/runtime/plugins/store.ts +80 -7
  225. package/src/runtime/plugins/types.ts +4 -0
  226. package/src/runtime/projections/git-status-sampler.ts +2 -19
  227. package/src/runtime/recovery/actions.ts +1 -1
  228. package/src/runtime/recovery/lifecycle-inventory.ts +1 -11
  229. package/src/runtime/recovery/probe.ts +2 -2
  230. package/src/runtime/release/release-coordinator.ts +20 -4
  231. package/src/runtime/root/controller-progression-composition.ts +67 -5
  232. package/src/runtime/root/package-connector-service.ts +123 -11
  233. package/src/runtime/root/package-runtime-release.ts +6 -18
  234. package/src/runtime/root/package-runtime-service.ts +7 -13
  235. package/src/runtime/root/release-execution-canary.ts +18 -5
  236. package/src/runtime/root/release-manifest.ts +0 -34
  237. package/src/runtime/root/release-materialize.ts +0 -78
  238. package/src/runtime/root/runtime.ts +1 -2
  239. package/src/runtime/root/scheduled-controller-composition.ts +2 -1
  240. package/src/runtime/root/service.ts +90 -11
  241. package/src/runtime/root/types.ts +0 -6
  242. package/src/runtime/root/workflow-supervisor-composition.ts +207 -19
  243. package/src/runtime/root/workflow-supervisor-runtime.ts +365 -10
  244. package/src/runtime/safe-tooling/google-credential-store.ts +1 -11
  245. package/src/runtime/safe-tooling/ios-development.ts +22 -8
  246. package/src/runtime/safe-tooling/job-summary.ts +1 -1
  247. package/src/runtime/safe-tooling/workspace-auth.ts +4 -1
  248. package/src/runtime/shared/atomic-text-file.ts +21 -0
  249. package/src/runtime/shared/json-files.ts +8 -3
  250. package/src/runtime/standalone-recovery/core.ts +189 -174
  251. package/src/runtime/standalone-recovery/entry.ts +62 -30
  252. package/src/runtime/standalone-recovery/operation-lock.ts +11 -1
  253. package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -0
  254. package/src/runtime/workflow/schedules/engine.ts +36 -14
  255. package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
  256. package/src/runtime/workflow/schedules/work-continuation.ts +51 -6
  257. package/supervisor/client.ts +31 -14
  258. package/supervisor/control-plane.ts +210 -115
  259. package/supervisor/forge-validators.ts +88 -21
  260. package/supervisor/native-browser-adapter.ts +393 -28
  261. package/supervisor/native-messaging/host.ts +21 -2
  262. package/supervisor/protocol.ts +74 -26
  263. package/supervisor/server.ts +16 -8
  264. package/supervisor/store.ts +476 -57
  265. package/supervisor/types.ts +19 -13
  266. package/SKILL.md +0 -427
  267. package/adapters/computer/chatgpt-target-router.ts +0 -103
  268. package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +0 -87
  269. package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
  270. package/adapters/mcp/toolset-selection.ts +0 -41
  271. package/agents/openai.yaml +0 -4
  272. package/assets/skill-hooks.json +0 -41
  273. package/assets/skill-version.json +0 -189
  274. package/assets/skills/claude-review/SKILL.md +0 -231
  275. package/assets/skills/codex-review/SKILL.md +0 -103
  276. package/assets/templates/helpers/check-skill-version.ts +0 -193
  277. package/scripts/check-skill-version.ts +0 -5
  278. package/scripts/ensure-codegraph.sh +0 -16
  279. package/scripts/run-skill-hook.ts +0 -244
  280. package/scripts/sync-codex-installed-copies.sh +0 -182
  281. package/src/cli/commands/tools.ts +0 -167
  282. package/src/cli/mcp/access-mode.ts +0 -2
  283. package/src/cli/mcp/access-tools.ts +0 -2
  284. package/src/cli/mcp/audit.ts +0 -2
  285. package/src/cli/mcp/auth.ts +0 -2
  286. package/src/cli/mcp/instructions.ts +0 -2
  287. package/src/cli/mcp/legacy-context.ts +0 -2
  288. package/src/cli/mcp/legacy-tool-service.ts +0 -2
  289. package/src/cli/mcp/multi-repository.ts +0 -2
  290. package/src/cli/mcp/oauth.ts +0 -2
  291. package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
  292. package/src/cli/mcp/paths.ts +0 -2
  293. package/src/cli/mcp/policy.ts +0 -2
  294. package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
  295. package/src/cli/mcp/proxy-env.ts +0 -2
  296. package/src/cli/mcp/readiness-projection.ts +0 -2
  297. package/src/cli/mcp/redaction.ts +0 -2
  298. package/src/cli/mcp/repo.ts +0 -2
  299. package/src/cli/mcp/repository-tools.ts +0 -2
  300. package/src/cli/mcp/server.ts +0 -2
  301. package/src/cli/mcp/setup.ts +0 -2
  302. package/src/cli/mcp/tool-capability-cache.ts +0 -2
  303. package/src/cli/mcp/tool-contract.ts +0 -2
  304. package/src/cli/mcp/tools.ts +0 -2
  305. package/src/cli/mcp/toolset-names.ts +0 -2
  306. package/src/cli/mcp/toolset-selection.ts +0 -2
  307. package/src/cli/mcp/toolset.ts +0 -2
  308. package/src/cli/mcp/transports/http.ts +0 -2
  309. package/src/cli/mcp/transports/session-registry.ts +0 -2
  310. package/src/cli/mcp/transports/stdio.ts +0 -2
  311. package/src/cli/mcp/types.ts +0 -2
  312. package/src/cli/mcp/umbrella-tools.ts +0 -2
  313. package/src/cli/tools/codegraph.ts +0 -695
  314. package/src/core/adoption/helper-wrapper-plan.ts +0 -159
  315. package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
  316. package/src/runtime/context/codegraph-read-provider.ts +0 -611
  317. package/src/runtime/context/codegraph-sidecar.cjs +0 -248
  318. package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
  319. package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
  320. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
  321. package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
  322. package/src/runtime/gateway/mcp/process-tools.ts +0 -2
  323. package/src/runtime/gateway/mcp/router.ts +0 -2
  324. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
  325. package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
  326. package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
  327. package/src/runtime/plugins/browser-provider-registry.ts +0 -2
  328. package/src/runtime/plugins/computer-chatgpt-macos-target.ts +0 -891
@@ -1108,12 +1108,119 @@ requireText('adapters/controller-process/controller-host.ts', 'createProcessCont
1108
1108
  requireText('src/runtime/workflow/schedules/engine.ts', 'workflow_supervisor_owns_outer_turn');
1109
1109
  requireText('src/runtime/root/workflow-supervisor-composition.ts', 'registerWorkflowSupervisorTask');
1110
1110
  requireText('src/runtime/root/workflow-supervisor-composition.ts', 'reserveWorkflowSupervisorEnrollment');
1111
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', 'getWorkflowSupervisorTask(forgeHome, taskId)');
1112
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', "stall.state === 'terminal'");
1113
+ requireText('supervisor/control-plane.ts', 'if (exhaustedLeaf && this.store.providerResumeExhausted(exhaustedLeaf.effectId)) sourceEffect = exhaustedLeaf;');
1114
+ requireText('supervisor/store.ts', "if (first.action !== 'CONTINUE' || second.action !== 'CONTINUE' || third.action !== 'DONE') continue;");
1115
+ requireText('supervisor/store.ts', 'const minimumRuntimeInstances = 2;');
1116
+ requireText('supervisor/store.ts', "kind = 'terminal_done'");
1117
+ requireText('supervisor/types.ts', "actions: ['CONTINUE', 'CONTINUE', 'DONE'];");
1118
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', 'WORKFLOW_SUPERVISOR_TASK_REQUIREMENT_CONFLICT');
1111
1119
  requireText('supervisor/entry.ts', 'forgeWorkflowSupervisorValidators()');
1120
+ requireText('supervisor/store.ts', 'workflowSupervisorCompletionContractSha256');
1121
+ requireText('supervisor/store.ts', "'task_semantic_binding_revised'");
1122
+ requireText('supervisor/store.ts', 'WORKFLOW_SUPERVISOR_COMPLETION_CONTRACT_REVISION_CONFLICT');
1123
+ requireText('supervisor/store.ts', 'WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_CONFLICT');
1124
+ requireText('supervisor/control-plane.ts', 'WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_WORK_NOT_FOUND');
1125
+ requireText('supervisor/control-plane.ts', 'WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_REQUIREMENT_NOT_FOUND');
1126
+ requireText('supervisor/client.ts', 'expected_completion_contract_sha256: input.expectedCompletionContractSha256');
1127
+ requireText('supervisor/server.ts', 'p.expected_completion_contract_sha256');
1128
+ requireText('adapters/mcp/runtime-gateway/runtime-tool-definitions.ts', 'expected_completion_contract_sha256');
1129
+ requireText('adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts', 'completionContractSha256: workflowSupervisorCompletionContractSha256(task.completionContract)');
1130
+ requireText('docs/architecture/CURRENT.md', 'An existing nonterminal unbound task may acquire one explicit Work or Requirement binding');
1112
1131
  forbid('supervisor/client.ts', /reserveWorkflowSupervisorSchedulerRecovery|reserve_scheduler_recovery/, 'Scheduler recovery is not a Supervisor RPC; reconciliation stays on the canonical effect ledger');
1113
1132
  forbid('supervisor/control-plane.ts', /reserveSchedulerRecovery/, 'Scheduler recovery must not regrow as a second Supervisor recovery authority');
1114
1133
  forbid('supervisor/server.ts', /reserve_scheduler_recovery/, 'Supervisor RPC surface must not expose retired Scheduler recovery authority');
1134
+ requireText('src/runtime/workflow/schedules/engine.ts', "const CONTROLLER_PROGRESSION_OPERATION = 'controller_progression';");
1135
+ requireText('packages/kernel/scheduler/application/eligibility.ts', 'return value >= min && value <= max && (value - min) % step === 0;');
1136
+ requireText('packages/kernel/scheduler/infrastructure/schedule-store.ts', "schedule.action.operation !== 'external_controller_wake' && schedule.action.operation !== 'controller_progression'");
1137
+ requireText('packages/kernel/scheduler/infrastructure/schedule-store.ts', 'const schedule: RepositorySchedule = { ...candidate, policy: boundedSchedulePolicy(candidate) };');
1138
+ requireText('packages/kernel/scheduler/infrastructure/schedule-store.ts', 'policy: boundedSchedulePolicy(candidate),');
1139
+ requireText('src/cli/local-bridge/console-automations.ts', "schedule.action.operation === 'external_controller_wake' || schedule.action.operation === 'controller_progression'");
1140
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "cronDue('0 8 * * *', Date.parse('2026-10-17T00:00:00.000Z'), 'Asia/Shanghai')");
1141
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "cronDue('0 8 * * *', Date.parse('2026-10-18T00:00:00.000Z'), 'Asia/Shanghai')");
1142
+ requireText('src/runtime/workflow/schedules/engine.ts', 'schedule.action.operation === CONTROLLER_PROGRESSION_OPERATION');
1143
+ requireText('src/runtime/workflow/schedules/work-continuation.ts', "const CONTROLLER_PROGRESSION_OPERATION = 'controller_progression';");
1144
+ requireText('src/runtime/workflow/schedules/pending-activation.ts', "const CONTROLLER_PROGRESSION_OPERATION = 'controller_progression';");
1145
+ requireText('src/runtime/workflow/schedules/pending-activation.ts', 'operation: CONTROLLER_PROGRESSION_OPERATION');
1146
+ requireText('src/runtime/plugins/gmail-adapter.ts', 'actualEmail !== configuredEmail');
1147
+ requireText('src/runtime/plugins/gmail-adapter.ts', "export const GMAIL_AUTOMATION_CAPABILITY_ID = 'scheduled-gmail-automation';");
1148
+ requireText('src/runtime/plugins/gmail-adapter.ts', "actionId: 'authorize_scheduled_gmail_automation'");
1149
+ requireText('src/runtime/plugins/gmail-adapter.ts', "requiredConfirmationText: 'authorize-scheduled-gmail-automation'");
1150
+ requireText('src/runtime/plugins/store.ts', 'if (action.requiredConfirmationText)');
1151
+ requireText('src/runtime/plugins/gmail-adapter.ts', "actionId: 'archive_scheduled_message'");
1152
+ requireText('src/runtime/plugins/gmail-adapter.ts', "actionId: 'send_owner_notification'");
1153
+ requireText('src/runtime/plugins/gmail-adapter.ts', 'to: [gmailAutomationMailbox(current)]');
1154
+ requireText('src/runtime/plugins/gmail-adapter.ts', 'requiresExplicitCapabilityGrant: true');
1155
+ requireText('src/runtime/plugins/gmail-adapter.ts', 'expiresInMinutes: GMAIL_AUTOMATION_GRANT_MINUTES');
1156
+ requireText('src/runtime/plugins/store.ts', 'if (action.requiresExplicitCapabilityGrant && !activeAuthorizationGrant)');
1157
+ requireText('src/runtime/plugins/store.ts', 'PLUGIN_CAPABILITY_GRANT_REQUIRED');
1158
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'notificationRequestId');
1159
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'export function recordUnknownSupervisorNotificationReceipt(');
1160
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'readPluginActionReceiptForRequest(controllerHome, input.requestId)');
1161
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'submitted.receipt');
1162
+ requireText('tests/runtime/thin-capability-substrate.test.ts', 'unknown Gmail Supervisor notification keeps one exact receipt');
1163
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', "notificationRequestId('stall', taskId, stall.state, stall.effectId)");
1164
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'getDirectActivity(controllerHome, stallActivityId(taskId))');
1165
+ requireText('packages/kernel/identity/infrastructure/activity-projection-store.ts', 'export function getDirectActivity(');
1166
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', "stall.state === 'retryable' && stall.generations >= stall.maxGenerations");
1167
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'workflow-supervisor.notification-auth:');
1168
+ requireText('supervisor/types.ts', "export type WorkflowSupervisorAction = 'CONTINUE' | 'WAIT' | 'DONE' | 'NEEDS_USER';");
1169
+ requireText('supervisor/types.ts', "state: 'waiting'; scheduleId: string; completionFingerprint: string");
1170
+ requireText('supervisor/protocol.ts', "scheduled_wake_schedule_id");
1171
+ requireText('supervisor/protocol.ts', "WORKFLOW_SUPERVISOR_WAIT_NOT_SCHEDULED");
1172
+ requireText('supervisor/store.ts', "scheduled-wake-bound:");
1173
+ requireText('supervisor/store.ts', "scheduled-wake-committed:");
1174
+ requireText('supervisor/store.ts', "completion_event.kind = 'assistant_completion'");
1175
+ requireText('supervisor/store.ts', "WORKFLOW_SUPERVISOR_SCHEDULED_WAKE_ALREADY_CONSUMED");
1176
+ requireText('supervisor/control-plane.ts', "action === 'WAIT'");
1177
+ requireText('supervisor/control-plane.ts', 'private async validateTerminalProposal');
1178
+ requireText('supervisor/control-plane.ts', "'scheduled_work_must_remain_open'");
1179
+ requireText('supervisor/protocol.ts', '不要用 DONE 或 NEEDS_USER 终结每日循环');
1180
+ requireText('supervisor/server.ts', "req.method === 'task_bind_scheduled_wake'");
1181
+ requireText('supervisor/server.ts', "req.method === 'task_wake_scheduled'");
1182
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', 'bindWorkflowSupervisorScheduledWakeForWork');
1183
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', 'scheduleOccurrenceId');
1184
+ requireText('src/runtime/workflow/schedules/engine.ts', 'scheduleOccurrenceId: occurrence.occurrenceId');
1185
+ requireText('adapters/mcp/runtime-gateway/scheduler-adapter.ts', 'bindWorkflowSupervisorScheduledWakeForWork');
1186
+ requireText('adapters/mcp/runtime-gateway/scheduler-adapter.ts', 'async function bindSupervisorWakeForSchedule');
1187
+ requireText('adapters/mcp/runtime-gateway/scheduler-adapter.ts', "operation === 'schedule_resume'");
1188
+ requireText('adapters/mcp/runtime-gateway/scheduler-adapter.ts', 'bindSupervisorWakeForSchedule(ctx, repository.repoId, saved)');
1189
+ requireText('src/runtime/root/workflow-supervisor-composition.ts', 'wakeWorkflowSupervisorScheduledTaskForWork');
1190
+ requireText('src/runtime/root/controller-progression-composition.ts', 'wakeWorkflowSupervisorScheduledTaskForWork');
1191
+ requireText('src/runtime/root/controller-progression-composition.ts', "if (wake.status === 'woken' && wake.taskId && wake.effectId)");
1192
+ requireText('src/runtime/root/controller-progression-composition.ts', "status: 'scheduled_supervisor_woken'");
1193
+ requireText('src/runtime/workflow/schedules/engine.ts', "progression.status === 'scheduled_supervisor_woken'");
1194
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', 'executes two distinct cron occurrences through the same durable WAIT task without pausing the Schedule');
1195
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "schedule_request_id: 'schedule-daily-gmail-two-consecutive-occurrences'");
1196
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "cron_expression: '0 8 * * *'");
1197
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "2026-10-18@08:00[Asia/Shanghai]");
1198
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', '2026-11-01T00:00:00.000Z');
1199
+ requireText('tests/runtime/rh-work-scheduler-adapter.test.ts', "evaluateSchedule(controllerHome, created.data.schedule, false, { source: 'timer' })");
1200
+ requireText('src/runtime/workflow/schedules/engine.ts', "schedule.action.operation !== CONTROLLER_PROGRESSION_OPERATION");
1201
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'authorizationGrantRefs: [grant.grantId]');
1202
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'workflow-supervisor.notification-send-auth:');
1203
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', "creationReason: 'scheduled_gmail_notification_authorization_failed'");
1204
+ forbidBetween('src/runtime/plugins/gmail-adapter.ts', "actionId: 'send_owner_notification'", "actionId: 'modify_message_labels',", /\b(?:to|recipient|cc|bcc)\s*:/i, 'scheduled Gmail owner notification must not accept a caller-selected recipient');
1115
1205
  requireText('supervisor/forge-validators.ts', "requirement.state !== 'done'");
1206
+ requireText('supervisor/forge-validators.ts', 'validateSemanticCompletionBinding(task, proposal)');
1207
+ requireText('supervisor/forge-validators.ts', 'function validateWorkCompletion(');
1208
+ requireText('supervisor/forge-validators.ts', 'function validateRequirementCompletion(');
1209
+ requireText('adapters/mcp/runtime-gateway/runtime-tool-definitions.ts', "work_id: { type: 'string', minLength: 1, maxLength: 256");
1210
+ requireText('adapters/mcp/runtime-gateway/runtime-tool-definitions.ts', "requirement_id: { type: 'string', minLength: 1, maxLength: 256");
1211
+ requireText('adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts', 'WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_AMBIGUOUS');
1212
+ requireText('adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts', 'WORKFLOW_SUPERVISOR_SEMANTIC_BINDING_REPO_REQUIRED');
1213
+ requireText('adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts', "...(workId ? { work_id: workId } : {})");
1214
+ requireText('adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts', "...(requirementId ? { requirement_id: requirementId } : {})");
1116
1215
  requireText('supervisor/forge-validators.ts', "requirement.state === 'waiting_for_user'");
1216
+ requireText('supervisor/native-browser-adapter.ts', "command.kind === 'recovery' && prepared.reasonCode === 'provider_recovery_stop_pending'");
1217
+ requireText('supervisor/native-browser-adapter.ts', 'provider-turn observation, not an infrastructure preparation failure');
1218
+ requireText('supervisor/store.ts', 'proofGeneration === ledger.lastGeneration');
1219
+ requireText('supervisor/store.ts', 'dispatch_generation: dispatch.lastGeneration');
1220
+ requireText('supervisor/store.ts', 'dispatch_generation: row?.dispatch_generation, pre_send_rejection: true');
1221
+ requireText('supervisor/store.ts', 'effect-dispatch-budget-refund:${effectId}:${proofGeneration}');
1222
+ requireText('supervisor/control-plane.ts', 'const recoveryStopPending = effect.kind === \'recovery\' && input.reason.trim() === \'provider_recovery_stop_pending\';');
1223
+ requireText('supervisor/native-browser-adapter.ts', "reasonCode: dispatch.reasonCode ?? 'COMPUTER_CHATGPT_DISPATCH_NOT_ATTEMPTED'");
1117
1224
  forbid('src/runtime/root/workflow-supervisor-composition.ts', /WorkflowSupervisorStore|supervisor\.sqlite|registerTask\(|reserveEffect\(/, 'Forge composition must access Supervisor state only through daemon RPC, never open its database or become a second writer');
1118
1225
  requireText('src/runtime/root/workflow-supervisor-composition.ts', 'workflowSupervisorBoundaryForWork');
1119
1226
  requireText('src/runtime/root/workflow-supervisor-composition.ts', '`forge:${repoId}:work:${workId}`');
@@ -1200,6 +1307,8 @@ forbid(
1200
1307
  requireMissing('src/runtime/control-plane/routing/workspace-admission.ts');
1201
1308
  forbid('packages/kernel/work/domain/types.ts', /requireHandoffOnAmbiguity|requireWorktree|directMainProhibited/, 'retired Work placement/handoff policy fields must not return as durable authority');
1202
1309
  forbid('adapters/mcp/runtime-gateway/work-adapter.ts', /require_handoff_on_ambiguity|require_worktree|direct_main_prohibited/, 'retired placement/handoff wire flags must not drive repository topology');
1310
+ requireText('adapters/mcp/runtime-gateway/work-adapter.ts', "rawConstraints.workspace_mode === 'current'\n ? 'current'\n : 'isolated'", 'repository-bound rh_work.start must default omitted placement to isolated execution');
1311
+ requireText('src/runtime/control-plane/execution/work-preparation-service.ts', 'WORK_PREPARE_PLACEMENT_CONFLICT', 'work_prepare must not silently reuse a conflicting existing WorkHandle placement');
1203
1312
  forbid('src/cli/controller/execution-policy.ts', /requiresHumanAcceptance|autoRunDeclaredChecks|autoCompleteAfterSuccessfulRun|requiresScopedPaths|requiresDiffEvidence|requiresAnyVerificationEvidence|requiresAcceptanceEvidence|READ_ONLY_INTENT|DESTRUCTIVE_INTENT|SENSITIVE_PATH_PATTERNS/, 'task risk/text/path classification must not decide workflow, placement, verification, scope, or acceptance authority');
1204
1313
  requireMissing('src/runtime/control-plane/daemon-entry.ts');
1205
1314
  requireMissing('scripts/smoke-runtime-control-plane.ts');
@@ -1226,6 +1335,10 @@ requireMissing('src/runtime/bootstrap/activation-transaction.ts');
1226
1335
  requireMissing('src/runtime/bootstrap/stable-bootstrap.ts');
1227
1336
  requireMissing('src/runtime/supervisor');
1228
1337
  requireText('supervisor/store.ts', 'BEGIN IMMEDIATE');
1338
+ requireText('supervisor/forge-validators.ts', "work.semanticState === 'completed'");
1339
+ requireText('supervisor/forge-validators.ts', 'work.predecessorWorkId');
1340
+ requireText('supervisor/forge-validators.ts', 'work.supersedes ?? []');
1341
+ requireText('supervisor/forge-validators.ts', 'work.supersededBy ? [work.supersededBy]');
1229
1342
  requireText('supervisor/store.ts', 'completions_one_per_source_effect');
1230
1343
  requireText('supervisor/store.ts', 'WORKFLOW_SUPERVISOR_SOURCE_EFFECT_COMPLETION_CONFLICT');
1231
1344
  requireText('supervisor/paths.ts', 'resolveControllerHome');
@@ -1241,37 +1354,78 @@ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'activeReleaseId:
1241
1354
  requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'createWorkflowSupervisorServer');
1242
1355
  requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'startWorkflowSupervisorNativeBrowserAdapter');
1243
1356
  requireText('supervisor/native-browser-adapter.ts', 'targetPort: ComputerChatgptConversationTargetPort;');
1357
+ requireText('src/runtime/root/workflow-supervisor-runtime.ts', 'const targetPort = extensionTargetPort;');
1358
+ forbid('src/runtime/root/workflow-supervisor-runtime.ts', /PreferredChatgptConversationTargetPort|MacOsChatgptConversationTargetPort|chatgpt-target-router/, 'Work-bound ChatGPT delivery uses one Chrome Extension target port, never a native fallback router');
1359
+ requireMissing('adapters/computer/chatgpt-target-router.ts');
1360
+ requireMissing('src/runtime/plugins/computer-chatgpt-macos-target.ts');
1361
+ requireMissing('src/runtime/plugins/browser-provider-registry.ts');
1362
+ requireText('src/runtime/plugins/browser-runtime.ts', 'options.providers.length !== 1');
1363
+ forbid('src/runtime/plugins/browser-runtime.ts', /excludedProviderIds|BrowserProviderUnavailableBeforeActionError/, 'Browser Runtime must not retry an action through another provider');
1244
1364
  forbid('supervisor/native-browser-adapter.ts', /MacOs|AppleEvents|browser-macos-bridge|\bwindowId\b|\btabId\b|window\.name/, 'Workflow Supervisor browser consumer must depend only on the provider-neutral Computer ChatGPT target port');
1245
1365
  forbid('supervisor/native-browser-adapter.ts', /supervisor\/store|sqlite|scheduler|packages\/kernel\/(?:work|controller)|control-plane\/persistence/, 'Native Supervisor browser adapter is transport-only and must not own durable lifecycle, Scheduler, Work, Controller, or persistence authority');
1246
1366
  requireText('src/runtime/root/workflow-supervisor-composition.ts', 'resolveWorkflowSupervisorForgeHome(options.controllerHome)');
1247
1367
  forbid('src/runtime/root/workflow-supervisor-runtime.ts', /createPlatformServiceManagerHost|launchd|systemd|startDetached/, 'Workflow Supervisor reuses the Canonical Runtime process lifecycle and must not own a second OS service');
1248
1368
  requireText('supervisor/entry.ts', "argument('--controller-home')");
1249
1369
  forbid('supervisor/entry.ts', /FORGE_HOME|--forge-home/, 'Workflow Supervisor foreground entry must use the canonical Controller Home authority rather than a second Forge-home root');
1250
- requireText('supervisor/control-plane.ts', 'await validator(task, parsed.proposal)');
1370
+ requireText('supervisor/control-plane.ts', 'await this.validateTerminalProposal(task, parsed.proposal)');
1251
1371
  requireText('supervisor/protocol.ts', 'SUPERVISOR_BLOCK_END');
1372
+ requireText('supervisor/protocol.ts', 'validateSupervisorObjective(task.objective)');
1373
+ forbid('supervisor/protocol.ts', /objective:\s*task\.objective\.slice\(/, 'Supervisor must reject oversized objectives, never silently truncate them in rendered effects');
1374
+ requireText('supervisor/store.ts', 'validateSupervisorObjective(input.objective)');
1375
+ requireText('supervisor/store.ts', 'const objective = validateSupervisorObjective(input.objective)');
1252
1376
  requireText('supervisor/server.ts', 'createWorkflowSupervisorServer');
1253
1377
  forbid('supervisor/server.ts', /from ['"]\.\/store['"]|supervisor\.sqlite|BEGIN IMMEDIATE/, 'Supervisor transport must relay typed commands through the control plane and never own persistence');
1378
+ forbid('src/runtime/plugins/browser-macos-bridge.ts', /PLUGIN_BROWSER_NATIVE_PROCESS_AMBIGUOUS|pids\.length\s*!==\s*1/, 'Chrome GUI PID selection has one authority: Desktop Operator');
1379
+ requireText('src/runtime/plugins/browser-macos-bridge.ts', 'await assertMacOsBrowserApplicationRunning(request.product, timeoutMs)');
1254
1380
  requireText('adapters/computer/chrome-extension/manifest.json', 'nativeMessaging');
1255
1381
  requireText('adapters/computer/chrome-extension/background.js', 'computer_extension_claim');
1256
1382
  requireText('adapters/computer/chrome-extension/background.js', 'computer_extension_complete');
1383
+ requireText('adapters/computer/chrome-extension/background.js', "typeof observation.composerText === 'string'");
1384
+ requireText('adapters/computer/chrome-extension/background.js', "command.identity.namespace === 'chatgpt.bootstrap'");
1385
+ forbid('adapters/computer/chrome-extension/background.js', /if \(typeof observation\?\.url === 'string' && observation\.url\) return observation/, 'New bootstrap URL does not attest composer/model hydration before pre-send preparation');
1257
1386
  requireText('adapters/computer/chrome-extension/background.js', 'chrome.runtime.connectNative');
1258
1387
  forbid('adapters/computer/chrome-extension/background.js', /browser_begin_effect|browser_observe_effect|browser_poll|browser_tasks|browser_observe_assistant|task_register|reserve_enrollment/, 'Computer Chrome provider must not consume or mutate Workflow Supervisor effect authority; it executes only typed Computer target commands');
1259
1388
  requireText('adapters/computer/chrome-extension/content.js', 'ForgeComputerChatgptCore');
1389
+ requireText('adapters/computer/chrome-extension/content.js', "bootstrapTargetGuard: 'project-checked-before-send-v1'");
1390
+ requireText('adapters/computer/chrome-extension/content.js', 'exactComposerText(payload)');
1391
+ requireText('adapters/computer/chrome-extension/content.js', "return text.trim() ? text : '';");
1392
+ requireText('adapters/computer/chrome-extension/content.js', "blocks.every((block) => block.tagName === 'P')");
1393
+ requireText('adapters/computer/chrome-extension/content.js', "blocks.map((block) => {");
1394
+ requireText('adapters/computer/chrome-extension/background.js', 'resolveTarget(command.identity, false, command.providerBinding)');
1395
+ requireText('adapters/computer/chatgpt-extension-target.ts', "response.result.code === 'COMPUTER_CHATGPT_BOOTSTRAP_PINNED_TAB_MISSING'");
1396
+ requireText('adapters/computer/chatgpt-extension-target.ts', 'this.authority.withSurfaceLease(this.controllerHome, previous.targetId');
1397
+ requireText('adapters/computer/chatgpt-extension-target.ts', 'return await this.openBootstrap(projectUrl, bootstrapKey, false)');
1398
+ requireText('adapters/computer/chatgpt-extension-target.ts', 'if (pinned && !bootstrapMatch) continue;');
1399
+ requireText('adapters/computer/chatgpt-extension-target.ts', 'const candidate = pinned');
1400
+ requireText('adapters/computer/chatgpt-extension-target.ts', 'observed.ownerToken === binding.ownerToken');
1401
+ forbid('adapters/computer/chrome-extension/background.js', /resolveTarget\(command\.identity,\s*false\)\.catch/, 'Extension worker must recover a pinned bootstrap from the durable Computer binding, not its ephemeral in-worker Map');
1402
+ forbid('adapters/computer/chrome-extension/content.js', /core\.normalizeText\(payload\)/, 'Provider pre-send evidence must preserve whitespace in immutable effect payload');
1260
1403
  requireMissing('supervisor/chrome-extension');
1261
- requireText('src/runtime/plugins/browser-adapter.ts', "browserMode: browserMode(raw.browserMode) ?? 'managed_persistent'");
1262
- requireText('src/runtime/plugins/browser-adapter.ts', "nativeAttachMode: browserNativeAttachMode(raw.nativeAttachMode) ?? 'disabled'");
1404
+ requireText('src/runtime/plugins/browser-adapter.ts', "browserMode: browserMode(raw.browserMode) ?? 'attach_preferred'");
1405
+ requireText('src/runtime/plugins/browser-adapter.ts', "nativeAttachMode: browserNativeAttachMode(raw.nativeAttachMode) ?? 'auto'");
1263
1406
  requireText('supervisor/native-messaging/host.ts', 'ALLOWED_BROWSER_METHODS');
1264
1407
  requireText('supervisor/native-messaging/host.ts', 'computer_extension_claim');
1265
1408
  forbid('supervisor/native-messaging/host.ts', /['"](?:browser_tasks|browser_poll|browser_begin_effect|browser_observe_effect|browser_observe_dispatch_failure|browser_observe_provider_turn|browser_observe_assistant|bootstrap_poll|bootstrap_project_url|bootstrap_begin_effect|bootstrap_observe_effect|bootstrap_bind_conversation)['"]/, 'Chrome Native Messaging transport must not expose Workflow Supervisor effect RPCs; extension traffic terminates at Computer target commands');
1266
1409
  requireText('supervisor/store.ts', 'recordEffectNotAppliedProof');
1410
+ requireText('supervisor/store.ts', 'preSendComposerObservation(effectId: string)');
1411
+ requireText('supervisor/store.ts', "if (value && typeof value === 'object' && !Array.isArray(value)) return value as Record<string, unknown>;");
1412
+ requireText('supervisor/native-browser-adapter.ts', 'function retiredBootstrapDraftReplacementPrompt(');
1413
+ requireText('supervisor/native-browser-adapter.ts', 'control.preSendComposerObservation(staleEffect.effectId)');
1414
+ requireText('supervisor/native-browser-adapter.ts', "retired?.terminal !== 'STOPPED'");
1415
+ requireText('supervisor/native-browser-adapter.ts', 'control.effectDispatchBudget(staleEffect.effectId).generations !== 0');
1416
+ requireText('adapters/computer/chrome-extension/content.js', 'FORGE_RETIRED_DRAFT_V1');
1417
+ requireText('docs/architecture/CURRENT.md', 'A STOPPED bootstrap draft may be replaced only from the canonical Supervisor ledger');
1418
+ requireText('supervisor/store.ts', 'tried.at(-1)?.eventId');
1419
+ requireText('supervisor/store.ts', 'WORKFLOW_SUPERVISOR_PRE_SEND_OPERATOR_REARM_EXHAUSTED');
1267
1420
  requireText('supervisor/store.ts', '`effect-dispatch:${effectId}:${generation}`');
1268
1421
  requireText('supervisor/control-plane.ts', 'PERSISTED_BROWSER_EVIDENCE_KEYS');
1269
1422
  requireText('supervisor/control-plane.ts', "reason: 'not_applied_proof_incomplete'");
1270
1423
  requireText('supervisor/server.ts', "if (!['applied','unknown'].includes(outcome))");
1271
- forbid('adapters/computer/chrome-extension/background.js', /chrome\.storage|supervisor\.sqlite|BEGIN IMMEDIATE/, 'Computer Chrome provider must reconstruct provider bindings from live inventory and Computer target authority rather than browser shadow persistence');
1424
+ forbid('adapters/computer/chrome-extension/background.js', /supervisor\.sqlite|BEGIN IMMEDIATE/, 'Computer Chrome provider must reconstruct provider bindings from live inventory and Computer target authority rather than browser shadow persistence');
1425
+ // Provider-local browser identity may persist; tasks and effects remain Supervisor-owned.
1272
1426
  forbid('adapters/computer/chrome-extension/content.js', /chrome\.storage|supervisor\.sqlite|BEGIN IMMEDIATE/, 'Computer Chrome content script must remain a page capability surface rather than durable authority');
1273
1427
  forbid('supervisor/native-messaging/host.ts', /task_register|reserve_enrollment|supervisor\.sqlite|BEGIN IMMEDIATE|bun:sqlite|node:sqlite|from ['"][^'"]*(?:store|control-plane)['"]/, 'Chrome Native Messaging host must remain a stateless browser-method relay and never own Supervisor persistence/lifecycle');
1274
- forbid('adapters/computer/chrome-extension/background.js', /task_register|reserve_enrollment|supervisor\.sqlite|BEGIN IMMEDIATE|chrome\.storage/, 'Computer Chrome provider must never become durable workflow authority');
1428
+ forbid('adapters/computer/chrome-extension/background.js', /task_register|reserve_enrollment|supervisor\.sqlite|BEGIN IMMEDIATE/, 'Computer Chrome provider must never become durable workflow authority');
1275
1429
  forbid('adapters/computer/chrome-extension/content.js', /task_register|reserve_enrollment|supervisor\.sqlite|BEGIN IMMEDIATE|chrome\.storage/, 'Computer Chrome content script must observe/execute one exact page only and never own durable workflow state');
1276
1430
 
1277
1431
  requireMissing('docs/architecture/current/stable-external-runtime-supervisor.md');
@@ -1363,6 +1517,9 @@ forbid(
1363
1517
  );
1364
1518
 
1365
1519
  requireText('docs/architecture/CURRENT.md', 'Canonical Runtime is activated as one immutable whole release');
1520
+ requireText('src/runtime/root/release-execution-canary.ts', 'releaseScriptRequiresBun');
1521
+ forbid('src/runtime/root/package-runtime-release.ts', /ownsProcessRuntimeCanary|PROCESS_RUNTIME_RELEASE_CANARY_ARG/, 'package Runtime wrappers must delegate release canaries to the attested Process Runner/Check Runner implementation');
1522
+ requireText('scripts/migrate-windows-wsl-controller-home.ts', 'assertRuntimeReleaseExecutionCanaries(stagedRelease.manifestPath, destination);');
1366
1523
  requireText('docs/architecture/CURRENT.md', 'Runtime availability/recovery keeps Forge itself healthy');
1367
1524
  requireText('docs/architecture/CURRENT.md', 'Historical Issue/Task/Local Job and compatibility projections must not become second mutable authorities.');
1368
1525
  requireText('src/runtime/root/runtime.ts', 'export class CanonicalForgeRuntime');
@@ -1412,12 +1569,17 @@ requireText('src/runtime/root/service.ts', 'SuccessfulExit');
1412
1569
  requireText('src/runtime/root/service.ts', 'ThrottleInterval');
1413
1570
  requireText('src/runtime/root/service-runner.ts', 'activeRuntimeReleaseManifest');
1414
1571
  requireText('src/runtime/standalone-recovery/core.ts', 'restartPrimaryRuntime');
1572
+ forbid('src/runtime/standalone-recovery/core.ts', /\bopenSync\s*\([^,]+,\s*['"]wx['"]/, 'Recovery Core must not create a second exclusive mutation lock writer');
1415
1573
  requireText('src/runtime/standalone-recovery/core.ts', 'recoverPrimaryRuntime');
1416
1574
  requireText('src/runtime/standalone-recovery/core.ts', "action: 'restart_primary_runtime'");
1417
1575
  requireText('src/runtime/standalone-recovery/core.ts', 'restartAttempts >= maximumRestartAttempts');
1418
1576
  requireText('src/runtime/standalone-recovery/core.ts', 'rollbackPreviousLocked');
1419
1577
  requireText('src/runtime/standalone-recovery/entry.ts', "'restart_primary_runtime'");
1420
1578
  requireText('src/runtime/standalone-recovery/entry.ts', "'recover_primary_runtime'");
1579
+ requireText('src/runtime/standalone-recovery/core.ts', 'armPackageConnectorCutoverDrain');
1580
+ requireText('src/runtime/standalone-recovery/entry.ts', "parsed.result.detail.startsWith('RELEASE_SESSION_CUTOVER_DEFERRED_FOR_MCP_ACTIVITY')");
1581
+ forbid('src/runtime/standalone-recovery/entry.ts', /if\s*\(decision\.required\s*&&\s*decision\.action\s*===\s*['"]cutover['"]\)\s*\{\s*const gate = await probeReleaseCutoverReadiness/, 'Automatic Recovery must enter the canonical fenced drain transaction rather than block cutover before the drain can be armed');
1582
+
1421
1583
  forbid(
1422
1584
  'src/runtime/standalone-recovery/core.ts',
1423
1585
  /runtime-slots|active-slot|blue\/green|StableSupervisor|component rollback/i,
@@ -1428,6 +1590,39 @@ requireText('src/cli/commands/init-hook.ts', "['open', 'next']");
1428
1590
  requireText('src/cli/commands/init-hook.ts', "command(name)");
1429
1591
  requireText('src/cli/commands/init-hook.ts', "command('close')");
1430
1592
  requireText('src/cli/commands/init-hook.ts', "'.forge'");
1593
+ // CLI setup/adoption must use one process/environment implementation, not three writers.
1594
+ requireText('src/cli/commands/setup-execution.ts', 'export function withProcessEnv');
1595
+ requireText('src/cli/commands/setup-execution.ts', 'export function runSetupProcess');
1596
+ requireMissing('src/core/adoption/helper-wrapper-plan.ts');
1597
+ // Service and release persistence use one writer rather than five sibling
1598
+ // open/write/rename algorithms with incompatible temporary-file identities.
1599
+ requireText('src/runtime/shared/atomic-text-file.ts', 'export function writeAtomicTextFile');
1600
+ requireText('src/runtime/maintenance/cleanup.ts', 'RUNTIME_CLEANUP_GIT_SOURCE_PROTECTED');
1601
+ requireText('src/runtime/maintenance/cleanup.ts', 'protectsGitSource(candidate.path)');
1602
+ for (const path of [
1603
+ 'src/runtime/root/service.ts',
1604
+ 'src/runtime/root/package-connector-service.ts',
1605
+ 'src/runtime/root/package-runtime-service.ts',
1606
+ 'src/runtime/root/package-runtime-release.ts',
1607
+ 'src/cli/controller/systemd-user.ts',
1608
+ ]) {
1609
+ forbid(path, /^function\s+atomicWrite\s*\(/m, 'service/release text writes must reuse the shared atomic writer');
1610
+ requireText(path, 'writeAtomicTextFile');
1611
+ }
1612
+
1613
+ // Job recovery and Scheduler must not drift on delegated-operation replay safety.
1614
+ requireText('src/runtime/execution/jobs/child-reference.ts', 'export function isAgentDelegationJob');
1615
+ for (const path of ['src/runtime/control-plane/global-scheduler/reconciliation.ts', 'src/runtime/execution/jobs/receipt-recovery.ts']) {
1616
+ forbid(path, /^function\s+isAgentDelegationJob\s*\(/m, 'delegation classification must stay in the shared child-reference owner');
1617
+ }
1618
+ // Live and sampled Git snapshots share the same porcelain partitioning semantics.
1619
+ requireText('src/cli/repositories/structured-git.ts', 'export function splitRepositoryGitStatus');
1620
+ forbid('src/runtime/projections/git-status-sampler.ts', /^function\s+splitStatus\s*\(/m, 'Git projection must not duplicate the live porcelain parser');
1621
+ for (const path of ['src/cli/commands/init.ts', 'src/cli/commands/init-hook.ts', 'src/cli/commands/global-runtime.ts']) {
1622
+ forbid(path, /^function\s+(?:withProcessEnv|runProcess)(?:<|\()/m, 'setup commands must import their canonical synchronous process/environment owner');
1623
+ }
1624
+ requireText('src/cli/editing/edit-session.ts', 'export function findOccurrence');
1625
+ forbid('src/cli/repositories/safe-patch.ts', /^function\s+findOccurrence\s*\(/m, 'Safe Patch preflight must reuse Direct Edit anchor occurrence matching');
1431
1626
  requireText('src/cli/editing/edit-session.ts', 'beforeMode');
1432
1627
  requireText('src/cli/editing/edit-session.ts', 'afterMode');
1433
1628
  requireText('src/cli/editing/edit-session.ts', '{ mode: record.beforeMode }');
@@ -1481,7 +1676,13 @@ forbid(
1481
1676
  requireText('adapters/mcp/runtime-gateway/router.ts', 'executionJobCreationRetired');
1482
1677
  requireText('adapters/mcp/runtime-gateway/router.ts', "'EXECUTION_JOB_RETIRED'");
1483
1678
  requireText('adapters/mcp/runtime-gateway/execution-tools.ts', 'isDurableWorkOperation');
1484
- requireText('adapters/mcp/runtime-gateway/execution-tools.ts', "'work_execute'");
1679
+ forbid('adapters/mcp/runtime-gateway/execution-tools.ts', /'work_execute'/, 'A Work-bound execution helper must not be a second public command tool');
1680
+ requireText('adapters/mcp/tool-mapping/repository-tools.ts', "definition('execute_command'");
1681
+ requireText('adapters/mcp/toolset-names.ts', "'execute_command'");
1682
+ forbid('adapters/mcp/toolset-names.ts', /'process_exec'|'repository_command_execute'|'work_execute'/, 'Only execute_command is a public generic command entry');
1683
+ forbid('adapters/mcp/runtime-gateway/process-tools.ts', /definition\(\s*'process_exec'/, 'The host command must not re-expose a separate process_exec schema');
1684
+ forbid('adapters/mcp/tool-mapping/repository-tools.ts', /definition\('repository_command_preview'/, 'Command dry_run preview must use execute_command rather than a second tool');
1685
+ forbid('src/runtime/plugins/local-system-adapter.ts', /actionId:\s*'execute_command'/, 'Do not reintroduce a duplicate local_system generic terminal capability');
1485
1686
  requireText('adapters/mcp/runtime-gateway/execution-tools.ts', "'work_validate'");
1486
1687
  forbid('adapters/mcp/runtime-gateway/execution-tools.ts', /work_finalize/, 'execution tools must not restore a Work finalization operation');
1487
1688
  requireText('src/runtime/execution/workers/executor.ts', 'executeWork(runtimeContext');
@@ -1633,6 +1834,16 @@ requireText('src/runtime/control-plane/global-scheduler/scheduler.ts', 'persistS
1633
1834
  requireText('src/runtime/control-plane/global-scheduler/worker-attachment.ts', 'attachExecutionWorker');
1634
1835
  requireText('src/runtime/control-plane/global-scheduler/scheduler.ts', 'runSchedulerPeriodicCleanup');
1635
1836
  requireText('src/runtime/control-plane/global-scheduler/maintenance.ts', 'runSchedulerValidationReconciliation');
1837
+ requireMatch(
1838
+ 'src/runtime/control-plane/global-scheduler/maintenance.ts',
1839
+ /input\.runtimeCleanup\(input\.controllerHome,\s*\{\s*reason:\s*['"]periodic['"]/s,
1840
+ 'route periodic maintenance through the canonical Runtime cleanup owner',
1841
+ );
1842
+ requireText('src/runtime/control-plane/runtime-cleanup.ts', 'cleanupControllerReleaseHistory');
1843
+ requireText('src/runtime/control-plane/release-retention.ts', "releasePaths.add(releasePathFromAuthorityRecord(releasesRoot, parsed.active, 'active'))");
1844
+ requireText('src/runtime/control-plane/release-retention.ts', 'const connectorRelease = loadPackageConnectorReleaseProtection(controllerHome, releasesRoot);');
1845
+ requireText('src/runtime/control-plane/release-retention.ts', 'const databaseBackup = (previous as Record<string, unknown>).databaseBackup;');
1846
+ requireText('src/runtime/root/scheduler.ts', 'isolatePeriodicCleanup: true');
1636
1847
  requireText('src/runtime/control-plane/global-scheduler/scheduler.ts', 'planSchedulerSourceSampling');
1637
1848
  requireText('src/runtime/control-plane/global-scheduler/source-scan.ts', 'selectSchedulerSourceScanRepositories');
1638
1849
  requireText('src/runtime/control-plane/global-scheduler/scheduler.ts', 'runSchedulerDurableAdmission');
@@ -1738,7 +1949,14 @@ requireText('adapters/mcp/transports/http-observation.ts', "'/repos/:repoId/heal
1738
1949
  requireText('src/runtime/control-plane/governance/external-effects.ts', 'EXTERNAL_EFFECT_AUTHORIZATION_REQUIRED');
1739
1950
  requireText('src/runtime/control-plane/governance/external-effects.ts', 'AUTOMATED_REQUIREMENT_REQUIRES_CANDIDATE');
1740
1951
  requireText('adapters/mcp/tool-mapping/tools.ts', "export * from './legacy-tool-service'");
1741
- requireText('src/cli/mcp/tools.ts', '@deprecated Kernel V2 compatibility shim');
1952
+ for (const retiredShim of [
1953
+ 'src/cli/mcp/access-tools.ts',
1954
+ 'src/cli/mcp/repository-tools.ts',
1955
+ 'src/cli/mcp/tools.ts',
1956
+ 'src/cli/mcp/toolset.ts',
1957
+ 'src/cli/mcp/toolset-names.ts',
1958
+ 'src/cli/mcp/toolset-selection.ts',
1959
+ ]) requireMissing(retiredShim);
1742
1960
 
1743
1961
  for (const path of [
1744
1962
  'adapters/mcp/runtime-gateway/router.ts',
@@ -1859,6 +2077,9 @@ const B7_ALLOWED_KERNEL_LEGACY_EDGES = new Set([
1859
2077
  ]);
1860
2078
  requireExactShrinkingDebt('Kernel -> legacy src dependency debt', b7KernelLegacyEdges, B7_ALLOWED_KERNEL_LEGACY_EDGES);
1861
2079
  const b7ProductionEdges = new Set(dependencyEdges(b7ProductionGraph));
2080
+ if (!b7ProductionEdges.has('src/runtime/standalone-recovery/core.ts -> src/runtime/standalone-recovery/operation-lock.ts')) {
2081
+ failures.push('Recovery Core must consume the single shared operation-lock authority');
2082
+ }
1862
2083
  for (const requiredEdge of [
1863
2084
  'packages/kernel/work/domain/types.ts -> packages/kernel/identity/api/index.ts',
1864
2085
  'packages/kernel/scheduler/domain/schedule.ts -> packages/kernel/identity/api/index.ts',
@@ -2083,7 +2304,7 @@ requireText('supervisor/protocol.ts', '(?:fx|crpe)_');
2083
2304
  // Cognitive Plane stays one advisory application path: all Controller tools expose the
2084
2305
  // same optional settlement metadata, the MCP server settles it after the primary
2085
2306
  // outcome, and Supervisor/external launchers consume Cognition-only projections.
2086
- requireText('adapters/mcp/toolset.ts', 'injectCognitionSettlementFields(injectAutomationEnvelopeFields(injectDurableCommandFields(definition)))');
2307
+ requireText('adapters/mcp/toolset.ts', 'injectCognitionSettlementFields(injectDurableCommandFields(definition))');
2087
2308
  requireText('adapters/mcp/server.ts', 'settleCognitionAfterTool(ctx, name, args, localResult)');
2088
2309
  forbid('adapters/mcp/runtime-gateway/runtime-tools.ts', /settleCognitionEnvelope/, 'cognition settlement belongs to the canonical all-tool MCP boundary, not the rh_* facade only');
2089
2310
  requireText('src/runtime/root/workflow-supervisor-composition.ts', 'renderCognitiveAttentionForWork');
@@ -2105,7 +2326,28 @@ forbid(
2105
2326
  /authority-env|BRAIN_CONTROLLER_AUTHORITY_REQUIRED|BRAIN_AUTHORITY_ENV_INVALID/,
2106
2327
  'advisory experience CLI must not require a Controller capability',
2107
2328
  );
2329
+ // Retired Gateway/CLI forwarding aliases must not be reintroduced: adapter
2330
+ // definitions and execution-domain reconciliation own their canonical paths.
2108
2331
  for (const path of [
2332
+ 'adapters/mcp/runtime-gateway/work-validation-reconciler.ts',
2333
+ 'src/cli/mcp/access-mode.ts',
2334
+ 'src/cli/mcp/audit.ts',
2335
+ 'src/cli/mcp/auth.ts',
2336
+ 'src/cli/mcp/multi-repository.ts',
2337
+ 'src/cli/mcp/openai-secure-tunnel.ts',
2338
+ 'src/cli/mcp/paths.ts',
2339
+ 'src/cli/mcp/policy.ts',
2340
+ 'src/cli/mcp/readiness-projection.ts',
2341
+ 'src/cli/mcp/redaction.ts',
2342
+ 'src/cli/mcp/repo.ts',
2343
+ 'src/cli/mcp/server.ts',
2344
+ 'src/cli/mcp/setup.ts',
2345
+ 'src/cli/mcp/transports/http.ts',
2346
+ 'src/cli/mcp/transports/session-registry.ts',
2347
+ 'src/cli/mcp/types.ts',
2348
+ 'src/cli/mcp/oauth.ts',
2349
+ 'src/cli/mcp/tool-contract.ts',
2350
+ 'src/cli/mcp/transports/stdio.ts',
2109
2351
  'src/runtime/gateway/mcp/execution-tools.ts',
2110
2352
  'src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts',
2111
2353
  'src/runtime/gateway/mcp/persisted-check-process.ts',
@@ -2114,17 +2356,7 @@ for (const path of [
2114
2356
  'src/runtime/gateway/mcp/runtime-tool-definitions.ts',
2115
2357
  'src/runtime/gateway/mcp/runtime-tools.ts',
2116
2358
  'src/runtime/gateway/mcp/work-validation-reconciler.ts',
2117
- ]) requireText(path, '@deprecated Kernel V2 compatibility shim');
2118
- for (const path of [
2119
- 'src/cli/mcp/access-tools.ts',
2120
- 'src/cli/mcp/legacy-context.ts',
2121
- 'src/cli/mcp/legacy-tool-service.ts',
2122
- 'src/cli/mcp/multi-repository.ts',
2123
- 'src/cli/mcp/repository-tools.ts',
2124
- 'src/cli/mcp/server.ts',
2125
- 'src/cli/mcp/tools.ts',
2126
- 'src/cli/mcp/toolset.ts',
2127
- ]) requireText(path, '@deprecated Kernel V2 compatibility shim');
2359
+ ]) requireMissing(path);
2128
2360
  requireText('src/runtime/control-plane/execution/work-execution-support.ts', 'packages/protocols/mcp/execution-context');
2129
2361
  requireText('src/runtime/control-plane/execution/work-preparation-service.ts', 'packages/protocols/mcp/execution-context');
2130
2362
  requireText('src/runtime/control-plane/execution/work-operation-service.ts', 'packages/protocols/mcp/execution-context');
@@ -2167,13 +2399,6 @@ forbidBetween(
2167
2399
  /\b(?:pid|process|endpoint|url|tunnel|token)\b/i,
2168
2400
  'ForgeInstanceIdentity creation must remain independent of process and adapter transport/auth metadata',
2169
2401
  );
2170
- for (const path of [
2171
- 'src/cli/mcp/auth.ts',
2172
- 'src/cli/mcp/setup.ts',
2173
- 'src/cli/mcp/openai-secure-tunnel.ts',
2174
- ]) {
2175
- requireText(path, '@deprecated Kernel V2 compatibility shim');
2176
- }
2177
2402
  requireText('adapters/mcp/auth.ts', 'forgeInstanceId?: string');
2178
2403
  forbid('adapters/mcp/auth.ts', /server:\s*\{[\s\S]{0,512}?instanceId\??:\s*string/, 'MCP server process identity must not share semantic Forge instanceId naming');
2179
2404
  requireText('adapters/mcp/setup.ts', 'ensureForgeInstanceIdentity');
@@ -2202,6 +2427,9 @@ for (const path of productionTypeScriptFiles()) {
2202
2427
  forbid(path, controllerRepoCallPattern, 'production controller-plugin paths must not recreate a fake controller RepositoryRecord');
2203
2428
  }
2204
2429
  requireText('src/runtime/plugins/store.ts', 'const CONTROLLER_PLUGIN_SCOPE_KEY = FORGE_INSTANCE_SCOPE_KEY');
2430
+ requireText('src/runtime/plugins/store.ts', 'export function preflightPluginActionWorkBinding(');
2431
+ requireText('src/runtime/plugins/action-application.ts', 'preflightPluginActionWorkBinding(input.controllerHome, input.scope, action, input.request);');
2432
+ requireText('tests/runtime/external-plugin-store-integration.test.ts', 'rejects invalid Work kind without consuming the Process request id');
2205
2433
  forbidBetween(
2206
2434
  'src/runtime/plugins/store.ts',
2207
2435
  'function controllerPluginActionScope',
@@ -2241,6 +2469,51 @@ requireText('packages/protocols/computer/contract.ts', 'export interface Compute
2241
2469
  forbid('adapters/computer/desktop-operator-negotiation.ts', /interface\s+ComputerCapabilityAdvertisement/, 'Desktop Operator negotiation must consume the provider-neutral Computer capability advertisement contract instead of redefining it');
2242
2470
  requireText('packages/plugin-runtime/computer/provider.ts', 'export interface ComputerProvider');
2243
2471
  requireText('packages/plugin-runtime/computer/provider-registry.ts', 'export class ComputerProviderRegistry');
2472
+ requireText('src/runtime/plugins/computer-registration.ts', 'return executeIosPhysicalDeviceAction(input)');
2473
+ requireText('scripts/smoke-ios-physical-device.ts', "pluginId: 'computer'");
2474
+ requireText('scripts/smoke-ios-physical-device.ts', 'artifact?.sha256 !== screenshotSha256');
2475
+ requireText('scripts/smoke-ios-physical-device.ts', 'semanticPriceVerified: false');
2476
+ requireText('src/runtime/plugins/computer-registration.ts', 'observationReady: physicalReady, inputReady: physicalInputReady');
2477
+ requireText('src/runtime/plugins/computer-registration.ts', 'const hidStatus = physicalReady && context ? remoteXpcHidCachedStatus(context.controllerHome) : undefined;');
2478
+ requireText('src/runtime/plugins/ios/remote-xpc-hid.ts', 'probeHidToolchain(python)');
2479
+ requireText('src/runtime/plugins/ios/remote-xpc-hid.ts', "'--expected-version', IOS_HID_TOOLCHAIN_VERSION");
2480
+ requireText('scripts/install-ios-hid-toolchain.sh', 'pymobiledevice3==$version');
2481
+ requireText('src/runtime/plugins/ios/remote-xpc-hid.ts', 'return hidToolchainStatus(controllerHome, env, false);');
2482
+ requireText('src/runtime/plugins/ios/remote-xpc-hid.ts', 'return hidToolchainStatus(controllerHome, env, true);');
2483
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'const confirmed = requireObservedPhysicalTargetForeground(state)');
2484
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'const reusable = reusablePhysicalSession(input, selected, bundleId);');
2485
+ requireText('src/runtime/plugins/ios-physical-device.ts', "appendEvent(input, reusable.interactionId, 'app_activated'");
2486
+ requireText('src/runtime/plugins/ios-physical-device.ts', "state: 'deferred_to_first_input'");
2487
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'input.args.prewarm_input === true && input.args.observe_after_open !== true');
2488
+ requireText('tests/runtime/ios-physical-device.test.ts', "it('reuses the same session but always reactivates its target app'");
2489
+ requireText('src/runtime/plugins/ios-physical-device.ts', "'IOS_DEVICE_LOCK_STATE_UNVERIFIED'");
2490
+ requireText('src/runtime/plugins/ios-physical-device.ts', "if (lockState.passcodeRequired === false) return;");
2491
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'if (!selected.connected) {');
2492
+ requireText('src/runtime/plugins/ios-physical-device.ts', "'IOS_DEVICE_SCREENSHOT_INVALID'");
2493
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'chmodSync(path, 0o700);');
2494
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'if (file.isFile()) chmodSync(path, 0o600);');
2495
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'state.lastScreenshot = undefined;');
2496
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'try { unlinkSync(path); } catch');
2497
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'PNG_CRC_TABLE');
2498
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'sawImageData && length === 0 && end + 4 === image.length');
2499
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'screenshotSha256, screenshotBytes: image.length');
2500
+ requireText('src/runtime/plugins/ios-physical-device.ts', "requiredConfirmationText: 'list-iphone-app-documents'");
2501
+ requireText('src/runtime/plugins/ios-physical-device.ts', "'IOS_DEVICE_DOCUMENT_LIST_UNVERIFIED'");
2502
+ requireText('src/runtime/plugins/ios-physical-device.ts', "listedNames.some((name) => typeof name !== 'string' || !name.trim())");
2503
+ requireText('src/runtime/plugins/ios-physical-device.ts', "requiredConfirmationText: 'export-iphone-app-document'");
2504
+ requireText('src/runtime/plugins/ios-physical-device.ts', "const indexPath = join(dir, 'index.json')");
2505
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'const MAX_DOCUMENT_INDEX_BYTES = 512 * 1024;');
2506
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'indexFile.size <= 0 || indexFile.size > MAX_DOCUMENT_INDEX_BYTES');
2507
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'index.interactionId !== record.interactionId || !validEntries');
2508
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'pngDisplayGeometry(bytes) !== undefined');
2509
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'bytes.subarray(-2).toString(\'hex\') === \'ffd9\'');
2510
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'bytes.readUInt32BE(0) >= 16 && bytes.readUInt32BE(0) <= bytes.length');
2511
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'entries: [...entries, entry] }, { mode: 0o600 });');
2512
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'organizedIndex: { localArtifact: indexPath, entryCount: entries.length + 1 }');
2513
+ requireText('src/runtime/plugins/ios-physical-device.ts', 'requireBundleId(input.args.bundle_id) !== state.bundleId');
2514
+ requireText('src/runtime/plugins/ios-physical-device.ts', "'--domain-type', 'appDataContainer', '--domain-identifier', state.bundleId");
2515
+ forbid('src/runtime/plugins/ios-physical-device.ts', /source:\s*'atomic_screenshot'/, 'bare iPhone screenshot IDs must never bypass explicit target-foreground confirmation');
2516
+ forbid('src/runtime/plugins/ios-adapter.ts', /\bexecuteIosPhysicalDeviceAction\b/, 'CoreDevice iPhone App mutations must have a single public Computer owner, not a retained iOS-adapter writer');
2244
2517
  requireText('adapters/computer/desktop-operator-contract.ts', 'DESKTOP_OPERATOR_PROVIDER_PLUGIN_ID');
2245
2518
  requireText('adapters/computer/desktop-operator-negotiation.ts', 'negotiateDesktopOperatorComputerHandshake');
2246
2519
  requireText('adapters/computer/desktop-operator-negotiation.ts', 'buildDesktopOperatorComputerInvocation');
@@ -2312,13 +2585,12 @@ forbid('packages/plugin-runtime/browser/provider-registry.ts', /AssistantPluginE
2312
2585
  requireText('packages/protocols/browser/session.ts', 'export interface BrowserSessionState');
2313
2586
  for (const path of [
2314
2587
  'src/runtime/plugins/browser-runtime-contract.ts',
2315
- 'src/runtime/plugins/browser-provider-registry.ts',
2316
2588
  'src/runtime/plugins/browser-session-types.ts',
2317
2589
  ]) {
2318
2590
  requireText(path, '@deprecated C0 compatibility shim');
2319
2591
  }
2320
2592
  for (const path of sourceFiles('src/runtime/plugins')) {
2321
- if (['src/runtime/plugins/browser-runtime-contract.ts', 'src/runtime/plugins/browser-provider-registry.ts', 'src/runtime/plugins/browser-session-types.ts'].includes(path)) continue;
2593
+ if (['src/runtime/plugins/browser-runtime-contract.ts', 'src/runtime/plugins/browser-session-types.ts'].includes(path)) continue;
2322
2594
  forbid(path, /from\s+['"]\.\/browser-(?:runtime-contract|provider-registry|session-types)['"]/, 'active Browser runtime code must consume plugin-runtime/protocol Browser contracts, not retired local owners');
2323
2595
  }
2324
2596
  // Computer SurfaceTarget is the only durable interaction-target authority. Browser
@@ -2358,6 +2630,11 @@ for (const path of sourceFiles('packages/workflow-runtime')) {
2358
2630
  forbid(path, /xiaohongshu|douyin|instagram|reddit|facebook/i, 'generic Workflow Runtime contracts must not own site/business choreography');
2359
2631
  forbid(path, /from\s+['"][^'"]*(?:src\/runtime|adapters)\//, 'Workflow Runtime package contracts must remain independent from Runtime/adapters implementation authority');
2360
2632
  }
2633
+ requireText('src/runtime/plugins/first-party-registry.ts', "from './computer-registration'");
2634
+ requireText('src/runtime/plugins/computer-registration.ts', 'buildBrowserPluginManifest(previousRevision, previousUpdatedAt, repoRoot, context, true)');
2635
+ requireText('src/runtime/plugins/computer-registration.ts', '__forge_computer_native_only: true');
2636
+ requireText('src/runtime/plugins/browser-adapter.ts', 'if (computerNativeOnly) return normalizeConfig({');
2637
+ requireText('src/runtime/plugins/browser-adapter.ts', 'if (computerNativeOnly) {');
2361
2638
  requireText('src/runtime/plugins/browser-registration.ts', 'export const browserPluginAdapter');
2362
2639
  requireText('src/runtime/plugins/first-party-registry.ts', "from './browser-registration'");
2363
2640
  forbid('src/runtime/plugins/first-party-registry.ts', /from\s+['"]\.\/browser-adapter['"]/, 'first-party registry must depend on the thin Browser registration entrypoint, not the action implementation');
@@ -373,60 +373,14 @@ install_dev_tools() {
373
373
  echo -e "${GREEN}Dev tools installed!${NC}"
374
374
  }
375
375
 
376
- # Write version stamp into the generated project
377
- write_version_stamp() {
378
- local skill_version_file="$SCRIPT_DIR/../assets/skill-version.json"
379
- local stamp_dir=".claude"
380
- local stamp_file="$stamp_dir/.skill-version"
381
- local sv_version="unknown"
382
- local sv_template_version="unknown"
383
-
384
- if [ -f "$skill_version_file" ] && command_exists bun; then
385
- sv_version=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).version)")
386
- sv_template_version=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).templateVersion)")
387
- elif [ -f "$skill_version_file" ] && command_exists node; then
388
- sv_version=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).version)")
389
- sv_template_version=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$skill_version_file','utf-8')).templateVersion)")
390
- fi
391
-
392
- mkdir -p "$stamp_dir"
393
- cat > "$stamp_file" << STAMP_EOF
394
- skill_version=$sv_version
395
- template_version=$sv_template_version
396
- generated_at=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
397
- plan_type=${STACK}
398
- STAMP_EOF
399
- echo -e "${GREEN}Version stamp written to $stamp_file${NC}"
400
- }
401
-
402
- # Run a skill lifecycle hook (if bun is available)
403
- run_skill_hook() {
404
- local event="$1"
405
- local hook_script="$SCRIPT_DIR/run-skill-hook.ts"
406
-
407
- if command_exists bun && [ -f "$hook_script" ]; then
408
- bun "$hook_script" "$event" --context "{\"projectName\":\"$PROJECT_NAME\",\"stack\":\"$STACK\"}" 2>&1 || {
409
- if [[ "$event" == pre-* ]]; then
410
- echo -e "${RED}Pre-hook $event failed, aborting.${NC}"
411
- return 1
412
- else
413
- echo -e "${YELLOW}Post-hook $event warning (non-fatal).${NC}"
414
- fi
415
- }
416
- fi
417
- }
418
-
419
376
  # Main execution
420
377
  main() {
421
- run_skill_hook "pre-init" || exit 1
422
378
 
423
379
  check_package_manager
424
380
  create_project
425
381
  create_structure
426
382
  install_dev_tools
427
- write_version_stamp
428
383
 
429
- run_skill_hook "post-init"
430
384
 
431
385
  echo ""
432
386
  echo -e "${GREEN}=== Project initialized successfully! ===${NC}"