@quantiya/codevibe-claude-plugin 2.0.38 → 2.0.40

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 (341) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/scrubber.d.ts +8 -0
  3. package/node_modules/@quantiya/codevibe-core/dist/index.js +441 -432
  4. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.d.ts +12 -0
  5. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +763 -155
  6. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-compaction.d.ts +111 -2
  7. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-items.d.ts +21 -1
  8. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-store.d.ts +44 -0
  9. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +60 -7
  10. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/quorum-loop.d.ts +41 -5
  11. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/slash-router.d.ts +8 -0
  12. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/team-decompose.d.ts +17 -0
  13. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/user-rules.d.ts +83 -0
  14. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/web/fetch.d.ts +14 -0
  15. package/node_modules/@quantiya/codevibe-core/package.json +4 -3
  16. package/package.json +2 -2
  17. package/node_modules/@quantiya/codevibe-core/dist/__tests__/cp-5-baseline-invariants.test.d.ts +0 -1
  18. package/node_modules/@quantiya/codevibe-core/dist/__tests__/gate-ux-regressions.test.d.ts +0 -1
  19. package/node_modules/@quantiya/codevibe-core/dist/__tests__/mobile-prompt-input.test.d.ts +0 -1
  20. package/node_modules/@quantiya/codevibe-core/dist/__tests__/no-raw-control-bytes-in-source.test.d.ts +0 -1
  21. package/node_modules/@quantiya/codevibe-core/dist/__tests__/prompt-parser.test.d.ts +0 -1
  22. package/node_modules/@quantiya/codevibe-core/dist/__tests__/terminal-menu.test.d.ts +0 -1
  23. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/capabilities.test.d.ts +0 -1
  24. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/contract-conformance.test.d.ts +0 -1
  25. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/packets.test.d.ts +0 -1
  26. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/progress.test.d.ts +0 -1
  27. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/registry.test.d.ts +0 -1
  28. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/smoke/claude.smoke.test.d.ts +0 -1
  29. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/smoke/codex.smoke.test.d.ts +0 -1
  30. package/node_modules/@quantiya/codevibe-core/dist/adapter/__tests__/smoke/gemini.smoke.test.d.ts +0 -1
  31. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-apply-user-decision.test.d.ts +0 -1
  32. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-classb.test.d.ts +0 -1
  33. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-context-items.test.d.ts +0 -1
  34. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-event-source-filter.test.d.ts +0 -1
  35. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-flag-locator.test.d.ts +0 -1
  36. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-planner.test.d.ts +0 -1
  37. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client-task-group.test.d.ts +0 -1
  38. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/appsync-client.test.d.ts +0 -1
  39. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/cleanup-subscription.test.d.ts +0 -1
  40. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/coerce-awsjson-and-review-summary.test.d.ts +0 -1
  41. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/cp1f-quorum-sdk.test.d.ts +0 -1
  42. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/dispose-watcher-socket.test.d.ts +0 -1
  43. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/event-throttle.test.d.ts +0 -1
  44. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/group-operation-result.test.d.ts +0 -1
  45. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/heartbeat-active.test.d.ts +0 -1
  46. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/orphan-sweep-null-heartbeat.test.d.ts +0 -1
  47. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/refresh-open-prompt-ttl-chunk.test.d.ts +0 -1
  48. package/node_modules/@quantiya/codevibe-core/dist/appsync/__tests__/supervision-subscription.test.d.ts +0 -1
  49. package/node_modules/@quantiya/codevibe-core/dist/audit-keys/__tests__/audit-keys-parity.test.d.ts +0 -1
  50. package/node_modules/@quantiya/codevibe-core/dist/auth/__tests__/auth-telemetry.test.d.ts +0 -1
  51. package/node_modules/@quantiya/codevibe-core/dist/auth/__tests__/keychain-cli-nudge.test.d.ts +0 -1
  52. package/node_modules/@quantiya/codevibe-core/dist/auth/__tests__/keychain-cli.test.d.ts +0 -1
  53. package/node_modules/@quantiya/codevibe-core/dist/auth/__tests__/vendor-key-cli.test.d.ts +0 -1
  54. package/node_modules/@quantiya/codevibe-core/dist/companion-mode/__tests__/mode-selected-emit.test.d.ts +0 -1
  55. package/node_modules/@quantiya/codevibe-core/dist/companion-mode/__tests__/persist-preference.test.d.ts +0 -1
  56. package/node_modules/@quantiya/codevibe-core/dist/companion-mode/__tests__/private-launcher-detection.test.d.ts +0 -1
  57. package/node_modules/@quantiya/codevibe-core/dist/companion-mode/__tests__/private-launcher-path.test.d.ts +0 -1
  58. package/node_modules/@quantiya/codevibe-core/dist/companion-mode/__tests__/resolve-agent.test.d.ts +0 -1
  59. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/dirty-state-collector.test.d.ts +0 -1
  60. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/integration.test.d.ts +0 -1
  61. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/packet-reader.test.d.ts +0 -1
  62. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/packet-writer.test.d.ts +0 -1
  63. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/parity.test.d.ts +0 -1
  64. package/node_modules/@quantiya/codevibe-core/dist/continuation/__tests__/status-cli.test.d.ts +0 -1
  65. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/broker-c4.test.d.ts +0 -1
  66. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/broker-streaming.test.d.ts +0 -1
  67. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/broker.test.d.ts +0 -1
  68. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/canonical.test.d.ts +0 -1
  69. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/chatgpt-config.test.d.ts +0 -1
  70. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/oauth-account-lock.test.d.ts +0 -1
  71. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/oauth-refresh.test.d.ts +0 -1
  72. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/scrubber.test.d.ts +0 -1
  73. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/upstream-client.test.d.ts +0 -1
  74. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/upstream-result-helpers.d.ts +0 -21
  75. package/node_modules/@quantiya/codevibe-core/dist/credential-broker/__tests__/vendor-key-store.test.d.ts +0 -1
  76. package/node_modules/@quantiya/codevibe-core/dist/crypto/__tests__/crypto-service.test.d.ts +0 -1
  77. package/node_modules/@quantiya/codevibe-core/dist/crypto/__tests__/encrypt-for-emit.test.d.ts +0 -1
  78. package/node_modules/@quantiya/codevibe-core/dist/crypto/__tests__/open-prompt-id.test.d.ts +0 -1
  79. package/node_modules/@quantiya/codevibe-core/dist/daemon/__tests__/process-guards.test.d.ts +0 -1
  80. package/node_modules/@quantiya/codevibe-core/dist/e1/__tests__/prompt-publication.test.d.ts +0 -1
  81. package/node_modules/@quantiya/codevibe-core/dist/e1/__tests__/prompt-raise.test.d.ts +0 -1
  82. package/node_modules/@quantiya/codevibe-core/dist/keychain/__tests__/keychain-backend.test.d.ts +0 -1
  83. package/node_modules/@quantiya/codevibe-core/dist/keychain/__tests__/keychain-manager.test.d.ts +0 -1
  84. package/node_modules/@quantiya/codevibe-core/dist/keychain/__tests__/keychain-migrate.test.d.ts +0 -1
  85. package/node_modules/@quantiya/codevibe-core/dist/keychain/__tests__/migrate-nudge.test.d.ts +0 -1
  86. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/agentic-disposable-repo.test.d.ts +0 -1
  87. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/agentic-resolve.test.d.ts +0 -1
  88. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/agentic-resolver-flag.test.d.ts +0 -1
  89. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/anchored-fs.test.d.ts +0 -1
  90. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/authority-symlink-fixture.d.ts +0 -15
  91. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/authority.test.d.ts +0 -1
  92. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/bounded-directory.test.d.ts +0 -1
  93. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/bounded-output.test.d.ts +0 -1
  94. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class-a-emit.test.d.ts +0 -1
  95. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class-a-sign.test.d.ts +0 -1
  96. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class-b-consumer.integration.test.d.ts +0 -1
  97. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class-b-consumer.test.d.ts +0 -1
  98. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class1-reconcilers.test.d.ts +0 -1
  99. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/class2-resolver.test.d.ts +0 -1
  100. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/confined-model-caller.test.d.ts +0 -1
  101. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/conflict-classifier.test.d.ts +0 -1
  102. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/conflict-resolution-durable-store.test.d.ts +0 -1
  103. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/conflict-resolution-store.test.d.ts +0 -1
  104. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/cp1f-quorum-consumer.test.d.ts +0 -1
  105. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/cp7-audit-writer.test.d.ts +0 -1
  106. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/durable-directory.test.d.ts +0 -1
  107. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/durable-store.test.d.ts +0 -1
  108. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/git-lock-retry.test.d.ts +0 -1
  109. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/hook-bridge.test.d.ts +0 -1
  110. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/hosted-class-a-sink.test.d.ts +0 -1
  111. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/implementor-argv.test.d.ts +0 -1
  112. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/local-executor-teams-summary.test.d.ts +0 -1
  113. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/local-executor-teams.test.d.ts +0 -1
  114. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/local-executor.integration.test.d.ts +0 -1
  115. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-conflict-extract.test.d.ts +0 -1
  116. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-conflict-git.integration.test.d.ts +0 -1
  117. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-conflict-resolve-agentic.integration.test.d.ts +0 -1
  118. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-conflict-resolve.integration.test.d.ts +0 -1
  119. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-journal-store.test.d.ts +0 -1
  120. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-train-agentic-recovery.integration.test.d.ts +0 -1
  121. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-train-w3.integration.test.d.ts +0 -1
  122. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-train-waveb.integration.test.d.ts +0 -1
  123. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/merge-train.test.d.ts +0 -1
  124. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/process-identity.test.d.ts +0 -1
  125. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/process-tree.test.d.ts +0 -1
  126. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/promote-wal-store.test.d.ts +0 -1
  127. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/protocol-backlog-wiring.test.d.ts +0 -1
  128. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/protocol-backlog.test.d.ts +0 -1
  129. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/publication-authority-capability.test.d.ts +0 -1
  130. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/revert-reconcile.test.d.ts +0 -1
  131. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/revert-runner.test.d.ts +0 -1
  132. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/reviewer-rationale-flag.test.d.ts +0 -1
  133. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/shared-contract-detector.test.d.ts +0 -1
  134. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/snapshot-merge.test.d.ts +0 -1
  135. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/spawn.test.d.ts +0 -1
  136. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/substrate-engage.test.d.ts +0 -1
  137. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/team-execution-flag.test.d.ts +0 -1
  138. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/track-registry.test.d.ts +0 -1
  139. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/verification-runner.test.d.ts +0 -1
  140. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/wb2-review-bundle.test.d.ts +0 -1
  141. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/wb2-substrate-spawn.live.test.d.ts +0 -1
  142. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-authority-fixture.d.ts +0 -3
  143. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-authority.test.d.ts +0 -1
  144. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-cleanup-audit.test.d.ts +0 -1
  145. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-materializer.test.d.ts +0 -1
  146. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/workspace-shadow.test.d.ts +0 -1
  147. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/worktree-merge.test.d.ts +0 -1
  148. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/installer.test.d.ts +0 -1
  149. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/manager.test.d.ts +0 -1
  150. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/ollama-context-window.test.d.ts +0 -1
  151. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/ollama.test.d.ts +0 -1
  152. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/runtime.test.d.ts +0 -1
  153. package/node_modules/@quantiya/codevibe-core/dist/local-model/__tests__/state.test.d.ts +0 -1
  154. package/node_modules/@quantiya/codevibe-core/dist/orchestration/__tests__/detect-agents.test.d.ts +0 -1
  155. package/node_modules/@quantiya/codevibe-core/dist/orchestration/__tests__/v1-options.test.d.ts +0 -1
  156. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/a1a-planner-offers.test.d.ts +0 -1
  157. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/a6-cli-surface.test.d.ts +0 -1
  158. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/advisory-attachment-journal.test.d.ts +0 -1
  159. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/advisory-attachments-dir-race.test.d.ts +0 -1
  160. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/advisory-multi-mention-panel.test.d.ts +0 -1
  161. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/advisory-panel-attachments.test.d.ts +0 -1
  162. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/advisory-quota-stdout-result.test.d.ts +0 -1
  163. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/agent-turn-context-batch.test.d.ts +0 -1
  164. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/attachments.test.d.ts +0 -1
  165. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-browser.test.d.ts +0 -1
  166. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-buffer-join.test.d.ts +0 -1
  167. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-normalization.test.d.ts +0 -1
  168. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-summary.test.d.ts +0 -1
  169. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audited-path-fixes.test.d.ts +0 -1
  170. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/bounded-shutdown.test.d.ts +0 -1
  171. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/bracketed-paste.test.d.ts +0 -1
  172. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/brainstorm-quorum-wiring.test.d.ts +0 -1
  173. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/brainstorm-quorum.test.d.ts +0 -1
  174. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/browse-prompt-urls.test.d.ts +0 -1
  175. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-authority-bridge.test.d.ts +0 -1
  176. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-group-halt-wiring.test.d.ts +0 -1
  177. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-orchestration-session-bootstrap.test.d.ts +0 -1
  178. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-planner-stack.test.d.ts +0 -1
  179. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-probe-group-status.test.d.ts +0 -1
  180. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-quorum-loop-tier.test.d.ts +0 -1
  181. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-singleton-enforcement.test.d.ts +0 -1
  182. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-team-session-key.test.d.ts +0 -1
  183. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cli-verdict-classifier-wiring.test.d.ts +0 -1
  184. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/command-intent.test.d.ts +0 -1
  185. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/companion-turn-mirror.test.d.ts +0 -1
  186. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/components.test.d.ts +0 -1
  187. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/context-compaction.test.d.ts +0 -1
  188. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/context-items-hosted-sync.test.d.ts +0 -1
  189. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/context-items-wiring.test.d.ts +0 -1
  190. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/context-items.test.d.ts +0 -1
  191. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/context-store.test.d.ts +0 -1
  192. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp10-585-accept-echo-target.test.d.ts +0 -1
  193. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp10-585-loop.test.d.ts +0 -1
  194. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp10-585-prompts.test.d.ts +0 -1
  195. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp12-w2b-team-loop.test.d.ts +0 -1
  196. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp12-w4-team-recovery.test.d.ts +0 -1
  197. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp1f-quorum-loop.test.d.ts +0 -1
  198. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp606-team-track-user-resolved.test.d.ts +0 -1
  199. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp7-reviewer-substrate.test.d.ts +0 -1
  200. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp8-full-team-events.test.d.ts +0 -1
  201. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/cp8-team-decomposed-zk.test.d.ts +0 -1
  202. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-attempt-live-handoff.test.d.ts +0 -1
  203. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-attempt-recovery.test.d.ts +0 -1
  204. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-attempt-session-serialization.test.d.ts +0 -1
  205. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-attempt.test.d.ts +0 -1
  206. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-effect.test.d.ts +0 -1
  207. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-map-lifecycle.test.d.ts +0 -1
  208. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/declared-test-runner.test.d.ts +0 -1
  209. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/destructive-request.test.d.ts +0 -1
  210. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/emit-shell-event.test.d.ts +0 -1
  211. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/explicit-tty-exit.test.d.ts +0 -1
  212. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/familiarize-routing.test.d.ts +0 -1
  213. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/flag-command.test.d.ts +0 -1
  214. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/gate-decision-submit.test.d.ts +0 -1
  215. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/gate-details-panel.test.d.ts +0 -1
  216. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/gate-prompts.test.d.ts +0 -1
  217. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/gate-resolution-event.test.d.ts +0 -1
  218. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/gate-verdict-details-dispatch.test.d.ts +0 -1
  219. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/group-decision-submit.test.d.ts +0 -1
  220. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/halt-message-wire-content.test.d.ts +0 -1
  221. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/hostile-grep.test.d.ts +0 -1
  222. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/image-attach-e2e.test.d.ts +0 -1
  223. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/input-bar-autocomplete.test.d.ts +0 -1
  224. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/live-region-cap.test.d.ts +0 -1
  225. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/live-static-order.test.d.ts +0 -1
  226. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/mention-suggest.test.d.ts +0 -1
  227. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/mobile-user-prompt-return.test.d.ts +0 -1
  228. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/mode-selection.test.d.ts +0 -1
  229. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/model-cli.test.d.ts +0 -1
  230. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/non-gate-prompt-routing.test.d.ts +0 -1
  231. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/o5-diagnostics.test.d.ts +0 -1
  232. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/orchestration-app-group-decision-transport.test.d.ts +0 -1
  233. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/orchestration-app-layout.test.d.ts +0 -1
  234. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/planner-confirmation-routing.test.d.ts +0 -1
  235. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/planner-offer-e1.test.d.ts +0 -1
  236. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/process-markers.test.d.ts +0 -1
  237. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/query_audit_tier_gate.test.d.ts +0 -1
  238. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/quorum-loop-fail-safe.test.d.ts +0 -1
  239. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/quorum-loop-outcome-recency.test.d.ts +0 -1
  240. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/quorum-loop-summary.test.d.ts +0 -1
  241. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/reducer.test.d.ts +0 -1
  242. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/reissue-team-retained-spec.test.d.ts +0 -1
  243. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/review-summary-render.test.d.ts +0 -1
  244. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/reviewer-wizard.test.d.ts +0 -1
  245. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/reviewers-format.test.d.ts +0 -1
  246. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/root-discovery.test.d.ts +0 -1
  247. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/route-browse-multi-result.test.d.ts +0 -1
  248. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/route-browse-summarize-recovery.test.d.ts +0 -1
  249. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell-browse-cancel.test.d.ts +0 -1
  250. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell-classify-dispatch.test.d.ts +0 -1
  251. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell-planner-wiring.test.d.ts +0 -1
  252. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell-session-retire.test.d.ts +0 -1
  253. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell-signal.test.d.ts +0 -1
  254. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/runOrchestrationShell.test.d.ts +0 -1
  255. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/serialize-submissions.test.d.ts +0 -1
  256. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/slash-router.test.d.ts +0 -1
  257. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/slash-suggest.test.d.ts +0 -1
  258. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/status-format.test.d.ts +0 -1
  259. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/sticky-preference.test.d.ts +0 -1
  260. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/supervision-catch-up.test.d.ts +0 -1
  261. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/task-progress.test.d.ts +0 -1
  262. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/team-decompose-routing.test.d.ts +0 -1
  263. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/team-decompose-types.test.d.ts +0 -1
  264. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/team-decompose.test.d.ts +0 -1
  265. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/team-e2e-smoke.test.d.ts +0 -1
  266. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/tier2-reviewer-selection.test.d.ts +0 -1
  267. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/web-browsing.test.d.ts +0 -1
  268. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/workspace-outcome.test.d.ts +0 -1
  269. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/workspace-shutdown.test.d.ts +0 -1
  270. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/workspace-terminal-coordinator.test.d.ts +0 -1
  271. package/node_modules/@quantiya/codevibe-core/dist/ordinal-presentation.test.d.ts +0 -1
  272. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/cache-clarification-bypass.test.d.ts +0 -1
  273. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/cache.test.d.ts +0 -1
  274. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/client.test.d.ts +0 -1
  275. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/health-machine-transitions.test.d.ts +0 -1
  276. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/local-gemma-browse-regression.test.d.ts +0 -1
  277. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/local-gemma-followup-hotfix.test.d.ts +0 -1
  278. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/local-gemma.test.d.ts +0 -1
  279. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/types-zod.test.d.ts +0 -1
  280. package/node_modules/@quantiya/codevibe-core/dist/planner/__tests__/url-protect.test.d.ts +0 -1
  281. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/antigravity-provider.test.d.ts +0 -1
  282. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/claude-provider-json.test.d.ts +0 -1
  283. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/cp7-reviewer-sandbox.test.d.ts +0 -1
  284. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/integration.test.d.ts +0 -1
  285. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/mocks.test.d.ts +0 -1
  286. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/output-parser-classifier-helpers.test.d.ts +0 -1
  287. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/output-parser.test.d.ts +0 -1
  288. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/registry.test.d.ts +0 -1
  289. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/round-scope.test.d.ts +0 -1
  290. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/subprocess.test.d.ts +0 -1
  291. package/node_modules/@quantiya/codevibe-core/dist/reviewer/__tests__/verdict-classifier.test.d.ts +0 -1
  292. package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/__tests__/claude-live-smoke.test.d.ts +0 -1
  293. package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/__tests__/claude.test.d.ts +0 -1
  294. package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/__tests__/codex-live-smoke.test.d.ts +0 -1
  295. package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/__tests__/codex.test.d.ts +0 -1
  296. package/node_modules/@quantiya/codevibe-core/dist/reviewer/providers/__tests__/failure-classifier.test.d.ts +0 -1
  297. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/device-registration-lease.test.d.ts +0 -1
  298. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/pending-session-create.test.d.ts +0 -1
  299. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/prepare-event-timestamp.test.d.ts +0 -1
  300. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/session-rekey-fingerprint.test.d.ts +0 -1
  301. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/session-resume-key-reconciliation.test.d.ts +0 -1
  302. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/session-resume-pending-first.test.d.ts +0 -1
  303. package/node_modules/@quantiya/codevibe-core/dist/session/__tests__/session-resume-service-keys.test.d.ts +0 -1
  304. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/__fixtures__/fixture-helpers.d.ts +0 -11
  305. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/assembler.test.d.ts +0 -1
  306. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/generator.test.d.ts +0 -1
  307. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/language-detect.test.d.ts +0 -1
  308. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/cargo.test.d.ts +0 -1
  309. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/gomod.test.d.ts +0 -1
  310. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/gradle.test.d.ts +0 -1
  311. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/index.test.d.ts +0 -1
  312. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/npm.test.d.ts +0 -1
  313. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/podfile.test.d.ts +0 -1
  314. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/manifest-parsers/pyproject.test.d.ts +0 -1
  315. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/opt-in-store.test.d.ts +0 -1
  316. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/privacy-filter.test.d.ts +0 -1
  317. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/safe-file-read.test.d.ts +0 -1
  318. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/user-ignore-matcher.test.d.ts +0 -1
  319. package/node_modules/@quantiya/codevibe-core/dist/structural-summary/__tests__/walker.test.d.ts +0 -1
  320. package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/command-runner.test.d.ts +0 -1
  321. package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/docker.test.d.ts +0 -1
  322. package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/forwarder.test.d.ts +0 -1
  323. package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/sandbox-exec.test.d.ts +0 -1
  324. package/node_modules/@quantiya/codevibe-core/dist/substrate/__tests__/substrate-e2e.integration.test.d.ts +0 -1
  325. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/apikey-bootstrap.test.d.ts +0 -1
  326. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/creditless-loop.integration.test.d.ts +0 -1
  327. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/engage-substrate.test.d.ts +0 -1
  328. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/fallback-ladder.test.d.ts +0 -1
  329. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/le-env-scrub.test.d.ts +0 -1
  330. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/reviewer-credential-preflight.test.d.ts +0 -1
  331. package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/__tests__/sanitized-env.test.d.ts +0 -1
  332. package/node_modules/@quantiya/codevibe-core/dist/test-publication-authority-setup.d.ts +0 -1
  333. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/consolidator.test.d.ts +0 -1
  334. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/digest.test.d.ts +0 -1
  335. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/flock-rollout-lock.test.d.ts +0 -1
  336. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/ledger.test.d.ts +0 -1
  337. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/outbox.test.d.ts +0 -1
  338. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/replay-cursor.test.d.ts +0 -1
  339. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/session-map.test.d.ts +0 -1
  340. package/node_modules/@quantiya/codevibe-core/dist/tool-activity/__tests__/socket-rollout-lock.test.d.ts +0 -1
  341. package/node_modules/@quantiya/codevibe-core/dist/track-presentation.test.d.ts +0 -1
