@sema-agent/core 7.47.0 → 7.49.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 (431) hide show
  1. package/CHANGELOG.md +472 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +39 -32
  51. package/dist/core/arg-summary.d.ts +17 -24
  52. package/dist/core/arg-summary.js +169 -68
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +95 -66
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +32 -7
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +4 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp-server-spec.d.ts +1 -1
  101. package/dist/core/mcp.d.ts +4 -0
  102. package/dist/core/mcp.js +70 -43
  103. package/dist/core/memory-engine/content-origin.js +2 -14
  104. package/dist/core/memory-engine/engine.d.ts +32 -22
  105. package/dist/core/memory-engine/engine.js +103 -55
  106. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  107. package/dist/core/memory-engine/file-backend.js +37 -252
  108. package/dist/core/memory-engine/index.d.ts +1 -1
  109. package/dist/core/memory-engine/index.js +1 -1
  110. package/dist/core/memory-engine/layout.d.ts +139 -9
  111. package/dist/core/memory-engine/layout.js +350 -7
  112. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  113. package/dist/core/memory-engine/scope-contract.js +8 -0
  114. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  115. package/dist/core/memory-engine/session-incarnation.js +5 -2
  116. package/dist/core/memory-engine/types.d.ts +10 -1
  117. package/dist/core/memory.js +5 -17
  118. package/dist/core/model-seat.d.ts +4 -4
  119. package/dist/core/model-seat.js +1 -1
  120. package/dist/core/mounted-mcp.d.ts +57 -0
  121. package/dist/core/mounted-mcp.js +19 -0
  122. package/dist/core/namespaced-rule-name.d.ts +29 -0
  123. package/dist/core/namespaced-rule-name.js +52 -0
  124. package/dist/core/park-selfcheck.d.ts +1 -1
  125. package/dist/core/park-selfcheck.js +16 -6
  126. package/dist/core/path-guard-rows.d.ts +99 -0
  127. package/dist/core/path-guard-rows.js +45 -0
  128. package/dist/core/path-identity.d.ts +22 -16
  129. package/dist/core/path-identity.js +10 -10
  130. package/dist/core/path-rule-binding.d.ts +2 -1
  131. package/dist/core/path-rule-binding.js +3 -1
  132. package/dist/core/pause-registry.d.ts +16 -2
  133. package/dist/core/pause-registry.js +6 -0
  134. package/dist/core/permission-rule-consent.js +0 -7
  135. package/dist/core/permission-rule-model.d.ts +68 -24
  136. package/dist/core/permission-rule-model.js +105 -24
  137. package/dist/core/permission-rule-store.js +2 -2
  138. package/dist/core/permission-rules.d.ts +3 -30
  139. package/dist/core/permission-rules.js +4 -54
  140. package/dist/core/read-root-candidate.d.ts +1 -3
  141. package/dist/core/read-root-candidate.js +4 -15
  142. package/dist/core/real-approval.d.ts +4 -3
  143. package/dist/core/retired-keys.d.ts +13 -0
  144. package/dist/core/retired-keys.js +14 -0
  145. package/dist/core/roles.d.ts +2 -3
  146. package/dist/core/roles.js +15 -6
  147. package/dist/core/runner/assemble-result.d.ts +0 -7
  148. package/dist/core/runner/assemble-result.js +19 -31
  149. package/dist/core/runner/caller-roster.d.ts +78 -0
  150. package/dist/core/runner/caller-roster.js +219 -0
  151. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  152. package/dist/core/runner/checkpoint-scope.js +2 -2
  153. package/dist/core/runner/child-tree.js +2 -2
  154. package/dist/core/runner/contracts.d.ts +68 -35
  155. package/dist/core/runner/decide-continuation.d.ts +51 -3
  156. package/dist/core/runner/decide-continuation.js +76 -21
  157. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  158. package/dist/core/runner/denial-limit-arms.js +11 -9
  159. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  160. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  161. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  162. package/dist/core/runner/finish-reason-seat.js +40 -0
  163. package/dist/core/runner/gate-exit.d.ts +44 -32
  164. package/dist/core/runner/gate-exit.js +112 -25
  165. package/dist/core/runner/inherited-ask-grants.js +6 -4
  166. package/dist/core/runner/mcp-redial.d.ts +3 -3
  167. package/dist/core/runner/mcp-redial.js +3 -4
  168. package/dist/core/runner/park-commit.d.ts +1 -1
  169. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  170. package/dist/core/runner/permission-rule-lanes.js +5 -4
  171. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  172. package/dist/core/runner/prepare-artifact.js +2 -1
  173. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  174. package/dist/core/runner/prepare-ask-lane.js +12 -6
  175. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  176. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  177. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  178. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  179. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  180. package/dist/core/runner/prepare-config-doors.js +10 -5
  181. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  182. package/dist/core/runner/prepare-defer-classify.js +5 -3
  183. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  184. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  185. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  186. package/dist/core/runner/prepare-gate-stations.js +9 -7
  187. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  188. package/dist/core/runner/prepare-hands-readface.js +7 -7
  189. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  190. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  191. package/dist/core/runner/prepare-listings.d.ts +7 -24
  192. package/dist/core/runner/prepare-listings.js +4 -5
  193. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  194. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  195. package/dist/core/runner/prepare-memory.d.ts +6 -0
  196. package/dist/core/runner/prepare-memory.js +13 -13
  197. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  198. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  199. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  200. package/dist/core/runner/prepare-park-ask.js +17 -10
  201. package/dist/core/runner/prepare-policy-chain.js +24 -44
  202. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  203. package/dist/core/runner/prepare-project-context.js +3 -4
  204. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  205. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  206. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  207. package/dist/core/runner/prepare-run-refs.js +2 -1
  208. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  209. package/dist/core/runner/prepare-safety-scan.js +1 -2
  210. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  211. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  212. package/dist/core/runner/prepare-task.d.ts +1 -1
  213. package/dist/core/runner/prepare-task.js +67 -56
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  215. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  216. package/dist/core/runner/resume-apply.js +7 -14
  217. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  218. package/dist/core/runner/resume-internals-and-config.js +2 -2
  219. package/dist/core/runner/resume-policy-outcome.js +5 -32
  220. package/dist/core/runner/resume-review-outcome.js +4 -1
  221. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  222. package/dist/core/runner/retired-runner-deps.js +10 -1
  223. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  224. package/dist/core/runner/run-brain-sinks.js +5 -2
  225. package/dist/core/runner/run-harness-handlers.js +27 -34
  226. package/dist/core/runner/run-leg.d.ts +0 -2
  227. package/dist/core/runner/run-leg.js +32 -33
  228. package/dist/core/runner/run-terminal-adoption.js +4 -3
  229. package/dist/core/runner/runtask.js +8 -8
  230. package/dist/core/runner/session-rule-policy.js +5 -5
  231. package/dist/core/runner/stream-settle-backstop.js +7 -4
  232. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  233. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  234. package/dist/core/runner/terminal-account.d.ts +48 -0
  235. package/dist/core/runner/terminal-account.js +186 -0
  236. package/dist/core/runner/tool-end-body.d.ts +54 -17
  237. package/dist/core/runner/tool-end-body.js +27 -2
  238. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  239. package/dist/core/runner/tool-face-overlay.js +6 -4
  240. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  241. package/dist/core/runner/tool-occurrence.js +123 -0
  242. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  243. package/dist/core/runner/tool-progress-lane.js +25 -34
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/safety-axis-vocab.d.ts +1 -1
  249. package/dist/core/safety-merge-corpus.d.ts +1 -1
  250. package/dist/core/secret-env.d.ts +16 -5
  251. package/dist/core/secret-env.js +23 -63
  252. package/dist/core/sensitive-path-policy.d.ts +19 -18
  253. package/dist/core/sensitive-path-policy.js +73 -49
  254. package/dist/core/session-policy-store.d.ts +6 -3
  255. package/dist/core/session-policy-store.js +28 -10
  256. package/dist/core/session-reconcile.d.ts +3 -0
  257. package/dist/core/session-reconcile.js +5 -4
  258. package/dist/core/session-store.d.ts +5 -0
  259. package/dist/core/session-store.js +12 -0
  260. package/dist/core/session.d.ts +13 -0
  261. package/dist/core/shared-memory/normalize.d.ts +17 -4
  262. package/dist/core/shared-memory/normalize.js +7 -7
  263. package/dist/core/shell-lexer.js +5 -4
  264. package/dist/core/shell-wrapper-table.d.ts +2 -2
  265. package/dist/core/shell-wrapper-table.js +1 -1
  266. package/dist/core/skill-grant.js +1 -1
  267. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  268. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  269. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  270. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  271. package/dist/core/stub-env.d.ts +2 -0
  272. package/dist/core/stub-env.js +1 -0
  273. package/dist/core/synthetic-read-verdict.js +2 -2
  274. package/dist/core/task-event.d.ts +59 -5
  275. package/dist/core/task-result.d.ts +1 -1
  276. package/dist/core/task-spec.d.ts +42 -9
  277. package/dist/core/terminal-cause.d.ts +94 -11
  278. package/dist/core/tighten-task-spec.d.ts +5 -4
  279. package/dist/core/tighten-task-spec.js +20 -25
  280. package/dist/core/tool-catalog-entries.d.ts +5 -7
  281. package/dist/core/tool-catalog-entries.js +14 -15
  282. package/dist/core/tool-face.d.ts +47 -0
  283. package/dist/core/tool-face.js +5 -0
  284. package/dist/core/tool-model-gate.d.ts +5 -5
  285. package/dist/core/tool-name-aliases.d.ts +35 -10
  286. package/dist/core/tool-name-aliases.js +15 -0
  287. package/dist/core/tool-name-list.d.ts +30 -0
  288. package/dist/core/tool-name-list.js +55 -0
  289. package/dist/core/tool-name-readings.d.ts +1 -9
  290. package/dist/core/tool-name-readings.js +1 -3
  291. package/dist/core/tool-policy.d.ts +195 -85
  292. package/dist/core/tool-policy.js +165 -381
  293. package/dist/core/tool-registry.d.ts +44 -1
  294. package/dist/core/tool-registry.js +26 -0
  295. package/dist/core/tool-roster.d.ts +19 -1
  296. package/dist/core/tool-roster.js +21 -2
  297. package/dist/core/tool-spec-members.d.ts +45 -0
  298. package/dist/core/tool-spec-members.js +169 -0
  299. package/dist/core/tool-spec.d.ts +46 -8
  300. package/dist/core/tools.d.ts +6 -2
  301. package/dist/core/tools.js +8 -4
  302. package/dist/core/untrusted-egress.js +29 -26
  303. package/dist/core/untrusted-text.d.ts +13 -10
  304. package/dist/core/untrusted-text.js +6 -44
  305. package/dist/core/workflow-journal-store.d.ts +4 -1
  306. package/dist/core/write-protect.d.ts +65 -29
  307. package/dist/core/write-protect.js +235 -177
  308. package/dist/engine/compaction/compaction.d.ts +2 -2
  309. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  310. package/dist/engine/execution-env/node-execution-env.js +16 -38
  311. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  312. package/dist/engine/execution-env/symlink-chain.js +32 -0
  313. package/dist/engine/harness/types.d.ts +7 -0
  314. package/dist/engine/llm/tool-turns.d.ts +3 -0
  315. package/dist/engine/llm/tool-turns.js +1 -0
  316. package/dist/engine/llm/types.d.ts +59 -23
  317. package/dist/engine/loop/agent-loop.js +16 -2
  318. package/dist/engine/session/memory-repo.js +11 -3
  319. package/dist/engine/session/repo-utils.d.ts +8 -0
  320. package/dist/engine/session/repo-utils.js +13 -0
  321. package/dist/index.d.ts +20 -23
  322. package/dist/index.js +17 -20
  323. package/dist/internal/harness.d.ts +1 -1
  324. package/dist/internal/harness.js +1 -1
  325. package/dist/internal/llm.d.ts +2 -2
  326. package/dist/internal/llm.js +1 -1
  327. package/dist/orchestration/governance-baseline-validity.js +1 -1
  328. package/dist/orchestration/run-spec.js +3 -3
  329. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  330. package/dist/orchestration/run-workflow-tool.js +38 -78
  331. package/dist/orchestration/workflow-governance.d.ts +21 -25
  332. package/dist/orchestration/workflow-governance.js +38 -78
  333. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  334. package/dist/orchestration/workflow-primitives.js +5 -12
  335. package/dist/orchestration/workflow-types.d.ts +1 -1
  336. package/dist/orchestration/workflow.d.ts +61 -11
  337. package/dist/orchestration/workflow.js +191 -119
  338. package/dist/prompt-assembly/types.d.ts +1 -1
  339. package/dist/scenarios/full-body.d.ts +1 -1
  340. package/dist/shell/lex.d.ts +0 -21
  341. package/dist/shell/lex.js +278 -70
  342. package/dist/shell/shell-words.d.ts +35 -0
  343. package/dist/shell/shell-words.js +65 -0
  344. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  345. package/dist/stores/file/checkpoint-store.js +5 -2
  346. package/dist/stores/file/index.d.ts +0 -8
  347. package/dist/stores/file/index.js +0 -12
  348. package/dist/stores/file/session-store.d.ts +3 -0
  349. package/dist/stores/file/session-store.js +44 -19
  350. package/dist/tools/artifact/artifact-tool.js +2 -0
  351. package/dist/tools/fs/bash-program-position.d.ts +17 -3
  352. package/dist/tools/fs/bash-program-position.js +25 -10
  353. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  354. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  355. package/dist/tools/fs/containment-face.d.ts +4 -0
  356. package/dist/tools/fs/containment-face.js +3 -0
  357. package/dist/tools/fs/fs-shared.d.ts +10 -0
  358. package/dist/tools/fs/fs-shared.js +18 -0
  359. package/dist/tools/fs/fs-write.js +4 -2
  360. package/dist/tools/fs/index.d.ts +3 -2
  361. package/dist/tools/fs/index.js +2 -2
  362. package/dist/tools/fs/program-read-model.d.ts +99 -23
  363. package/dist/tools/fs/program-read-model.js +129 -55
  364. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  365. package/dist/tools/fs/program-read-model.rows.js +18 -10
  366. package/dist/tools/fs/read-deny-home.d.ts +35 -30
  367. package/dist/tools/fs/read-deny-home.js +45 -38
  368. package/dist/tools/fs/read-deny.d.ts +35 -27
  369. package/dist/tools/fs/read-deny.js +126 -92
  370. package/dist/tools/fs/removal-targets.d.ts +56 -23
  371. package/dist/tools/fs/removal-targets.js +74 -87
  372. package/dist/tools/fs/safety.d.ts +29 -22
  373. package/dist/tools/fs/safety.js +17 -11
  374. package/dist/tools/fs/search.js +10 -8
  375. package/dist/tools/fs/shell-read-argv.d.ts +4 -7
  376. package/dist/tools/fs/shell-read-argv.js +6 -8
  377. package/dist/tools/fs/shell-read-bindings.d.ts +203 -46
  378. package/dist/tools/fs/shell-read-bindings.js +488 -144
  379. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  380. package/dist/tools/fs/shell-read-builtins.js +43 -0
  381. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  382. package/dist/tools/fs/shell-read-check.js +51 -42
  383. package/dist/tools/fs/shell-read-establish.js +9 -10
  384. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  385. package/dist/tools/fs/shell-read-functions.js +29 -0
  386. package/dist/tools/fs/shell-read-judge.d.ts +48 -18
  387. package/dist/tools/fs/shell-read-judge.js +33 -4
  388. package/dist/tools/fs/shell-read-plan.d.ts +13 -20
  389. package/dist/tools/fs/shell-read-plan.js +200 -194
  390. package/dist/tools/fs/shell-read-start.d.ts +80 -0
  391. package/dist/tools/fs/shell-read-start.js +99 -0
  392. package/dist/tools/fs/shell-read-word.d.ts +35 -6
  393. package/dist/tools/fs/shell-read-word.js +89 -9
  394. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  395. package/dist/tools/fs/shell-read-workdir.js +281 -0
  396. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  397. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  398. package/dist/tools/fs/shell-reentry-text.d.ts +26 -26
  399. package/dist/tools/fs/shell-reentry-text.js +31 -34
  400. package/dist/tools/task-list.d.ts +1 -2
  401. package/dist/tools/web.js +1 -1
  402. package/package.json +4 -1
  403. package/test/export-surface.snapshot.json +107 -143
  404. package/wire-changes/core@7.48.0.json +252 -0
  405. package/wire-changes/core@7.49.0.json +4765 -0
  406. package/dist/agents/teacher.d.ts +0 -159
  407. package/dist/agents/teacher.js +0 -577
  408. package/dist/agents/team.d.ts +0 -226
  409. package/dist/agents/team.js +0 -257
  410. package/dist/core/strategy-store.d.ts +0 -238
  411. package/dist/core/strategy-store.js +0 -253
  412. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  413. package/dist/orchestration/builtin-workflows.js +0 -159
  414. package/dist/scenarios/env.d.ts +0 -40
  415. package/dist/scenarios/env.js +0 -39
  416. package/dist/scenarios/scenario-registry.d.ts +0 -110
  417. package/dist/scenarios/scenario-registry.js +0 -140
  418. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  419. package/dist/scenarios/teacher-quickstart.js +0 -12
  420. package/dist/stores/cc/lockfile.d.ts +0 -10
  421. package/dist/stores/cc/lockfile.js +0 -98
  422. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  423. package/dist/stores/cc/mailbox-store.js +0 -255
  424. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  425. package/dist/stores/cc/roster-adapter.js +0 -117
  426. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  427. package/dist/stores/cc/sidecar-transcript.js +0 -264
  428. package/dist/stores/cc/task-list-store.d.ts +0 -2
  429. package/dist/stores/cc/task-list-store.js +0 -125
  430. package/dist/stores/file/strategy-store.d.ts +0 -97
  431. package/dist/stores/file/strategy-store.js +0 -341
