clinkx 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (555) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +10 -0
  3. package/README.md +82 -26
  4. package/clinkx-workflows/dist/allowed-roots.d.ts +1 -0
  5. package/clinkx-workflows/dist/allowed-roots.js +5 -0
  6. package/clinkx-workflows/dist/allowed-roots.js.map +1 -0
  7. package/clinkx-workflows/dist/artifacts.d.ts +20 -1
  8. package/clinkx-workflows/dist/artifacts.js +38 -9
  9. package/clinkx-workflows/dist/artifacts.js.map +1 -1
  10. package/clinkx-workflows/dist/backend.d.ts +4 -0
  11. package/clinkx-workflows/dist/citation-check.d.ts +40 -0
  12. package/clinkx-workflows/dist/citation-check.js +348 -0
  13. package/clinkx-workflows/dist/citation-check.js.map +1 -0
  14. package/clinkx-workflows/dist/clink-client.d.ts +2 -1
  15. package/clinkx-workflows/dist/clink-client.js +17 -4
  16. package/clinkx-workflows/dist/clink-client.js.map +1 -1
  17. package/clinkx-workflows/dist/config.d.ts +145 -16
  18. package/clinkx-workflows/dist/config.js +384 -26
  19. package/clinkx-workflows/dist/config.js.map +1 -1
  20. package/clinkx-workflows/dist/contained-file.d.ts +172 -0
  21. package/clinkx-workflows/dist/contained-file.js +483 -0
  22. package/clinkx-workflows/dist/contained-file.js.map +1 -0
  23. package/clinkx-workflows/dist/context-builder-lifecycle-contract.d.ts +416 -0
  24. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js +328 -0
  25. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js.map +1 -0
  26. package/clinkx-workflows/dist/context-builder-lifecycle-router.d.ts +24 -0
  27. package/clinkx-workflows/dist/context-builder-lifecycle-router.js +39 -0
  28. package/clinkx-workflows/dist/context-builder-lifecycle-router.js.map +1 -0
  29. package/clinkx-workflows/dist/context-cache-key.d.ts +53 -0
  30. package/clinkx-workflows/dist/context-cache-key.js +91 -0
  31. package/clinkx-workflows/dist/context-cache-key.js.map +1 -0
  32. package/clinkx-workflows/dist/context-mode-resolver.d.ts +27 -0
  33. package/clinkx-workflows/dist/context-mode-resolver.js +126 -0
  34. package/clinkx-workflows/dist/context-mode-resolver.js.map +1 -0
  35. package/clinkx-workflows/dist/context-preflight.d.ts +184 -0
  36. package/clinkx-workflows/dist/context-preflight.js +91 -0
  37. package/clinkx-workflows/dist/context-preflight.js.map +1 -0
  38. package/clinkx-workflows/dist/council-expander.d.ts +1 -1
  39. package/clinkx-workflows/dist/council-expander.js +2 -1
  40. package/clinkx-workflows/dist/council-expander.js.map +1 -1
  41. package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +165 -0
  42. package/clinkx-workflows/dist/dashboard/activity-contract.js +105 -0
  43. package/clinkx-workflows/dist/dashboard/activity-contract.js.map +1 -0
  44. package/clinkx-workflows/dist/dashboard/activity-lease.d.ts +25 -0
  45. package/clinkx-workflows/dist/dashboard/activity-lease.js +34 -0
  46. package/clinkx-workflows/dist/dashboard/activity-lease.js.map +1 -0
  47. package/clinkx-workflows/dist/dashboard/activity-reader.d.ts +86 -0
  48. package/clinkx-workflows/dist/dashboard/activity-reader.js +480 -0
  49. package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
  50. package/clinkx-workflows/dist/dashboard/api-routes.d.ts +36 -0
  51. package/clinkx-workflows/dist/dashboard/api-routes.js +1047 -0
  52. package/clinkx-workflows/dist/dashboard/api-routes.js.map +1 -0
  53. package/clinkx-workflows/dist/dashboard/artifact-index.d.ts +37 -0
  54. package/clinkx-workflows/dist/dashboard/artifact-index.js +145 -0
  55. package/clinkx-workflows/dist/dashboard/artifact-index.js.map +1 -0
  56. package/clinkx-workflows/dist/dashboard/auth/challenge-store.d.ts +31 -0
  57. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js +65 -0
  58. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js.map +1 -0
  59. package/clinkx-workflows/dist/dashboard/auth/controller.d.ts +26 -0
  60. package/clinkx-workflows/dist/dashboard/auth/controller.js +596 -0
  61. package/clinkx-workflows/dist/dashboard/auth/controller.js.map +1 -0
  62. package/clinkx-workflows/dist/dashboard/auth/credential-store.d.ts +60 -0
  63. package/clinkx-workflows/dist/dashboard/auth/credential-store.js +776 -0
  64. package/clinkx-workflows/dist/dashboard/auth/credential-store.js.map +1 -0
  65. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.d.ts +9 -0
  66. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js +44 -0
  67. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js.map +1 -0
  68. package/clinkx-workflows/dist/dashboard/auth/session-store.d.ts +17 -0
  69. package/clinkx-workflows/dist/dashboard/auth/session-store.js +77 -0
  70. package/clinkx-workflows/dist/dashboard/auth/session-store.js.map +1 -0
  71. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.d.ts +25 -0
  72. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js +71 -0
  73. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js.map +1 -0
  74. package/clinkx-workflows/dist/dashboard/context-run-liveness.d.ts +37 -0
  75. package/clinkx-workflows/dist/dashboard/context-run-liveness.js +49 -0
  76. package/clinkx-workflows/dist/dashboard/context-run-liveness.js.map +1 -0
  77. package/clinkx-workflows/dist/dashboard/context-run-reader.d.ts +222 -0
  78. package/clinkx-workflows/dist/dashboard/context-run-reader.js +1178 -0
  79. package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
  80. package/clinkx-workflows/dist/dashboard/contracts.d.ts +8936 -0
  81. package/clinkx-workflows/dist/dashboard/contracts.js +1157 -0
  82. package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -0
  83. package/clinkx-workflows/dist/dashboard/generation.d.ts +14 -0
  84. package/clinkx-workflows/dist/dashboard/generation.js +41 -0
  85. package/clinkx-workflows/dist/dashboard/generation.js.map +1 -0
  86. package/clinkx-workflows/dist/dashboard/index.d.ts +28 -0
  87. package/clinkx-workflows/dist/dashboard/index.js +16 -0
  88. package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
  89. package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +101 -0
  90. package/clinkx-workflows/dist/dashboard/lazy-content.js +748 -0
  91. package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
  92. package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +303 -0
  93. package/clinkx-workflows/dist/dashboard/progress-report-contract.js +221 -0
  94. package/clinkx-workflows/dist/dashboard/progress-report-contract.js.map +1 -0
  95. package/clinkx-workflows/dist/dashboard/progress-report-reader.d.ts +50 -0
  96. package/clinkx-workflows/dist/dashboard/progress-report-reader.js +581 -0
  97. package/clinkx-workflows/dist/dashboard/progress-report-reader.js.map +1 -0
  98. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +89 -0
  99. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js +71 -0
  100. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js.map +1 -0
  101. package/clinkx-workflows/dist/dashboard/progress-report-status-store.d.ts +28 -0
  102. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +110 -0
  103. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js.map +1 -0
  104. package/clinkx-workflows/dist/dashboard/read-model.d.ts +86 -0
  105. package/clinkx-workflows/dist/dashboard/read-model.js +440 -0
  106. package/clinkx-workflows/dist/dashboard/read-model.js.map +1 -0
  107. package/clinkx-workflows/dist/dashboard/request-admission.d.ts +31 -0
  108. package/clinkx-workflows/dist/dashboard/request-admission.js +126 -0
  109. package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
  110. package/clinkx-workflows/dist/dashboard/scanner.d.ts +75 -0
  111. package/clinkx-workflows/dist/dashboard/scanner.js +1110 -0
  112. package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
  113. package/clinkx-workflows/dist/dashboard/server-factory.d.ts +50 -0
  114. package/clinkx-workflows/dist/dashboard/server-factory.js +431 -0
  115. package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
  116. package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2611 -0
  117. package/clinkx-workflows/dist/dashboard/session-log-contract.js +480 -0
  118. package/clinkx-workflows/dist/dashboard/session-log-contract.js.map +1 -0
  119. package/clinkx-workflows/dist/dashboard/session-log-identity.d.ts +21 -0
  120. package/clinkx-workflows/dist/dashboard/session-log-identity.js +101 -0
  121. package/clinkx-workflows/dist/dashboard/session-log-identity.js.map +1 -0
  122. package/clinkx-workflows/dist/dashboard/session-log-journal.d.ts +43 -0
  123. package/clinkx-workflows/dist/dashboard/session-log-journal.js +522 -0
  124. package/clinkx-workflows/dist/dashboard/session-log-journal.js.map +1 -0
  125. package/clinkx-workflows/dist/dashboard/session-log-reader.d.ts +61 -0
  126. package/clinkx-workflows/dist/dashboard/session-log-reader.js +378 -0
  127. package/clinkx-workflows/dist/dashboard/session-log-reader.js.map +1 -0
  128. package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +6 -0
  129. package/clinkx-workflows/dist/dashboard/session-log-redaction.js +367 -0
  130. package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -0
  131. package/clinkx-workflows/dist/dashboard/session-log-retention.d.ts +23 -0
  132. package/clinkx-workflows/dist/dashboard/session-log-retention.js +212 -0
  133. package/clinkx-workflows/dist/dashboard/session-log-retention.js.map +1 -0
  134. package/clinkx-workflows/dist/dashboard/static-responses.d.ts +10 -0
  135. package/clinkx-workflows/dist/dashboard/static-responses.js +94 -0
  136. package/clinkx-workflows/dist/dashboard/static-responses.js.map +1 -0
  137. package/clinkx-workflows/dist/dashboard/worker-lock-observer.d.ts +28 -0
  138. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js +241 -0
  139. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js.map +1 -0
  140. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  141. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  142. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  143. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  144. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  145. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  146. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  147. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  148. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  149. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  150. package/clinkx-workflows/dist/dashboard-ui/assets/index-DOkMXTfB.js +25 -0
  151. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  152. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  153. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  154. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  155. package/clinkx-workflows/dist/dashboard-ui/assets/style-ChJsn0KD.css +1 -0
  156. package/clinkx-workflows/dist/dashboard-ui/contracts/council-plan-review-input-v1.json +158 -0
  157. package/clinkx-workflows/dist/dashboard-ui/index.html +15 -0
  158. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Mono-OFL.txt +93 -0
  159. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Sans-OFL.txt +93 -0
  160. package/clinkx-workflows/dist/dashboard-ui/licenses/JetBrains-Mono-OFL.txt +93 -0
  161. package/clinkx-workflows/dist/dashboard-ui/licenses/NOTICE.md +32 -0
  162. package/clinkx-workflows/dist/dashboard-ui/theme-init.js +8 -0
  163. package/clinkx-workflows/dist/definition-normalizer.d.ts +19 -0
  164. package/clinkx-workflows/dist/definition-normalizer.js.map +1 -1
  165. package/clinkx-workflows/dist/delegate-validate.d.ts +78 -0
  166. package/clinkx-workflows/dist/delegate-validate.js +97 -0
  167. package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
  168. package/clinkx-workflows/dist/engine.d.ts +141 -0
  169. package/clinkx-workflows/dist/engine.js +882 -28
  170. package/clinkx-workflows/dist/engine.js.map +1 -1
  171. package/clinkx-workflows/dist/errors.d.ts +2 -0
  172. package/clinkx-workflows/dist/errors.js.map +1 -1
  173. package/clinkx-workflows/dist/fingerprint.d.ts +1 -1
  174. package/clinkx-workflows/dist/fingerprint.js +1 -1
  175. package/clinkx-workflows/dist/index.d.ts +19 -0
  176. package/clinkx-workflows/dist/index.js +15 -0
  177. package/clinkx-workflows/dist/index.js.map +1 -1
  178. package/clinkx-workflows/dist/loader.d.ts +9 -3
  179. package/clinkx-workflows/dist/loader.js +92 -21
  180. package/clinkx-workflows/dist/loader.js.map +1 -1
  181. package/clinkx-workflows/dist/plan-review/admission.d.ts +160 -0
  182. package/clinkx-workflows/dist/plan-review/admission.js +290 -0
  183. package/clinkx-workflows/dist/plan-review/admission.js.map +1 -0
  184. package/clinkx-workflows/dist/plan-review/context-policy.d.ts +55 -0
  185. package/clinkx-workflows/dist/plan-review/context-policy.js +146 -0
  186. package/clinkx-workflows/dist/plan-review/context-policy.js.map +1 -0
  187. package/clinkx-workflows/dist/plan-review/contract.d.ts +763 -0
  188. package/clinkx-workflows/dist/plan-review/contract.js +289 -0
  189. package/clinkx-workflows/dist/plan-review/contract.js.map +1 -0
  190. package/clinkx-workflows/dist/plan-review/digest.d.ts +68 -0
  191. package/clinkx-workflows/dist/plan-review/digest.js +241 -0
  192. package/clinkx-workflows/dist/plan-review/digest.js.map +1 -0
  193. package/clinkx-workflows/dist/plan-review/discovery.d.ts +45 -0
  194. package/clinkx-workflows/dist/plan-review/discovery.js +36 -0
  195. package/clinkx-workflows/dist/plan-review/discovery.js.map +1 -0
  196. package/clinkx-workflows/dist/plan-review/execution-contract.d.ts +298 -0
  197. package/clinkx-workflows/dist/plan-review/execution-contract.js +194 -0
  198. package/clinkx-workflows/dist/plan-review/execution-contract.js.map +1 -0
  199. package/clinkx-workflows/dist/plan-review/expander.d.ts +48 -0
  200. package/clinkx-workflows/dist/plan-review/expander.js +243 -0
  201. package/clinkx-workflows/dist/plan-review/expander.js.map +1 -0
  202. package/clinkx-workflows/dist/plan-review/projector.d.ts +126 -0
  203. package/clinkx-workflows/dist/plan-review/projector.js +437 -0
  204. package/clinkx-workflows/dist/plan-review/projector.js.map +1 -0
  205. package/clinkx-workflows/dist/plan-review/publication.d.ts +95 -0
  206. package/clinkx-workflows/dist/plan-review/publication.js +182 -0
  207. package/clinkx-workflows/dist/plan-review/publication.js.map +1 -0
  208. package/clinkx-workflows/dist/plan-review/ranking-reducer.d.ts +34 -0
  209. package/clinkx-workflows/dist/plan-review/ranking-reducer.js +139 -0
  210. package/clinkx-workflows/dist/plan-review/ranking-reducer.js.map +1 -0
  211. package/clinkx-workflows/dist/plan-review/resume.d.ts +38 -0
  212. package/clinkx-workflows/dist/plan-review/resume.js +122 -0
  213. package/clinkx-workflows/dist/plan-review/resume.js.map +1 -0
  214. package/clinkx-workflows/dist/plan-review/rubric.d.ts +7 -0
  215. package/clinkx-workflows/dist/plan-review/rubric.js +24 -0
  216. package/clinkx-workflows/dist/plan-review/rubric.js.map +1 -0
  217. package/clinkx-workflows/dist/plan-review/run-state.d.ts +398 -0
  218. package/clinkx-workflows/dist/plan-review/run-state.js +183 -0
  219. package/clinkx-workflows/dist/plan-review/run-state.js.map +1 -0
  220. package/clinkx-workflows/dist/plan-review/runtime-policy.d.ts +74 -0
  221. package/clinkx-workflows/dist/plan-review/runtime-policy.js +186 -0
  222. package/clinkx-workflows/dist/plan-review/runtime-policy.js.map +1 -0
  223. package/clinkx-workflows/dist/plan-review/snapshot.d.ts +81 -0
  224. package/clinkx-workflows/dist/plan-review/snapshot.js +170 -0
  225. package/clinkx-workflows/dist/plan-review/snapshot.js.map +1 -0
  226. package/clinkx-workflows/dist/plan-review/stage-error.d.ts +19 -0
  227. package/clinkx-workflows/dist/plan-review/stage-error.js +20 -0
  228. package/clinkx-workflows/dist/plan-review/stage-error.js.map +1 -0
  229. package/clinkx-workflows/dist/post-processors/index.d.ts +20 -0
  230. package/clinkx-workflows/dist/post-processors/index.js +21 -0
  231. package/clinkx-workflows/dist/post-processors/index.js.map +1 -0
  232. package/clinkx-workflows/dist/prompt-budget.d.ts +7 -0
  233. package/clinkx-workflows/dist/prompt-budget.js +7 -1
  234. package/clinkx-workflows/dist/prompt-budget.js.map +1 -1
  235. package/clinkx-workflows/dist/reducers/index.js +2 -0
  236. package/clinkx-workflows/dist/reducers/index.js.map +1 -1
  237. package/clinkx-workflows/dist/run-lock-heartbeat.d.ts +2 -0
  238. package/clinkx-workflows/dist/run-lock-heartbeat.js +3 -0
  239. package/clinkx-workflows/dist/run-lock-heartbeat.js.map +1 -0
  240. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.d.ts +34 -0
  241. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js +74 -0
  242. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js.map +1 -0
  243. package/clinkx-workflows/dist/run-summary/cards/index.js +5 -0
  244. package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -1
  245. package/clinkx-workflows/dist/run-summary.d.ts +13 -0
  246. package/clinkx-workflows/dist/run-summary.js +29 -1
  247. package/clinkx-workflows/dist/run-summary.js.map +1 -1
  248. package/clinkx-workflows/dist/schema.d.ts +76 -21
  249. package/clinkx-workflows/dist/schema.js +10 -1
  250. package/clinkx-workflows/dist/schema.js.map +1 -1
  251. package/clinkx-workflows/dist/seed-terms.d.ts +30 -0
  252. package/clinkx-workflows/dist/seed-terms.js +176 -0
  253. package/clinkx-workflows/dist/seed-terms.js.map +1 -0
  254. package/clinkx-workflows/dist/server.d.ts +5 -2
  255. package/clinkx-workflows/dist/server.js +82 -52
  256. package/clinkx-workflows/dist/server.js.map +1 -1
  257. package/clinkx-workflows/dist/shutdown.d.ts +18 -20
  258. package/clinkx-workflows/dist/shutdown.js +43 -61
  259. package/clinkx-workflows/dist/shutdown.js.map +1 -1
  260. package/clinkx-workflows/dist/state-schema.d.ts +38 -0
  261. package/clinkx-workflows/dist/state.d.ts +170 -3
  262. package/clinkx-workflows/dist/state.js +1275 -28
  263. package/clinkx-workflows/dist/state.js.map +1 -1
  264. package/clinkx-workflows/dist/transport.d.ts +15 -0
  265. package/clinkx-workflows/dist/transport.js +19 -10
  266. package/clinkx-workflows/dist/transport.js.map +1 -1
  267. package/clinkx-workflows/dist/types.d.ts +14 -2
  268. package/clinkx-workflows/dist/validators/council.d.ts +318 -85
  269. package/clinkx-workflows/dist/validators/council.js +52 -13
  270. package/clinkx-workflows/dist/validators/council.js.map +1 -1
  271. package/clinkx-workflows/dist/validators/index.d.ts +1 -0
  272. package/clinkx-workflows/dist/validators/index.js +3 -0
  273. package/clinkx-workflows/dist/validators/index.js.map +1 -1
  274. package/clinkx-workflows/dist/validators/plan-review.d.ts +398 -0
  275. package/clinkx-workflows/dist/validators/plan-review.js +316 -0
  276. package/clinkx-workflows/dist/validators/plan-review.js.map +1 -0
  277. package/clinkx-workflows/dist/workflow-receipt.js +188 -4
  278. package/clinkx-workflows/dist/workflow-receipt.js.map +1 -1
  279. package/clinkx-workflows/dist/workflow-tools.d.ts +48 -3
  280. package/clinkx-workflows/dist/workflow-tools.js +1402 -59
  281. package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
  282. package/clinkx-workflows/dist/workspace-signature.d.ts +16 -0
  283. package/clinkx-workflows/dist/workspace-signature.js +388 -0
  284. package/clinkx-workflows/dist/workspace-signature.js.map +1 -0
  285. package/clinkx-workflows/templates/council/answer-specialist.txt +2 -1
  286. package/clinkx-workflows/templates/council/code-review-chairman.txt +13 -0
  287. package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +4 -1
  288. package/clinkx-workflows/templates/council/code-review-reviewer.txt +19 -3
  289. package/clinkx-workflows/templates/council/debug-debugger.txt +2 -1
  290. package/clinkx-workflows/templates/council/discover-analyst.txt +2 -1
  291. package/clinkx-workflows/templates/council/member.txt +2 -1
  292. package/clinkx-workflows/templates/council/plan-review-chairman.txt +68 -0
  293. package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +51 -0
  294. package/clinkx-workflows/templates/council/plan-review-reviewer.txt +60 -0
  295. package/clinkx-workflows/templates/plan-review/chairman.txt +48 -0
  296. package/clinkx-workflows/templates/plan-review/cross-review.txt +52 -0
  297. package/clinkx-workflows/templates/plan-review/ranking.txt +16 -0
  298. package/clinkx-workflows/templates/plan-review/reviewer.txt +57 -0
  299. package/clinkx-workflows/workflows/council-answer.yaml +97 -8
  300. package/clinkx-workflows/workflows/council-code-review.yaml +103 -8
  301. package/clinkx-workflows/workflows/council-debug.yaml +97 -8
  302. package/clinkx-workflows/workflows/council-default.yaml +97 -8
  303. package/clinkx-workflows/workflows/council-discover.yaml +97 -8
  304. package/clinkx-workflows/workflows/council-plan-review.yaml +250 -0
  305. package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
  306. package/conf/adapters/agy.json +49 -0
  307. package/conf/adapters/claude.json +5 -0
  308. package/conf/adapters/codex-app-server.json +44 -0
  309. package/conf/adapters/codex.json +7 -2
  310. package/conf/adapters/glm.json +5 -0
  311. package/conf/adapters/grok.json +60 -0
  312. package/conf/adapters/hapi/agy.json +52 -0
  313. package/conf/adapters/hapi/claude.json +5 -0
  314. package/conf/adapters/hapi/codex.json +7 -2
  315. package/conf/adapters/hapi/glm.json +5 -0
  316. package/dist/activity-journal.d.ts +42 -0
  317. package/dist/activity-journal.js +381 -0
  318. package/dist/activity-journal.js.map +1 -0
  319. package/dist/allowed-roots.d.ts +41 -0
  320. package/dist/allowed-roots.js +125 -3
  321. package/dist/allowed-roots.js.map +1 -1
  322. package/dist/codex/activity-session-log.d.ts +14 -0
  323. package/dist/codex/activity-session-log.js +206 -0
  324. package/dist/codex/activity-session-log.js.map +1 -0
  325. package/dist/codex/agent-tools.d.ts +23 -0
  326. package/dist/codex/agent-tools.js +1270 -0
  327. package/dist/codex/agent-tools.js.map +1 -0
  328. package/dist/codex/app-server-client.d.ts +76 -0
  329. package/dist/codex/app-server-client.js +582 -0
  330. package/dist/codex/app-server-client.js.map +1 -0
  331. package/dist/codex/app-server-registry.d.ts +389 -0
  332. package/dist/codex/app-server-registry.js +1407 -0
  333. package/dist/codex/app-server-registry.js.map +1 -0
  334. package/dist/codex/client-types.d.ts +109 -0
  335. package/dist/codex/client-types.js +2 -0
  336. package/dist/codex/client-types.js.map +1 -0
  337. package/dist/codex/protocol.d.ts +5375 -0
  338. package/dist/codex/protocol.js +614 -0
  339. package/dist/codex/protocol.js.map +1 -0
  340. package/dist/codex/session.d.ts +263 -0
  341. package/dist/codex/session.js +466 -0
  342. package/dist/codex/session.js.map +1 -0
  343. package/dist/config.d.ts +185 -19
  344. package/dist/config.js +82 -16
  345. package/dist/config.js.map +1 -1
  346. package/dist/context-builder/anchors.d.ts +1 -0
  347. package/dist/context-builder/anchors.js +3 -0
  348. package/dist/context-builder/anchors.js.map +1 -1
  349. package/dist/context-builder/bundle.d.ts +35 -2
  350. package/dist/context-builder/bundle.js +342 -2417
  351. package/dist/context-builder/bundle.js.map +1 -1
  352. package/dist/context-builder/codemap.d.ts +5 -0
  353. package/dist/context-builder/codemap.js +387 -13
  354. package/dist/context-builder/codemap.js.map +1 -1
  355. package/dist/context-builder/config.d.ts +1 -0
  356. package/dist/context-builder/config.js +12 -0
  357. package/dist/context-builder/config.js.map +1 -1
  358. package/dist/context-builder/context-run-catalog.d.ts +17 -0
  359. package/dist/context-builder/context-run-catalog.js +99 -0
  360. package/dist/context-builder/context-run-catalog.js.map +1 -0
  361. package/dist/context-builder/delegate-packet.d.ts +37 -0
  362. package/dist/context-builder/delegate-packet.js +359 -67
  363. package/dist/context-builder/delegate-packet.js.map +1 -1
  364. package/dist/context-builder/delegate-validation.d.ts +10 -1
  365. package/dist/context-builder/delegate-validation.js +153 -41
  366. package/dist/context-builder/delegate-validation.js.map +1 -1
  367. package/dist/context-builder/delegate.d.ts +2 -0
  368. package/dist/context-builder/delegate.js +1 -0
  369. package/dist/context-builder/delegate.js.map +1 -1
  370. package/dist/context-builder/diagnostics.d.ts +11 -2
  371. package/dist/context-builder/diagnostics.js +39 -6
  372. package/dist/context-builder/diagnostics.js.map +1 -1
  373. package/dist/context-builder/discovery.d.ts +29 -1
  374. package/dist/context-builder/discovery.js +475 -175
  375. package/dist/context-builder/discovery.js.map +1 -1
  376. package/dist/context-builder/globs.js +10 -10
  377. package/dist/context-builder/globs.js.map +1 -1
  378. package/dist/context-builder/handler.d.ts +26 -2
  379. package/dist/context-builder/handler.js +1158 -2416
  380. package/dist/context-builder/handler.js.map +1 -1
  381. package/dist/context-builder/lifecycle-contract.d.ts +424 -0
  382. package/dist/context-builder/lifecycle-contract.js +523 -0
  383. package/dist/context-builder/lifecycle-contract.js.map +1 -0
  384. package/dist/context-builder/lifecycle-journal.d.ts +62 -0
  385. package/dist/context-builder/lifecycle-journal.js +88 -0
  386. package/dist/context-builder/lifecycle-journal.js.map +1 -0
  387. package/dist/context-builder/lifecycle-observer.d.ts +102 -0
  388. package/dist/context-builder/lifecycle-observer.js +258 -0
  389. package/dist/context-builder/lifecycle-observer.js.map +1 -0
  390. package/dist/context-builder/lifecycle-reconcile.d.ts +32 -0
  391. package/dist/context-builder/lifecycle-reconcile.js +191 -0
  392. package/dist/context-builder/lifecycle-reconcile.js.map +1 -0
  393. package/dist/context-builder/lifecycle-recovery.d.ts +2 -0
  394. package/dist/context-builder/lifecycle-recovery.js +14 -0
  395. package/dist/context-builder/lifecycle-recovery.js.map +1 -0
  396. package/dist/context-builder/path-signals.js +9 -5
  397. package/dist/context-builder/path-signals.js.map +1 -1
  398. package/dist/context-builder/progress.d.ts +3 -1
  399. package/dist/context-builder/progress.js +23 -0
  400. package/dist/context-builder/progress.js.map +1 -1
  401. package/dist/context-builder/receipt.d.ts +6 -4
  402. package/dist/context-builder/receipt.js +12 -1
  403. package/dist/context-builder/receipt.js.map +1 -1
  404. package/dist/context-builder/refine-handler.d.ts +14 -0
  405. package/dist/context-builder/refine-handler.js +790 -0
  406. package/dist/context-builder/refine-handler.js.map +1 -0
  407. package/dist/context-builder/review-coverage.d.ts +84 -0
  408. package/dist/context-builder/review-coverage.js +437 -0
  409. package/dist/context-builder/review-coverage.js.map +1 -0
  410. package/dist/context-builder/schema.d.ts +239 -1
  411. package/dist/context-builder/schema.js +112 -6
  412. package/dist/context-builder/schema.js.map +1 -1
  413. package/dist/context-builder/secrets.d.ts +28 -0
  414. package/dist/context-builder/secrets.js +1473 -44
  415. package/dist/context-builder/secrets.js.map +1 -1
  416. package/dist/context-builder/selection.d.ts +7 -3
  417. package/dist/context-builder/selection.js +200 -738
  418. package/dist/context-builder/selection.js.map +1 -1
  419. package/dist/context-builder/session-log-identity.d.ts +1 -0
  420. package/dist/context-builder/session-log-identity.js +66 -0
  421. package/dist/context-builder/session-log-identity.js.map +1 -0
  422. package/dist/context-builder/slice-range-math.d.ts +16 -0
  423. package/dist/context-builder/slice-range-math.js +137 -0
  424. package/dist/context-builder/slice-range-math.js.map +1 -0
  425. package/dist/context-builder/status.d.ts +22 -1
  426. package/dist/context-builder/status.js +59 -4
  427. package/dist/context-builder/status.js.map +1 -1
  428. package/dist/context-builder/storage.d.ts +35 -2
  429. package/dist/context-builder/storage.js +271 -14
  430. package/dist/context-builder/storage.js.map +1 -1
  431. package/dist/context-builder/token-estimate.d.ts +13 -2
  432. package/dist/context-builder/token-estimate.js +77 -4
  433. package/dist/context-builder/token-estimate.js.map +1 -1
  434. package/dist/context-builder/versions.d.ts +29 -0
  435. package/dist/context-builder/versions.js +30 -0
  436. package/dist/context-builder/versions.js.map +1 -0
  437. package/dist/context-builder/workflow-runner.d.ts +69 -0
  438. package/dist/context-builder/workflow-runner.js +1051 -0
  439. package/dist/context-builder/workflow-runner.js.map +1 -0
  440. package/dist/context-builder/write-watchdog.d.ts +14 -0
  441. package/dist/context-builder/write-watchdog.js +38 -0
  442. package/dist/context-builder/write-watchdog.js.map +1 -0
  443. package/dist/dashboard-adapter-catalog.d.ts +9 -0
  444. package/dist/dashboard-adapter-catalog.js +46 -0
  445. package/dist/dashboard-adapter-catalog.js.map +1 -0
  446. package/dist/dashboard-cli.d.ts +79 -0
  447. package/dist/dashboard-cli.js +585 -0
  448. package/dist/dashboard-cli.js.map +1 -0
  449. package/dist/dashboard-companion/client.d.ts +36 -0
  450. package/dist/dashboard-companion/client.js +210 -0
  451. package/dist/dashboard-companion/client.js.map +1 -0
  452. package/dist/dashboard-companion/config.d.ts +8 -0
  453. package/dist/dashboard-companion/config.js +52 -0
  454. package/dist/dashboard-companion/config.js.map +1 -0
  455. package/dist/dashboard-companion/http-proxy.d.ts +10 -0
  456. package/dist/dashboard-companion/http-proxy.js +234 -0
  457. package/dist/dashboard-companion/http-proxy.js.map +1 -0
  458. package/dist/dashboard-companion/protocol.d.ts +80 -0
  459. package/dist/dashboard-companion/protocol.js +455 -0
  460. package/dist/dashboard-companion/protocol.js.map +1 -0
  461. package/dist/dashboard-companion/standalone-assets.d.ts +12 -0
  462. package/dist/dashboard-companion/standalone-assets.js +72 -0
  463. package/dist/dashboard-companion/standalone-assets.js.map +1 -0
  464. package/dist/dashboard-companion/standalone-entry.d.ts +1 -0
  465. package/dist/dashboard-companion/standalone-entry.js +17 -0
  466. package/dist/dashboard-companion/standalone-entry.js.map +1 -0
  467. package/dist/dashboard-gateway/config.d.ts +9 -0
  468. package/dist/dashboard-gateway/config.js +44 -0
  469. package/dist/dashboard-gateway/config.js.map +1 -0
  470. package/dist/dashboard-gateway/index.d.ts +11 -0
  471. package/dist/dashboard-gateway/index.js +755 -0
  472. package/dist/dashboard-gateway/index.js.map +1 -0
  473. package/dist/dashboard-gateway/main.d.ts +1 -0
  474. package/dist/dashboard-gateway/main.js +25 -0
  475. package/dist/dashboard-gateway/main.js.map +1 -0
  476. package/dist/dashboard-pairing-token.d.ts +1 -0
  477. package/dist/dashboard-pairing-token.js +5 -0
  478. package/dist/dashboard-pairing-token.js.map +1 -0
  479. package/dist/elaris/client.d.ts +73 -0
  480. package/dist/elaris/client.js +825 -0
  481. package/dist/elaris/client.js.map +1 -0
  482. package/dist/elaris/config.d.ts +18 -0
  483. package/dist/elaris/config.js +75 -0
  484. package/dist/elaris/config.js.map +1 -0
  485. package/dist/elaris/errors.d.ts +41 -0
  486. package/dist/elaris/errors.js +205 -0
  487. package/dist/elaris/errors.js.map +1 -0
  488. package/dist/elaris/github-repo.d.ts +18 -0
  489. package/dist/elaris/github-repo.js +89 -0
  490. package/dist/elaris/github-repo.js.map +1 -0
  491. package/dist/elaris/index.d.ts +10 -0
  492. package/dist/elaris/index.js +11 -0
  493. package/dist/elaris/index.js.map +1 -0
  494. package/dist/elaris/redact.d.ts +89 -0
  495. package/dist/elaris/redact.js +423 -0
  496. package/dist/elaris/redact.js.map +1 -0
  497. package/dist/elaris/run-id.d.ts +5 -0
  498. package/dist/elaris/run-id.js +20 -0
  499. package/dist/elaris/run-id.js.map +1 -0
  500. package/dist/elaris/status.d.ts +45 -0
  501. package/dist/elaris/status.js +122 -0
  502. package/dist/elaris/status.js.map +1 -0
  503. package/dist/elaris/tool-schemas.d.ts +314 -0
  504. package/dist/elaris/tool-schemas.js +208 -0
  505. package/dist/elaris/tool-schemas.js.map +1 -0
  506. package/dist/elaris/tools.d.ts +73 -0
  507. package/dist/elaris/tools.js +1065 -0
  508. package/dist/elaris/tools.js.map +1 -0
  509. package/dist/elaris/types.d.ts +1541 -0
  510. package/dist/elaris/types.js +252 -0
  511. package/dist/elaris/types.js.map +1 -0
  512. package/dist/errors.d.ts +16 -0
  513. package/dist/errors.js +19 -0
  514. package/dist/errors.js.map +1 -1
  515. package/dist/handler.d.ts +4 -0
  516. package/dist/handler.js +10 -1
  517. package/dist/handler.js.map +1 -1
  518. package/dist/index.d.ts +2 -1
  519. package/dist/index.js +13 -3
  520. package/dist/index.js.map +1 -1
  521. package/dist/local-clink-backend.d.ts +3 -0
  522. package/dist/local-clink-backend.js +4 -0
  523. package/dist/local-clink-backend.js.map +1 -1
  524. package/dist/package-info.d.ts +2 -0
  525. package/dist/package-info.js +18 -0
  526. package/dist/package-info.js.map +1 -0
  527. package/dist/parsers/codex-jsonl.js +48 -3
  528. package/dist/parsers/codex-jsonl.js.map +1 -1
  529. package/dist/parsers/extract.d.ts +10 -1
  530. package/dist/parsers/extract.js +11 -3
  531. package/dist/parsers/extract.js.map +1 -1
  532. package/dist/pipeline.d.ts +4 -0
  533. package/dist/pipeline.js +129 -8
  534. package/dist/pipeline.js.map +1 -1
  535. package/dist/run-dir.d.ts +24 -0
  536. package/dist/run-dir.js +201 -2
  537. package/dist/run-dir.js.map +1 -1
  538. package/dist/runner.d.ts +13 -0
  539. package/dist/runner.js +184 -15
  540. package/dist/runner.js.map +1 -1
  541. package/dist/safety.d.ts +4 -4
  542. package/dist/safety.js +4 -4
  543. package/dist/schema.d.ts +7 -7
  544. package/dist/server.d.ts +1 -0
  545. package/dist/server.js +359 -17
  546. package/dist/server.js.map +1 -1
  547. package/dist/session-log-stream.d.ts +18 -0
  548. package/dist/session-log-stream.js +319 -0
  549. package/dist/session-log-stream.js.map +1 -0
  550. package/package.json +46 -5
  551. package/conf/adapters/gemini.json +0 -44
  552. package/conf/adapters/hapi/gemini.json +0 -47
  553. package/dist/parsers/gemini-json.d.ts +0 -2
  554. package/dist/parsers/gemini-json.js +0 -72
  555. package/dist/parsers/gemini-json.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { boundContextBuilderOmissions, isRequestedEvidenceOmission, requestedEvidenceOmission, } from "./diagnostics.js";