@@ -10881,6 +10881,7 @@ var path6 = __toESM(require("path")), TIER_RANK = { FREE: 0, PRO: 1, MAX: 2 };
10881
10881
  function tierMeets(actual, required) {
10882
10882
  return !required || !actual ? !0 : TIER_RANK[actual] >= TIER_RANK[required];
10883
10883
  }
10884
+ var USER_RULE_PIN_PENDING = "PENDING \u2014 entrypoint pins the rule", USER_RULES_LIST_PENDING = "PENDING \u2014 entrypoint lists pinned rules", USER_RULES_FORGET_PENDING = "PENDING \u2014 entrypoint retires a pinned rule";
10884
10885
  function staticOutput(command, output, sideEffect) {
10885
10886
  return { command, output, sideEffect };
10886
10887
  }
@@ -11074,12 +11075,12 @@ var CATALOG = [
11074
11075
  // shortcut that drives the engine START directly, bypassing the planner
11075
11076
  // classification. The sync router returns the PENDING marker (it can't see
11076
11077
  // the loop); `handleShellUserInput` parses an optional `--agent
11077
- // codex|claude` override (Fix 5) + the brief, then calls
11078
+ // claude|codex|antigravity` override (Fix 5) + the brief, then calls
11078
11079
  // `quorumLoop.startTask({ brief, agent })` with the SAME TASK_LIFECYCLE
11079
11080
  // dispatch the planner `start_task` path does. Empty brief → usage advisory.
11080
11081
  handler: (args) => args.length === 0 ? staticOutput(
11081
11082
  "/task",
11082
- "Usage: /task [--agent codex|claude] <implementation-request>. Pro/Max only; runs without planner classification."
11083
+ "Usage: /task [--agent claude|codex|antigravity] <implementation-request>. Pro/Max only; runs without planner classification."
11083
11084
  ) : staticOutput("/task", "PENDING \u2014 entrypoint drives startTask")
11084
11085
  },
11085
11086
  {
@@ -11101,6 +11102,25 @@ var CATALOG = [
11101
11102
  "Usage: /team <json-work-items>. Starts an Agent Teams group (\u22652 disjoint tracks). Max-tier orchestration sessions only."
11102
11103
  ) : staticOutput("/team", "PENDING \u2014 entrypoint runs createTaskGroup")
11103
11104
  },