@@ -7,19 +7,25 @@
7
7
  * opaque here — the runner knows only that it started and has not ended — so this lane runs a slow beat for
8
8
  * any in-flight call silent for {@link TOOL_HEARTBEAT_MS}.
9
9
  *
10
- * THE LANE OWNS TIME, the producer owns FACTS. A producer reports what it has seen (the tail, the totals),
11
- * never how long it has run: `elapsedTimeSeconds` is computed HERE from one origin per call, because the two
12
- * producers do not start their clocks together — the station registers a call when it ENTERS EXECUTION, a
13
- * shell command's own clock could only start at its spawn. With two origins a 30 s beat could be followed
14
- * moments later by a shell tick reporting 1 s, breaking the monotonicity the frame promises.
10
+ * THE CALLS IN FLIGHT ARE THE LEG'S OCCURRENCES (`tool-occurrence.ts`), not a set of this lane's own: the record
11
+ * that carries a call's start frame carries its elapsed origin, its silence clock and its wait on the person, so
12
+ * the beat can never describe a call the frames say ended, nor miss one they say started.
13
+ *
14
+ * ONE ORIGIN PER CALL, the producer owns FACTS. A producer reports what it has seen (the tail, the totals),
15
+ * never how long it has run: `elapsedTimeSeconds` is computed HERE from the occurrence's origin — its
16
+ * announcement — because a shell command's own clock could only start at its spawn. With two origins a 30 s
17
+ * beat could be followed moments later by a shell tick reporting 1 s, breaking the monotonicity the frame promises.
15
18
  *