2
2
  import { normalizeContextBuilderRootRelativePath, } from "./paths.js";
3
- import { scanHighConfidenceSecretContent, scanSecretPath } from "./secrets.js";
3
+ import { orderEvidenceClasses, } from "./review-coverage.js";
4
+ import { hasConservativeResidualSecret, scanSecretPath } from "./secrets.js";
4
5
  import { estimateContextBuilderTokensFromUtf8Bytes } from "./token-estimate.js";
5
6
  export const CONTEXT_BUILDER_DELEGATE_PACKET_CAP_DEFAULTS = Object.freeze({
6
7
  max_candidates: 300,
@@ -62,8 +63,15 @@ export function contextBuilderRangeId(candidateId, startLine, endLine) {
62
63
  }
63
64
  function buildContextBuilderDelegatePacket(purpose, input) {
64
65
  const caps = normalizeCaps(input.caps, input.budget);
66
+ // Packet BUILD defaults allow-secrets ON to match the feature's global
67
+ // default (resolveAllowSecrets → true); the delegate VALIDATOR defaults
68
+ // fail-closed (?? false) as a conservative validation boundary. These never
69
+ // diverge on the live path — the handler always passes the resolved boolean
70
+ // to both. The asymmetry is intentional, not a missed seam.
71
+ const allowSecrets = input.allowSecrets ?? true;
65
72
  const state = {
66
73
  caps,
74
+ allowSecrets,
67
75
  evidenceBytes: 0,
68
76
  evidenceByteCapHit: false,
69
77
  searchIncluded: 0,
@@ -76,11 +84,13 @@ function buildContextBuilderDelegatePacket(purpose, input) {
76
84
  contextBuilderCandidateId(selected.root_index, selected.path),
77
85
  index,
78
86
  ]));
79
- const selectedRanges = buildSelectedRangeIndex(input.selection.selected);
80
- const evidence = buildCandidateEvidenceIndex(input);
81
- const seeds = buildCandidateSeeds(input, selectedIds, selectedRanks, evidence).filter(shouldIncludeDelegateCandidateSeed);
87
+ const selectedRanges = buildSelectedRangeIndex(input.selection.selected, allowSecrets);
88
+ const evidence = buildCandidateEvidenceIndex(input, allowSecrets);
89
+ const coveragePolicy = normalizeCoveragePolicy(input.coveragePolicy, input.discovery.review_obligations, caps);
90
+ const seeds = orderCandidateSeedsForCoverage(buildCandidateSeeds(input, selectedIds, selectedRanks, evidence).filter(shouldIncludeDelegateCandidateSeed), coveragePolicy);
82
91
  const requestedCoverage = buildRequestedPacketCoverage(input, selectedRanges);
83
92
  const requestedCoverageIndex = buildRequestedCoverageIndex(requestedCoverage);
93
+ const protection = buildPacketProtectionIndex(input, allowSecrets);
84
94
  const candidates = seeds
85
95
  .map((seed) => buildPacketCandidate(seed, input, selectedRanges, requestedCoverageIndex, state))
86
96
  .filter((candidate) => candidate.ranges.length > 0)
@@ -88,11 +98,11 @@ function buildContextBuilderDelegatePacket(purpose, input) {
88
98
  const candidatesOmittedByCountCap = Math.max(0, seeds.length - candidates.length);
89
99
  const candidateLineCounts = new Map(candidates.map((candidate) => [candidate.id, candidate.line_count]));
90
100
  const candidateIds = new Set(candidateLineCounts.keys());
91
- const deterministicSelection = buildDeterministicSelection(input.selection.selected, candidateIds);
101
+ const deterministicSelection = buildDeterministicSelection(input.selection.selected, candidateIds, allowSecrets);
92
102
  const packet = {
93
103
  version: "context-builder.delegate-packet.v1",
94
104
  purpose,
95
- task: sanitizePacketText(input.task, caps.max_task_chars).text,
105
+ task: sanitizePacketText(input.task, caps.max_task_chars, allowSecrets).text,
96
106
  rules: {
97
107
  local_candidate_universe_only: true,
98
108
  provider_must_not_discover_paths: true,
@@ -101,12 +111,13 @@ function buildContextBuilderDelegatePacket(purpose, input) {
101
111
  raw_full_content_included: false,
102
112
  },
103
113
  budget: input.budget,
114
+ coverage_policy: coveragePolicy,
104
115
  candidates,
105
116
  deterministic_selection: {
106
117
  metrics: input.selection.metrics,
107
118
  selected: deterministicSelection,
108
119
  },
109
- omissions: buildPacketOmissions(input.discovery.omissions, input.selection.omissions, caps),
120
+ omissions: buildPacketOmissions(input.discovery.omissions, input.selection.omissions, caps, allowSecrets),
110
121
  metrics: {
111
122
  discovery: input.discovery.metrics,
112
123
  selection: input.selection.metrics,
@@ -120,10 +131,22 @@ function buildContextBuilderDelegatePacket(purpose, input) {
120
131
  evidence_byte_cap_hit: state.evidenceByteCapHit,
121
132
  packet_estimated_tokens: 0,
122
133
  packet_token_cap_hit: false,
134
+ compaction: {
135
+ candidates_before_compaction: candidates.length,
136
+ candidates_after_compaction: candidates.length,
137
+ candidates_evicted_by_compaction: 0,
138
+ evidence_bytes_before_compaction: 0,
139
+ evidence_bytes_after_compaction: 0,
140
+ search_records_before_compaction: 0,
141
+ search_records_after_compaction: 0,
142
+ slice_records_before_compaction: 0,
143
+ slice_records_after_compaction: 0,
144
+ all_non_focus_candidates_evidence_free: false,
145
+ },
123
146
  },
124
147
  ...(purpose === "finalizer" && "curator_proposal" in input
125
148
  ? {
126
- curator_proposal: sanitizeCuratorProposal(input.curator_proposal, candidateLineCounts, caps),
149
+ curator_proposal: sanitizeCuratorProposal(input.curator_proposal, candidateLineCounts, caps, allowSecrets),
127
150
  local_selection_summary: {
128
151
  selected: deterministicSelection,
129
152
  },
@@ -131,16 +154,17 @@ function buildContextBuilderDelegatePacket(purpose, input) {
131
154
  : {}),
132
155
  };
133
156
  syncSelectionSummariesToCandidateRanges(packet);
134
- enforcePacketTokenCap(packet, caps, requestedCoverageIndex);
157
+ enforcePacketTokenCap(packet, caps, requestedCoverageIndex, protection);
135
158
  syncCandidateCoverageToPacketRanges(packet);
136
159
  syncSelectionSummariesToCandidateRanges(packet);
137
160
  appendMissingRequestedCoverageOmissions(packet, requestedCoverage);
138
161
  return packet;
139
162
  }
140
163
  function buildCandidateSeeds(input, selectedIds, selectedRanks, evidence) {
164
+ const allowSecrets = input.allowSecrets ?? true;
141
165
  const eligibleTree = new Map();
142
166
  for (const file of input.discovery.tree) {
143
- const normalized = normalizePacketPath(file.path);
167
+ const normalized = normalizePacketPath(file.path, allowSecrets);
144
168
  if (normalized == null ||
145
169
  !file.eligible ||
146
170
  !file.content_eligible ||
@@ -154,7 +178,7 @@ function buildCandidateSeeds(input, selectedIds, selectedRanks, evidence) {
154
178
  }
155
179
  const seeds = [];
156
180
  for (const candidate of input.discovery.content_candidates) {
157
- const normalized = normalizePacketPath(candidate.path);
181
+ const normalized = normalizePacketPath(candidate.path, allowSecrets);
158
182
  if (normalized == null) {
159
183
  continue;
160
184
  }
@@ -163,6 +187,7 @@ function buildCandidateSeeds(input, selectedIds, selectedRanks, evidence) {
163
187
  continue;
164
188
  }
165
189
  const id = contextBuilderCandidateId(candidate.root_index, normalized);
190
+ const classifiedCandidate = candidate;
166
191
  seeds.push({
167
192
  id,
168
193
  root_index: candidate.root_index,
@@ -175,6 +200,7 @@ function buildCandidateSeeds(input, selectedIds, selectedRanks, evidence) {
175
200
  has_focus_evidence: evidence.focusIds.has(id),
176
201
  has_slice_evidence: evidence.sliceIds.has(id),
177
202
  has_search_evidence: evidence.searchIds.has(id),
203
+ evidence_classes: orderEvidenceClasses(classifiedCandidate.evidence_classes ?? []),
178
204
  });
179
205
  }
180
206
  return seeds.sort(compareCandidateSeeds);
@@ -188,12 +214,12 @@ function shouldIncludeDelegateCandidateSeed(seed) {
188
214
  function isWorkbenchArtifactPath(path) {
189
215
  return path.startsWith(".ai/") || path.includes("/.ai/");
190
216
  }
191
- function buildCandidateEvidenceIndex(input) {
217
+ function buildCandidateEvidenceIndex(input, allowSecrets) {
192
218
  const focusIds = new Set(input.discovery.slices
193
219
  .filter((slice) => slice.source === "focus")
194
220
  .map((slice) => contextBuilderCandidateId(slice.root_index, slice.path)));
195
221
  for (const candidate of input.discovery.content_candidates) {
196
- const normalized = normalizePacketPath(candidate.path);
222
+ const normalized = normalizePacketPath(candidate.path, allowSecrets);
197
223
  if (normalized != null &&
198
224
  candidateMatchesFocusPath(candidate.root_index, normalized, input.focus_paths ?? [])) {
199
225
  focusIds.add(contextBuilderCandidateId(candidate.root_index, normalized));
@@ -232,6 +258,7 @@ function buildPacketCandidate(seed, input, selectedRanges, requestedCoverage, st
232
258
  size_bytes: seed.size_bytes,
233
259
  estimated_tokens: seed.estimated_tokens,
234
260
  discovery_reason: discoveryReason(ranges, searchHits),
261
+ evidence_classes: [...seed.evidence_classes],
235
262
  focus_requested: seed.has_focus_evidence,
236
263
  ...(requiredFocusRanges.length === 0
237
264
  ? {}
@@ -244,10 +271,10 @@ function buildPacketCandidate(seed, input, selectedRanges, requestedCoverage, st
244
271
  search_hits: searchHits,
245
272
  };
246
273
  }
247
- function buildSelectedRangeIndex(selected) {
274
+ function buildSelectedRangeIndex(selected, allowSecrets) {
248
275
  const byCandidate = new Map();
249
276
  for (const file of selected) {
250
- const normalized = normalizePacketPath(file.path);
277
+ const normalized = normalizePacketPath(file.path, allowSecrets);
251
278
  if (normalized == null) {
252
279
  continue;
253
280
  }
@@ -279,14 +306,14 @@ function buildRequestedPacketCoverage(input, selectedRanges) {
279
306
  };
280
307
  for (const [candidateId, ranges] of selectedRanges) {
281
308
  const selection = input.selection.selected.find((file) => {
282
- const normalized = normalizePacketPath(file.path);
309
+ const normalized = normalizePacketPath(file.path, input.allowSecrets ?? true);
283
310
  return (normalized != null &&
284
311
  contextBuilderCandidateId(file.root_index, normalized) === candidateId);
285
312
  });
286
313
  if (selection == null) {
287
314
  continue;
288
315
  }
289
- const normalized = normalizePacketPath(selection.path);
316
+ const normalized = normalizePacketPath(selection.path, input.allowSecrets ?? true);
290
317
  if (normalized == null) {
291
318
  continue;
292
319
  }
@@ -298,7 +325,7 @@ function buildRequestedPacketCoverage(input, selectedRanges) {
298
325
  }
299
326
  }
300
327
  for (const slice of input.discovery.slices) {
301
- const normalized = normalizePacketPath(slice.path);
328
+ const normalized = normalizePacketPath(slice.path, input.allowSecrets ?? true);
302
329
  if (normalized == null) {
303
330
  continue;
304
331
  }
@@ -314,6 +341,24 @@ function buildRequestedPacketCoverage(input, selectedRanges) {
314
341
  end_line: slice.end_line,
315
342
  });
316
343
  }
344
+ for (const target of input.discovery.review_obligations?.targets ?? []) {
345
+ for (const range of target.ranges) {
346
+ appendRange(target.root_index, target.path, {
347
+ id: contextBuilderRangeId(target.candidate_id, range.start_line, range.end_line),
348
+ start_line: range.start_line,
349
+ end_line: range.end_line,
350
+ });
351
+ }
352
+ for (const link of target.regression_links) {
353
+ for (const range of link.ranges) {
354
+ appendRange(link.root_index, link.path, {
355
+ id: contextBuilderRangeId(link.candidate_id, range.start_line, range.end_line),
356
+ start_line: range.start_line,
357
+ end_line: range.end_line,
358
+ });
359
+ }
360
+ }
361
+ }
317
362
  return [...requestedByCandidate.values()].map((coverage) => ({
318
363
  ...coverage,
319
364
  ranges: coverage.ranges.sort((left, right) => left.start_line - right.start_line || left.end_line - right.end_line),
@@ -397,10 +442,10 @@ function buildSearchHits(seed, search, state) {
397
442
  }
398
443
  return hits;
399
444
  }
400
- function buildDeterministicSelection(selected, candidateIds) {
445
+ function buildDeterministicSelection(selected, candidateIds, allowSecrets) {
401
446
  return selected
402
447
  .map((file) => {
403
- const normalized = normalizePacketPath(file.path);
448
+ const normalized = normalizePacketPath(file.path, allowSecrets);
404
449
  if (normalized == null) {
405
450
  return undefined;
406
451
  }
@@ -424,7 +469,7 @@ function buildDeterministicSelection(selected, candidateIds) {
424
469
  })
425
470
  .filter((item) => item != null);
426
471
  }
427
- function sanitizeCuratorProposal(proposal, candidateLineCounts, caps) {
472
+ function sanitizeCuratorProposal(proposal, candidateLineCounts, caps, allowSecrets) {
428
473
  const maxSelected = Math.min(caps.max_candidates, MAX_CURATOR_PROPOSAL_SELECTED);
429
474
  const maxRangesPerSelection = Math.min(caps.max_paths_per_omission, MAX_CURATOR_PROPOSAL_RANGES_PER_SELECTION);
430
475
  const maxWarnings = Math.min(caps.max_omissions, MAX_CURATOR_PROPOSAL_WARNINGS);
@@ -444,9 +489,9 @@ function sanitizeCuratorProposal(proposal, candidateLineCounts, caps) {
444
489
  .map((range) => ({
445
490
  start_line: range.start_line,
446
491
  end_line: range.end_line,
447
- reason: sanitizePacketText(range.reason, caps.max_preview_bytes).text,
492
+ reason: sanitizePacketText(range.reason, caps.max_preview_bytes, allowSecrets).text,
448
493
  })),
449
- reason: sanitizePacketText(selection.reason, caps.max_preview_bytes).text,
494
+ reason: sanitizePacketText(selection.reason, caps.max_preview_bytes, allowSecrets).text,
450
495
  };
451
496
  })
452
497
  .filter((selection) => selection != null && selection.ranges.length > 0)
@@ -454,13 +499,13 @@ function sanitizeCuratorProposal(proposal, candidateLineCounts, caps) {
454
499
  .slice(0, maxSelected),
455
500
  warnings: proposal.warnings
456
501
  .slice(0, maxWarnings)
457
- .map((warning) => sanitizePacketText(warning, caps.max_preview_bytes).text),
502
+ .map((warning) => sanitizePacketText(warning, caps.max_preview_bytes, allowSecrets).text),
458
503
  open_questions: proposal.open_questions
459
504
  .slice(0, maxOpenQuestions)
460
- .map((question) => sanitizePacketText(question, caps.max_preview_bytes).text),
505
+ .map((question) => sanitizePacketText(question, caps.max_preview_bytes, allowSecrets).text),
461
506
  };
462
507
  }
463
- function buildPacketOmissions(discoveryOmissions, selectionOmissions, caps) {
508
+ function buildPacketOmissions(discoveryOmissions, selectionOmissions, caps, allowSecrets) {
464
509
  return boundContextBuilderOmissions([...discoveryOmissions, ...selectionOmissions].map((omission) => ({
465
510
  ...(omission.root_index == null ? {} : { root_index: omission.root_index }),
466
511
  reason: omission.reason,
@@ -469,7 +514,7 @@ function buildPacketOmissions(discoveryOmissions, selectionOmissions, caps) {
469
514
  ? {}
470
515
  : {
471
516
  paths: omission.paths
472
- .map(normalizePacketPath)
517
+ .map((path) => normalizePacketPath(path, allowSecrets))
473
518
  .filter((item) => item != null),
474
519
  }),
475
520
  })), {
@@ -477,48 +522,193 @@ function buildPacketOmissions(discoveryOmissions, selectionOmissions, caps) {
477
522
  max_paths_per_omission: caps.max_paths_per_omission,
478
523
  });
479
524
  }
480
- function enforcePacketTokenCap(packet, caps, requestedCoverage) {
525
+ function enforcePacketTokenCap(packet, caps, requestedCoverage, protection) {
481
526
  const maxTokens = Math.max(1, caps.max_packet_estimated_tokens);
527
+ const before = countPacketEvidence(packet);
528
+ const compaction = packet.metrics.compaction;
529
+ compaction.candidates_before_compaction = packet.candidates.length;
530
+ compaction.evidence_bytes_before_compaction = before.evidenceBytes;
531
+ compaction.search_records_before_compaction = before.searchRecords;
532
+ compaction.slice_records_before_compaction = before.sliceRecords;
533
+ refreshPacketCompactionState(packet);
482
534
  packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
483
535
  while (packet.metrics.packet_estimated_tokens > maxTokens ||
484
536
  estimatePacketJsonBytes(packet) > MAX_DELEGATE_PACKET_JSON_BYTES) {
485
- if (dropOneEvidence(packet)) {
486
- packet.metrics.packet_token_cap_hit = true;
487
- packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
488
- continue;
537
+ // Reduction ladder: evict low-value candidates before touching evidence,
538
+ // preserve one discriminative evidence item on protected candidates
539
+ // (focus, deterministic-baseline, exact-caller-hit) for as long as they
540
+ // remain in the packet, and only fall back to unrestricted stripping when
541
+ // nothing else can shrink the packet — caps stay hard.
542
+ const reduced = evictOneCompactionCandidate(packet, requestedCoverage, protection, "no_evidence") ||
543
+ evictOneCompactionCandidate(packet, requestedCoverage, protection, "unprotected") ||
544
+ dropOneCuratorProposalMetadata(packet) ||
545
+ dropOneEvidence(packet, protection) ||
546
+ dropOneCandidateRecord(packet, requestedCoverage, protection) ||
547
+ dropOneCandidate(packet, requestedCoverage) ||
548
+ dropOneEvidence(packet, null) ||
549
+ dropOneCandidateRecord(packet, requestedCoverage, null);
550
+ packet.metrics.packet_token_cap_hit = true;
551
+ refreshPacketCompactionState(packet);
552
+ packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
553
+ if (!reduced) {
554
+ return;
555
+ }
556
+ }
557
+ }
558
+ function countPacketEvidence(packet) {
559
+ let evidenceBytes = 0;
560
+ let searchRecords = 0;
561
+ let sliceRecords = 0;
562
+ for (const candidate of packet.candidates) {
563
+ sliceRecords += candidate.ranges.length;
564
+ searchRecords += candidate.search_hits.length;
565
+ for (const range of candidate.ranges) {
566
+ evidenceBytes += Buffer.byteLength(range.excerpt, "utf8");
567
+ }
568
+ for (const hit of candidate.search_hits) {
569
+ evidenceBytes += Buffer.byteLength(hit.preview, "utf8");
570
+ }
571
+ }
572
+ return { evidenceBytes, searchRecords, sliceRecords };
573
+ }
574
+ function refreshPacketCompactionState(packet) {
575
+ const counts = countPacketEvidence(packet);
576
+ const compaction = packet.metrics.compaction;
577
+ compaction.candidates_after_compaction = packet.candidates.length;
578
+ compaction.candidates_evicted_by_compaction = Math.max(0, compaction.candidates_before_compaction - packet.candidates.length);
579
+ compaction.evidence_bytes_after_compaction = counts.evidenceBytes;
580
+ compaction.search_records_after_compaction = counts.searchRecords;
581
+ compaction.slice_records_after_compaction = counts.sliceRecords;
582
+ const nonFocusCandidates = packet.candidates.filter((candidate) => candidate.focus_requested !== true);
583
+ const evidenceFree = nonFocusCandidates.length > 0 &&
584
+ nonFocusCandidates.every((candidate) => !candidateHasEvidence(candidate));
585
+ compaction.all_non_focus_candidates_evidence_free = evidenceFree;
586
+ if (evidenceFree) {
587
+ packet.evidence_warning = {
588
+ code: "all_non_focus_candidates_evidence_free",
589
+ message: "packet compaction left every non-focus candidate without a search-hit preview or slice excerpt; non-focus candidates carry path metadata only",
590
+ non_focus_candidate_count: nonFocusCandidates.length,
591
+ };
592
+ }
593
+ else {
594
+ delete packet.evidence_warning;
595
+ }
596
+ }
597
+ function buildPacketProtectionIndex(input, allowSecrets) {
598
+ const callerTerms = new Set((input.caller_search_terms ?? [])
599
+ .map((term) => term.trim())
600
+ .filter((term) => term.length > 0));
601
+ const callerHitIds = new Set();
602
+ const callerTermIndexes = new Set();
603
+ if (callerTerms.size > 0) {
604
+ for (const record of input.discovery.search) {
605
+ if (!callerTerms.has(record.search_term.trim())) {
606
+ continue;
607
+ }
608
+ callerTermIndexes.add(record.search_term_index);
609
+ const normalized = normalizePacketPath(record.path, allowSecrets);
610
+ if (normalized != null) {
611
+ callerHitIds.add(contextBuilderCandidateId(record.root_index, normalized));
612
+ }
489
613
  }
490
- if (dropOneCuratorProposalMetadata(packet)) {
491
- packet.metrics.packet_token_cap_hit = true;
492
- packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
614
+ }
615
+ return { callerHitIds, callerTermIndexes };
616
+ }
617
+ function isProtectedPacketCandidate(candidate, protection) {
618
+ return (candidate.focus_requested === true ||
619
+ candidate.deterministic_selected ||
620
+ protection.callerHitIds.has(candidate.id));
621
+ }
622
+ function candidateHasEvidence(candidate) {
623
+ return (candidate.ranges.some((range) => range.excerpt.length > 0) ||
624
+ candidate.search_hits.some((hit) => hit.preview.length > 0));
625
+ }
626
+ function reservedEvidenceFor(candidate, protection) {
627
+ if (!isProtectedPacketCandidate(candidate, protection)) {
628
+ return null;
629
+ }
630
+ if (protection.callerHitIds.has(candidate.id)) {
631
+ const callerHitIndex = candidate.search_hits.findIndex((hit) => hit.preview.length > 0 &&
632
+ protection.callerTermIndexes.has(hit.search_term_index));
633
+ if (callerHitIndex >= 0) {
634
+ return { kind: "hit", index: callerHitIndex };
635
+ }
636
+ }
637
+ const rangeIndex = candidate.ranges.findIndex((range) => range.excerpt.length > 0);
638
+ if (rangeIndex >= 0) {
639
+ return { kind: "range", index: rangeIndex };
640
+ }
641
+ const hitIndex = candidate.search_hits.findIndex((hit) => hit.preview.length > 0);
642
+ if (hitIndex >= 0) {
643
+ return { kind: "hit", index: hitIndex };
644
+ }
645
+ return null;
646
+ }
647
+ function evictOneCompactionCandidate(packet, requestedCoverage, protection, mode) {
648
+ if (packet.candidates.length <= 1) {
649
+ return false;
650
+ }
651
+ for (let index = packet.candidates.length - 1; index >= 0; index -= 1) {
652
+ const candidate = packet.candidates[index];
653
+ if (candidate == null || isProtectedPacketCandidate(candidate, protection)) {
493
654
  continue;
494
655
  }
495
- if (dropOneCandidateRecord(packet, requestedCoverage)) {
496
- packet.metrics.packet_token_cap_hit = true;
497
- packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
656
+ if (mode === "no_evidence" && candidateHasEvidence(candidate)) {
498
657
  continue;
499
658
  }
500
- if (dropOneCandidate(packet, requestedCoverage)) {
501
- packet.metrics.packet_token_cap_hit = true;
502
- packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
659
+ if (requestedCoverage.has(candidate.id) ||
660
+ wouldRemoveCuratorProposalSelection(packet, candidate.id) ||
661
+ wouldRemoveRequiredEvidenceClass(packet, candidate)) {
503
662
  continue;
504
663
  }
505
- packet.metrics.packet_token_cap_hit = true;
506
- packet.metrics.packet_estimated_tokens = estimatePacketTokens(packet);
664
+ evictPacketCandidateAt(packet, index);
665
+ return true;
666
+ }
667
+ return false;
668
+ }
669
+ function evictPacketCandidateAt(packet, index) {
670
+ const candidate = packet.candidates[index];
671
+ if (candidate == null) {
507
672
  return;
508
673
  }
674
+ packet.candidates.splice(index, 1);
675
+ packet.metrics.candidates_included = packet.candidates.length;
676
+ packet.metrics.candidates_omitted_by_packet_cap += 1;
677
+ for (const range of candidate.ranges) {
678
+ packet.metrics.evidence_bytes -= Buffer.byteLength(range.excerpt, "utf8");
679
+ }
680
+ for (const hit of candidate.search_hits) {
681
+ packet.metrics.evidence_bytes -= Buffer.byteLength(hit.preview, "utf8");
682
+ }
683
+ packet.metrics.search_records_omitted_by_packet_cap += candidate.search_hits.length;
684
+ packet.metrics.slice_records_omitted_by_packet_cap += candidate.ranges.length;
685
+ pruneReferencesToCandidate(packet, candidate.id);
509
686
  }
510
- function dropOneEvidence(packet) {
687
+ function dropOneEvidence(packet, protection) {
511
688
  for (const candidate of [...packet.candidates].reverse()) {
512
- const range = candidate.ranges.at(-1);
513
- if (range != null && range.excerpt.length > 0) {
689
+ const reserved = protection == null ? null : reservedEvidenceFor(candidate, protection);
690
+ for (let index = candidate.ranges.length - 1; index >= 0; index -= 1) {
691
+ if (reserved?.kind === "range" && reserved.index === index) {
692
+ continue;
693
+ }
694
+ const range = candidate.ranges[index];
695
+ if (range == null || range.excerpt.length === 0) {
696
+ continue;
697
+ }
514
698
  packet.metrics.evidence_bytes -= Buffer.byteLength(range.excerpt, "utf8");
515
699
  range.excerpt = "";
516
700
  range.excerpt_truncated = true;
517
701
  packet.metrics.evidence_byte_cap_hit = true;
518
702
  return true;
519
703
  }
520
- const hit = candidate.search_hits.at(-1);
521
- if (hit != null && hit.preview.length > 0) {
704
+ for (let index = candidate.search_hits.length - 1; index >= 0; index -= 1) {
705
+ if (reserved?.kind === "hit" && reserved.index === index) {
706
+ continue;
707
+ }
708
+ const hit = candidate.search_hits[index];
709
+ if (hit == null || hit.preview.length === 0) {
710
+ continue;
711
+ }
522
712
  packet.metrics.evidence_bytes -= Buffer.byteLength(hit.preview, "utf8");
523
713
  hit.preview = "";
524
714
  hit.preview_truncated = true;
@@ -553,22 +743,37 @@ function dropOneCuratorProposalMetadata(packet) {
553
743
  }
554
744
  return false;
555
745
  }
556
- function dropOneCandidateRecord(packet, requestedCoverage) {
746
+ function dropOneCandidateRecord(packet, requestedCoverage, protection) {
557
747
  for (const candidate of [...packet.candidates].reverse()) {
558
- const hit = candidate.search_hits.pop();
559
- if (hit != null) {
748
+ const reserved = protection == null ? null : reservedEvidenceFor(candidate, protection);
749
+ for (let index = candidate.search_hits.length - 1; index >= 0; index -= 1) {
750
+ if (reserved?.kind === "hit" && reserved.index === index) {
751
+ continue;
752
+ }
753
+ const hit = candidate.search_hits[index];
754
+ if (hit == null) {
755
+ continue;
756
+ }
757
+ candidate.search_hits.splice(index, 1);
560
758
  packet.metrics.evidence_bytes -= Buffer.byteLength(hit.preview, "utf8");
561
759
  packet.metrics.search_records_omitted_by_packet_cap += 1;
562
760
  return true;
563
761
  }
564
762
  if (candidate.ranges.length > 1) {
565
- const range = candidate.ranges.pop();
566
- if (range != null) {
567
- if (!curatorProposalStillCovered(packet, candidate.id, candidate.ranges) ||
568
- !requestedCoverageStillCovered(requestedCoverage, candidate.id, candidate.ranges)) {
569
- candidate.ranges.push(range);
763
+ for (let index = candidate.ranges.length - 1; index >= 0; index -= 1) {
764
+ if (reserved?.kind === "range" && reserved.index === index) {
765
+ continue;
766
+ }
767
+ const range = candidate.ranges[index];
768
+ if (range == null) {
769
+ continue;
770
+ }
771
+ const remaining = candidate.ranges.filter((_, rangeIndex) => rangeIndex !== index);
772
+ if (!curatorProposalStillCovered(packet, candidate.id, remaining) ||
773
+ !requestedCoverageStillCovered(requestedCoverage, candidate.id, remaining)) {
570
774
  continue;
571
775
  }
776
+ candidate.ranges.splice(index, 1);
572
777
  packet.metrics.evidence_bytes -= Buffer.byteLength(range.excerpt, "utf8");
573
778
  packet.metrics.slice_records_omitted_by_packet_cap += 1;
574
779
  pruneReferencesToRange(packet, candidate.id, range.id);
@@ -586,17 +791,21 @@ function dropOneCandidate(packet, requestedCoverage) {
586
791
  const candidate = packet.candidates[index];
587
792
  if (candidate == null ||
588
793
  requestedCoverage.has(candidate.id) ||
589
- wouldRemoveCuratorProposalSelection(packet, candidate.id)) {
794
+ wouldRemoveCuratorProposalSelection(packet, candidate.id) ||
795
+ wouldRemoveRequiredEvidenceClass(packet, candidate)) {
590
796
  continue;
591
797
  }
592
- packet.candidates.splice(index, 1);
593
- packet.metrics.candidates_included = packet.candidates.length;
594
- packet.metrics.candidates_omitted_by_packet_cap += 1;
595
- pruneReferencesToCandidate(packet, candidate.id);
798
+ evictPacketCandidateAt(packet, index);
596
799
  return true;
597
800
  }
598
801
  return false;
599
802
  }
803
+ function wouldRemoveRequiredEvidenceClass(packet, candidate) {
804
+ const required = new Set(packet.coverage_policy.required_when_available);
805
+ return candidate.evidence_classes.some((evidenceClass) => required.has(evidenceClass) &&
806
+ !packet.candidates.some((other) => other.id !== candidate.id &&
807
+ other.evidence_classes.includes(evidenceClass)));
808
+ }
600
809
  function buildRequestedCoverageIndex(requestedCoverage) {
601
810
  return new Map(requestedCoverage.map((coverage) => [coverage.candidate_id, coverage.ranges]));
602
811
  }
@@ -764,15 +973,15 @@ function takeEvidenceText(text, maxBytes, state) {
764
973
  return { text: "", truncated: true };
765
974
  }
766
975
  const remaining = state.caps.max_total_evidence_bytes - state.evidenceBytes;
767
- const bounded = sanitizePacketText(text, Math.min(maxBytes, remaining));
976
+ const bounded = sanitizePacketText(text, Math.min(maxBytes, remaining), state.allowSecrets);
768
977
  state.evidenceBytes += Buffer.byteLength(bounded.text, "utf8");
769
978
  if (bounded.truncated || state.evidenceBytes >= state.caps.max_total_evidence_bytes) {
770
979
  state.evidenceByteCapHit = true;
771
980
  }
772
981
  return bounded;
773
982
  }
774
- function sanitizePacketText(text, maxBytes) {
775
- const secretSafe = scanHighConfidenceSecretContent(text).length > 0
983
+ function sanitizePacketText(text, maxBytes, allowSecrets) {
984
+ const secretSafe = !allowSecrets && hasConservativeResidualSecret(text)
776
985
  ? "[redacted-sensitive]"
777
986
  : redactAbsolutePaths(text);
778
987
  return boundUtf8(secretSafe.replace(/\u0000/g, "?"), maxBytes);
@@ -791,7 +1000,7 @@ function boundUtf8(text, maxBytes) {
791
1000
  }
792
1001
  return { text: output, truncated: false };
793
1002
  }
794
- function normalizePacketPath(input) {
1003
+ function normalizePacketPath(input, allowSecrets) {
795
1004
  if (input.includes("\u0000") ||
796
1005
  input.startsWith("/") ||
797
1006
  input.startsWith("\\") ||
@@ -800,7 +1009,8 @@ function normalizePacketPath(input) {
800
1009
  }
801
1010
  try {
802
1011
  const normalized = normalizeContextBuilderRootRelativePath(input);
803
- if (normalized === "" || scanSecretPath(normalized).length > 0) {
1012
+ if (normalized === "" ||
1013
+ (!allowSecrets && scanSecretPath(normalized).length > 0)) {
804
1014
  return undefined;
805
1015
  }
806
1016
  return normalized;
@@ -828,6 +1038,66 @@ function normalizeCaps(caps, budget) {
828
1038
  max_packet_estimated_tokens: positiveInteger(merged.max_packet_estimated_tokens),
829
1039
  };
830
1040
  }
1041
+ function normalizeCoveragePolicy(policy, obligations, caps) {
1042
+ if (policy?.id !== "review_deep_v1") {
1043
+ return { policy_id: null, required_when_available: [] };
1044
+ }
1045
+ return {
1046
+ policy_id: policy.id,
1047
+ required_when_available: orderEvidenceClasses(policy.required_when_available),
1048
+ ...(obligations == null
1049
+ ? {}
1050
+ : {
1051
+ obligations: {
1052
+ targets: obligations.targets.slice(0, caps.max_candidates).map((target) => ({
1053
+ ...target,
1054
+ ranges: target.ranges.slice(0, caps.max_paths_per_omission),
1055
+ regression_links: target.regression_links
1056
+ .slice(0, caps.max_candidates)
1057
+ .map((link) => ({
1058
+ ...link,
1059
+ ranges: link.ranges.slice(0, caps.max_paths_per_omission),
1060
+ })),
1061
+ })),
1062
+ },
1063
+ }),
1064
+ };
1065
+ }
1066
+ function orderCandidateSeedsForCoverage(seeds, policy) {
1067
+ if (policy.policy_id === null || policy.required_when_available.length === 0) {
1068
+ return [...seeds];
1069
+ }
1070
+ const ordered = [];
1071
+ const included = new Set();
1072
+ for (const target of policy.obligations?.targets ?? []) {
1073
+ for (const candidateId of [
1074
+ target.candidate_id,
1075
+ ...target.regression_links.map((link) => link.candidate_id),
1076
+ ]) {
1077
+ const seed = seeds.find((candidate) => candidate.id === candidateId);
1078
+ if (seed != null && !included.has(seed.id)) {
1079
+ ordered.push(seed);
1080
+ included.add(seed.id);
1081
+ }
1082
+ }
1083
+ }
1084
+ for (const evidenceClass of policy.required_when_available) {
1085
+ if (ordered.some((seed) => seed.evidence_classes.includes(evidenceClass))) {
1086
+ continue;
1087
+ }
1088
+ const representative = seeds.find((seed) => seed.evidence_classes.includes(evidenceClass));
1089
+ if (representative != null && !included.has(representative.id)) {
1090
+ ordered.push(representative);
1091
+ included.add(representative.id);
1092
+ }
1093
+ }
1094
+ for (const seed of seeds) {
1095
+ if (!included.has(seed.id)) {
1096
+ ordered.push(seed);
1097
+ }
1098
+ }
1099
+ return ordered;
1100
+ }
831
1101
  function positiveInteger(value) {
832
1102
  return Number.isSafeInteger(value) && value > 0 ? value : 1;
833
1103
  }
@@ -858,7 +1128,29 @@ function estimatePacketJsonBytes(packet) {
858
1128
  function redactAbsolutePaths(text) {
859
1129
  return text
860
1130
  .replace(/\b[A-Za-z]:[\\/][^\s"'`)]+/g, "[redacted-absolute-path]")
861
- .replace(/(^|[\s"'(])\/[^\s"'`)]+/g, "$1[redacted-absolute-path]");
1131
+ .replace(/(^|[\s"'(])(\/[^\s"'`)]+)/g, (_match, boundary, token) => {
1132
+ // Compact comments and slash-led paths share the same token shape, so
1133
+ // classify the complete token instead of inferring intent via lookahead.
1134
+ if (token === "/*") {
1135
+ return `${boundary}${token}`;
1136
+ }
1137
+ if (token.startsWith("/*") && token[2] !== "/") {
1138
+ const closeIndex = token.indexOf("*/", 2);
1139
+ if (closeIndex >= 0) {
1140
+ const commentEnd = closeIndex + 2;
1141
+ const suffix = token.slice(commentEnd);
1142
+ return /^[\\/]/.test(suffix)
1143
+ ? `${boundary}${token.slice(0, commentEnd)}[redacted-absolute-path]`
1144
+ : `${boundary}${token}`;
1145
+ }
1146
+ }
1147
+ // A bare //host is indistinguishable from //comment; preserving it is
1148
+ // an accepted residual limitation needed for compact comment fidelity.
1149
+ if (/^\/\/[^/\\]*$/.test(token)) {
1150
+ return `${boundary}${token}`;
1151
+ }
1152
+ return `${boundary}[redacted-absolute-path]`;
1153
+ });
862
1154
  }
863
1155
  function compareCandidateSeeds(left, right) {
864
1156
  return (booleanRank(right.has_focus_evidence) - booleanRank(left.has_focus_evidence) ||