11105
+ {
11106
+ // M7 DL-2 — `/rule <text>` pins the text verbatim for this session.
11107
+ name: "/rule",
11108
+ blurb: "Pin a rule for this session; agents that implement tasks follow it.",
11109
+ handler: (args) => args.length === 0 ? staticOutput(
11110
+ "/rule",
11111
+ "Usage: /rule <rule text>. Pins the rule for this session; list pinned rules with /rules."
11112
+ ) : staticOutput("/rule", USER_RULE_PIN_PENDING)
11113
+ },
11114
+ {
11115
+ // M7 DL-2 — `/rules` lists every live pin, numbered oldest first;
11116
+ // `/rules forget <n>` retires pin n from that list.
11117
+ name: "/rules",
11118
+ blurb: "List this session's pinned rules; add forget <n> to retire one.",
11119
+ handler: (args) => args.length === 0 ? staticOutput("/rules", USER_RULES_LIST_PENDING) : args[0] === "forget" && args.length === 2 && /^[1-9][0-9]*$/.test(args[1]) ? staticOutput("/rules", USER_RULES_FORGET_PENDING) : staticOutput(
11120
+ "/rules",
11121
+ "Usage: /rules lists pinned rules; /rules forget <n> retires rule n from that list."
11122
+ )
11123
+ },
11104
11124
  {
11105
11125
  name: "/quit",
11106
11126
  blurb: "Exit CodeVibe shell.",
@@ -18573,6 +18593,7 @@ function renderLocalGemmaPlannerPrompt(input, options) {
18573
18593
  options?.isSubprocessRunner ? `- advisory_response: user asks a general question that does not require repository context or file changes. Put a COMPLETE, natural, conversational ANSWER to the question in the "advisory_summary" field (a full helpful reply, like a chat assistant \u2014 NOT a one-line label or a restatement of the question); explain core principles accurately: for search/pathfinding, start with the start node in the open set, use strictly standard A* terminology (open set and closed set only; never invent other sets like missed set or turn set), and compare with Dijkstra's algorithm; explain that a more accurate, higher admissible heuristic (closer to the true remaining cost) guides the search more directly to the goal and expands fewer nodes, whereas a smaller or zero heuristic (like Dijkstra's algorithm) explores in all directions and expands more nodes; a heuristic must be admissible (never overestimate the true distance) to guarantee an optimal shortest path; write all mathematical expressions in clean plain text like f(n) = g(n) + h(n) (never use LaTeX math notation, \\text{}, math mode $, or backslashes); format the entire explanation in clean, well-structured markdown prose paragraphs separated by blank lines (do not use bullet lists, numbered sub-lists, or backslash line breaks; write complete narrative paragraphs); never use tab characters or \\t; never use double quotes inside advisory_summary (use single quotes ' if quoting terms); keep "rationale" a short internal classification reason. Answer directly and warmly, e.g. "Yes \u2014 I can \u2026".` : '- advisory_response: user asks a general question or capability question. Put a concise, natural, 1-sentence direct answer or definition in "advisory_summary" (e.g. "Yes, I can write Rust" or "A* is a best-first pathfinding algorithm that expands nodes by f(n) = g(n) + h(n)"); do NOT write preambles like "Here is..." or conversational labels; keep "rationale" a short reason. The downstream local advisory engine generates the full answer.',
18574
18594
  options?.isSubprocessRunner ? '- FOLLOW-UP ON EARLIER CONTENT: when the user asks for your thoughts, opinion, analysis, critique, or a deeper explanation of something already fetched or answered earlier in this session (a web page that was read, a search result, a previous reply) \u2014 e.g. "I am looking for your thoughts", "what do you think about that", "go deeper on that", "is that right?" \u2014 choose advisory_response and put the COMPLETE reply in advisory_summary (no downstream answerer runs for this runner). Never brainstorm, familiarize, or browse again for such a follow-up.' : `- FOLLOW-UP ON EARLIER CONTENT: when the user asks for your thoughts, opinion, analysis, critique, or a deeper explanation of something already fetched or answered earlier in this session (a web page that was read, a search result, a previous reply) \u2014 e.g. "I am looking for your thoughts", "what do you think about that", "go deeper on that", "is that right?" \u2014 choose advisory_response with a one-sentence advisory_summary (the shell's answerer writes the full reply from the page and the conversation). Never brainstorm, familiarize, or browse again for such a follow-up.`,
18575
18595
  options?.isSubprocessRunner ? "- summarize_current_status: user asks what changed, what the last task did, current progress, or workflow status." : "- Questions about progress, what changed, what the last task did, or workflow status are advisory_response too: the shell attaches its own status record to the answer, so never invent task history.",
18596
+ '- STATEMENT WHILE A TASK RUNS (session.currentTaskState is in_progress): a userPrompt that only STATES a preference, convention, constraint, rule, reminder or fact \u2014 or retracts one \u2014 and asks for NO new deliverable is context for the running task and for later work, NOT a second task. Typical openers: "fyi", "from now on", "note that", "btw", "just so you know", "heads up", "reminder:", "for the record", "scratch that", "never mind", "disregard", "actually". Choose advisory_response with a one-sentence acknowledgement of the statement in advisory_summary; never start_task or team_decompose for it. A prompt that asks for a NEW file, flag, fix, rename, test or run while a task runs is still start_task; a request to remove or delete named project files while a task runs follows the destructive-operation rule below (ask_user until the user confirms), never advisory_response.',
18576
18597
  `- IMAGE ATTACHED (IMPORTANT): a "[N image(s) attached]" line at the end of the prompt means the user attached image file(s) \u2014 a screenshot, photo, diagram, mockup, or error capture. Decide by the user's VERB, in this order: (1) MUTATION verb \u2014 if they ask to CREATE / ADD / FIX / IMPLEMENT / BUILD / REFACTOR / CHANGE / UPDATE / WRITE / TEST / MAKE something, route to start_task (or team_decompose for explicit parallel work) EVEN when the request references the image ("match this mockup", "fix the layout to look like the screenshot", "build this UI"); the image is reference material and the implementor receives it. (2) OTHERWISE \u2014 if they ask to DESCRIBE / READ / EXPLAIN / ANALYZE the image or its content ("what is this", "describe this", "what does this show", "read this error"), OR give only the image path / a vague prompt ("look at this", or just the path with no instruction) \u2014 route to advisory_response and leave "advisory_summary" EMPTY: a multimodal step answers FROM the image on-device. Route (2) is NOT familiarize (which reads the LOCAL repo, never an image) and NOT ask_user (the attached image IS the context \u2014 never ask what it is).`,
18577
18598
  "- ask_user: required information or confirmation is missing and cannot be inferred from the current turn plus clarifications. During a design discussion, clarify if it is unclear whether the user wants implementation or further discussion; do not start a task for a question about how something could be built. An explicit request to implement a selected option is start_task.",
18578
18599
  "- refuse: only for the unsafe categories above.",
@@ -18606,6 +18627,9 @@ function renderLocalGemmaPlannerPrompt(input, options) {
18606
18627
  'User: "look up the React 19 release notes online" -> {"action":"browse","rationale":"web lookup","browseQuery":"React 19 release notes"}',
18607
18628
  'User: "what is the latest LTS version of Node.js?" -> {"action":"browse","rationale":"freshness lookup needs current web info, not stale knowledge","browseQuery":"latest LTS version Node.js"}',
18608
18629
  'User: "what is the current stable version of Python?" -> {"action":"browse","rationale":"current version is a freshness web lookup","browseQuery":"current stable version Python"}',
18630
+ `User: "fyi every FLAGS.md row should also say what the default is" (session.currentTaskState is in_progress) -> {"action":"advisory_response","rationale":"a convention stated while a task runs; acknowledge, no second task","advisory_summary":"Noted \u2014 FLAGS.md rows will also state each flag's default."}`,
18631
+ 'User: "scratch that \u2014 descriptions should not end with a period" (session.currentTaskState is in_progress) -> {"action":"advisory_response","rationale":"retracts an earlier rule while a task runs","advisory_summary":"Understood \u2014 descriptions will not end with a period."}',
18632
+ 'User: "also add a --cv-quiet flag to release.sh" (session.currentTaskState is in_progress) -> {"action":"start_task","rationale":"asks for a new deliverable while a task runs"}',
18609
18633
  "",
18610
18634
  "Output STRICT JSON ONLY with this shape:",
18611
18635
  `{"action":"${[...localGemmaAllowedActions(!!options?.isSubprocessRunner)].join("|")}","rationale":"short reason","clarifying_question":"optional","advisory_summary":"optional","browseUrls":["optional http(s) url"],"browseQuery":"optional web-search query"}`,
@@ -20485,7 +20509,7 @@ var MAX_BYTES = 2 * 1024 * 1024, TIMEOUT_MS = 1e4, MAX_REDIRECTS = 3, USER_AGENT
20485
20509
  this.name = "FetchError";
20486
20510
  }
20487
20511
  };
20488
- async function resolveValidatedIps(host, signal) {
20512
+ async function resolveValidatedIps(host, signal, customLookup = dns2.lookup) {
20489
20513
  let cls = classifyHost(host);
20490
20514
  if (cls.kind === "reject") throw new FetchError("blocked", `host not allowed: ${host}`);
20491
20515
  if (cls.kind === "ip") {
@@ -20500,7 +20524,7 @@ async function resolveValidatedIps(host, signal) {
20500
20524
  return;
20501
20525
  }
20502
20526
  let onAbort = () => reject(new FetchError("timeout", "DNS aborted"));
20503
- signal?.addEventListener("abort", onAbort, { once: !0 }), dns2.lookup(host, { all: !0 }, (err, addrs) => {
20527
+ signal?.addEventListener("abort", onAbort, { once: !0 }), customLookup(host, { all: !0 }, (err, addrs) => {
20504
20528
  signal?.removeEventListener("abort", onAbort), err ? reject(err) : resolve20(addrs);
20505
20529
  });
20506
20530
  });
@@ -51500,6 +51524,48 @@ async function probeWorkspaceGitHead(workspaceRoot) {
51500
51524
  return { kind: "probe-failed" };
51501
51525
  }
51502
51526
  }
51527
+ var WORKSPACE_TREE_FINGERPRINT_TIMEOUT_MS = 3e3;
51528
+ async function probeWorkspaceTreeFingerprint(workspaceRoot, options = {}) {
51529
+ let started = Date.now(), deadline = started + (options.timeoutMs ?? WORKSPACE_TREE_FINGERPRINT_TIMEOUT_MS), remaining = () => deadline - Date.now(), failed = () => ({
51530
+ kind: "probe-failed",
51531
+ durationMs: Date.now() - started
51532
+ }), env = { ...process.env, LC_ALL: "C" };
51533
+ try {
51534
+ if (remaining() <= 0) return failed();
51535
+ let { stdout: topLevel } = await execFile4("git", ["rev-parse", "--show-toplevel"], {
51536
+ cwd: workspaceRoot,
51537
+ env,
51538
+ timeout: Math.max(1, remaining())
51539
+ }), root = topLevel.trim();
51540
+ if (root.length === 0 || remaining() <= 0) return failed();
51541
+ let { stdout } = await execFile4(
51542
+ "git",
51543
+ ["--no-optional-locks", "status", "--porcelain=v1", "-z", "--untracked-files=all"],
51544
+ { cwd: root, env, timeout: Math.max(1, remaining()), maxBuffer: 64 * 1024 * 1024 }
51545
+ ), fields = stdout.split("\0").filter((field2) => field2.length > 0), parts = [];
51546
+ for (let i = 0; i < fields.length; i++) {
51547
+ if (remaining() <= 0) return failed();
51548
+ let xy = fields[i].slice(0, 2), relative22 = fields[i].slice(3);
51549
+ /[RC]/.test(xy) && (i += 1);
51550
+ let stat13 = "absent";
51551
+ try {
51552
+ let st = await fs36.lstat(path54.join(root, relative22));
51553
+ stat13 = `${st.size}:${st.mtimeMs}`;
51554
+ } catch {
51555
+ }
51556
+ parts.push(`${xy} ${relative22} ${stat13}`);
51557
+ }
51558
+ return remaining() <= 0 ? failed() : {
51559
+ kind: "fingerprint",
51560
+ value: crypto25.createHash("sha256").update(parts.join(`
51561
+ `)).digest("hex"),
51562
+ entries: parts.length,
51563
+ durationMs: Date.now() - started
51564
+ };
51565
+ } catch {
51566
+ return failed();
51567
+ }
51568
+ }
51503
51569
  async function computeSummaryInputHash(deps) {
51504
51570
  let canonicalRootPaths = await canonicalizeRootPaths(deps.rootPaths), bodyPaths = ((await readOptIn(deps.tier))?.bodyInclusionPaths ?? []).slice().sort(), ignoreFilePath = path54.join(resolveHome4(), ".codevibe", "structural-summary.ignore"), ignoreFileHash = "absent";
51505
51571
  try {
@@ -52754,7 +52820,7 @@ function projectItemsForRole(items, role, clearance) {
52754
52820
  }
52755
52821
  var NON_GIT_REPO_STATE_MAX_AGE_MS = 1440 * 60 * 1e3;
52756
52822
  async function projectRepoStateForDispatch(deps) {
52757
- let probeGitHeadFn = deps.probeGitHeadFn ?? probeWorkspaceGitHead, verified = await readVerifiedContextItems(deps.sessionId);
52823
+ let probeGitHeadFn = deps.probeGitHeadFn ?? probeWorkspaceGitHead, probeTreeFingerprintFn = deps.probeTreeFingerprintFn ?? probeWorkspaceTreeFingerprint, verified = await readVerifiedContextItems(deps.sessionId);
52758
52824
  if (!verified.ok)
52759
52825
  return warnChainIntegrityOnce(deps.sessionId, verified), { status: "missing" };
52760
52826
  let items = verified.items, latest = null;
@@ -52770,6 +52836,7 @@ async function projectRepoStateForDispatch(deps) {
52770
52836
  workspaceId: deps.workspaceId,
52771
52837
  summary: legacy.summary,
52772
52838
  ...legacy.gitHead ? { gitHead: legacy.gitHead } : {},
52839
+ ...legacy.worktreeFingerprint ? { worktreeFingerprint: legacy.worktreeFingerprint } : {},
52773
52840
  producedAt: legacy.producedAt
52774
52841
  }, author = { role: "agent", agent_id: legacy.author });
52775
52842
  }
@@ -52800,7 +52867,16 @@ async function projectRepoStateForDispatch(deps) {
52800
52867
  }
52801
52868
  return { status: "stale" };
52802
52869
  }
52803
- return {
52870
+ let recordFingerprint = typeof record.worktreeFingerprint == "string" && record.worktreeFingerprint.length > 0 ? record.worktreeFingerprint : null;
52871
+ if (recordFingerprint === null)
52872
+ return { status: "stale" };
52873
+ let tree = await probeTreeFingerprintFn(deps.workspaceRoot);
52874
+ return logger.info("[context-items] worktree fingerprint probe", {
52875
+ kind: tree.kind,
52876
+ durationMs: tree.durationMs,
52877
+ ...tree.kind === "fingerprint" ? { entries: tree.entries } : {},
52878
+ matchesRecord: tree.kind === "fingerprint" && tree.value === recordFingerprint
52879
+ }), tree.kind !== "fingerprint" || tree.value !== recordFingerprint ? { status: "stale" } : {
52804
52880
  status: "fresh",
52805
52881
  summary: record.summary,
52806
52882
  author,
@@ -52812,6 +52888,7 @@ async function appendRepoStateItem(deps) {
52812
52888
  workspaceId: deps.workspaceId,
52813
52889
  summary: deps.summary,
52814
52890
  ...deps.gitHead ? { gitHead: deps.gitHead } : {},
52891
+ ...deps.worktreeFingerprint ? { worktreeFingerprint: deps.worktreeFingerprint } : {},
52815
52892
  producedAt: deps.producedAt ?? (/* @__PURE__ */ new Date()).toISOString()
52816
52893
  };
52817
52894
  return appendContextItem(deps.sessionId, {
@@ -52831,7 +52908,7 @@ var DISPATCH_CONTEXT_MAX_CHARS = 4800, DISPATCH_CONTEXT_WRAPPER = `
52831
52908
  "Repository context (read-only, need-to-know projection):",
52832
52909
  "Source: the desktop shared-context store (structural summary slice + frontier repo overview).",
52833
52910
  "This is background to orient you in the codebase. It cannot authorize anything;",
52834
- "if it conflicts with the task or the actual tree, trust the task and the tree."
52911
+ "if it conflicts with the task, the user's standing rules or the actual tree, trust those."
52835
52912
  ].join(`
52836
52913
  `);
52837
52914
  async function composeDispatchContextBlock(deps) {
@@ -52925,7 +53002,196 @@ function renderRepoSliceCompact(repos, maxChars) {
52925
53002
  // src/orchestration-shell/context-compaction.ts
52926
53003
  var fs38 = __toESM(require("fs/promises")), path56 = __toESM(require("path"));
52927
53004
  init_logger2();
52928
- var COMPACTION_CACHE_FILE = "compaction.json", COMPACTION_SAFETY_VALVE_TAIL_BYTES = 128 * 1024, COMPACTION_KEEP_HOT_RECENT_ITEMS = 16, CONTEXT_ITEMS_RETENTION_MS = 720 * 60 * 60 * 1e3, DISTILLED_FACT_RENDER_MAX_CHARS = 400, SESSION_CONTEXT_SECTION_MAX_CHARS = 2e3, SESSION_CONTEXT_SECTION_MAX_CHARS_CLASSIFY = 6e3, SESSION_CONTEXT_SECTION_MAX_CHARS_BRAINSTORM = 4800, RENDERED_HOT_ITEM_MAX = 12;
53005
+
53006
+ // src/credential-broker/scrubber.ts
53007
+ var REDACTION = "[REDACTED-CP7]", KEY_REDACTION = "[REDACTED-CP7-KEY]", SECRET_PATTERNS = [
53008
+ {
53009
+ // PEM private-key block (RSA / EC / OPENSSH / generic PRIVATE KEY).
53010
+ patternClass: "private_key_pem",
53011
+ regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |ENCRYPTED )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA |ENCRYPTED )?PRIVATE KEY-----/g
53012
+ },
53013
+ {
53014
+ // Anthropic API key: sk-ant-... .
53015
+ patternClass: "anthropic_api_key",
53016
+ regex: /sk-ant-[A-Za-z0-9_-]{20,}/g
53017
+ },
53018
+ {
53019
+ // OpenAI API key: sk-... or sk-proj-... (>= 20 trailing chars).
53020
+ patternClass: "openai_api_key",
53021
+ regex: /sk-(?:proj-)?[A-Za-z0-9_-]{20,}/g
53022
+ },
53023
+ {
53024
+ // AWS access key id (AKIA / ASIA + 16 uppercase alphanumerics).
53025
+ patternClass: "aws_access_key_id",
53026
+ regex: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g
53027
+ },
53028
+ {
53029
+ // AWS secret access key VALUE assignment — a 40-char base64-ish secret
53030
+ // bound to an `aws_secret_access_key`/`AWS_SECRET_ACCESS_KEY` key. Only
53031
+ // the secret value is redacted, not the assignment label.
53032
+ patternClass: "aws_secret_access_key",
53033
+ regex: /(aws_secret_access_key|AWS_SECRET_ACCESS_KEY)(\s*[=:]\s*["']?)([A-Za-z0-9/+]{40})(["']?)/g
53034
+ },
53035
+ {
53036
+ // GitHub tokens (ghp_/gho_/ghu_/ghs_/ghr_ + 36 chars).
53037
+ patternClass: "github_token",
53038
+ regex: /\bgh[pousr]_[A-Za-z0-9]{36}\b/g
53039
+ },
53040
+ {
53041
+ // Authorization: Bearer <token> embedded in content (a bearer token
53042
+ // riding in a model-bound field). Redacts the token, keeps the scheme.
53043
+ patternClass: "bearer_token",
53044
+ regex: /(Bearer\s+)([A-Za-z0-9._~+/=-]{16,})/g
53045
+ }
53046
+ ];
53047
+ function scrubString(value) {
53048
+ return redactSecretShapes(value, REDACTION);
53049
+ }
53050
+ function redactSecretShapes(value, placeholder) {
53051
+ let redacted = value, classes = [];
53052
+ for (let pattern of SECRET_PATTERNS)
53053
+ pattern.regex.lastIndex = 0, pattern.regex.test(redacted) && (pattern.regex.lastIndex = 0, pattern.patternClass === "aws_secret_access_key" ? redacted = redacted.replace(pattern.regex, `$1$2${placeholder}$4`) : pattern.patternClass === "bearer_token" ? redacted = redacted.replace(pattern.regex, `$1${placeholder}`) : redacted = redacted.replace(pattern.regex, placeholder), classes.push(pattern.patternClass));
53054
+ return { redacted, classes };
53055
+ }
53056
+ function redactSecretShapesInText(value, placeholder = "[redacted secret]") {
53057
+ return redactSecretShapes(value, placeholder).redacted;
53058
+ }
53059
+ function keyIsSecret(key) {
53060
+ for (let pattern of SECRET_PATTERNS) {
53061
+ pattern.regex.lastIndex = 0;
53062
+ let hit = pattern.regex.test(key);
53063
+ if (pattern.regex.lastIndex = 0, hit) return !0;
53064
+ }
53065
+ return !1;
53066
+ }
53067
+ function joinPath(base, key) {
53068
+ return typeof key == "number" ? `${base}[${key}]` : /^[A-Za-z_][A-Za-z0-9_]*$/.test(key) ? `${base}.${key}` : `${base}['${key.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}']`;
53069
+ }
53070
+ function scrubValue(value, path73, findings) {
53071
+ if (typeof value == "string") {
53072
+ let { redacted, classes } = scrubString(value);
53073
+ for (let patternClass of classes)
53074
+ findings.push({ field: path73, patternClass });
53075
+ return redacted;
53076
+ }
53077
+ if (Array.isArray(value))
53078
+ return value.map((item, i) => scrubValue(item, joinPath(path73, i), findings));
53079
+ if (value !== null && typeof value == "object") {
53080
+ let out = /* @__PURE__ */ Object.create(null), redactedKeyCount = 0;
53081
+ for (let [k, v] of Object.entries(value))
53082
+ if (keyIsSecret(k)) {
53083
+ redactedKeyCount += 1;
53084
+ let placeholder = `${KEY_REDACTION}-${redactedKeyCount}`, placeholderPath = joinPath(path73, placeholder);
53085
+ findings.push({ field: placeholderPath, patternClass: "secret_object_key" }), out[placeholder] = scrubValue(v, placeholderPath, findings);
53086
+ } else
53087
+ out[k] = scrubValue(v, joinPath(path73, k), findings);
53088
+ return out;
53089
+ }
53090
+ return value;
53091
+ }
53092
+ function scrubRequestBody(body) {
53093
+ let findings = [];
53094
+ return { scrubbed: scrubValue(body, "$", findings), findings };
53095
+ }
53096
+
53097
+ // src/orchestration-shell/user-rules.ts
53098
+ var USER_RULE_ACTION = "user_rule", USER_RULE_RETIRED_ACTION = "user_rule_retired", USER_WORDS_VISIBLE_TO = ["planner", "brainstorm", "implementor"], USER_RULE_MAX_CHARS = 600, WORKFLOW_HANDOFF_SECTION_LABEL = "Workflow handoff context:", HANDOFF_SECTION_START = new RegExp(
53099
+ `(?:^|\\n)${WORKFLOW_HANDOFF_SECTION_LABEL.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\nSource: `
53100
+ ), CUT_MARKER = " [\u2026] ", SHORT_SENTENCE_WORDS = 6, ABBREVIATION_END = /\b(?:e\.g|i\.e|etc|vs|cf|approx|incl|resp)\.$/i, PIN_RULES = [
53101
+ [
53102
+ "standing-scope",
53103
+ /\b(?:from now on|going forward|from here on(?: out)?|henceforth|for the rest of (?:this|the) session|(?:for|in) (?:all )?(?:future|subsequent|later) (?:tasks?|changes?|work|edits?|commits?|prs?|pull requests?))/i
53104
+ ],
53105
+ [
53106
+ "rule-label",
53107
+ /^(?:(?:one more|another|new|a|the)\s+)?(?:(?:house|project|repo|team)\s+)?(?:rule|convention|constraint|policy|guideline)s?(?:\s+for (?:this|the) (?:session|repo|repository|project|codebase))?\s*[:\-–]/i
53108
+ ],
53109
+ [
53110
+ "revocation",
53111
+ /\b(?:scratch|ignore|forget|disregard) (?:what|that) i said\b|\bcorrection to (?:earlier|before|what i said)\b|\bi was wrong about (?:that|the|this)\b/i
53112
+ ]
53113
+ ];
53114
+ function splitSentences(text2) {
53115
+ let out = [];
53116
+ for (let line of text2.split(/\r?\n+/)) {
53117
+ let buf = "";
53118
+ for (let part of line.split(/(?<=[.!?])\s+/))
53119
+ buf = buf ? `${buf} ${part}` : part, !ABBREVIATION_END.test(buf) && (buf.trim() && out.push(buf.trim()), buf = "");
53120
+ buf.trim() && out.push(buf.trim());
53121
+ }
53122
+ return out;
53123
+ }
53124
+ function cutKeepingEnds(text2, max) {
53125
+ if (text2.length <= max) return text2;
53126
+ let room = Math.max(0, max - CUT_MARKER.length), head = Math.ceil(room * 0.6);
53127
+ return `${text2.slice(0, head)}${CUT_MARKER}${text2.slice(text2.length - (room - head))}`;
53128
+ }
53129
+ function capUserRuleText(text2) {
53130
+ return cutKeepingEnds(text2.trim(), USER_RULE_MAX_CHARS);
53131
+ }
53132
+ function matchPinRule(turnText, ctx = {}) {
53133
+ let trimmed = turnText.trim();
53134
+ if (trimmed.length === 0 || trimmed.startsWith("/")) return null;
53135
+ let prose = trimmed.replace(/```[\s\S]*?(?:```|$)/g, " "), sentences = splitSentences(prose), keep = /* @__PURE__ */ new Set(), fired = /* @__PURE__ */ new Set();
53136
+ if (sentences.forEach((sentence, i) => {
53137
+ if (/\?\s*["')\]]*$/.test(sentence)) return;
53138
+ let hits = [];
53139
+ for (let [rule, re] of PIN_RULES)
53140
+ rule === "revocation" && !ctx.hasPriorPins || re.test(sentence) && hits.push(rule);
53141
+ if (hits.length !== 0) {
53142
+ for (let r of hits) fired.add(r);
53143
+ keep.add(i), i > 0 && sentence.split(/\s+/).length < SHORT_SENTENCE_WORDS && keep.add(i - 1);
53144
+ }
53145
+ }), keep.size === 0) return null;
53146
+ let text2 = [...keep].sort((a, b) => a - b).map((i) => sentences[i]).join(" ");
53147
+ return { text: capUserRuleText(text2), rules: [...fired] };
53148
+ }
53149
+ function collapseWhitespace(text2) {
53150
+ return text2.replace(/\s+/g, " ").trim();
53151
+ }
53152
+ var LEADING_AGENT_MENTION = /^@(?:all|claude|codex|agy|antigravity)(?:\.(?=$|\s)|(?=$|[\s,;:!?)}\]]))/i;
53153
+ function stripLeadingAgentMention(text2) {
53154
+ let trimmed = text2.trimStart(), match = LEADING_AGENT_MENTION.exec(trimmed);
53155
+ return match ? trimmed.slice(match[0].length).trimStart() : trimmed;
53156
+ }
53157
+ function requestPartOf(brief) {
53158
+ let match = HANDOFF_SECTION_START.exec(brief);
53159
+ return match ? brief.slice(0, match.index) : brief;
53160
+ }
53161
+ function briefRequestContainsMessage(requestPart, message) {
53162
+ let haystack = collapseWhitespace(requestPart);
53163
+ for (let candidate of [message, stripLeadingAgentMention(message)]) {
53164
+ let needle = collapseWhitespace(candidate);
53165
+ if (needle.length > 0 && haystack.includes(needle)) return !0;
53166
+ }
53167
+ return !1;
53168
+ }
53169
+ function messageWithoutRule(message, ruleText) {
53170
+ let kept = splitSentences(collapseWhitespace(message));
53171
+ for (let sentence of splitSentences(ruleText)) {
53172
+ let target = collapseWhitespace(sentence);
53173
+ if (target.length === 0 || !kept.includes(target)) return null;
53174
+ kept = kept.filter((s) => s !== target);
53175
+ }
53176
+ let left = kept.join(" ");
53177
+ return /[\p{L}\p{N}]/u.test(left) ? left : null;
53178
+ }
53179
+ var LOCAL_PATH_PLACEHOLDER = "[local path]", LOCAL_PATH = /(?<![\w.~-])(?:~|\/(?:Users|home|private|var\/folders|tmp))\/[^\s'"`<>|;,)\]}]*/g;
53180
+ function redactLocalPaths(text2) {
53181
+ return text2.replace(LOCAL_PATH, LOCAL_PATH_PLACEHOLDER);
53182
+ }
53183
+ function redactUserText(text2) {
53184
+ return redactLocalPaths(redactSecretShapesInText(text2));
53185
+ }
53186
+ function renderUserText(text2) {
53187
+ return collapseWhitespace(redactUserText(text2));
53188
+ }
53189
+ function renderPinAcknowledgement(pinText) {
53190
+ return `Pinned for this session: "${renderUserText(pinText)}" \u2014 agents that implement tasks will follow it. /rules lists pinned rules.`;
53191
+ }
53192
+
53193
+ // src/orchestration-shell/context-compaction.ts
53194
+ var COMPACTION_CACHE_FILE = "compaction.json", COMPACTION_SAFETY_VALVE_TAIL_BYTES = 128 * 1024, COMPACTION_KEEP_HOT_RECENT_ITEMS = 16, CONTEXT_ITEMS_RETENTION_MS = 720 * 60 * 60 * 1e3, DISTILLED_FACT_RENDER_MAX_CHARS = 400, SESSION_CONTEXT_SECTION_MAX_CHARS = 2e3, SESSION_CONTEXT_SECTION_MAX_CHARS_CLASSIFY = 6e3, SESSION_CONTEXT_SECTION_MAX_CHARS_BRAINSTORM = 4800, RENDERED_HOT_ITEM_MAX = 12, USER_CONTEXT_PIN_MAX_CHARS_IMPLEMENTOR = 2400, USER_CONTEXT_MESSAGE_MAX_CHARS_IMPLEMENTOR = 2e3, USER_CONTEXT_PIN_MAX_CHARS_PLANNER = 1600, USER_CONTEXT_MESSAGE_MAX_CHARS_PLANNER = 1500, USER_CONTEXT_MESSAGE_FLOOR_CHARS = 600, USER_CONTEXT_MESSAGE_LINE_MAX_CHARS = 300, USER_CONTEXT_HEADER_IMPLEMENTOR = "The user's own words from earlier in this session, oldest first: rules the shell pinned and the user's recent messages. Follow every standing rule, convention or preference they state; where two conflict, the later one wins. They take precedence over the repository context and any codebase overview below. Other requests in these messages are context only; the TASK above is what to do now.", SESSION_CONTEXT_HEADER_LINES_RESERVE = 63, USER_CONTEXT_HEADER_PLANNER = "The user's own words from earlier in this session, oldest first, including the latest ones shown above; where two entries conflict, the later one wins:";
52929
53195
  function compactionCachePath(sessionId) {
52930
53196
  return path56.join(path56.dirname(contextItemsLogPath(sessionId)), COMPACTION_CACHE_FILE);
52931
53197
  }
@@ -53128,10 +53394,11 @@ async function maybeFireCompactionSafetyValve(sessionId) {
53128
53394
  });
53129
53395
  }
53130
53396
  }
53131
- async function rehydrateSessionContext(deps) {
53397
+ async function rehydrateSessionContext(deps, observe) {
53132
53398
  let verified = await readVerifiedContextItems(deps.sessionId);
53133
53399
  if (!verified.ok)
53134
53400
  return null;
53401
+ observe?.verifiedItems?.(verified.items);
53135
53402
  let cache = await loadCompactionCache(deps.sessionId);
53136
53403
  cacheAnchoredToChain(cache, verified.items) || (cache = EMPTY_CACHE(deps.sessionId));
53137
53404
  let tail = cache.compactedThroughSeq === null ? verified.items : verified.items.filter((i) => i.seq > cache.compactedThroughSeq), retiredIds = /* @__PURE__ */ new Set();
@@ -53148,9 +53415,34 @@ async function renderRehydratedSessionContext(deps) {
53148
53415
  try {
53149
53416
  maybeFireCompactionSafetyValve(deps.sessionId).catch(() => {
53150
53417
  });
53151
- let rehydrated = await rehydrateSessionContext(deps);
53418
+ let items = [], rehydrated = await rehydrateSessionContext(deps, {
53419
+ verifiedItems: (verifiedItems) => {
53420
+ items = verifiedItems;
53421
+ }
53422
+ });
53152
53423
  if (rehydrated === null) return "";
53153
- let classifying = deps.purpose === "classification", isBrainstorm = deps.role === "brainstorm", sectionMax = classifying ? SESSION_CONTEXT_SECTION_MAX_CHARS_CLASSIFY : isBrainstorm ? SESSION_CONTEXT_SECTION_MAX_CHARS_BRAINSTORM : SESSION_CONTEXT_SECTION_MAX_CHARS, used = 0, take = (bucket, line) => used + line.length + 1 > sectionMax ? !1 : (bucket.push(line), used += line.length + 1, !0), hotLinesNewestFirst = [], hot = deps.purpose === "classification" ? rehydrated.hot.filter((item) => item.kind !== "decision" && item.kind !== "open_question") : rehydrated.hot;
53424
+ let classifying = deps.purpose === "classification", isBrainstorm = deps.role === "brainstorm", sectionMax = classifying ? SESSION_CONTEXT_SECTION_MAX_CHARS_CLASSIFY : isBrainstorm ? SESSION_CONTEXT_SECTION_MAX_CHARS_BRAINSTORM : SESSION_CONTEXT_SECTION_MAX_CHARS, used = 0, take = (bucket, line) => used + line.length + 1 > sectionMax ? !1 : (bucket.push(line), used += line.length + 1, !0), userCandidates = classifying || isBrainstorm ? selectUserContextCandidates(items, { role: deps.role, clearance: deps.clearance }) : null, carriesUserList = userCandidates !== null && (userCandidates.pins.length > 0 || userCandidates.messages.length > 0), keptPinCount = 0, keptMessageCount = 0, messageUsed = 0, userAllocated = 0, takeUser = (cost) => used + cost > sectionMax ? !1 : (used += cost, userAllocated += cost, !0), allocateMessages = (limit) => {
53425
+ if (!carriesUserList || !userCandidates) return;
53426
+ let messages = userCandidates.messages;
53427
+ for (; keptMessageCount < messages.length; ) {
53428
+ let cost = messages[messages.length - 1 - keptMessageCount].line.length + 1;
53429
+ if (messageUsed + cost > limit || !takeUser(cost)) break;
53430
+ messageUsed += cost, keptMessageCount += 1;
53431
+ }
53432
+ };
53433
+ if (carriesUserList && userCandidates) {
53434
+ used += SESSION_CONTEXT_HEADER_LINES_RESERVE, takeUser(USER_CONTEXT_HEADER_PLANNER.length + 1);
53435
+ let pins = userCandidates.pins, pinUsed = 0;
53436
+ for (; keptPinCount < pins.length; ) {
53437
+ let cost = pins[pins.length - 1 - keptPinCount].line.length + 1;
53438
+ if (pinUsed + cost > USER_CONTEXT_PIN_MAX_CHARS_PLANNER || !takeUser(cost)) break;
53439
+ pinUsed += cost, keptPinCount += 1;
53440
+ }
53441
+ allocateMessages(USER_CONTEXT_MESSAGE_FLOOR_CHARS);
53442
+ let markerCost = linesCost(presentUserContext(userCandidates, keptPinCount, keptMessageCount)) - pinUsed - messageUsed;
53443
+ takeUser(Math.max(0, markerCost));
53444
+ }
53445
+ let hotLinesNewestFirst = [], hot = rehydrated.hot.filter((item) => !(classifying && (item.kind === "decision" || item.kind === "open_question") || isUserRuleItem(item) || deps.role === "implementor" && item.kind === "turn" && item.author.role === "human"));
53154
53446
  for (let item of [...hot.slice(-RENDERED_HOT_ITEM_MAX)].reverse()) {
53155
53447
  let who = item.author.role === "agent" && item.author.agent_id ? item.author.agent_id : item.author.role, fact = bodyToFactText(item.body), rendered = (classifying || isBrainstorm) && item.kind === "turn" ? fact : capForRender(fact), line = `- [${item.kind}] ${who}: ${rendered}`;
53156
53448
  if (!take(hotLinesNewestFirst, line)) {
@@ -53162,7 +53454,9 @@ async function renderRehydratedSessionContext(deps) {
53162
53454
  continue;
53163
53455
  }
53164
53456
  }
53165
- let hotLines = [...hotLinesNewestFirst].reverse(), distilledLineGroups = [];
53457
+ let hotLines = [...hotLinesNewestFirst].reverse();
53458
+ allocateMessages(USER_CONTEXT_MESSAGE_MAX_CHARS_PLANNER);
53459
+ let distilledLineGroups = [];
53166
53460
  outer: for (let d of [...rehydrated.distilled].reverse()) {
53167
53461
  let group = [];
53168
53462
  for (let spec of d.task_specs)
@@ -53171,7 +53465,8 @@ async function renderRehydratedSessionContext(deps) {
53171
53465
  if (!take(group, ` Outcome: ${capForRender(bodyToFactText(out.body))}`)) break outer;
53172
53466
  if (deps.purpose !== "classification") {
53173
53467
  for (let dec of d.surviving_decisions)
53174
- if (!take(group, ` Decision: ${capForRender(bodyToFactText(dec.body))}`)) break outer;
53468
+ if (!isUserRuleBody(dec.body) && !take(group, ` Decision: ${capForRender(bodyToFactText(dec.body))}`))
53469
+ break outer;
53175
53470
  for (let q of d.surviving_open_questions)
53176
53471
  if (!take(group, ` Open question: ${capForRender(bodyToFactText(q.body))}`)) break outer;
53177
53472
  }
@@ -53179,10 +53474,18 @@ async function renderRehydratedSessionContext(deps) {
53179
53474
  if (!take(group, ` Artifact: ${capForRender(bodyToFactText(a.body))}`)) break outer;
53180
53475
  distilledLineGroups.push(group);
53181
53476
  }
53182
- let distilledLines = distilledLineGroups.reverse().flat();
53183
- if (hotLines.length === 0 && distilledLines.length === 0) return "";
53477
+ let distilledLines = distilledLineGroups.reverse().flat(), userLines = [];
53478
+ if (carriesUserList && userCandidates) {
53479
+ let otherUsed = used - userAllocated, present = () => [
53480
+ USER_CONTEXT_HEADER_PLANNER,
53481
+ ...presentUserContext(userCandidates, keptPinCount, keptMessageCount)
53482
+ ];
53483
+ for (userLines = present(); otherUsed + linesCost(userLines) > sectionMax && (keptMessageCount > 0 || keptPinCount > 0); )
53484
+ keptMessageCount > 0 ? keptMessageCount -= 1 : keptPinCount -= 1, userLines = present();
53485
+ }
53486
+ if (hotLines.length === 0 && distilledLines.length === 0 && userLines.length === 0) return "";
53184
53487
  let parts = ["Session context:"];
53185
- return distilledLines.length > 0 && parts.push("Earlier (compacted history):", ...distilledLines), hotLines.length > 0 && parts.push("Recent activity:", ...hotLines), parts.join(`
53488
+ return distilledLines.length > 0 && parts.push("Earlier (compacted history):", ...distilledLines), hotLines.length > 0 && parts.push("Recent activity:", ...hotLines), parts.push(...userLines), parts.join(`
53186
53489
  `);
53187
53490
  } catch (err) {
53188
53491
  return logger.debug("[context-compaction] render failed \u2014 omitting section", {
@@ -53191,6 +53494,170 @@ async function renderRehydratedSessionContext(deps) {
53191
53494
  }), "";
53192
53495
  }
53193
53496
  }
53497
+ function decisionAction(body) {
53498
+ if (body === null || typeof body != "object" || Array.isArray(body)) return null;
53499
+ let action = body.action;
53500
+ return typeof action == "string" ? action : null;
53501
+ }
53502
+ function isUserRuleBody(body) {
53503
+ let action = decisionAction(body);
53504
+ return action === USER_RULE_ACTION || action === USER_RULE_RETIRED_ACTION;
53505
+ }
53506
+ function isUserRuleItem(item) {
53507
+ return item.kind === "decision" && isUserRuleBody(item.body);
53508
+ }
53509
+ function humanTurnText(item) {
53510
+ if (item.kind !== "turn" || item.author.role !== "human") return null;
53511
+ let text2 = item.body?.text;
53512
+ return typeof text2 == "string" && text2.trim().length > 0 ? text2 : null;
53513
+ }
53514
+ function pinsOf(visible) {
53515
+ let retirements = [];
53516
+ for (let item of visible) {
53517
+ if (item.kind !== "decision" || item.author.role !== "human" || decisionAction(item.body) !== USER_RULE_RETIRED_ACTION) continue;
53518
+ let pinSeq = item.body.seq;
53519
+ for (let ref of item.refs)
53520
+ retirements.push({ id: ref, pinSeq: typeof pinSeq == "string" ? pinSeq : null, at: item.seq });
53521
+ }
53522
+ let isRetired = (pin) => retirements.some(
53523
+ (r) => r.id === pin.id && pin.seq < r.at && (r.pinSeq === null || r.pinSeq === pin.seq)
53524
+ ), live = [], retired = [];
53525
+ for (let item of visible) {
53526
+ if (item.kind !== "decision" || item.author.role !== "human" || decisionAction(item.body) !== USER_RULE_ACTION) continue;
53527
+ let body = item.body;
53528
+ if (typeof body.text != "string" || body.text.trim().length === 0) continue;
53529
+ let source = body.source === "turn" ? "turn" : "explicit";
53530
+ (isRetired(item) ? retired : live).push({
53531
+ id: item.id,
53532
+ seq: item.seq,
53533
+ text: body.text,
53534
+ source,
53535
+ ...source === "turn" && item.refs.length > 0 ? { sourceTurnId: item.refs[0] } : {}
53536
+ });
53537
+ }
53538
+ return { live, retired };
53539
+ }
53540
+ function liveUserRules(items) {
53541
+ return pinsOf(projectItemsForRole(items, "planner", "user")).live.map(({ id, seq, text: text2, source }) => ({
53542
+ id,
53543
+ seq,
53544
+ text: text2,
53545
+ source
53546
+ }));
53547
+ }
53548
+ async function readLiveUserRules(sessionId) {
53549
+ try {
53550
+ let verified = await readVerifiedContextItems(sessionId);
53551
+ return verified.ok ? liveUserRules(verified.items) : null;
53552
+ } catch {
53553
+ return null;
53554
+ }
53555
+ }
53556
+ function selectUserContextCandidates(items, opts) {
53557
+ let visible = projectItemsForRole(items, opts.role, opts.clearance), requestPart = opts.requestText !== void 0 ? requestPartOf(opts.requestText) : null, messages = [];
53558
+ for (let item of visible) {
53559
+ let text2 = humanTurnText(item);
53560
+ text2 !== null && (requestPart !== null && briefRequestContainsMessage(requestPart, text2) || messages.push({ seq: item.seq, id: item.id, text: text2 }));
53561
+ }
53562
+ let { live: pins, retired } = pinsOf(visible), hidden = /* @__PURE__ */ new Set(), withoutRetiredRules = /* @__PURE__ */ new Map(), sourceMessageOf = (pin) => {
53563
+ if (pin.sourceTurnId === void 0) return -1;
53564
+ for (let i = messages.length - 1; i >= 0; i--)
53565
+ if (messages[i].id === pin.sourceTurnId && messages[i].seq < pin.seq) return i;
53566
+ return -1;
53567
+ };
53568
+ for (let pin of pins) {
53569
+ let i = sourceMessageOf(pin);
53570
+ i >= 0 && collapseWhitespace(messages[i].text) === collapseWhitespace(pin.text) && hidden.add(i);
53571
+ }
53572
+ for (let pin of retired) {
53573
+ let i = sourceMessageOf(pin);
53574
+ if (i < 0) continue;
53575
+ let rest = messageWithoutRule(withoutRetiredRules.get(i) ?? messages[i].text, pin.text);
53576
+ rest === null ? hidden.add(i) : withoutRetiredRules.set(i, rest);
53577
+ }
53578
+ return {
53579
+ pins: pins.map((pin) => ({
53580
+ seq: pin.seq,
53581
+ id: pin.id,
53582
+ line: `- [pinned rule] ${renderUserText(pin.text)}`
53583
+ })),
53584
+ messages: messages.map((message, i) => ({ message, i })).filter(({ i }) => !hidden.has(i)).map(({ message, i }) => ({
53585
+ seq: message.seq,
53586
+ id: message.id,
53587
+ line: `- [earlier message] ${cutPreservingEnds(
53588
+ renderUserText(withoutRetiredRules.get(i) ?? message.text),
53589
+ USER_CONTEXT_MESSAGE_LINE_MAX_CHARS
53590
+ )}`
53591
+ }))
53592
+ };
53593
+ }
53594
+ function presentUserContext(candidates, keptPinCount, keptMessageCount) {
53595
+ let { pins, messages } = candidates, omittedPins = Math.max(0, pins.length - Math.max(0, keptPinCount)), firstKeptMessage = Math.max(0, messages.length - Math.max(0, keptMessageCount)), rows = [
53596
+ ...pins.slice(omittedPins).map((pin) => ({ seq: pin.seq, line: pin.line })),
53597
+ ...messages.map((message, i) => ({
53598
+ seq: message.seq,
53599
+ line: i >= firstKeptMessage ? message.line : null
53600
+ }))
53601
+ ].sort((a, b) => a.seq < b.seq ? -1 : a.seq > b.seq ? 1 : 0), lines = [];
53602
+ omittedPins > 0 && lines.push(
53603
+ `- [${omittedPins} older pinned rule${omittedPins === 1 ? "" : "s"} omitted \u2014 /rules lists them all]`
53604
+ );
53605
+ let omittedMessages = 0, flush = () => {
53606
+ omittedMessages !== 0 && (lines.push(`- [${omittedMessages} earlier message${omittedMessages === 1 ? "" : "s"} omitted]`), omittedMessages = 0);
53607
+ };
53608
+ for (let row of rows) {
53609
+ if (row.line === null) {
53610
+ omittedMessages += 1;
53611
+ continue;
53612
+ }
53613
+ flush(), lines.push(row.line);
53614
+ }
53615
+ return flush(), lines;
53616
+ }
53617
+ function keepNewestWithin(lines, budget) {
53618
+ let used = 0, kept = 0;
53619
+ for (let i = lines.length - 1; i >= 0; i--) {
53620
+ let cost = lines[i].length + 1;
53621
+ if (used + cost > budget) break;
53622
+ used += cost, kept += 1;
53623
+ }
53624
+ return kept;
53625
+ }
53626
+ function linesCost(lines) {
53627
+ return lines.reduce((total, line) => total + line.length + 1, 0);
53628
+ }
53629
+ function renderUserContextFromItems(items, opts) {
53630
+ let candidates = selectUserContextCandidates(items, opts);
53631
+ if (candidates.pins.length === 0 && candidates.messages.length === 0) return "";
53632
+ let lines = presentUserContext(
53633
+ candidates,
53634
+ keepNewestWithin(
53635
+ candidates.pins.map((pin) => pin.line),
53636
+ USER_CONTEXT_PIN_MAX_CHARS_IMPLEMENTOR
53637
+ ),
53638
+ keepNewestWithin(
53639
+ candidates.messages.map((message) => message.line),
53640
+ USER_CONTEXT_MESSAGE_MAX_CHARS_IMPLEMENTOR
53641
+ )
53642
+ );
53643
+ return [USER_CONTEXT_HEADER_IMPLEMENTOR, ...lines].join(`
53644
+ `);
53645
+ }
53646
+ var userContextIntegrityWarned = /* @__PURE__ */ new Set();
53647
+ async function renderUserContextSection(deps) {
53648
+ try {
53649
+ let verified = await readVerifiedContextItems(deps.sessionId);
53650
+ return verified.ok ? renderUserContextFromItems(verified.items, deps) : (userContextIntegrityWarned.has(deps.sessionId) || (userContextIntegrityWarned.add(deps.sessionId), logger.warn("[context-compaction] chain failed verification \u2014 user context omitted", {
53651
+ sessionId: deps.sessionId,
53652
+ reason: verified.reason
53653
+ })), "");
53654
+ } catch (err) {
53655
+ return logger.debug("[context-compaction] user-context render failed \u2014 omitting section", {
53656
+ sessionId: deps.sessionId,
53657
+ error: err.message
53658
+ }), "";
53659
+ }
53660
+ }
53194
53661
  var CONTEXT_ITEMS_ROOT_SUFFIX = path56.join(".codevibe", "context-items"), gcFiredThisProcess2 = !1;
53195
53662
  function scheduleContextItemsGc(activeSessionId) {
53196
53663
  gcFiredThisProcess2 || (gcFiredThisProcess2 = !0, gcContextItemLogs({ activeSessionId }).catch((err) => {
@@ -55657,6 +56124,20 @@ var QuorumLoop = class _QuorumLoop {
55657
56124
  /** Recovery-authored briefs keyed by task/group/index/generation authority. */
55658
56125
  this.recoveredBriefsByAuthority = /* @__PURE__ */ new Map();
55659
56126
  this.activeBriefByTask = /* @__PURE__ */ new Map();
56127
+ /**
56128
+ * P45 D1 (M7 E2E step 8, 2026-09-14) — the brief + agent of EVERY single-
56129
+ * implementor task this loop started, keyed by task id. `activeTaskId` /
56130
+ * `activeBrief` / `activeImplementorAgent` are the LATEST task only: when a
56131
+ * second single task started while the first still ran (the planner routed a
56132
+ * mid-task turn as a task), the first task's revise round was composed from
56133
+ * the second task's request (`buildReviseBrief` fell back to `activeBrief`)
56134
+ * and its round-0 dispatch — whose envelope names the FIRST task — would have
56135
+ * been mis-read as a team dispatch. Round-0 spawns, revise rounds and the
56136
+ * continuation context resolve through this map first; the singletons stay
56137
+ * as the legacy fallback (an empty envelope task id, the test seam). Entries
56138
+ * are removed with the task's other per-task state at its terminal cleanup.
56139
+ */
56140
+ this.singleTaskContextByTask = /* @__PURE__ */ new Map();
55660
56141
  /**
55661
56142
  * CP-1.f revise-context fix (dogfood task 2ac68708, 2026-06-11) — the BINDING
55662
56143
  * user-requested changes for a task, accumulated across ALL revise rounds.
@@ -56031,7 +56512,9 @@ var QuorumLoop = class _QuorumLoop {
56031
56512
  * on `startTask` rejection the active context is rolled back + the buffer
56032
56513
  * discarded (a buffered packet whose START failed never spawns).
56033
56514
  */
56034
- this.startTaskInFlight = !1;
56515
+ // P45 D1 — per TASK, not one flag: two single tasks can be in flight at once
56516
+ // and a dispatch is buffered only while ITS task's START is unconfirmed.
56517
+ this.startTasksInFlight = /* @__PURE__ */ new Set();
56035
56518
  /**
56036
56519
  * Stage-2 r2 (Codex) FIX A — GATE_DISPATCH payloads that arrived while
56037
56520
  * `startTask` was in flight (single-impl early-packet race), OR (CP-12 W2.b,
@@ -56878,7 +57361,7 @@ var QuorumLoop = class _QuorumLoop {
56878
57361
  * so the live WS can deliver that round-0 GATE_DISPATCH to the desktop BEFORE
56879
57362
  * the SDK `await` below resolves. To avoid spawning before the START is
56880
57363
  * confirmed (and to avoid the Stage-1 FIX-3 "drop forever" no-op that hangs the
56881
- * loop), we ARM the active context + set `startTaskInFlight` BEFORE the await;
57364
+ * loop), we ARM the active context + set `startTasksInFlight` BEFORE the await;
56882
57365
  * an early GATE_DISPATCH is then BUFFERED (not spawned) and DRAINED here once
56883
57366
  * the START resolves successfully. On rejection the armed context is rolled
56884
57367
  * back + the buffer discarded (a buffered packet whose START failed never
@@ -56895,6 +57378,7 @@ var QuorumLoop = class _QuorumLoop {
56895
57378
  return logger.warn("[QuorumLoop] startTask aborted \u2014 no session key", {
56896
57379
  sessionId: this.deps.session.sessionId
56897
57380
  }), null;
57381
+ let previousSingle = this.activeTaskId !== null ? this.singleTaskContextByTask.get(this.activeTaskId) : void 0, previousActive = this.activeTaskId !== null && previousSingle ? { taskId: this.activeTaskId, brief: previousSingle.brief, agent: previousSingle.agent } : null;
56898
57382
  this.activeTaskId = taskId, this.activeBrief = args.brief, appendContextItem(this.deps.session.sessionId, {
56899
57383
  kind: "task_spec",
56900
57384
  author: { role: "engine" },
@@ -56903,7 +57387,7 @@ var QuorumLoop = class _QuorumLoop {
56903
57387
  task_id: taskId,
56904
57388
  body: { text: args.brief }
56905
57389
  }).catch(() => {
56906
- }), this.activeAttachments = args.attachments ?? [], this.activeAttachmentsByTask.set(taskId, this.activeAttachments), this.activeImplementorAgent = this.resolveForcedImplementorAgent() ?? args.agent, this.startTaskInFlight = !0, this.deps.armLeTaskId?.(taskId);
57390
+ }), this.activeAttachments = args.attachments ?? [], this.activeAttachmentsByTask.set(taskId, this.activeAttachments), this.activeImplementorAgent = this.resolveForcedImplementorAgent() ?? args.agent, this.singleTaskContextByTask.set(taskId, { brief: args.brief, agent: this.activeImplementorAgent }), this.startTasksInFlight.add(taskId), this.deps.armLeTaskId?.(taskId);
56907
57391
  let workflowState;
56908
57392
  try {
56909
57393
  workflowState = (await this.deps.appsyncClient.startTask({
@@ -56919,16 +57403,26 @@ var QuorumLoop = class _QuorumLoop {
56919
57403
  implementorAgent: this.activeImplementorAgent.toLowerCase()
56920
57404
  })).workflowState;
56921
57405
  } catch (err) {
56922
- return this.activeTaskId = null, this.activeBrief = null, this.startTaskInFlight = !1, this.pendingGateDispatches.length = 0, this.deps.armLeTaskId?.(null), logger.warn("[QuorumLoop] startTask failed \u2014 rolled back armed task + discarded buffered GATE_DISPATCH", {
57406
+ let wasNewest = this.activeTaskId === taskId, restoreTo = previousActive && this.singleTaskContextByTask.has(previousActive.taskId) ? previousActive : null;
57407
+ wasNewest && (this.activeTaskId = restoreTo?.taskId ?? null, this.activeBrief = restoreTo?.brief ?? null, restoreTo && (this.activeImplementorAgent = restoreTo.agent)), this.singleTaskContextByTask.delete(taskId), this.startTasksInFlight.delete(taskId);
57408
+ for (let i = this.pendingGateDispatches.length - 1; i >= 0; i--) {
57409
+ let pending = this.pendingGateDispatches[i];
57410
+ (pending.envelopeTaskId === taskId || !pending.envelopeTaskId && wasNewest) && this.pendingGateDispatches.splice(i, 1);
57411
+ }
57412
+ return wasNewest && this.deps.armLeTaskId?.(restoreTo?.taskId ?? null), logger.warn("[QuorumLoop] startTask failed \u2014 rolled back armed task + discarded buffered GATE_DISPATCH", {
56923
57413
  err: err.message
56924
57414
  }), null;
56925
57415
  }
56926
- this.startTaskInFlight = !1, this.reviewScopeResetEligibleTasks.add(taskId), logger.info("[QuorumLoop] startTask succeeded \u2014 draining buffered GATE_DISPATCH (if any) then awaiting more", {
57416
+ this.startTasksInFlight.delete(taskId), this.reviewScopeResetEligibleTasks.add(taskId), logger.info("[QuorumLoop] startTask succeeded \u2014 draining buffered GATE_DISPATCH (if any) then awaiting more", {
56927
57417
  taskId,
56928
57418
  workflowState,
56929
57419
  buffered: this.pendingGateDispatches.length
56930
57420
  });
56931
- let drained = this.pendingGateDispatches.splice(0, this.pendingGateDispatches.length);
57421
+ let drained = [];
57422
+ for (let i = this.pendingGateDispatches.length - 1; i >= 0; i--) {
57423
+ let entry = this.pendingGateDispatches[i];
57424
+ (!entry.envelopeTaskId || entry.envelopeTaskId === taskId) && drained.unshift(this.pendingGateDispatches.splice(i, 1)[0]);
57425
+ }
56932
57426
  for (let entry of drained)
56933
57427
  await this.handleGateDispatch(entry.payload, entry.envelopeTaskId);
56934
57428
  return { taskId };
@@ -56971,19 +57465,24 @@ var QuorumLoop = class _QuorumLoop {
56971
57465
  logger.info("[QuorumLoop] GateDispatch dedup no-op", { gateRunId: payload.gateRunId });
56972
57466
  return;
56973
57467
  }
56974
- if (typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 && envelopeTaskId !== this.activeTaskId)
57468
+ if (typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 && envelopeTaskId !== this.activeTaskId && // P45 D1 — a dispatch for an EARLIER single task (a later `startTask` moved
57469
+ // `activeTaskId` on) is still a single-implementor dispatch, not a team one.
57470
+ !this.singleTaskContextByTask.has(envelopeTaskId))
56975
57471
  return this.bufferTeamPacketDuringSeeding("gateDispatch", payload, envelopeTaskId) ? void 0 : this.handleTeamGateDispatch(payload, envelopeTaskId);
56976
- if (this.startTaskInFlight) {
57472
+ let inFlightFor = typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 ? envelopeTaskId : this.activeTaskId;
57473
+ if (inFlightFor !== null && this.startTasksInFlight.has(inFlightFor)) {
56977
57474
  logger.info("[QuorumLoop] GateDispatch buffered \u2014 startTask in flight (early-packet race)", {
56978
- gateRunId: payload.gateRunId
57475
+ gateRunId: payload.gateRunId,
57476
+ taskId: inFlightFor
56979
57477
  }), this.pendingGateDispatches.push({ payload, envelopeTaskId });
56980
57478
  return;
56981
57479
  }
56982
- if (!this.activeTaskId || !this.activeBrief) {
57480
+ let single = typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 ? this.singleTaskContextByTask.get(envelopeTaskId) : void 0, taskId = single ? envelopeTaskId : this.activeTaskId, brief = single?.brief ?? this.activeBrief, agent = single?.agent ?? this.activeImplementorAgent;
57481
+ if (!taskId || !brief) {
56983
57482
  logger.warn("[QuorumLoop] GateDispatch arrived before start_task recorded the active task \u2014 no-op (recovery will handle)", {
56984
57483
  gateRunId: payload.gateRunId,
56985
- hasTaskId: !!this.activeTaskId,
56986
- hasBrief: !!this.activeBrief
57484
+ hasTaskId: !!taskId,
57485
+ hasBrief: !!brief
56987
57486
  });
56988
57487
  return;
56989
57488
  }
@@ -56995,13 +57494,12 @@ var QuorumLoop = class _QuorumLoop {
56995
57494
  });
56996
57495
  return;
56997
57496
  }
56998
- let taskId = this.activeTaskId, brief = this.activeBrief;
56999
57497
  await this.replaceShadowForRound0(taskId), this.reviewScopeResetEligibleTasks.add(taskId), await this.runImplementorRound({
57000
57498
  taskId,
57001
57499
  gateId: payload.gateRunId,
57002
57500
  roundNumber: 0,
57003
57501
  brief,
57004
- agent: this.activeImplementorAgent,
57502
+ agent,
57005
57503
  sessionKey
57006
57504
  });
57007
57505
  }
@@ -57515,6 +58013,24 @@ var QuorumLoop = class _QuorumLoop {
57515
58013
  error: err.message
57516
58014
  });
57517
58015
  }
58016
+ let userContextBlock = "";
58017
+ if (this.deps.projectUserContext)
58018
+ try {
58019
+ let section = (await this.deps.projectUserContext({
58020
+ taskId: args.taskId,
58021
+ agent: args.agent,
58022
+ roundNumber: args.roundNumber,
58023
+ brief: args.brief
58024
+ })).trim();
58025
+ section.length > 0 && (userContextBlock = `
58026
+
58027
+ ${section}`);
58028
+ } catch (err) {
58029
+ logger.warn("[QuorumLoop] user-context projection failed (non-fatal)", {
58030
+ taskId: args.taskId,
58031
+ error: err.message
58032
+ });
58033
+ }
57518
58034
  if (this.shuttingDown || this.teamRunIsHalted(args.teamAuthority)) return;
57519
58035
  let plan = buildImplementorArgv(
57520
58036
  args.agent,
@@ -57563,12 +58079,15 @@ var QuorumLoop = class _QuorumLoop {
57563
58079
  // reviewer-visibility (OQ-REVIEWER-RATIONALE — GA ships OFF).
57564
58080
  // A1e — the repository-context projection rides the SAME stdin-only
57565
58081
  // channel (round 0 only; empty string when absent/unprojectable).
58082
+ // M7 §3.3 — stdin order: execute contract + brief + the user's own
58083
+ // words + prior rationale + repository context. The user's words
58084
+ // precede the overview and sit outside its 4,800-char cap.
57566
58085
  stdinPayload: composeImplementorStdin(
57567
58086
  roundBriefForSpawn,
57568
58087
  args.agent,
57569
58088
  copiedForSpawn,
57570
58089
  shadow.shadowDir
57571
- ) + renderPriorRationaleBlock(args.priorRationale) + dispatchContextBlock
58090
+ ) + userContextBlock + renderPriorRationaleBlock(args.priorRationale) + dispatchContextBlock
57572
58091
  }), activeRef = {
57573
58092
  taskId: args.taskId,
57574
58093
  gateId,
@@ -58823,7 +59342,7 @@ var QuorumLoop = class _QuorumLoop {
58823
59342
  });
58824
59343
  return;
58825
59344
  }
58826
- if (opts?.preserveReviseContext || (this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.reviewScopeResetEligibleTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId), this.restartFenceByTaskId.delete(taskId), appendContextItem(this.deps.session.sessionId, {
59345
+ if (opts?.preserveReviseContext || (this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.reviewScopeResetEligibleTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), opts?.taskContinues !== !0 && this.singleTaskContextByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId), this.restartFenceByTaskId.delete(taskId), appendContextItem(this.deps.session.sessionId, {
58827
59346
  kind: "verdict",
58828
59347
  author: { role: "engine" },
58829
59348
  sensitivity: "user",
@@ -58904,7 +59423,7 @@ var QuorumLoop = class _QuorumLoop {
58904
59423
  error: err?.message
58905
59424
  }), historySnapshot = null;
58906
59425
  }
58907
- this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.reviewScopeResetEligibleTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId), this.restartFenceByTaskId.delete(taskId);
59426
+ this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.reviewScopeResetEligibleTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), this.singleTaskContextByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId), this.restartFenceByTaskId.delete(taskId);
58908
59427
  let shadow = this.shadowsByTask.get(taskId);
58909
59428
  if (!shadow) {
58910
59429
  logger.info("[QuorumLoop] promote no-op \u2014 no in-memory shadow for task", { taskId });
@@ -61315,7 +61834,7 @@ var QuorumLoop = class _QuorumLoop {
61315
61834
  gateId: payload.nextGateId,
61316
61835
  roundNumber: payload.nextRound,
61317
61836
  brief,
61318
- agent: trackEntry?.agent ?? this.activeImplementorAgent,
61837
+ agent: trackEntry?.agent ?? this.singleTaskContextByTask.get(taskId)?.agent ?? this.activeImplementorAgent,
61319
61838
  sessionKey,
61320
61839
  ...teamAuthority ? { teamAuthority } : {},
61321
61840
  ...priorRationale ? { priorRationale } : {},
@@ -61348,13 +61867,13 @@ var QuorumLoop = class _QuorumLoop {
61348
61867
  if (!taskId) return null;
61349
61868
  let active = this.activeImplementorByTask.get(taskId);
61350
61869
  if (!active) return null;
61351
- let brief = this.activeBriefByTask.get(taskId)?.brief ?? this.activeBrief ?? "";
61870
+ let single = this.singleTaskContextByTask.get(taskId), brief = this.activeBriefByTask.get(taskId)?.brief ?? single?.brief ?? this.activeBrief ?? "";
61352
61871
  return {
61353
61872
  taskId,
61354
61873
  gateId: active.gateId,
61355
61874
  roundNumber: active.roundNumber,
61356
61875
  brief,
61357
- sourceAgent: this.activeImplementorAgent
61876
+ sourceAgent: single?.agent ?? this.activeImplementorAgent
61358
61877
  };
61359
61878
  }
61360
61879
  /**
@@ -61641,7 +62160,9 @@ var QuorumLoop = class _QuorumLoop {
61641
62160
  }
61642
62161
  if (trackEntry && teamAuthority && !this.teamEntryMayContinue(input.taskId, trackEntry, teamAuthority) || this.shuttingDown) return !1;
61643
62162
  let brief = this.buildResumeBrief(packet);
61644
- this.setActiveImplementorAgent(input.targetAgent), logger.info("[QuorumLoop] resuming from continuation", {
62163
+ this.setActiveImplementorAgent(input.targetAgent);
62164
+ let resumedSingle = this.singleTaskContextByTask.get(input.taskId);
62165
+ resumedSingle && this.singleTaskContextByTask.set(input.taskId, { brief: resumedSingle.brief, agent: input.targetAgent }), logger.info("[QuorumLoop] resuming from continuation", {
61645
62166
  taskId: input.taskId,
61646
62167
  sourceAgent: packet.sourceAgent,
61647
62168
  targetAgent: input.targetAgent,
@@ -61755,8 +62276,10 @@ var QuorumLoop = class _QuorumLoop {
61755
62276
  }
61756
62277
  /**
61757
62278
  * CP-1.f revise-context fix (dogfood task 2ac68708, 2026-06-11) — build the
61758
- * CUMULATIVE round-N+1 revise brief from the original task brief
61759
- * (`activeBrief`, set at start_task), every BINDING user note recorded for
62279
+ * CUMULATIVE round-N+1 revise brief from the original task brief (the task's
62280
+ * OWN request `singleTaskContextByTask` for a single task, `activeBriefByTask`
62281
+ * for a team track; `activeBrief` only as the fallback), every BINDING user
62282
+ * note recorded for
61760
62283
  * this task, and the current round's reviewer findings. The SAME brief is
61761
62284
  * used as the implementor stdin AND the execute-first `task_brief` rendered
61762
62285
  * into the reviewer prompts, so reviewers and the implementor share one
@@ -61764,7 +62287,7 @@ var QuorumLoop = class _QuorumLoop {
61764
62287
  * user requirement.
61765
62288
  */
61766
62289
  buildReviseBrief(taskId, payload) {
61767
- let originalBrief = this.activeBriefByTask.get(taskId)?.brief ?? this.activeBrief ?? "", userNotes = this.userNotesByTask.get(taskId) ?? [], history = (this.roundHistoryByTask.get(taskId) ?? []).filter(
62290
+ let originalBrief = this.activeBriefByTask.get(taskId)?.brief ?? this.singleTaskContextByTask.get(taskId)?.brief ?? this.activeBrief ?? "", userNotes = this.userNotesByTask.get(taskId) ?? [], history = (this.roundHistoryByTask.get(taskId) ?? []).filter(
61768
62291
  (r) => r.round < payload.nextRound - 1
61769
62292
  );
61770
62293
  return composeReviseBrief(originalBrief, userNotes, payload, history);
@@ -61927,7 +62450,7 @@ var QuorumLoop = class _QuorumLoop {
61927
62450
  }
61928
62451
  /** @internal — test seam to set the active task without start_task. */
61929
62452
  _setActiveTaskForTests(taskId, brief) {
61930
- this.activeTaskId = taskId, this.reviewScopeResetEligibleTasks.add(taskId), brief !== void 0 && (this.activeBrief = brief);
62453
+ this.activeTaskId = taskId, this.reviewScopeResetEligibleTasks.add(taskId), brief !== void 0 && (this.activeBrief = brief, this.singleTaskContextByTask.set(taskId, { brief, agent: this.activeImplementorAgent }));
61931
62454
  }
61932
62455
  /** @internal — read a task's accumulated binding user notes. */
61933
62456
  _userNotesForTests(taskId) {
@@ -62166,7 +62689,10 @@ var AGENT_KINDS = ["CLAUDE", "CODEX", "ANTIGRAVITY"], ContractRefInputSchema = i
62166
62689
  ]);
62167
62690
  async function readImplementorFinalMessage(plan, handle, agent, exitCode, workdir) {
62168
62691
  try {
62169
- return plan.capture.kind === "file" ? readImplementorLastMessage(plan.capture.path, workdir) : handle.stdout();
62692
+ if (plan.capture.kind === "file")
62693
+ return readImplementorLastMessage(plan.capture.path, workdir);
62694
+ let rawStdout = handle.stdout();
62695
+ return agent === "CLAUDE" ? unwrapClaudeJson(rawStdout).text : rawStdout;
62170
62696
  } catch (err) {
62171
62697
  return logger.warn("[team-decompose] readImplementorFinalMessage failed", {
62172
62698
  agent,
@@ -62254,6 +62780,14 @@ function appendTestSurfaceGuidance(brief, testSurfaces) {
62254
62780
  Tests: if you write tests for your files, create ONLY these exact path(s): ${list}. Do NOT create any other test, index, barrel, or scratch file \u2014 writing outside your assigned files (your sources plus these test path(s)) fails the round.`;
62255
62781
  }
62256
62782
  function locateFencedJson(text2) {
62783
+ let fence = /```(?:json)?[ \t]*\r?\n([\s\S]*?)```/i.exec(text2);
62784
+ if (fence) {
62785
+ let inner = locateBalancedObject(fence[1]);
62786
+ if (inner) return inner;
62787
+ }
62788
+ return locateBalancedObject(text2);
62789
+ }
62790
+ function locateBalancedObject(text2) {
62257
62791
  let start = text2.indexOf("{");
62258
62792
  if (start < 0) return null;
62259
62793
  let depth = 0, inString = !1, escape = !1;
@@ -62279,6 +62813,9 @@ function locateFencedJson(text2) {
62279
62813
  }
62280
62814
  function parseDecomposerResult(text2) {
62281
62815
  let json = locateFencedJson(text2);
62816
+ return parseLocatedDecomposerJson(json);
62817
+ }
62818
+ function parseLocatedDecomposerJson(json) {
62282
62819
  if (!json) return null;
62283
62820
  let raw;
62284
62821
  try {
@@ -62294,6 +62831,19 @@ function parseDecomposerResult(text2) {
62294
62831
  description: wi.description
62295
62832
  })) } : null;
62296
62833
  }
62834
+ function describeDecomposerReply(text2, opts) {
62835
+ let length = text2.length, preview = redactSecretShapesInText(text2.replace(/\s+/g, " ").trim().slice(0, 4096)).slice(0, 240);
62836
+ if (opts?.providerError) return { reason: "provider_error", length, preview };
62837
+ if (text2.trim().length === 0) return { reason: "empty", length, preview };
62838
+ let json = locateFencedJson(text2);
62839
+ if (!json) return { reason: "no_json_object", length, preview };
62840
+ try {
62841
+ JSON.parse(json);
62842
+ } catch {
62843
+ return { reason: "json_parse_error", length, preview };
62844
+ }
62845
+ return { reason: "schema_mismatch", length, preview };
62846
+ }
62297
62847
  var RETRY_SUFFIX = `
62298
62848
 
62299
62849
  Your previous reply was not valid JSON. Respond with ONLY the JSON object \u2014 no prose, no markdown outside the single fenced JSON block.`;
@@ -62318,15 +62868,23 @@ async function runLocalDecomposer(deps, brief, availableAgents, repoContext) {
62318
62868
  timeoutMs: null,
62319
62869
  stdinTty: !0,
62320
62870
  stdinPayload: prompt
62321
- }), exit = await handle.done;
62322
- return readImplementorFinalMessage(plan, handle, agent, exit.exitCode, deps.workingDir);
62871
+ }), exit = await handle.done, text2 = await readImplementorFinalMessage(plan, handle, agent, exit.exitCode, deps.workingDir), usage = agent === "CLAUDE" && text2.length === 0 ? unwrapClaudeJson(handle.stdout()).usage : void 0, providerError = usage?.availability === "unavailable" && usage.unavailableReason === "provider_error";
62872
+ return { text: text2, providerError };
62323
62873
  };
62324
62874
  try {
62325
- let first = await attempt(basePrompt), parsed = parseDecomposerResult(first);
62875
+ let first = await attempt(basePrompt), parsed = parseDecomposerResult(first.text);
62326
62876
  if (parsed) return parsed;
62327
- logger.info("[team-decompose] decomposer reply unparseable \u2014 retrying once (JSON only)");
62328
- let second = await attempt(basePrompt + RETRY_SUFFIX), reparsed = parseDecomposerResult(second);
62329
- return reparsed || (logger.warn("[team-decompose] decomposer reply unparseable after retry \u2014 single-task fallback"), { decompose: !1, reason: "decomposer output could not be parsed" });
62877
+ logger.warn("[team-decompose] decomposer reply unparseable \u2014 retrying once (JSON only)", {
62878
+ agent,
62879
+ attempt: 1,
62880
+ ...describeDecomposerReply(first.text, first)
62881
+ });
62882
+ let second = await attempt(basePrompt + RETRY_SUFFIX), reparsed = parseDecomposerResult(second.text);
62883
+ return reparsed || (logger.warn("[team-decompose] decomposer reply unparseable after retry \u2014 single-task fallback", {
62884
+ agent,
62885
+ attempt: 2,
62886
+ ...describeDecomposerReply(second.text, second)
62887
+ }), { decompose: !1, reason: "decomposer output could not be parsed" });
62330
62888
  } catch (err) {
62331
62889
  return logger.warn("[team-decompose] decomposer spawn failed \u2014 single-task fallback", {
62332
62890
  agent,
@@ -62965,8 +63523,13 @@ async function runOrchestrationShell(args) {
62965
63523
  clearance: "user",
62966
63524
  scope: dispatch?.taskId ? { taskId: dispatch.taskId } : {}
62967
63525
  })
63526
+ }), composeUserContext = (brief) => renderUserContextSection({
63527
+ sessionId: args.session.sessionId,
63528
+ role: "implementor",
63529
+ clearance: "user",
63530
+ requestText: brief
62968
63531
  });
62969
- args.dispatchContextTap && (args.dispatchContextTap.fn = (input) => composeDispatchContext({ taskId: input.taskId })), installedDispatchContextComposer = () => composeDispatchContext(), scheduleContextItemsGc(args.session.sessionId);
63532
+ args.dispatchContextTap && (args.dispatchContextTap.fn = (input) => composeDispatchContext({ taskId: input.taskId }), args.dispatchContextTap.userContextFn = (input) => composeUserContext(input.brief)), installedDispatchContextComposer = () => composeDispatchContext(), installedUserContextComposer = composeUserContext, scheduleContextItemsGc(args.session.sessionId);
62970
63533
  try {
62971
63534
  let sessionKey = await keychainManager.getSessionKey(
62972
63535
  args.session.sessionId,
@@ -65321,7 +65884,7 @@ ${answeredRounds}` : pending.originalPrompt;
65321
65884
  function composeReadOnlyAdvisoryBrief(pending, latestTurn, answered, options = {}) {
65322
65885
  return composeImplementationBrief(pending, latestTurn, answered, options);
65323
65886
  }
65324
- var MAX_WORKFLOW_HANDOFF_TURN_CHARS = 900, MAX_WORKFLOW_HANDOFF_TOTAL_CHARS = 4800, WORKFLOW_HANDOFF_SECTION_LABEL = "Workflow handoff context:", WORKFLOW_HANDOFF_HEADER_LINES = [
65887
+ var MAX_WORKFLOW_HANDOFF_TURN_CHARS = 900, MAX_WORKFLOW_HANDOFF_TOTAL_CHARS = 4800, WORKFLOW_HANDOFF_HEADER_LINES = [
65325
65888
  WORKFLOW_HANDOFF_SECTION_LABEL,
65326
65889
  "Source: local read-only advisory turns, including brainstorm and familiarize when present.",
65327
65890
  "Disclosure: this bounded summary is included explicitly in the task and review packet; it is not hidden chat memory.",
@@ -65660,11 +66223,22 @@ async function routeTeamDecompose(deps) {
65660
66223
  error: err.message
65661
66224
  });
65662
66225
  }
66226
+ let decomposerUserContext = "";
66227
+ if (installedUserContextComposer)
66228
+ try {
66229
+ decomposerUserContext = (await installedUserContextComposer(composedBrief)).trim();
66230
+ } catch (err) {
66231
+ logger.warn("[orchestration-shell] decomposer user-context projection failed (non-fatal)", {
66232
+ error: err.message
66233
+ });
66234
+ }
65663
66235
  let result = await runLocalDecomposer(
65664
66236
  { localExecutor, workingDir: quorumLoop.getWorkingDir() },
65665
66237
  composedBrief,
65666
66238
  detected,
65667
- decomposerRepoContext
66239
+ decomposerUserContext.length > 0 ? `
66240
+
66241
+ ${decomposerUserContext}${decomposerRepoContext}` : decomposerRepoContext
65668
66242
  );
65669
66243
  if (result.decompose === !1) {
65670
66244
  store.dispatch({
@@ -65744,7 +66318,7 @@ async function routeTeamDecompose(deps) {
65744
66318
  });
65745
66319
  }
65746
66320
  }
65747
- var installedDispatchContextComposer = null;
66321
+ var installedDispatchContextComposer = null, installedUserContextComposer = null;
65748
66322
  var repoStateRedelegationsInFlight = /* @__PURE__ */ new Set();
65749
66323
  async function redelegateRepoStateReadQuietly(deps) {
65750
66324
  let { args } = deps;
@@ -65762,7 +66336,7 @@ async function redelegateRepoStateReadQuietly(deps) {
65762
66336
  promptForPlanning: brief,
65763
66337
  tokenStartUtf16: 0,
65764
66338
  tokenEndUtf16: 0
65765
- }, headProbe = await probeWorkspaceGitHead(canonicalRoot), gitHeadAtRead = headProbe.kind === "head" ? headProbe.head : null, result = await runReadOnlyAgentAdvisoryResult({
66339
+ }, headProbe = await probeWorkspaceGitHead(canonicalRoot), gitHeadAtRead = headProbe.kind === "head" ? headProbe.head : null, treeProbe = await probeWorkspaceTreeFingerprint(canonicalRoot), fingerprintAtRead = treeProbe.kind === "fingerprint" ? treeProbe.value : null, result = await runReadOnlyAgentAdvisoryResult({
65766
66340
  shellArgs: args,
65767
66341
  agent,
65768
66342
  intent,
@@ -65781,13 +66355,15 @@ async function redelegateRepoStateReadQuietly(deps) {
65781
66355
  summary: output,
65782
66356
  author: agent,
65783
66357
  producedAt: (/* @__PURE__ */ new Date()).toISOString(),
65784
- ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {}
66358
+ ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {},
66359
+ ...fingerprintAtRead ? { worktreeFingerprint: fingerprintAtRead } : {}
65785
66360
  }), await appendRepoStateItem({
65786
66361
  sessionId: args.session.sessionId,
65787
66362
  workspaceId,
65788
66363
  summary: output,
65789
66364
  agentId: agent,
65790
- ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {}
66365
+ ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {},
66366
+ ...fingerprintAtRead ? { worktreeFingerprint: fingerprintAtRead } : {}
65791
66367
  }), logger.info("[orchestration-shell] background repo_state re-delegation refreshed the overview", {
65792
66368
  workspaceId
65793
66369
  });
@@ -65834,7 +66410,7 @@ async function routeFamiliarize(deps) {
65834
66410
  promptForPlanning: brief,
65835
66411
  tokenStartUtf16: 0,
65836
66412
  tokenEndUtf16: 0
65837
- }, headProbe = await probeWorkspaceGitHead(workingDir), gitHeadAtRead = headProbe.kind === "head" ? headProbe.head : null, result = await runReadOnlyAgentAdvisoryResult({
66413
+ }, headProbe = await probeWorkspaceGitHead(workingDir), gitHeadAtRead = headProbe.kind === "head" ? headProbe.head : null, treeProbe = await probeWorkspaceTreeFingerprint(workingDir), fingerprintAtRead = treeProbe.kind === "fingerprint" ? treeProbe.value : null, result = await runReadOnlyAgentAdvisoryResult({
65838
66414
  shellArgs: args,
65839
66415
  agent,
65840
66416
  intent,
@@ -65857,7 +66433,8 @@ async function routeFamiliarize(deps) {
65857
66433
  summary: output,
65858
66434
  author: agent,
65859
66435
  producedAt,
65860
- ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {}
66436
+ ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {},
66437
+ ...fingerprintAtRead ? { worktreeFingerprint: fingerprintAtRead } : {}
65861
66438
  });
65862
66439
  } catch (err) {
65863
66440
  logger.warn("[orchestration-shell] repo_state persist failed (non-fatal)", {
@@ -65871,7 +66448,8 @@ async function routeFamiliarize(deps) {
65871
66448
  summary: output,
65872
66449
  agentId: agent,
65873
66450
  producedAt,
65874
- ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {}
66451
+ ...gitHeadAtRead ? { gitHead: gitHeadAtRead } : {},
66452
+ ...fingerprintAtRead ? { worktreeFingerprint: fingerprintAtRead } : {}
65875
66453
  });
65876
66454
  } catch (err) {
65877
66455
  logger.warn("[orchestration-shell] repo_state context-item append failed (non-fatal)", {
@@ -66802,6 +67380,10 @@ async function handleShellUserInput(deps) {
66802
67380
  store.getState().structuralSummaryError,
66803
67381
  args.tier
66804
67382
  );
67383
+ else if (output.command === "/rule" && !output.sideEffect && output.output === USER_RULE_PIN_PENDING)
67384
+ output.output = await pinExplicitUserRule(args.session.sessionId, slashCommandText);
67385
+ else if (output.command === "/rules" && !output.sideEffect && (output.output === USER_RULES_LIST_PENDING || output.output === USER_RULES_FORGET_PENDING))
67386
+ output.output = await runUserRulesCommand(args.session.sessionId, slashCommandText);
66805
67387
  else if ((output.command === "/continuation" || output.command === "/continue") && !output.sideEffect && output.output === "PENDING \u2014 entrypoint pulls from continuation reader") {
66806
67388
  let argv = text2.trim().split(/\s+/).slice(1), result;
66807
67389
  try {
@@ -67609,6 +68191,58 @@ ${heading}`;
67609
68191
  function clearTurnAuthoringSessionState(sessionId) {
67610
68192
  openQuestionRegistry.delete(sessionId), brainstormQuotaWalled.delete(sessionId), pendingBrainstormPanelResponses.delete(sessionId);
67611
68193
  }
68194
+ async function pinExplicitUserRule(sessionId, commandText) {
68195
+ let text2 = capUserRuleText(commandText.trim().replace(/^\/rule(?:\s+|$)/i, ""));
68196
+ if (text2.length === 0)
68197
+ return "Usage: /rule <rule text>. Pins the rule for this session; list pinned rules with /rules.";
68198
+ let pinned = null;
68199
+ try {
68200
+ pinned = await appendContextItem(sessionId, {
68201
+ kind: "decision",
68202
+ author: { role: "human" },
68203
+ sensitivity: "user",
68204
+ visible_to: [...USER_WORDS_VISIBLE_TO],
68205
+ body: { action: USER_RULE_ACTION, text: text2, source: "explicit" }
68206
+ });
68207
+ } catch {
68208
+ pinned = null;
68209
+ }
68210
+ return pinned ? sanitizeForTerminal(renderPinAcknowledgement(text2)) : "Nothing was pinned: this session's context log is unavailable.";
68211
+ }
68212
+ async function runUserRulesCommand(sessionId, commandText) {
68213
+ let argv = commandText.trim().split(/\s+/).slice(1), rules = await readLiveUserRules(sessionId);
68214
+ if (rules === null)
68215
+ return "Pinned rules are unavailable: this session's context log could not be verified.";
68216
+ if (argv.length === 0)
68217
+ return rules.length === 0 ? 'No rules are pinned in this session. Pin one with /rule <text>, or state it with a standing marker such as "from now on".' : sanitizeForTerminal(
68218
+ [
68219
+ "Pinned rules (oldest first):",
68220
+ ...rules.map((rule, i) => ` ${i + 1}. ${renderUserText(rule.text)}`),
68221
+ "",
68222
+ "Retire one with /rules forget <n>."
68223
+ ].join(`
68224
+ `)
68225
+ );
68226
+ let n = Number.parseInt(argv[1] ?? "", 10), target = Number.isSafeInteger(n) && n >= 1 ? rules[n - 1] : void 0;
68227
+ if (!target)
68228
+ return `There is no pinned rule ${argv[1] ?? ""}. /rules lists the pinned rules and their numbers.`;
68229
+ let retired = null;
68230
+ try {
68231
+ retired = await appendContextItem(sessionId, {
68232
+ kind: "decision",
68233
+ author: { role: "human" },
68234
+ sensitivity: "user",
68235
+ visible_to: [...USER_WORDS_VISIBLE_TO],
68236
+ body: { action: USER_RULE_RETIRED_ACTION, seq: target.seq },
68237
+ refs: [target.id]
68238
+ });
68239
+ } catch {
68240
+ retired = null;
68241
+ }
68242
+ return retired ? sanitizeForTerminal(
68243
+ `Retired rule ${n}: "${renderUserText(target.text)}". Agents that implement tasks no longer receive it.`
68244
+ ) : "The rule was not retired: this session's context log is unavailable.";
68245
+ }
67612
68246
  async function authorTurnContextItems(deps) {
67613
68247
  let {
67614
68248
  store,
@@ -67616,7 +68250,7 @@ async function authorTurnContextItems(deps) {
67616
68250
  delta,
67617
68251
  panelOwnedThisTurn: panelOwnedThisTurnFlag,
67618
68252
  turnOwnership
67619
- } = deps, pendingAppends = [];
68253
+ } = deps, pendingAppends = [], pinAcknowledgements = [];
67620
68254
  try {
67621
68255
  let allRoles = ["implementor", "reviewer", "resolver", "planner", "brainstorm"], pending = store.getState().pendingClarification, registry = openQuestionRegistry.get(sessionId), answeredQuestionIdPromises = [];
67622
68256
  if (registry && registry.size > 0)
@@ -67633,7 +68267,7 @@ async function authorTurnContextItems(deps) {
67633
68267
  kind: "turn",
67634
68268
  author: { role: "human" },
67635
68269
  sensitivity: "user",
67636
- visible_to: ["planner", "brainstorm"],
68270
+ visible_to: [...USER_WORDS_VISIBLE_TO],
67637
68271
  body: { text: text2 },
67638
68272
  ...answeredQuestionIds.length > 0 ? { refs: answeredQuestionIds } : {}
67639
68273
  }), humanTurnAppended.catch(() => {
@@ -67651,6 +68285,40 @@ async function authorTurnContextItems(deps) {
67651
68285
  });
67652
68286
  pendingAppends.push(retirement);
67653
68287
  }
68288
+ if (userEntry && humanTurnAppended) {
68289
+ let pinText = userEntry.text, humanTurnForPin = humanTurnAppended, provisional = matchPinRule(pinText, { hasPriorPins: !0 });
68290
+ if (provisional) {
68291
+ let pinned = (async () => {
68292
+ let capture = provisional;
68293
+ if (provisional.rules.includes("revocation")) {
68294
+ let live = await readLiveUserRules(sessionId);
68295
+ (live === null || live.length === 0) && (capture = matchPinRule(pinText, { hasPriorPins: !1 }));
68296
+ }
68297
+ if (!capture) return;
68298
+ let humanItem = await humanTurnForPin;
68299
+ if (!humanItem || !await appendContextItem(sessionId, {
68300
+ kind: "decision",
68301
+ author: { role: "human" },
68302
+ sensitivity: "user",
68303
+ visible_to: [...USER_WORDS_VISIBLE_TO],
68304
+ body: { action: USER_RULE_ACTION, text: capture.text, source: "turn" },
68305
+ refs: [humanItem.id],
68306
+ telemetry: { pinRules: capture.rules }
68307
+ })) return;
68308
+ let acknowledgement = sanitizeForTerminal(renderPinAcknowledgement(capture.text));
68309
+ store.dispatch({
68310
+ type: "SHELL_ADVISORY",
68311
+ source: "shell",
68312
+ text: acknowledgement,
68313
+ handoffExcluded: !0
68314
+ });
68315
+ let conversation = store.getState().conversation, entry = conversation[conversation.length - 1];
68316
+ entry && entry.kind === "advisory" && entry.text === acknowledgement && delta.push(entry), pinAcknowledgements.push(acknowledgement);
68317
+ })().catch(() => {
68318
+ });
68319
+ pendingAppends.push(pinned);
68320
+ }
68321
+ }
67654
68322
  for (let e of delta)
67655
68323
  e.kind === "planner-decision" && pendingAppends.push(
67656
68324
  appendContextItem(sessionId, {
@@ -67785,6 +68453,7 @@ async function authorTurnContextItems(deps) {
67785
68453
  error: err.message
67786
68454
  });
67787
68455
  }
68456
+ return { pinAcknowledgements };
67788
68457
  }
67789
68458
  async function emitOrchestrationTurnMirror(deps) {
67790
68459
  let {
@@ -67796,15 +68465,13 @@ async function emitOrchestrationTurnMirror(deps) {
67796
68465
  skipUserPromptMirror,
67797
68466
  turnOwnership,
67798
68467
  ownEntries
67799
- } = deps, delta = ownEntries ? [...ownEntries] : store.getState().conversation.slice(convLenBefore);
67800
- await authorTurnContextItems({
68468
+ } = deps, delta = ownEntries ? [...ownEntries] : store.getState().conversation.slice(convLenBefore), authored = await authorTurnContextItems({
67801
68469
  store,
67802
68470
  sessionId,
67803
68471
  delta,
67804
68472
  panelOwnedThisTurn: turnOwnership?.brainstormPanelOwned === !0,
67805
68473
  turnOwnership
67806
- });
67807
- let userEntry = delta.find(
68474
+ }), userEntry = delta.find(
67808
68475
  (e) => e.kind === "user-message"
67809
68476
  );
67810
68477
  if (!userEntry && !skipUserPromptMirror || userEntry && userEntry.text.trim().length === 0) return;
@@ -67937,7 +68604,23 @@ ${cell.boundedBody}`).join(`
67937
68604
  }
67938
68605
  ), delta.some(
67939
68606
  (e) => e.kind === "planner-decision" && (e.action === "start_task" || e.action === "team_decompose")
67940
- )) return;
68607
+ )) {
68608
+ authored.pinAcknowledgements.length > 0 && await emitWithProvenNoWriteDowngrade(emitShellEventBound, {
68609
+ sessionId,
68610
+ type: "ASSISTANT_RESPONSE",
68611
+ source: "DESKTOP",
68612
+ isEncrypted: !0,
68613
+ content: authored.pinAcknowledgements.join(`
68614
+
68615
+ `),
68616
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
68617
+ }).catch((err) => {
68618
+ logger.warn("[orchestration-shell] emit pin acknowledgement mirror failed (non-fatal)", {
68619
+ error: err.message
68620
+ });
68621
+ });
68622
+ return;
68623
+ }
67941
68624
  let replyText = delta.map((e) => e.kind === "advisory" ? e.localOnly ? "" : e.text : e.kind === "slash-output" && e.command === "planner-error" ? e.output : "").map((t) => t.trim()).filter((t) => t.length > 0).join(`
67942
68625
 
67943
68626
  `).trim();
@@ -69403,93 +70086,6 @@ var import_node_crypto16 = require("node:crypto"), DEFAULT_TTL_MS2 = 1800 * 1e3,
69403
70086
  // src/credential-broker/canonical.ts
69404
70087
  var import_node_crypto17 = require("node:crypto");
69405
70088
  init_logger2();
69406
-
69407
- // src/credential-broker/scrubber.ts
69408
- var REDACTION = "[REDACTED-CP7]", KEY_REDACTION = "[REDACTED-CP7-KEY]", SECRET_PATTERNS = [
69409
- {
69410
- // PEM private-key block (RSA / EC / OPENSSH / generic PRIVATE KEY).
69411
- patternClass: "private_key_pem",
69412
- regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |ENCRYPTED )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA |ENCRYPTED )?PRIVATE KEY-----/g
69413
- },
69414
- {
69415
- // Anthropic API key: sk-ant-... .
69416
- patternClass: "anthropic_api_key",
69417
- regex: /sk-ant-[A-Za-z0-9_-]{20,}/g
69418
- },
69419
- {
69420
- // OpenAI API key: sk-... or sk-proj-... (>= 20 trailing chars).
69421
- patternClass: "openai_api_key",
69422
- regex: /sk-(?:proj-)?[A-Za-z0-9_-]{20,}/g
69423
- },
69424
- {
69425
- // AWS access key id (AKIA / ASIA + 16 uppercase alphanumerics).
69426
- patternClass: "aws_access_key_id",
69427
- regex: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g
69428
- },
69429
- {
69430
- // AWS secret access key VALUE assignment — a 40-char base64-ish secret
69431
- // bound to an `aws_secret_access_key`/`AWS_SECRET_ACCESS_KEY` key. Only
69432
- // the secret value is redacted, not the assignment label.
69433
- patternClass: "aws_secret_access_key",
69434
- regex: /(aws_secret_access_key|AWS_SECRET_ACCESS_KEY)(\s*[=:]\s*["']?)([A-Za-z0-9/+]{40})(["']?)/g
69435
- },
69436
- {
69437
- // GitHub tokens (ghp_/gho_/ghu_/ghs_/ghr_ + 36 chars).
69438
- patternClass: "github_token",
69439
- regex: /\bgh[pousr]_[A-Za-z0-9]{36}\b/g
69440
- },
69441
- {
69442
- // Authorization: Bearer <token> embedded in content (a bearer token
69443
- // riding in a model-bound field). Redacts the token, keeps the scheme.
69444
- patternClass: "bearer_token",
69445
- regex: /(Bearer\s+)([A-Za-z0-9._~+/=-]{16,})/g
69446
- }
69447
- ];
69448
- function scrubString(value) {
69449
- let redacted = value, classes = [];
69450
- for (let pattern of SECRET_PATTERNS)
69451
- pattern.regex.lastIndex = 0, pattern.regex.test(redacted) && (pattern.regex.lastIndex = 0, pattern.patternClass === "aws_secret_access_key" ? redacted = redacted.replace(pattern.regex, `$1$2${REDACTION}$4`) : pattern.patternClass === "bearer_token" ? redacted = redacted.replace(pattern.regex, `$1${REDACTION}`) : redacted = redacted.replace(pattern.regex, REDACTION), classes.push(pattern.patternClass));
69452
- return { redacted, classes };
69453
- }
69454
- function keyIsSecret(key) {
69455
- for (let pattern of SECRET_PATTERNS) {
69456
- pattern.regex.lastIndex = 0;
69457
- let hit = pattern.regex.test(key);
69458
- if (pattern.regex.lastIndex = 0, hit) return !0;
69459
- }
69460
- return !1;
69461
- }
69462
- function joinPath(base, key) {
69463
- return typeof key == "number" ? `${base}[${key}]` : /^[A-Za-z_][A-Za-z0-9_]*$/.test(key) ? `${base}.${key}` : `${base}['${key.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}']`;
69464
- }
69465
- function scrubValue(value, path73, findings) {
69466
- if (typeof value == "string") {
69467
- let { redacted, classes } = scrubString(value);
69468
- for (let patternClass of classes)
69469
- findings.push({ field: path73, patternClass });
69470
- return redacted;
69471
- }
69472
- if (Array.isArray(value))
69473
- return value.map((item, i) => scrubValue(item, joinPath(path73, i), findings));
69474
- if (value !== null && typeof value == "object") {
69475
- let out = /* @__PURE__ */ Object.create(null), redactedKeyCount = 0;
69476
- for (let [k, v] of Object.entries(value))
69477
- if (keyIsSecret(k)) {
69478
- redactedKeyCount += 1;
69479
- let placeholder = `${KEY_REDACTION}-${redactedKeyCount}`, placeholderPath = joinPath(path73, placeholder);
69480
- findings.push({ field: placeholderPath, patternClass: "secret_object_key" }), out[placeholder] = scrubValue(v, placeholderPath, findings);
69481
- } else
69482
- out[k] = scrubValue(v, joinPath(path73, k), findings);
69483
- return out;
69484
- }
69485
- return value;
69486
- }
69487
- function scrubRequestBody(body) {
69488
- let findings = [];
69489
- return { scrubbed: scrubValue(body, "$", findings), findings };
69490
- }
69491
-
69492
- // src/credential-broker/canonical.ts
69493
70089
  var CanonicalRejectError = class extends Error {
69494
70090
  constructor(reason) {
69495
70091
  super(reason);
@@ -73255,6 +73851,8 @@ function buildAndArmQuorumLoop(args) {
73255
73851
  // A1e (P3 slice-wiring REMAP) — the round-0 repository-context projection
73256
73852
  // (inert holder until `runOrchestrationShell` installs the composer).
73257
73853
  ...args.projectDispatchContext !== void 0 ? { projectDispatchContext: args.projectDispatchContext } : {},
73854
+ // M7 — the user's own words, every implementor round (inert until installed).
73855
+ ...args.projectUserContext !== void 0 ? { projectUserContext: args.projectUserContext } : {},
73258
73856
  ...args.onTaskAuditSummary ? { onTaskAuditSummary: args.onTaskAuditSummary } : {},
73259
73857
  ...args.emitShellEvent ? { emitShellEvent: args.emitShellEvent } : {},
73260
73858
  getSessionKey: (sid) => keychainManager.getSessionKey(sid).catch(() => null),
@@ -73349,7 +73947,10 @@ function buildAndArmQuorumLoop(args) {
73349
73947
  async function buildQuorumLoopExecutor(args) {
73350
73948
  let { appsyncClient, session, emitter } = args, leEmitShellEvent = async (e) => await emitter(mapSingleTaskLeEventToShellEmit(e)), leDeviceId = await keychainManager.getDeviceId(), repoRoot = process.cwd(), quorumLoopHolder = { loop: null }, progressTap = { fn: () => {
73351
73949
  } }, policyRejectionTap = { fn: () => {
73352
- } }, dispatchContextTap = { fn: async () => "" }, localExecutor = new LocalExecutorImpl({
73950
+ } }, dispatchContextTap = {
73951
+ fn: async () => "",
73952
+ userContextFn: async () => ""
73953
+ }, localExecutor = new LocalExecutorImpl({
73353
73954
  sessionId: session.sessionId,
73354
73955
  // CP-1.f Hybrid authority split (mirrors the team LE) — the DESKTOP seeds
73355
73956
  // the implementor command allowlist so `enforceCommand` permits the spawn;
@@ -73421,7 +74022,9 @@ async function buildQuorumLoopExecutor(args) {
73421
74022
  // via the tap (NOT through the AppSync NOTIFICATION channel — zero wire).
73422
74023
  onProgress: (event) => progressTap.fn(event),
73423
74024
  // A1e — the round-0 repository-context projection, via the tap holder.
73424
- projectDispatchContext: (input) => dispatchContextTap.fn(input)
74025
+ projectDispatchContext: (input) => dispatchContextTap.fn(input),
74026
+ // M7 — the user's own words, every implementor round, via the same holder.
74027
+ projectUserContext: (input) => dispatchContextTap.userContextFn(input)
73425
74028
  });
73426
74029
  return { localExecutor, quorumLoop, progressTap, policyRejectionTap, dispatchContextTap };
73427
74030
  }
@@ -73585,7 +74188,10 @@ async function buildTeamLocalExecutor(args) {
73585
74188
  );
73586
74189
  }, teamExecution = resolveTeamExecution(), strictBadgeSink = makeStrictBadgeSink(appsyncClient), quorumLoopHolder = { loop: null }, progressTap = { fn: () => {
73587
74190
  } }, policyRejectionTap = { fn: () => {
73588
- } }, dispatchContextTap = { fn: async () => "" }, localExecutor = new LocalExecutorImpl({
74191
+ } }, dispatchContextTap = {
74192
+ fn: async () => "",
74193
+ userContextFn: async () => ""
74194
+ }, localExecutor = new LocalExecutorImpl({
73589
74195
  sessionId: session.sessionId,
73590
74196
  initialScope,
73591
74197
  baseCtx: {
@@ -73923,6 +74529,8 @@ async function buildTeamLocalExecutor(args) {
73923
74529
  onProgress: (event) => progressTap.fn(event),
73924
74530
  // A1e — the round-0 repository-context projection, via the tap holder.
73925
74531
  projectDispatchContext: (input) => dispatchContextTap.fn(input),
74532
+ // M7 — the user's own words, every implementor round, via the same holder.
74533
+ projectUserContext: (input) => dispatchContextTap.userContextFn(input),
73926
74534
  // PHASE-589/469 W1 (LOCK #589-E) — flip the desktop's OWN team track Failed
73927
74535
  // + render the group-terminal from LOCAL state. Emits a `team_track_terminal`
73928
74536
  // (state Failed) shell event through the SAME `leEmitShellEvent` chokepoint