16
19
  * THE CADENCE HAS ONE ENFORCEMENT POINT, same reason: a producer's timer is a SAMPLING clock, not the
17
20
  * contract. `emit` drops a frame landing inside {@link TOOL_PROGRESS_MIN_INTERVAL_MS} of that call's last.
18
21
  *
19
- * ONE RULE FOR THE BEAT: a call is beaten when nothing has been emitted FOR IT for a whole interval,
22
+ * ONE RULE FOR THE BEAT: a call is beaten when nothing has been heard FROM IT for a whole interval,
20
23
  * counting its own start as the first such event — covering both "it only just started" and "the tool
21
24
  * already ticks faster than this". The interval is the RUN's, so a first beat lands anywhere in
22
25
  * [TOOL_HEARTBEAT_MS, 2 × TOOL_HEARTBEAT_MS): the price of one timer per run, stated rather than hidden.
26
+ * And the beat reads the one activity fact: when EVERY call in flight is waiting on the person, nothing is
27
+ * working and nothing is beaten; a call back from the person is heard from at that moment, so its silence
28
+ * is counted afresh.
23
29
  *
24
30
  * THE CLOCK IS MONOTONIC: every predicate here is a DIFFERENCE of two readings (is this call due a beat, is
25
31
  * this offer inside the floor, how long has it run), and off the wall clock a backward step — NTP, a
@@ -30,6 +36,7 @@
30
36
  * every emission is fault-contained. */
31
37
  import type { TaskEvent, TaskEventIdentity } from "../types.js";
32
38
  import type { ToolProgressLane } from "./contracts.js";
39
+ import { type ToolOccurrenceTable } from "./tool-occurrence.js";
33
40
  /** How long a tool call may stay silent before this lane beats for it, in ms. ONE SOURCE, and CC
34
41
  * 2.1.259's own per-tool heartbeat interval (`Cct`) — this engine keeps the cadence and folds the beat
35
42
  * into the one progress frame instead of minting a second shape (registered divergence). */
@@ -38,5 +45,6 @@ export declare const TOOL_HEARTBEAT_MS = 30000;
38
45
  * nowhere else so it holds across producers rather than inside each one. */
39
46
  export declare const TOOL_PROGRESS_MIN_INTERVAL_MS = 1000;
40
47
  /** Build the lane over the run's content pusher (`pushContent` — the ONE seat that puts a frame on this
41
- * run's queue and, for a sub-agent, forwards it to the parent's sink) and its identity mint. */
42
- export declare function createToolProgressLane(push: (e: TaskEvent) => void, ident: () => TaskEventIdentity): ToolProgressLane;
48
+ * run's queue and, for a sub-agent, forwards it to the parent's sink), its identity mint and the leg's
49
+ * occurrence table (the calls in flight). */
50
+ export declare function createToolProgressLane(push: (e: TaskEvent) => void, ident: () => TaskEventIdentity, occurrences: ToolOccurrenceTable): ToolProgressLane;
@@ -1,8 +1,7 @@
1
+ import { occurrenceClock } from "./tool-occurrence.js";
1
2
  export const TOOL_HEARTBEAT_MS = 30_000;
2
3
  export const TOOL_PROGRESS_MIN_INTERVAL_MS = 1_000;
3
- const monotonicNow = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
4
- export function createToolProgressLane(push, ident) {
5
- const inFlight = new Map();
4
+ export function createToolProgressLane(push, ident, occurrences) {
6
5
  let timer;
7
6
  const arm = () => {
8
7
  if (timer !== undefined)
@@ -10,51 +9,43 @@ export function createToolProgressLane(push, ident) {
10
9
  timer = setInterval(beat, TOOL_HEARTBEAT_MS);
11
10
  timer.unref?.();
12
11
  };
12
+ const disarm = () => {
13
+ if (timer === undefined)
14
+ return;
15
+ clearInterval(timer);
16
+ timer = undefined;
17
+ };
18
+ occurrences.onOpen(arm);
13
19
  const emit = (body) => {
14
- const now = monotonicNow();
15
- let live = inFlight.get(body.toolCallId);
16
- if (live === undefined) {
17
- live = { toolName: body.toolName, startedAt: now, lastAt: now - TOOL_PROGRESS_MIN_INTERVAL_MS };
18
- inFlight.set(body.toolCallId, live);
19
- arm();
20
- }
21
- if (now - live.lastAt < TOOL_PROGRESS_MIN_INTERVAL_MS)
20
+ const now = occurrenceClock();
21
+ const unseen = occurrences.get(body.toolCallId) === undefined;
22
+ const occ = occurrences.ensure({ toolCallId: body.toolCallId, spelledName: body.toolName, args: undefined });
23
+ if (!unseen && now - occ.lastHeardAt < TOOL_PROGRESS_MIN_INTERVAL_MS)
22
24
  return;
23
- live.lastAt = now;
25
+ occurrences.heard(occ.toolCallId);
24
26
  try {
25
- push({ type: "tool_progress", ...body, elapsedTimeSeconds: Math.floor((now - live.startedAt) / 1000), ...ident() });
27
+ push({ type: "tool_progress", ...body, elapsedTimeSeconds: Math.floor((now - occ.startedAt) / 1000), ...ident() });
26
28
  }
27
29
  catch {
28
30
  }
29
31
  };
30
32
  function beat() {
31
- const now = monotonicNow();
32
- for (const [toolCallId, live] of inFlight) {
33
- if (now - live.lastAt < TOOL_HEARTBEAT_MS)
33
+ const now = occurrenceClock();
34
+ const inFlight = occurrences.live().filter((o) => o.beating);
35
+ if (inFlight.length === 0)
36
+ return disarm();
37
+ if (inFlight.every((o) => o.awaitingUser > 0))
38
+ return;
39
+ for (const o of inFlight) {
40
+ if (now - o.lastHeardAt < TOOL_HEARTBEAT_MS)
34
41
  continue;
35
- emit({ toolCallId, toolName: live.toolName });
42
+ emit({ toolCallId: o.toolCallId, toolName: o.spelledName });
36
43
  }
37
44
  }
38
- const disarm = () => {
39
- if (timer === undefined)
40
- return;
41
- clearInterval(timer);
42
- timer = undefined;
43
- };
44
45
  return {
45
46
  emit,
46
- noteStart(toolCallId, toolName) {
47
- const startedAt = monotonicNow();
48
- inFlight.set(toolCallId, { toolName, startedAt, lastAt: startedAt });
49
- arm();
50
- },
51
- noteEnd(toolCallId) {
52
- inFlight.delete(toolCallId);
53
- if (inFlight.size === 0)
54
- disarm();
55
- },
56
47
  clear() {
57
- inFlight.clear();
48
+ occurrences.quiesce();
58
49
  disarm();
59
50
  },
60
51
  };
@@ -983,7 +983,7 @@ export declare const MCP_INSTRUCTIONS_MAX_CHARS: number;
983
983
  * re-derived here. The earlier shape did re-derive it — a local `sanitizeUntrustedText` pre-pass with
984
984
  * the DEFAULT (reminder-only) tag set, measured against the cap — and that mirror silently stopped
985
985
  * matching once the fence widened its neutralization to the whole authority-envelope family: each
986
- * widened-family tag occurrence adds a ZWSP the pre-count never saw, so a server could land its text
986
+ * widened-family tag occurrence adds an entity the pre-count never saw, so a server could land its text
987
987
  * in the `(cap − N, cap]` window and get the body clipped with the honesty note withheld, N being its
988
988
  * own choice of tag count. One measurement, taken where the cut happens, is the only shape that cannot
989
989
  * drift.
@@ -22,20 +22,32 @@
22
22
  */
23
23
  import type { ExecutionEnv } from "../../internal/harness.js";
24
24
  import type { RunnerDeps } from "../runner-deps.js";
25
+ import type { TaskSpec } from "../task-spec.js";
25
26
  import type { ToolRoster } from "../tool-roster.js";
27
+ import type { ToolPolicy } from "../tool-policy.js";
26
28
  import { type WriteProtectionMount } from "../write-protect.js";
27
29
  import type { ShellReadBoundary } from "../../tools/fs/shell-read-judge.js";
28
- /** The leg's mount plus the same judge over a bare ABSOLUTE target — what the shell station asks about each write target
29
- * a command names (`ShellReadBoundary.writeProtectionJudge`): `true` ⇔ a row covers it. */
30
- export interface LegWriteProtection extends WriteProtectionMount {
31
- readonly judgeTarget: NonNullable<ShellReadBoundary["writeProtectionJudge"]>;
30
+ /** The leg's write judgment, read by its two readers: the gate's tighten over the always-on table (`mount`, absent when that
31
+ * table is empty) and the shell station's ONE question about each write target a command names (`judgeWriteTarget`, over
32
+ * the table and the chain's guarded write rows together; absent when neither has a row). */
33
+ export interface LegWriteProtection {
34
+ readonly mount: WriteProtectionMount | undefined;
35
+ readonly judgeWriteTarget: ShellReadBoundary["writeTargetJudge"];
36
+ }
37
+ /** The leg's write-guard seats: its one exempt root (the leg's single resolution of `RunnerDeps.memoryEngineDir`, the same
38
+ * list every policy adjudication of the leg is stamped with) and the chain policies' guarded write rows. */
39
+ export interface LegWriteGuard {
40
+ readonly exemptRoots: readonly string[];
41
+ readonly rows: ToolPolicy["writeGuardRows"];
32
42
  }
33
43
  export declare function mountWriteProtection(input: {
34
44
  /** borrowed-readonly — the deployment seats: the table (`writeProtectedPaths`; absent ⇒ the default
35
- * table, `[]` ⇒ opted out), the data root the memory library is materialized under
36
- * (`memoryEngineDir`; absent ⇒ the resolver's env/default chain), the configuration root the host
37
- * declared (`agentConfigDir`) and the operator sink. */
38
- deps: Pick<RunnerDeps, "writeProtectedPaths" | "memoryEngineDir" | "agentConfigDir" | "onNotice">;
45
+ * table, `[]` ⇒ opted out), the configuration root the host declared (`agentConfigDir`) and the operator sink. */
46
+ deps: Pick<RunnerDeps, "writeProtectedPaths" | "agentConfigDir" | "onNotice">;
47
+ /** borrowed-readonly — the leg's one exempt root and the chain's guarded write rows ({@link LegWriteGuard}). */
48
+ guard: LegWriteGuard;
49
+ /** borrowed-readonly — the request's own rows (already judged at the task layer's door). */
50
+ spec: Pick<TaskSpec, "writeProtectedAdditions">;
39
51
  /** The HANDS' environment, or `undefined` with no hands — the driver's own predicate, not a second
40
52
  * reading of the env seats, so the judge sees exactly the environment the write tools do. */
41
53
  env: ExecutionEnv | undefined;
@@ -45,4 +57,4 @@ export declare function mountWriteProtection(input: {
45
57
  roster: ToolRoster;
46
58
  sessionId: string;
47
59
  runId: string;
48
- }): LegWriteProtection | undefined;
60
+ }): LegWriteProtection;
@@ -1,11 +1,13 @@
1
1
  import { deliverEngineNotice } from "../engine-notice.js";
2
+ import { unionAddOnly } from "../child-clamp-seats.js";
2
3
  import { protectivePathTargetOf } from "../tool-registry.js";
3
- import { compileWriteProtection, writeProtectionMountOver } from "../write-protect.js";
4
+ import { compileLegWriteJudgment, resolveWriteProtectedTable, writeProtectionMountOver } from "../write-protect.js";
4
5
  const ABSENCE_REASON = { symlink: "unresolved-symlink", target: "unresolvable-target" };
5
6
  export function mountWriteProtection(input) {
6
7
  const announced = new Set();
7
- const matcher = compileWriteProtection(input.deps.writeProtectedPaths, {
8
- ...(input.deps.memoryEngineDir !== undefined ? { dataRoot: input.deps.memoryEngineDir } : {}),
8
+ const judgment = compileLegWriteJudgment(unionAddOnly("writeProtectedAdditions", resolveWriteProtectedTable(input.deps.writeProtectedPaths), input.spec.writeProtectedAdditions), {
9
+ exemptRoots: input.guard.exemptRoots,
10
+ ...(input.guard.rows !== undefined ? { guardRows: input.guard.rows } : {}),
9
11
  ...(input.deps.agentConfigDir !== undefined ? { agentConfigDir: input.deps.agentConfigDir } : {}),
10
12
  ...(input.env !== undefined ? { env: input.env } : {}),
11
13
  rootPath: input.rootPath,
@@ -15,22 +17,23 @@ export function mountWriteProtection(input) {
15
17
  return;
16
18
  announced.add(reason);
17
19
  deliverEngineNotice(input.deps.onNotice, {
18
- code: "config.write_protection_unresolved",
19
- message: `This run's write-protection judge could not resolve a write target in its execution environment ` +
20
- `(${reason === ABSENCE_REASON.symlink ? "a symlink whose real target is unknowable" : "the environment refused or errored on the spelling"}: ${absence.cause}). ` +
21
- `A view that cannot answer does not vote, so that write was judged by its SPELLING against the table and nothing else — ` +
22
- `a target reaching a protected path only through an alias, a bind mount or a ".." walk is cleared. Nothing about this run was ` +
23
- `refused because of it, and nothing here is a defect in the write itself: an environment that cannot answer path questions is a ` +
24
- `deployment fact. Announced once per leg per reason; later writes of the same shape are judged the same way, silently.`,
20
+ code: "config.path_view_unresolved",
21
+ message: `This run's write-protection judge did not get an answer from its execution environment for one lookup of a write's judgment ` +
22
+ `(${reason === ABSENCE_REASON.symlink ? "a symlink whose real target is unknowable" : "the environment refused, errored or did not answer in time"}: ${absence.cause}). ` +
23
+ `A write whose target's real destination (or link chain) could not be determined is refused where the table has rows — the ` +
24
+ `table cannot say it is not a protected path; a root whose key did not come back exempts and places nothing; guarded write rows ` +
25
+ `a deployment's policy did not return are held, so the writes they could guard are not placed. Every row a source that did ` +
26
+ `answer met stays met. An environment that cannot answer path questions is a deployment fact: fix the environment (or the ` +
27
+ `link) and the same writes are judged again. Announced once per leg per reason; later writes of the same shape are judged ` +
28
+ `the same way, silently.`,
25
29
  detail: { reason, cause: absence.cause, sessionId: input.sessionId, runId: input.runId },
26
30
  });
27
31
  },
28
32
  });
29
- if (matcher === undefined)
30
- return undefined;
31
- const mount = { ...writeProtectionMountOver(matcher, input.rootPath), judgeTarget: async (target, opts) => (await matcher.judge(target, { ...(opts?.signal !== undefined ? { signal: opts.signal } : {}), ...(opts?.canonical === true ? { canonical: true } : {}) })).kind === "hit" };
32
- if (mount.targetView !== "spelling-only")
33
- return mount;
33
+ const matcher = judgment.matcher;
34
+ const leg = { mount: matcher === undefined ? undefined : writeProtectionMountOver(matcher, input.rootPath), judgeWriteTarget: judgment.judgeWriteTarget };
35
+ if (leg.mount === undefined || leg.mount.targetView !== "spelling-only")
36
+ return leg;
34
37
  const covered = input.roster.entries
35
38
  .filter((e) => [e.name, ...e.aliases].some((name) => {
36
39
  const target = protectivePathTargetOf({ toolName: name, args: {}, face: e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {} });
@@ -39,7 +42,7 @@ export function mountWriteProtection(input) {
39
42
  .map((e) => e.name)
40
43
  .sort();
41
44
  if (covered.length === 0)
42
- return mount;
45
+ return leg;
43
46
  deliverEngineNotice(input.deps.onNotice, {
44
47
  code: "config.write_protection_target_view_absent",
45
48
  message: `This run mounted path-confinable write tools [${covered.join(", ")}] while its write-protection judge has NO execution environment, ` +
@@ -50,5 +53,5 @@ export function mountWriteProtection(input) {
50
53
  `writeProtection.targetView.`,
51
54
  detail: { tools: covered, sessionId: input.sessionId, runId: input.runId },
52
55
  });
53
- return mount;
56
+ return leg;
54
57
  }
@@ -249,8 +249,9 @@ export interface RunnerDeps {
249
249
  * approval flows the ordinary ask-resolution chain — classifier, blanket `onAsk`, durable park —
250
250
  * with no `requiresRealApproval` mandate). Absent =
251
251
  * {@link import("./write-protect.js").WRITE_PROTECTED_DEFAULT_TABLE} (the CC triple verbatim +
252
- * the two argued sema rows). This key IS the whole-table escape hatch, deployment seat ONLY (no
253
- * TaskSpec twin, no governed-workflow channel): `[]` = no table (explicit and legal); a non-empty
252
+ * the two argued sema rows). This key IS the whole-table escape hatch, deployment seat ONLY — the
253
+ * task layer's twin is add-only ({@link TaskSpec.writeProtectedAdditions}: its rows UNION this
254
+ * table and can remove none), and no governed-workflow channel reaches either: `[]` = no table (explicit and legal); a non-empty
254
255
  * list REPLACES the built-in table whole (compose additions as
255
256
  * `[...WRITE_PROTECTED_DEFAULT_TABLE, …]`; drop rows by filtering the exported table — the
256
257
  * visible/deletable admin face). Bad values refuse loudly at prepare (#123): garbage shapes,
@@ -355,14 +356,6 @@ export interface RunnerDeps {
355
356
  memoryCaptureRecordStore?: (plane: {
356
357
  controlDir: string;
357
358
  }) => import("./memory-engine/layout.js").SessionCaptureRecordStore;
358
- /** which occupant of a session id is running now (a purge may delete a session tree and the
359
- * id be handed out again; without this seat a standing opt-out or pollution record binds the NEXT
360
- * occupant too). An opaque token, STABLE for one occupant's life, DIFFERENT for the next, only
361
- * ever compared ({@link import("./memory-engine/layout.js").sessionRecordBindsIncarnation}).
362
- * ABSENT ⇒ records bind by id (the pre-incarnation bytes); an empty or throwing answer reads the same. */
363
- memorySessionIncarnation?: (session: {
364
- sessionId: string;
365
- }) => string | undefined;
366
359
  /**
367
360
  * design/339 §6.1 — the v3 memory-consolidation switch, threaded verbatim to the engine seat
368
361
  * ({@link import("../core/memory-engine/engine.js").MemoryEngineOptions.consolidation} — same
@@ -689,7 +682,8 @@ export interface RunnerDeps {
689
682
  * denied capability that the spec explicitly requests refuses the prepare loudly
690
683
  * (`config.compliance_denied`, or `config.compliance_required` when the refusal came from the
691
684
  * resolver fault rather than an adjudicated posture). `undefined` (no resolver / no posture for
692
- * the principal) = no compliance restriction — existing deployments are untouched.
685
+ * the principal) = no compliance restriction from the deployment — existing deployments are untouched. The run's deny
686
+ * set is this posture's UNION the request's own denies ({@link TaskSpec.complianceAdditionalDenies}, add-only).
693
687
  */
694
688
  compliancePostureResolver?: (principal: string | undefined) => import("./compliance.js").CompliancePosture | undefined | Promise<import("./compliance.js").CompliancePosture | undefined>;
695
689
  /**
@@ -1031,12 +1025,8 @@ export interface RunnerDeps {
1031
1025
  /** B5/F2 + design/140 §6 1a — the script-persistence / named-registry seam, threaded into the auto-mounted
1032
1026
  * run_workflow tool: every invocation's resolved script is persisted (iterate via `{scriptPath}`), `{name}`
1033
1027
  * resolves a saved workflow, and a registration's `defaultArgs` merge under the call-time args. Opt-in
1034
- * (absent ⇒ inline `script` + built-in names only). */
1028
+ * (absent ⇒ inline `script` only — the engine ships no built-in named workflows). */
1035
1029
  workflowScriptStore?: import("../orchestration/workflow-script-store.js").WorkflowScriptStore;
1036
- /** design/140 §6 1c — `false` removes the BUILT-IN named workflows (`discussion`, …) from the
1037
- * auto-mounted run_workflow tool (the `builtinAgents:false` analog; default ON). A deployment
1038
- * `workflowScriptStore` registration of the same name shadows a built-in regardless. */
1039
- builtinWorkflows?: boolean;
1040
1030
  /**
1041
1031
  * design/97 CORE-9 (Part B) — a TRUSTED deployment sink for the steerable handle of every agent an LLM-authored
1042
1032
  * (`run_workflow` tool) workflow spawns. When set, the tool's `agent()` primitive runs each agent STEERABLE and
@@ -1044,12 +1034,12 @@ export interface RunnerDeps {
1044
1034
  * the handle — no host-context leak into the runner); the deployment registers it by `runId`+`label` to route a
1045
1035
  * human/cross-replica steer to `handle.steer(...)`. Unset ⇒ agents run non-steerable (no overhead). Opt-in.
1046
1036
  *
1047
- * **Interaction with {@link workflowJournalStore}**: a steerable agent runs via
1048
- * `agentStream`, whose results ARE RECORDED in the journal since 1.355 (complete read-face: the journal
1049
- * API / diagnostics coordinate show every agent) but are NEVER REPLAYED — `resumeFromRunId` on a
1050
- * steerable workflow still re-runs agents LIVE (steer input is not deterministic; a cache would replay
1051
- * a result the operator steered). Pre-1.355 the stream lane recorded NOTHING — with both deps set the
1052
- * journal read empty on every workflow (the zero-write case), silently.
1037
+ * **Interaction with {@link workflowJournalStore}**: a steerable agent runs via `agentStream`, which reads the
1038
+ * resume journal exactly as the non-steerable lane does — recorded under the same call key, replayed by the same
1039
+ * unchanged-prefix rule. A completed agent a `resumeFromRunId` replays is emitted here as an already-settled
1040
+ * handle: `result()` resolves at once to the journaled result, `steer()` is refused `steering.not_running`.
1041
+ * A result the operator steered replays as what it was — the run's record of the work, like any model answer
1042
+ * that would come out differently if asked again.
1053
1043
  */
1054
1044
  onWorkflowAgentSpawn?: (handle: import("../orchestration/workflow.js").WorkflowAgentHandle) => void;
1055
1045
  /** design/72 §2.2 (B): deployment default for the suspend-loop cap (see `TaskSpec.maxSuspends`).
@@ -2,7 +2,7 @@
2
2
  * `SAFETY_AXIS_VOCABULARY` — the PUBLISHED safety-axis vocabulary as a zero-logic, zero-runtime-dependency DATA
3
3
  * artifact (pure string / number / boolean literal constants).
4
4
  *
5
- * **design/99 center control-plane seam (2026-06-27).** The sema-registry control plane's per-field
5
+ * **design/99 center control-plane seam (2026-06-27).** The web-admin control plane's per-field
6
6
  * safety-classification table lives in `@sema-agent/registry-core` and, for every safety-critical config field, cites a
7
7
  * core axis VALUE (e.g. `effect: "write"`, `irreversibility: "always"`). That contract package **must not depend on
8
8
  * `@sema-agent/core` (the engine) at runtime** — so it dev-imports THIS const (test-only) and runs a conformance test
@@ -1,6 +1,6 @@
1
1
  import type { SessionPermissionRules } from "./session-policy-store.js";
2
2
  /**
3
- * design/99 (sema-registry center control-plane seam, channel review R2): the PUBLISHED golden conformance corpus
3
+ * design/99 (web-admin control-plane seam, channel review R2): the PUBLISHED golden conformance corpus
4
4
  * for the safety-domain MERGE predicate {@link loosenReasons}.
5
5
  *
6
6
  * THE SEAM. The center control-plane's ConfigBundle merger is a DISPATCHER: for any field it classifies
@@ -6,18 +6,25 @@
6
6
  * deleted whole, never rewritten; `"all"` and a `string[]` allow list are the caller's explicit alternatives
7
7
  * ({@link inheritedHostEnv}). One judgment per variable ({@link classifySecretEnvEntry}), the first rule that answers:
8
8
  * 1. exempt — git's environment config and the proxy variables, handed on as written ({@link isExemptEnvName});
9
- * 2. `exact-name` — a known credential name ({@link CREDENTIAL_ENV_NAMES});
9
+ * 2. `exact-name` — a known credential name (the vocabulary's exact env names);
10
10
  * 3. `prefix-rule` — the OpenTelemetry settings ({@link OTEL_ENV_RE});
11
11
  * 4. `namespace-rule` — a credential word as any segment of a name in the engine's own `SEMA_` namespace;
12
- * 5. `name-rule` — a credential-shaped name ({@link nameIsCredentialShaped}) off {@link NON_SECRET_ENV_EXACT_NAMES};
13
- * 6. `value-rule` — a value that carries a credential ({@link valueCarriesCredential}).
14
- * {@link isSecretEnvKey} and {@link scrubSecretEnv} both answer with this one judgment. The exempt families, the
12
+ * 5. `name-rule` — a credential-shaped name ({@link nameIsCredentialShaped}) off the vocabulary's non-secret exact names;
13
+ * 6. `value-rule` — a value that carries a credential ({@link looksLikeCredentialValue}).
14
+ * {@link isSecretEnvKey} and {@link scrubSecretEnv} both answer with this one judgment; rules 2–5 are its name half
15
+ * ({@link isSensitiveName}), rule 6 its value half, and rule 1 the env-entry exemption read before both. The exempt families, the
15
16
  * credential names, the name shape and the value predicate follow the reference implementation's subprocess-env scrub
16
17
  * as written, three ways stricter: plural `TOKENS` is a credential word unless a count word touches it, the GitHub
17
18
  * token names are not held back from the name shape, and the name shape always runs.
18
19
  */
19
- import type { RedactionConfidence, RedactionSource } from "./arg-summary.js";
20
+ import { type RedactionConfidence, type RedactionSource } from "./credential-vocabulary.js";
20
21
  import { type EngineNotice } from "./engine-notice.js";
22
+ /** Does a value carry a credential? A URL userinfo (after every `scheme://`, and a leading `//`) with a password or a
23
+ * token-like user; a scheme-less `user:password@host`; a credential assignment; a webhook URL; a Sonar login; a
24
+ * private-key header; an `Authorization` header, `token …`, `Bearer …` or `Basic …` with credential-shaped content.
25
+ * Reads the first {@link VALUE_SCAN_LIMIT} code units. The value half of the judgment, exported apart from the env
26
+ * entry's exemptions ({@link isExemptEnvName}): a caller holding a value that is no environment variable asks this. */
27
+ export declare function looksLikeCredentialValue(value: string): boolean;
21
28
  /** Which rule withheld an entry. */
22
29
  export type SecretEnvFindingKind = "exact-name" | "name-rule" | "namespace-rule" | "prefix-rule" | "value-rule";
23
30
  /** One env entry the `"scrub"` policy withheld (deleted): its name — never its value, so the record is loggable —, the
@@ -28,6 +35,10 @@ export interface SecretEnvFinding {
28
35
  confidence: RedactionConfidence;
29
36
  source: RedactionSource;
30
37
  }
38
+ /** Does `key` name a credential? The name half of the judgment ({@link sensitiveNameKind}), exported apart from the env
39
+ * entry's exemptions ({@link isExemptEnvName}): a caller holding a key that is no environment variable (a member of a
40
+ * record) asks this, and an exempt name is no exception there. */
41
+ export declare function isSensitiveName(key: string): boolean;
31
42
  /** Does the `"scrub"` policy withhold `key`? With `value`, exactly the answer {@link scrubSecretEnv} gives for that
32
43
  * entry; without it, the answer for its name alone (the value rule then has nothing to read). */
33
44
  export declare function isSecretEnvKey(key: string, value?: string): boolean;
@@ -1,65 +1,25 @@
1
+ import { CREDENTIAL_VOCABULARY, envNameView, splitCamelCase } from "./credential-vocabulary.js";
1
2
  import { deliverEngineNotice } from "./engine-notice.js";
2
3
  const GIT_CONFIG_ENV_RE = /^GIT_CONFIG_(?:COUNT|PARAMETERS|(?:KEY|VALUE)_[0-9]+)$/;
3
4
  const PROXY_ENV_RE = /^(?:(?:https?|ftp|all|no)_proxy|npm_config_(?:https?_)?proxy|npm_config_noproxy|yarn_proxy|(?:yarn|global_agent|docker|claude_code)_(?:https?|no)_proxy|cloudsdk_proxy_[a-z]+|electron_get_use_proxy)$/i;
4
5
  function isExemptEnvName(name) {
5
6
  return GIT_CONFIG_ENV_RE.test(name) || PROXY_ENV_RE.test(name);
6
7
  }
7
- const CREDENTIAL_ENV_NAMES = new Set([
8
- "ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "CLAUDE_CODE_ARTIFACTS_API_TOKEN", "CLAUDE_CODE_MEMORY_API_TOKEN",
9
- "CLAUDE_CODE_SLACK_TAG_TOKEN", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_FOUNDRY_API_KEY", "ANTHROPIC_FOUNDRY_AUTH_TOKEN",
10
- "ANTHROPIC_AWS_API_KEY", "ANTHROPIC_CUSTOM_HEADERS", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN",
11
- "AWS_BEARER_TOKEN_BEDROCK", "GOOGLE_APPLICATION_CREDENTIALS", "GOOGLE_GHA_CREDS_PATH", "AZURE_CLIENT_SECRET",
12
- "IDENTITY_HEADER", "MSI_SECRET", "AZURE_CLIENT_CERTIFICATE_PATH", "AZURE_CLIENT_CERTIFICATE_PASSWORD",
13
- "AZURE_PASSWORD", "AZURE_FEDERATED_TOKEN_FILE", "AWS_WEB_IDENTITY_TOKEN_FILE",
14
- "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "AWS_CONTAINER_CREDENTIALS_FULL_URI",
15
- "AWS_CONTAINER_AUTHORIZATION_TOKEN", "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", "CLOUDSDK_AUTH_ACCESS_TOKEN",
16
- "GOOGLE_OAUTH_ACCESS_TOKEN", "CLAUDE_CODE_OAUTH_REFRESH_TOKEN", "HF_TOKEN", "HUGGING_FACE_HUB_TOKEN",
17
- "HUGGINGFACEHUB_API_TOKEN", "NODE_AUTH_TOKEN", "NUGET_AUTH_TOKEN", "CARGO_REGISTRY_TOKEN", "TWINE_PASSWORD",
18
- "TWINE_USERNAME", "PYPI_TOKEN", "PYPI_API_TOKEN", "UV_PUBLISH_TOKEN", "UV_PUBLISH_PASSWORD", "UV_PUBLISH_USERNAME",
19
- "FLIT_PASSWORD", "FLIT_USERNAME", "HATCH_INDEX_AUTH", "HATCH_INDEX_USER", "GEM_HOST_API_KEY", "MATURIN_PYPI_TOKEN",
20
- "MATURIN_PASSWORD", "MATURIN_USERNAME", "CONAN_LOGIN_USERNAME", "CONAN_PASSWORD", "ANACONDA_API_TOKEN",
21
- "BINSTAR_API_TOKEN", "VAULT_TOKEN", "VAULT_AUTH_TOKEN", "VAULT_ROLE_ID", "VAULT_SECRET_ID", "CONSUL_HTTP_TOKEN",
22
- "CONSUL_HTTP_AUTH", "NOMAD_TOKEN", "NOMAD_HTTP_AUTH", "CI_REGISTRY_USER", "CI_DEPLOY_USER", "JF_USER",
23
- "FASTLANE_SESSION", "MATCH_GIT_BASIC_AUTHORIZATION", "SONAR_TOKEN", "SONARQUBE_SCANNER_PARAMS",
24
- "SONAR_SCANNER_JSON_PARAMS", "SLACK_WEBHOOK_URL", "SLACK_WEBHOOK", "DISCORD_WEBHOOK", "DISCORD_WEBHOOK_URL",
25
- "TEAMS_WEBHOOK_URL", "MS_TEAMS_WEBHOOK_URI", "ANTHROPIC_IDENTITY_TOKEN", "ANTHROPIC_IDENTITY_TOKEN_FILE",
26
- "CLOUDSDK_AUTH_ACCESS_TOKEN_FILE", "CLOUDSDK_AUTH_AUTHORIZATION_TOKEN_FILE", "AZURE_AUTH_LOCATION",
27
- "ACTIONS_ID_TOKEN_REQUEST_TOKEN", "ACTIONS_ID_TOKEN_REQUEST_URL", "ACTIONS_RUNTIME_TOKEN", "ACTIONS_RUNTIME_URL",
28
- "ALL_INPUTS", "VSS_NUGET_EXTERNAL_FEED_ENDPOINTS", "ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS",
29
- "VSS_NUGET_ACCESSTOKEN", "ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN", "COMPOSER_AUTH", "OVERRIDE_GITHUB_TOKEN",
30
- "DEFAULT_WORKFLOW_TOKEN", "SSH_SIGNING_KEY"
31
- ].flatMap((name) => [name, `INPUT_${name}`]));
8
+ const ENV_NAMES = envNameView(CREDENTIAL_VOCABULARY);
32
9
  const OTEL_ENV_RE = /^(?:INPUT_)?OTEL_/i;
33
- const COUNTED_TOKENS = "(?<!(?:^|_)(?:MAX|OUTPUT|INPUT|THINKING|NUM|TOTAL)_)TOKENS";
34
- const SEMA_NAMESPACE_SECRET_RE = new RegExp(`^SEMA_(?:.*_)?(?:KEY|KEYS|TOKEN|${COUNTED_TOKENS}|SECRET|SECRETS|PASSWORD|PASSWORDS|PASSWD|CREDENTIAL|CREDENTIALS|PRIVATEKEY|APIKEY)(?:_|$)`, "is");
35
- const LEADING_WORDS = [
36
- "TOKEN", "SECRET", "PASSWORD", "PASSWD", "PASSPHRASE", "KEY", "AUTH", "COOKIE", "PAT", "DSN", "WEBHOOK", "CREDENTIAL",
37
- "CREDENTIALS", "CREDS", "APIKEY", "ACCESSKEY", "SECRETKEY", "ACCOUNTKEY", "PRIVATEKEY", "AUTHKEY", "SSHKEY",
38
- "SIGNINGKEY", "MASTERKEY", "DEPLOYKEY", "ENCRYPTIONKEY", "PGPASSWORD", "SSHPASS",
39
- ];
40
- const PLURAL_WORDS = ["KEY", "SECRET", "PASSWORD", "CREDENTIAL"];
41
- const SEPARATED_WORDS = ["PWD", "PASS", "JWT"];
42
- const EMBEDDED_WORDS = ["TOKEN", "SECRET", "PASSWORD", "PASSWD", "PASSPHRASE"];
43
- const CREDENTIAL_WORD_RE = new RegExp(`((^|_)(${LEADING_WORDS.join("|")}|(${PLURAL_WORDS.join("|")})S|${COUNTED_TOKENS})|_(${SEPARATED_WORDS.join("|")})|(${EMBEDDED_WORDS.join("|")}))(?=$|[_0-9])`, "i");
44
- const CONNECTION_STRING_RE = /CONN(ECT(ION)?)?_?STR(ING)?S?(?=$|[_0-9])/i;
10
+ const SEMA_NAMESPACE_SECRET_RE = new RegExp(`^SEMA_(?:.*_)?(?:KEY|KEYS|TOKEN|${ENV_NAMES.countedPlural}|SECRET|SECRETS|PASSWORD|PASSWORDS|PASSWD|CREDENTIAL|CREDENTIALS|PRIVATEKEY|APIKEY)(?:_|$)`, "is");
45
11
  const BUNDLER_SETTINGS = ["BUILD", "LOCAL", "MIRROR", "PATH", "WITH", "WITHOUT", "CACHE", "DISABLE", "IGNORE", "ONLY"];
46
12
  const BUNDLER_HOST = "(?:[A-Za-z0-9]+(?:___[A-Za-z0-9]+)*__)+[A-Za-z]{2,}";
47
13
  const BUNDLER_CREDENTIAL_RE = new RegExp(`^(?:INPUT_)?BUNDLE_(?!(?:${BUNDLER_SETTINGS.join("|")})__(?!${BUNDLER_HOST}$))\\w*__`, "i");
48
- const GIT_CONFIG_KEY_NAME_RE = /^GIT_CONFIG_KEY_[0-9][A-Za-z0-9_]*$/;
49
14
  const PUBLISHER_PREFIX_RE = /^(?:INPUT_|ORG_GRADLE_PROJECT_|POETRY_PYPI_TOKEN_|POETRY_HTTP_BASIC_|CARGO_REGISTRIES_|CONAN_LOGIN_USERNAME_|CONAN_PASSWORD_)/i;
50
15
  const PUBLISHER_LOGIN_PREFIX_RE = /^(?:INPUT_)?(?:POETRY_HTTP_BASIC_|CONAN_LOGIN_USERNAME_)/i;
51
16
  const USER_NAME_TAIL_RE = /USER(?:_?NAME)?_?[0-9]*$/i;
52
- function splitCamelCase(name) {
53
- return ["OAuth", "NextAuth"]
54
- .reduce((text, word) => text.replaceAll(word, word[0] + word.slice(1).toLowerCase()), name)
55
- .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
56
- .replace(/([A-Z])([A-Z][a-z])/g, "$1_$2");
57
- }
58
17
  function nameShapeHolds(name) {
59
- const words = name.replace(/^AUTH0_/i, "").replace(/-/g, "_");
18
+ const words = name.replace(ENV_NAMES.nonCredentialPrefix, "").replace(/-/g, "_");
60
19
  const split = splitCamelCase(words);
61
- const shaped = CREDENTIAL_WORD_RE.test(words) || CREDENTIAL_WORD_RE.test(split) || CONNECTION_STRING_RE.test(words) || CONNECTION_STRING_RE.test(split) || BUNDLER_CREDENTIAL_RE.test(words);
62
- return shaped && !GIT_CONFIG_KEY_NAME_RE.test(name);
20
+ const { credentialWord, connectionStringName } = ENV_NAMES;
21
+ const shaped = credentialWord.test(words) || credentialWord.test(split) || connectionStringName.test(words) || connectionStringName.test(split) || BUNDLER_CREDENTIAL_RE.test(words);
22
+ return shaped && !ENV_NAMES.nonSecretNameShape.test(name);
63
23
  }
64
24
  function nameIsCredentialShaped(name) {
65
25
  if (BUNDLER_CREDENTIAL_RE.test(name) || nameShapeHolds(name))
@@ -67,16 +27,9 @@ function nameIsCredentialShaped(name) {
67
27
  const words = name.replace(/-/g, "_");
68
28
  return PUBLISHER_PREFIX_RE.test(words) && (PUBLISHER_LOGIN_PREFIX_RE.test(words) || USER_NAME_TAIL_RE.test(words) || nameShapeHolds(words));
69
29
  }
70
- const NON_SECRET_ENV_EXACT_NAMES = new Set([
71
- "PARTITION_KEY", "SORT_KEY", "RANGE_KEY", "IDEMPOTENCY_KEY", "CACHE_KEY", "ROUTING_KEY",
72
- "DB_FOREIGN_KEYS", "JSON_SORT_KEYS",
73
- "MAX_NEW_TOKENS", "MAX_COMPLETION_TOKENS", "AIDER_MAP_TOKENS", "AIDER_MAX_CHAT_HISTORY_TOKENS",
74
- "MAX_BATCH_PREFILL_TOKENS", "MAX_WAITING_TOKENS", "MAX_TOP_N_TOKENS", "RATE_LIMIT_TOKENS",
75
- "PROMPT_TOKENS", "CONTEXT_TOKENS",
76
- ]);
77
30
  const VALUE_SCAN_LIMIT = 8192;
78
31
  function looksLikeToken(user) {
79
- return /^(?:gh[opusr]_|github_pat_|glpat-|xox[abpr]-|sk-|pk-|AKIA|eyJ|ya29\.|npm_)/.test(user) || (user.length >= 20 && /[0-9]/.test(user) && /[a-z]/i.test(user));
32
+ return ENV_NAMES.tokenPrefix.test(user) || (user.length >= 20 && /[0-9]/.test(user) && /[a-z]/i.test(user));
80
33
  }
81
34
  const HOST_RE = /^(?:localhost|[a-z0-9_-]+(?:\.[a-z0-9_-]+)*\.(?=[a-z0-9-]*[a-z])[a-z0-9-]+|[a-z0-9_.-]+(?=:\d+(?:[/?#]|$))|\d{1,3}(?:\.\d{1,3}){3}|\[[0-9a-f:.]+\])(?::\d+)?(?:[/?#]|$)/i;
82
35
  const HOSTLIKE_RE = /^(?:(?=[a-z0-9._-]*[a-z])[a-z0-9._-]+|\d{1,3}(?:\.\d{1,3}){3}|\[[0-9a-f:.]+\])(?::\d+)?(?:[/?#]|$)/i;
@@ -119,7 +72,7 @@ const PRIVATE_KEY_HEADER_RE = /-----BEGIN [A-Z ]*PRIVATE KEY(?: BLOCK)?-----/;
119
72
  const AUTHORIZATION_HEADER_RE = /\bauthorization\s*[:=]\s*["']?[a-z][a-z0-9_-]*\s+[A-Za-z0-9._~+\/=-]{8,}/i;
120
73
  const TOKEN_WORD_RE = /\b(?:[Tt]oken|TOKEN)\s+(?=[A-Za-z0-9_~+=-]*[0-9])(?=[A-Za-z0-9_~+=-]*[A-Z])(?=([A-Za-z0-9_~+=-]{20,}))\1(?![\/.])/;
121
74
  const BEARER_BASIC_RE = /\b(?:Bearer|Basic)\s+(?=[A-Za-z._~+\/=-]*[0-9]|(?:[A-Za-z0-9._~+\/=-]*?[a-z][A-Z](?![a-z])){2}|[A-Za-z0-9.-]*[_~+\/=])[A-Za-z0-9._~+\/=-]{8,}/;
122
- function valueCarriesCredential(value) {
75
+ export function looksLikeCredentialValue(value) {
123
76
  const text = value.length > VALUE_SCAN_LIMIT ? value.slice(0, VALUE_SCAN_LIMIT) : value;
124
77
  for (let at = text.indexOf("://"); at !== -1; at = text.indexOf("://", at + 3)) {
125
78
  if (at > 0 && /[a-z0-9+.-]/i.test(text[at - 1] ?? "") && authorityCarriesCredential(text.slice(at + 3)))
@@ -143,18 +96,25 @@ const SECRET_ENV_KIND_CONFIDENCE = {
143
96
  "name-rule": "medium",
144
97
  "namespace-rule": "medium",
145
98
  };
146
- function classifySecretEnvEntry(name, value) {
147
- if (isExemptEnvName(name))
148
- return undefined;
149
- if (CREDENTIAL_ENV_NAMES.has(name.toUpperCase().replace(/-/g, "_")))
99
+ function sensitiveNameKind(name) {
100
+ if (ENV_NAMES.exactNames.has(name.toUpperCase().replace(/-/g, "_")))
150
101
  return "exact-name";
151
102
  if (OTEL_ENV_RE.test(name))
152
103
  return "prefix-rule";
153
104
  if (SEMA_NAMESPACE_SECRET_RE.test(name))
154
105
  return "namespace-rule";
155
- if (!NON_SECRET_ENV_EXACT_NAMES.has(name.toUpperCase()) && nameIsCredentialShaped(name))
156
- return "name-rule";
157
- return value !== undefined && valueCarriesCredential(typeof value === "string" ? value : String(value)) ? "value-rule" : undefined;
106
+ return !ENV_NAMES.nonSecretExactNames.has(name.toUpperCase()) && nameIsCredentialShaped(name) ? "name-rule" : undefined;
107
+ }
108
+ export function isSensitiveName(key) {
109
+ return sensitiveNameKind(key) !== undefined;
110
+ }
111
+ function classifySecretEnvEntry(name, value) {
112
+ if (isExemptEnvName(name))
113
+ return undefined;
114
+ const named = sensitiveNameKind(name);
115
+ if (named !== undefined)
116
+ return named;
117
+ return value !== undefined && looksLikeCredentialValue(typeof value === "string" ? value : String(value)) ? "value-rule" : undefined;
158
118
  }
159
119
  export function isSecretEnvKey(key, value) {
160
120
  return classifySecretEnvEntry(key, value) !== undefined;