@sema-agent/core 5.20.0 → 5.21.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 (312) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/agents/agent-definition.d.ts +7 -0
  3. package/dist/agents/agent-transcript-tool.d.ts +30 -0
  4. package/dist/agents/builtin-agents.d.ts +60 -0
  5. package/dist/agents/cascade.d.ts +107 -0
  6. package/dist/agents/cumulative-stats.d.ts +56 -0
  7. package/dist/agents/observer.d.ts +162 -0
  8. package/dist/agents/peer-admission.d.ts +95 -0
  9. package/dist/agents/repair-loop.d.ts +226 -0
  10. package/dist/agents/retain-ledger.d.ts +141 -0
  11. package/dist/agents/roster-store.d.ts +105 -0
  12. package/dist/agents/send-message-tool.d.ts +92 -0
  13. package/dist/agents/session-util.d.ts +5 -0
  14. package/dist/agents/subagent-steps.d.ts +66 -0
  15. package/dist/agents/subagent.d.ts +600 -0
  16. package/dist/agents/suspend-guard.d.ts +29 -0
  17. package/dist/agents/teacher.d.ts +75 -0
  18. package/dist/agents/team.d.ts +120 -1
  19. package/dist/agents/tool-filter.d.ts +34 -0
  20. package/dist/agents/verify.d.ts +198 -0
  21. package/dist/bench/metrics.d.ts +455 -0
  22. package/dist/brain/anthropic.d.ts +30 -0
  23. package/dist/brain/circuit-breaker.d.ts +33 -0
  24. package/dist/brain/context-overflow.d.ts +60 -3
  25. package/dist/brain/degrading.d.ts +67 -0
  26. package/dist/brain/errors.d.ts +42 -0
  27. package/dist/brain/failover.d.ts +15 -0
  28. package/dist/brain/media-degrade.d.ts +39 -0
  29. package/dist/brain/model-presets.d.ts +31 -0
  30. package/dist/brain/open-responses.d.ts +19 -0
  31. package/dist/brain/openai.d.ts +46 -0
  32. package/dist/brain/reasoning.d.ts +106 -1
  33. package/dist/brain/repetition.d.ts +83 -0
  34. package/dist/brain/request-params.d.ts +56 -0
  35. package/dist/brain/retry.d.ts +46 -0
  36. package/dist/brain/routing.d.ts +12 -0
  37. package/dist/brain/status-sink.d.ts +30 -1
  38. package/dist/brain/stream-engine.d.ts +147 -0
  39. package/dist/brain/stream-shared.d.ts +34 -0
  40. package/dist/brain/terminal-cause.d.ts +31 -0
  41. package/dist/brain/timeout.d.ts +107 -0
  42. package/dist/brain/tool-call-id.d.ts +20 -0
  43. package/dist/brain/tool-call-repair.d.ts +13 -0
  44. package/dist/config/catalog.d.ts +47 -0
  45. package/dist/config/defaults.d.ts +33 -0
  46. package/dist/core/a2a-task-state.d.ts +53 -0
  47. package/dist/core/a2a.d.ts +51 -0
  48. package/dist/core/arg-summary.d.ts +62 -0
  49. package/dist/core/ask-question.d.ts +272 -2
  50. package/dist/core/auto-compaction.d.ts +467 -0
  51. package/dist/core/auto-compaction.js +20 -6
  52. package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
  53. package/dist/core/auto-mode-prompt.d.ts +27 -0
  54. package/dist/core/auto-mode.d.ts +54 -3
  55. package/dist/core/auto-promote.d.ts +100 -0
  56. package/dist/core/background-agent-store.d.ts +292 -0
  57. package/dist/core/background-shell.d.ts +110 -0
  58. package/dist/core/cache-break-detector.d.ts +34 -0
  59. package/dist/core/canonical-json.d.ts +57 -0
  60. package/dist/core/checkpoint-store.d.ts +1574 -16
  61. package/dist/core/compliance.d.ts +30 -0
  62. package/dist/core/consolidate-scope.d.ts +75 -0
  63. package/dist/core/context-edit.d.ts +99 -0
  64. package/dist/core/context-guard.d.ts +46 -0
  65. package/dist/core/exec-gate.d.ts +44 -0
  66. package/dist/core/exec-output-tail.d.ts +61 -0
  67. package/dist/core/file-snapshot-store.d.ts +104 -0
  68. package/dist/core/fs-write-gate-policy.d.ts +36 -0
  69. package/dist/core/git-worktree-env.d.ts +31 -0
  70. package/dist/core/governance-codes.d.ts +19 -0
  71. package/dist/core/hooks.d.ts +608 -1
  72. package/dist/core/human-input-projection.d.ts +37 -0
  73. package/dist/core/human-input-projection.js +13 -0
  74. package/dist/core/image-downsample.d.ts +74 -0
  75. package/dist/core/locked-config.d.ts +37 -0
  76. package/dist/core/lsp-diagnostics.d.ts +77 -0
  77. package/dist/core/lsp-protocol.d.ts +29 -0
  78. package/dist/core/lsp-session.d.ts +60 -1
  79. package/dist/core/lsp.d.ts +150 -1
  80. package/dist/core/mailbox-store.d.ts +57 -0
  81. package/dist/core/mcp.d.ts +381 -0
  82. package/dist/core/media-byte-cap.d.ts +21 -0
  83. package/dist/core/memory-admission.d.ts +71 -0
  84. package/dist/core/memory-engine/content-origin.d.ts +64 -0
  85. package/dist/core/memory-engine/data-plane.d.ts +43 -0
  86. package/dist/core/memory-engine/dual-root.d.ts +24 -0
  87. package/dist/core/memory-engine/engine.d.ts +230 -0
  88. package/dist/core/memory-engine/engine.js +103 -35
  89. package/dist/core/memory-engine/file-backend.d.ts +155 -0
  90. package/dist/core/memory-engine/frontmatter.d.ts +16 -0
  91. package/dist/core/memory-engine/layout.d.ts +217 -0
  92. package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
  93. package/dist/core/memory-engine/migrate.d.ts +9 -0
  94. package/dist/core/memory-engine/scan.d.ts +12 -0
  95. package/dist/core/memory-engine/scope-contract.d.ts +61 -1
  96. package/dist/core/memory-engine/sync-client.d.ts +87 -0
  97. package/dist/core/memory-engine/sync.d.ts +60 -0
  98. package/dist/core/memory-engine/tools.d.ts +41 -0
  99. package/dist/core/memory-engine/types.d.ts +188 -0
  100. package/dist/core/memory-recall.d.ts +141 -0
  101. package/dist/core/memory-vector.d.ts +20 -0
  102. package/dist/core/memory.d.ts +458 -0
  103. package/dist/core/message-utils.d.ts +6 -0
  104. package/dist/core/oracle-isolation.d.ts +69 -0
  105. package/dist/core/permission-rule-consent.d.ts +138 -0
  106. package/dist/core/permission-rule-model.d.ts +122 -0
  107. package/dist/core/permission-rule-store.d.ts +119 -3
  108. package/dist/core/permission-rules.d.ts +87 -1
  109. package/dist/core/present-plan-tool.d.ts +20 -0
  110. package/dist/core/pricing.d.ts +26 -0
  111. package/dist/core/property-harness.d.ts +86 -0
  112. package/dist/core/protocol-naming.d.ts +38 -0
  113. package/dist/core/protocol-table.d.ts +61 -0
  114. package/dist/core/push-queue.d.ts +1 -0
  115. package/dist/core/remote-env.d.ts +383 -1
  116. package/dist/core/retention-policy.d.ts +33 -0
  117. package/dist/core/retention.d.ts +51 -0
  118. package/dist/core/roles.d.ts +59 -0
  119. package/dist/core/runner/active-skill-scope.d.ts +34 -0
  120. package/dist/core/runner/assemble-result.d.ts +134 -0
  121. package/dist/core/runner/compaction-call-options.d.ts +97 -1
  122. package/dist/core/runner/grounding-signal.d.ts +10 -0
  123. package/dist/core/runner/image.d.ts +17 -0
  124. package/dist/core/runner/image.js +29 -15
  125. package/dist/core/runner/memory-consolidation.d.ts +60 -0
  126. package/dist/core/runner/prepare-memory.d.ts +59 -0
  127. package/dist/core/runner/prepare-task.d.ts +1011 -2
  128. package/dist/core/runner/prepare-task.js +12 -11
  129. package/dist/core/runner/prompt-suggestions.d.ts +7 -0
  130. package/dist/core/runner/runtask.d.ts +304 -3
  131. package/dist/core/runner/session-file-state-replay.d.ts +49 -0
  132. package/dist/core/runner/session-rule-policy.d.ts +58 -0
  133. package/dist/core/runner/strict-output-schema.d.ts +18 -3
  134. package/dist/core/runner/synthetic-tools.d.ts +113 -0
  135. package/dist/core/runner/teardown-bounded.d.ts +34 -0
  136. package/dist/core/runner/tool-disclosure.d.ts +227 -0
  137. package/dist/core/runner/tool-output-projection.d.ts +6 -0
  138. package/dist/core/runner/turn-attachments.d.ts +634 -0
  139. package/dist/core/runner/usage-accounting.d.ts +32 -0
  140. package/dist/core/runtime.d.ts +9 -0
  141. package/dist/core/safe-notify.d.ts +64 -0
  142. package/dist/core/safety-axis-vocab.d.ts +23 -0
  143. package/dist/core/safety-merge-corpus.d.ts +37 -0
  144. package/dist/core/scheduler.d.ts +121 -0
  145. package/dist/core/secret-env.d.ts +32 -0
  146. package/dist/core/select-model.d.ts +15 -0
  147. package/dist/core/sensitive-path-policy.d.ts +42 -0
  148. package/dist/core/session-policy-store.d.ts +94 -0
  149. package/dist/core/session-reconcile.d.ts +80 -0
  150. package/dist/core/session-store.d.ts +85 -0
  151. package/dist/core/session.d.ts +153 -0
  152. package/dist/core/shared-memory/contract.d.ts +22 -0
  153. package/dist/core/shared-memory/normalize.d.ts +123 -2
  154. package/dist/core/shared-memory/tools.d.ts +14 -0
  155. package/dist/core/shared-memory/types.d.ts +105 -0
  156. package/dist/core/shutdown-debug.d.ts +6 -0
  157. package/dist/core/side-query.d.ts +38 -0
  158. package/dist/core/side-query.js +6 -1
  159. package/dist/core/skill-tool-specifier.d.ts +72 -0
  160. package/dist/core/skills-directory.d.ts +100 -1
  161. package/dist/core/spec-contract.d.ts +89 -0
  162. package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
  163. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
  164. package/dist/core/store-contracts/contract-harness.d.ts +20 -0
  165. package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
  166. package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
  167. package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
  168. package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
  169. package/dist/core/strategy-store.d.ts +37 -0
  170. package/dist/core/stub-env.d.ts +7 -0
  171. package/dist/core/surrogate-safe-slice.d.ts +35 -0
  172. package/dist/core/task-notification.d.ts +202 -0
  173. package/dist/core/task-outcome.d.ts +53 -0
  174. package/dist/core/task-registry-agent.d.ts +337 -1
  175. package/dist/core/task-registry-monitor.d.ts +12 -0
  176. package/dist/core/task-registry-shared.d.ts +540 -0
  177. package/dist/core/task-registry.d.ts +343 -0
  178. package/dist/core/task-registry.js +13 -2
  179. package/dist/core/task-tool-shape.d.ts +44 -0
  180. package/dist/core/tighten-task-spec.d.ts +21 -0
  181. package/dist/core/tool-detach.d.ts +21 -0
  182. package/dist/core/tool-errors.d.ts +131 -0
  183. package/dist/core/tool-errors.js +4 -0
  184. package/dist/core/tool-name-aliases.d.ts +27 -0
  185. package/dist/core/tool-policy.d.ts +555 -0
  186. package/dist/core/tool-result-budget.d.ts +32 -0
  187. package/dist/core/tool-result-store.d.ts +174 -1
  188. package/dist/core/tools.d.ts +45 -0
  189. package/dist/core/trace.d.ts +323 -0
  190. package/dist/core/types.d.ts +3859 -2
  191. package/dist/core/untrusted-egress.d.ts +8 -0
  192. package/dist/core/untrusted-text.d.ts +156 -0
  193. package/dist/core/usage-window-store.d.ts +95 -0
  194. package/dist/core/version.d.ts +1 -0
  195. package/dist/core/warm-resume.d.ts +17 -0
  196. package/dist/core/wiring-manifest.d.ts +169 -0
  197. package/dist/core/with-retry.d.ts +24 -0
  198. package/dist/core/workflow-journal-store.d.ts +160 -0
  199. package/dist/core/workflow-run-store-contract.d.ts +25 -0
  200. package/dist/core/workflow-run-store.d.ts +119 -0
  201. package/dist/engine/compaction/compaction.d.ts +256 -1
  202. package/dist/engine/compaction/utils.d.ts +94 -0
  203. package/dist/engine/execution-env/kill-tree.d.ts +29 -0
  204. package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
  205. package/dist/engine/harness/agent-harness.d.ts +116 -0
  206. package/dist/engine/harness/agent-harness.js +3 -14
  207. package/dist/engine/harness/messages.d.ts +15 -0
  208. package/dist/engine/harness/types.d.ts +464 -2
  209. package/dist/engine/llm/diagnostics.d.ts +4 -0
  210. package/dist/engine/llm/event-stream.d.ts +3 -0
  211. package/dist/engine/llm/index.d.ts +7 -0
  212. package/dist/engine/llm/types.d.ts +500 -3
  213. package/dist/engine/llm/validation.d.ts +3 -0
  214. package/dist/engine/loop/agent-loop.d.ts +87 -2
  215. package/dist/engine/loop/runtime-deps.d.ts +7 -0
  216. package/dist/engine/loop/types.d.ts +424 -0
  217. package/dist/engine/lsp/frame-decoder.d.ts +13 -0
  218. package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
  219. package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
  220. package/dist/engine/session/import-validate.d.ts +27 -0
  221. package/dist/engine/session/log-digest.d.ts +93 -0
  222. package/dist/engine/session/memory-repo.d.ts +6 -0
  223. package/dist/engine/session/memory-storage.d.ts +2 -0
  224. package/dist/engine/session/session.d.ts +75 -0
  225. package/dist/engine/session/storage-base.d.ts +8 -0
  226. package/dist/fixtures/index.d.ts +36 -0
  227. package/dist/index.d.ts +16 -1
  228. package/dist/index.js +0 -1
  229. package/dist/internal/harness-types.d.ts +6 -0
  230. package/dist/internal/harness.d.ts +11 -0
  231. package/dist/internal/llm.d.ts +6 -0
  232. package/dist/orchestration/builtin-workflows.d.ts +53 -0
  233. package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
  234. package/dist/orchestration/goal.d.ts +57 -0
  235. package/dist/orchestration/goal.js +3 -0
  236. package/dist/orchestration/run-spec.d.ts +42 -0
  237. package/dist/orchestration/run-workflow-tool.d.ts +169 -0
  238. package/dist/orchestration/workflow-governance.d.ts +61 -0
  239. package/dist/orchestration/workflow-meta.d.ts +28 -0
  240. package/dist/orchestration/workflow-observe.d.ts +60 -0
  241. package/dist/orchestration/workflow-primitives.d.ts +23 -1
  242. package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
  243. package/dist/orchestration/workflow-script-runner.d.ts +88 -0
  244. package/dist/orchestration/workflow-script-store.d.ts +98 -0
  245. package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
  246. package/dist/orchestration/workflow-types.d.ts +169 -2
  247. package/dist/orchestration/workflow.d.ts +358 -0
  248. package/dist/prompt-assembly/artifact-store.d.ts +33 -0
  249. package/dist/prompt-assembly/artifact.d.ts +25 -0
  250. package/dist/prompt-assembly/assemble.d.ts +20 -0
  251. package/dist/prompt-assembly/composer.d.ts +29 -0
  252. package/dist/prompt-assembly/epoch.d.ts +55 -1
  253. package/dist/prompt-assembly/event-registry.d.ts +35 -0
  254. package/dist/prompt-assembly/explain.d.ts +12 -0
  255. package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
  256. package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
  257. package/dist/prompt-assembly/types.d.ts +115 -0
  258. package/dist/prompts/coordinator.d.ts +27 -0
  259. package/dist/prompts/default.d.ts +539 -0
  260. package/dist/prompts/simple-sections.d.ts +45 -0
  261. package/dist/prompts/supervisor.d.ts +66 -0
  262. package/dist/scenarios/env.d.ts +28 -0
  263. package/dist/scenarios/full-body.d.ts +50 -0
  264. package/dist/scenarios/scenario-registry.d.ts +60 -0
  265. package/dist/scenarios/teacher-quickstart.d.ts +27 -0
  266. package/dist/server/http.d.ts +17 -0
  267. package/dist/stores/cc/lockfile.d.ts +6 -0
  268. package/dist/stores/cc/mailbox-store.d.ts +8 -0
  269. package/dist/stores/cc/roster-adapter.d.ts +4 -0
  270. package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
  271. package/dist/stores/file/background-agent-store.d.ts +24 -0
  272. package/dist/stores/file/checkpoint-store.d.ts +38 -0
  273. package/dist/stores/file/file-snapshot-store.d.ts +25 -0
  274. package/dist/stores/file/fs-atomic.d.ts +155 -0
  275. package/dist/stores/file/index.d.ts +89 -0
  276. package/dist/stores/file/mailbox-store.d.ts +36 -0
  277. package/dist/stores/file/memory-store.d.ts +82 -0
  278. package/dist/stores/file/permission-rule-store.d.ts +79 -0
  279. package/dist/stores/file/session-policy-store.d.ts +28 -0
  280. package/dist/stores/file/session-store.d.ts +40 -0
  281. package/dist/stores/file/shared-ledger.d.ts +83 -0
  282. package/dist/stores/file/tool-result-store.d.ts +11 -0
  283. package/dist/stores/file/usage-window-store.d.ts +18 -0
  284. package/dist/stores/file/workflow-journal-store.d.ts +100 -0
  285. package/dist/stores/file/workflow-run-store.d.ts +11 -0
  286. package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
  287. package/dist/tools/fs/encoding.d.ts +60 -0
  288. package/dist/tools/fs/fs-bash.d.ts +133 -0
  289. package/dist/tools/fs/fs-pdf.d.ts +28 -0
  290. package/dist/tools/fs/fs-search-tools.d.ts +5 -0
  291. package/dist/tools/fs/fs-shared.d.ts +360 -0
  292. package/dist/tools/fs/fs-write.d.ts +16 -0
  293. package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
  294. package/dist/tools/fs/index.d.ts +79 -0
  295. package/dist/tools/fs/notebook.d.ts +56 -0
  296. package/dist/tools/fs/pdf.d.ts +70 -0
  297. package/dist/tools/fs/pdf.js +8 -2
  298. package/dist/tools/fs/repo-map.d.ts +10 -0
  299. package/dist/tools/fs/safety.d.ts +376 -0
  300. package/dist/tools/fs/search.d.ts +131 -0
  301. package/dist/tools/loop-tick.d.ts +24 -0
  302. package/dist/tools/monitor.d.ts +55 -0
  303. package/dist/tools/scheduler-tools.d.ts +51 -0
  304. package/dist/tools/sql-adapters.d.ts +18 -0
  305. package/dist/tools/sql.d.ts +25 -0
  306. package/dist/tools/task-list.d.ts +77 -0
  307. package/dist/tools/todo.d.ts +8 -0
  308. package/dist/tools/web.d.ts +184 -0
  309. package/dist/tools/worktree.d.ts +81 -0
  310. package/package.json +2 -2
  311. package/dist/tools/gitea-issue.d.ts +0 -13
  312. package/dist/tools/gitea-issue.js +0 -75
@@ -1,26 +1,76 @@
1
+ /**
2
+ * design/179 §8 — the persisted allow-rule store seam, its core-private write face, and the removal entry.
3
+ *
4
+ * ## Two faces, deliberately unequal
5
+ *
6
+ * A deployment sees a READ face: `list()`, scoped to one verified principal by a factory. There is no
7
+ * exported write API at all — the only way a rule enters the store through the engine is the core-private
8
+ * redemption path (`permission-rule-consent.ts`), which requires an approved durable approval record.
9
+ * `expectedRev` is concurrency control, not authorization, so "hold a put API and skip the ticket" is not
10
+ * a shape that exists here rather than a rule someone must remember.
11
+ *
12
+ * That claim is scoped to the API. A standard in-process deployment shares filesystem credentials with the
13
+ * user, so it can edit a file backend's file directly — the same trust model the settings file it mirrors
14
+ * has. The checksum detects corruption, not an editor who recomputes it. This is stated, not defended
15
+ * against, in v1: the file backend's trust is host = user, no more and no less.
16
+ *
17
+ * ## Principal scoping is a factory boundary, not a parameter
18
+ *
19
+ * `forPrincipal` returns a store already anchored to one identity, so `list()` has no cross-tenant
20
+ * argument to pass wrong. An unauthenticated task (`principal === undefined`) resolves to ZERO rules
21
+ * rather than to a shared bucket — fail-closed on a loosening face means fewer allows, never a shared one.
22
+ *
23
+ * ## Delete is a tombstone, and the tombstone IS the operation's identity
24
+ *
25
+ * Removal takes the observed-remove form: the tombstone carries every add dot the deleting replica could
26
+ * see at delete time, and that observation is FIXED when the call constructs it. An OCC retry inside that
27
+ * one live call re-submits the SAME tombstone — re-snapshotting would suck a concurrently landed add into
28
+ * `removedDots` and swallow a legitimate re-add. The fixing is scoped to one live call on purpose: there
29
+ * is no cross-process or cross-restart continuation of a delete in v1, so calling the entry again after a
30
+ * restart is a NEW delete intent (a new observation, a new tombstone) — which is the correct reading of a
31
+ * person pressing delete a second time.
32
+ */
1
33
  import type { PersistedAllowRule, RuleAdd, RuleDot, RuleScope, RuleTombstone } from "./permission-rule-model.js";
2
34
  import type { StoreDurability, StoreFidelity } from "./checkpoint-store.js";
35
+ /** One store read: the rules as persisted, their tombstones, and the revision they were read at. */
3
36
  export interface StoredAllowRules {
37
+ /** Rules with their FULL add sets — tombstoned dots already removed by the backend on read. */
4
38
  rules: PersistedAllowRule[];
5
39
  tombstones: RuleTombstone[];
40
+ /** Monotonic revision of this store, for optimistic concurrency on every write. */
6
41
  rev: number;
42
+ /** Integrity fingerprint the backend computed, when it has one. Corruption detection only. */
7
43
  checksum?: string;
8
44
  }
45
+ /**
46
+ * The host-visible store face: read-only, already anchored to a single principal.
47
+ *
48
+ * A backend that fails to read must not silently report an empty set as if it were an empty store — it
49
+ * throws, and the lane's caller turns that into zero rules PLUS a loud disclosure. Both outcomes deny
50
+ * more than they allow; only one of them is honest about why.
51
+ */
9
52
  export interface PermissionRuleStore {
10
53
  list(): Promise<StoredAllowRules>;
54
+ /** Declared durability; an undeclared backend reads fail-closed as `"process-local"`. */
11
55
  readonly durability?: StoreDurability;
56
+ /** Declared serialization fidelity, same doctrine as the other store families. */
12
57
  readonly fidelity?: StoreFidelity;
13
58
  }
59
+ /** Resolves a store for one verified principal. `undefined` ⇒ a store that reports zero rules. */
14
60
  export interface PermissionRuleStoreProvider {
15
61
  forPrincipal(principal: string | undefined): PermissionRuleStore;
16
62
  }
63
+ /** The outcome of one accepted write. */
17
64
  export interface PutResult {
18
65
  rev: number;
19
66
  }
67
+ /** Authorization accompanying an add: the redemption that produced it. Carrying the record id makes the
68
+ * add's logical operation identity checkable at the backend, not just at the caller. */
20
69
  export interface RedemptionAuthorization {
21
70
  recordId: string;
22
71
  principal: string;
23
72
  }
73
+ /** The add half of the write union: one redeemed approval becoming one dot on one (rule, scope). */
24
74
  export interface RuleAddDelta {
25
75
  kind: "redemption-add";
26
76
  rule: string;
@@ -31,12 +81,25 @@ export interface RuleAddDelta {
31
81
  add: RuleAdd;
32
82
  redemption: RedemptionAuthorization;
33
83
  }
84
+ /** The delete half: appending one tombstone, and nothing else. */
34
85
  export interface RuleDeleteDelta {
35
86
  kind: "tighten-delete";
36
87
  tombstone: RuleTombstone;
37
88
  }
89
+ /**
90
+ * What a write may say. Authorization discriminates on the DELTA SHAPE, not on a full snapshot: only the
91
+ * add arm can introduce a dot, and the delete arm carries a tombstone and no adds. A backend additionally
92
+ * REFUSES at runtime any delete that would introduce a new add dot — structure and runtime check together,
93
+ * so "pick the delete arm and smuggle an add" is neither expressible nor accepted.
94
+ */
38
95
  export type RuleWriteDelta = RuleAddDelta | RuleDeleteDelta;
96
+ /**
97
+ * The core-private write face. Deliberately absent from the package's public exports: a host cannot hold
98
+ * one, so no API-level path to the store bypasses the consent protocol.
99
+ */
39
100
  export interface PermissionRuleWriter {
101
+ /** Mint the next dot for this replica. Counters need only be unique and monotonic, so a dot minted for
102
+ * an operation that then fails is simply never used. */
40
103
  nextDot(): Promise<RuleDot>;
41
104
  apply(delta: RuleWriteDelta, opts: {
42
105
  expectedRev: number;
@@ -45,28 +108,75 @@ export interface PermissionRuleWriter {
45
108
  rev: number;
46
109
  }>;
47
110
  }
111
+ /**
112
+ * The internal handle a writable backend hangs its write face on. Not exported from the package index —
113
+ * that omission IS the boundary described in the module doc.
114
+ */
48
115
  export declare const PERMISSION_RULE_WRITER = "__semaPermissionRuleWriter";
116
+ /** A store that also carries the core-private write face. */
49
117
  export interface WritablePermissionRuleStore extends PermissionRuleStore {
50
118
  readonly [PERMISSION_RULE_WRITER]: PermissionRuleWriter;
51
119
  }
120
+ /** The writer of a store, or `undefined` when the backend is read-only from the engine's side. */
52
121
  export declare function writerOf(store: PermissionRuleStore): PermissionRuleWriter | undefined;
122
+ /** Do two scopes name the same place? */
53
123
  export declare function sameScope(a: RuleScope, b: RuleScope): boolean;
124
+ /**
125
+ * Apply tombstones to a raw persisted set: an add survives iff its dot appears in no tombstone for the
126
+ * same (rule, scope). The criterion is dot IDENTITY — single dots across replicas carry no order to
127
+ * compare — and an add the deleting replica never observed survives (add-wins), because behind every add
128
+ * there is one real human approval.
129
+ */
54
130
  export declare function applyTombstones(rules: readonly PersistedAllowRule[], tombstones: readonly RuleTombstone[]): PersistedAllowRule[];
131
+ /** Fold one delta into a raw rule set, returning the new set. Pure — the backends share it so the file and
132
+ * in-memory forms cannot drift in what a delta MEANS. */
55
133
  export declare function foldDelta(rules: readonly PersistedAllowRule[], delta: RuleAddDelta): PersistedAllowRule[];
134
+ /** Every add dot present in a rule set. */
56
135
  export declare function addDotsOf(rules: readonly PersistedAllowRule[]): RuleDot[];
136
+ /**
137
+ * The runtime half of the delete-arm authorization, shared by every backend so the two cannot drift on
138
+ * what a delta MEANS.
139
+ *
140
+ * The union already makes "pick the delete arm and also add something" unspellable in TypeScript, and a
141
+ * union does not constrain a JavaScript caller's payload — so the check is executed, not merely intended.
142
+ * Every backend calls this before appending a tombstone.
143
+ */
57
144
  export declare function assertDeleteDeltaCarriesNoAdd(delta: RuleDeleteDelta): void;
145
+ /** Integrity fingerprint over a store's own facts. Corruption detection, not tamper-proofing. */
58
146
  export declare function ruleStoreChecksum(payload: unknown): Promise<string>;
59
- export type RemoveResult = {
147
+ /**
148
+ * The result of a removal.
149
+ *
150
+ * `conflict` is not a member: an OCC conflict is retried internally to a terminal state, so a caller never
151
+ * has to write the retry loop that must not re-snapshot.
152
+ */
153
+ export type RemoveResult =
154
+ /** The tombstone landed and none of the observed dots survive. `stillLive` reports whether an approval
155
+ * that landed DURING this call keeps the rule alive anyway (add-wins) — a real outcome with a name,
156
+ * not an anomaly. */
157
+ {
60
158
  status: "removed";
61
159
  rev: number;
62
160
  stillLive: boolean;
63
- } | {
161
+ }
162
+ /** Nothing to remove — including a repeated delete. No empty tombstone is minted. */
163
+ | {
64
164
  status: "no-op";
65
165
  rev: number;
66
- } | {
166
+ }
167
+ /** Terminal failure, confirmed by read-back to have written NOTHING. When the read-back itself failed,
168
+ * `error` says so and the caller reconciles with `list()`. */
169
+ | {
67
170
  status: "failed";
68
171
  error: string;
69
172
  };
173
+ /**
174
+ * Remove a persisted rule.
175
+ *
176
+ * Removal is the TIGHTENING direction, so it needs no approval-record ceremony: a host may narrow on a
177
+ * user's behalf, it may not widen. The asymmetry is the point — minting takes a human's click, revoking
178
+ * does not.
179
+ */
70
180
  export declare function removePersistedRule(opts: {
71
181
  rule: string;
72
182
  scope: RuleScope;
@@ -74,7 +184,13 @@ export declare function removePersistedRule(opts: {
74
184
  provider: PermissionRuleStoreProvider;
75
185
  }): Promise<RemoveResult>;
76
186
  export declare function errText(err: unknown): string;
187
+ /** A store that always reports zero rules — what an unauthenticated principal resolves to, and the shape a
188
+ * failed read degrades to at the consumption site. */
77
189
  export declare const EMPTY_RULE_STORE: PermissionRuleStore;
190
+ /**
191
+ * In-memory backend — the reference implementation of the delta semantics, and the one the tests drive.
192
+ * `process-local` by declaration: it makes no durability promise it cannot keep.
193
+ */
78
194
  export declare class InMemoryPermissionRuleStore implements WritablePermissionRuleStore {
79
195
  private readonly actor;
80
196
  readonly durability: StoreDurability;
@@ -1,17 +1,54 @@
1
+ /**
2
+ * design/127 — **参数级权限规则 DSL**(CC 2.1.201 追平批 γ)。声明式规则字符串 → {@link ToolPolicy}
3
+ * 编译器:`"Tool"`(裸)/ `"Tool(param:pattern)"`(参数级,`*` 通配全串锚定)。CC ground truth
4
+ * 行号级:解析 `Lh` :55214 · 通配 `ZMr` :55196 · 参数级 matcher `gnn` :595123 · 评估序 `G1e` :595272。
5
+ *
6
+ * 架构边界(design/127 §0,重判过的「core 不长 rule interpreter」):这是纯函数式、opt-in、零
7
+ * run-loop 介入的「声明式数据→ToolPolicy」工厂(`createCoarseCommandNamePolicy` 同形态先例)。
8
+ * core 不读设置文件、不管 source 层级合并 —— Settings-loader 把各层合并成**单一规则表**后编译
9
+ * **一个** policy(不要按层各编译再组合:combinePolicies 的 fold 里 ask 胜 allow,跨 policy 的
10
+ * 显式 allow 规则会被另一 policy 的 ask 吞掉 —— codex 127 审 B3)。
11
+ *
12
+ * 🔴 与 CC 的三处有意差(design/127 r2):
13
+ * - CC 参数级 generic 道无 allow lane(gnn 只有 deny/ask)—— 我们同样:`allow` + 参数级 content =
14
+ * 无效规则;auto-allow 只来自裸工具规则。
15
+ * - CC 对尾缀垃圾静默降级为裸名(Lh `n !== len-1`)—— `parsePermissionRule` 保持 CC parity,但
16
+ * **工厂 validator strict**:降级即 invalid(fail-fast 世界观,写错的规则不能静默变宽)。
17
+ * - 已知主字段参数规则(如 `Bash(command:…)`)默认 **reject**:通配是 trim 后**整串 lexical**
18
+ * 匹配,不是 shell AST / 前缀 lane —— `Bash(command:git push*)` 匹配不了 `cd /x && git push`,
19
+ * 「以为挡住了」比没挡更危险(codex 127 审 M2)。`primaryFieldGeneric:"allow-lexical"` 显式解锁。
20
+ */
1
21
  import type { NamedToolPolicy } from "./tool-policy.js";
22
+ /** [K-PLATFORM-SWEEP] MINOR#11: Bash's REAL non-primary arg names, accepted as generic param rules
23
+ * (`Bash(timeout:...)`). Exported SOLELY so a lockstep test can assert it against the live Bash tool
24
+ * schema — a schema param added without updating this set would compile to silently-never-matching
25
+ * rules (the exact drift class the Opus 复审 m note warned about). */
2
26
  export declare const BASH_GENERIC_PARAMS: ReadonlySet<string>;
3
27
  export interface PermissionRule {
28
+ /** CC 语法:`"Tool"` 或 `"Tool(param:pattern)"`。`Tool()`/`Tool(*)` 归一为裸规则;括号可 `\(`/`\)` 转义。 */
4
29
  rule: string;
5
30
  behavior: "deny" | "ask" | "allow";
31
+ /** Provenance(codex 127 审 M7):进 deny/ask 的 message 供审计(e.g. `"policySettings"`)。层级
32
+ * 优先级/tighten-only 语义在 Settings-loader,不在这里。 */
6
33
  source?: string;
7
34
  }
35
+ /** Parse result — CC `Lh` parity (INCLUDING the silent bare-name downgrade on malformed parens; the
36
+ * factory validator is strict on top of this, see module doc). */
8
37
  export interface ParsedPermissionRule {
9
38
  toolName: string;
10
39
  ruleContent?: string;
11
40
  }
12
41
  export interface PermissionRuleIssue {
13
42
  rule: string;
14
- code: "invalid.empty_tool" | "invalid.paren" | "invalid.param_split" | "invalid.allow_param_rule" | "invalid.primary_field" | "invalid.cap_exceeded" | "unsupported.bash_prefix" | "unsupported.bash_prefix_rules_store" | "unsupported.file_glob" | "unsupported.mcp_paren" | "unsupported.unknown_param";
43
+ /** `invalid.*` = 语法/语义错;`unsupported.*` = CC 合法但 v1 不支持的 lane(codex 127 B5:独立
44
+ * 分类,绝不静默 no-op —— `Bash(npm run:*)` 被当 generic 参数规则接受后永不匹配是最危险的失败形态)。 */
45
+ code: "invalid.empty_tool" | "invalid.paren" | "invalid.param_split" | "invalid.allow_param_rule" | "invalid.primary_field" | "invalid.cap_exceeded" | "unsupported.bash_prefix"
46
+ /** design/179 D7: a Bash prefix rule under `bashPrefixLane:"rules-store"` — reported so a migration
47
+ * report can tell "route this through the rule store" apart from "this is a mistake". */
48
+ | "unsupported.bash_prefix_rules_store" | "unsupported.file_glob" | "unsupported.mcp_paren"
49
+ /** HRD-PRM-7: a param-level rule naming a parameter the target tool does not carry. Additive member —
50
+ * the lane that used to compile silently and never match (see {@link FILE_TOOL_PARAMS}). */
51
+ | "unsupported.unknown_param";
15
52
  message: string;
16
53
  }
17
54
  export interface PermissionRuleCaps {
@@ -19,18 +56,67 @@ export interface PermissionRuleCaps {
19
56
  maxRuleLength: number;
20
57
  maxPatternLength: number;
21
58
  maxStars: number;
59
+ /** Scalar arg values longer than this are NOT matched textually — the rule **fail-closes** to its
60
+ * lane (a deny rule targeting an oversized value denies; an ask rule asks). 租户规则 × 模型巨串
61
+ * 的热路径成本上界(codex 127 审 M6)。 */
22
62
  maxScalarValueChars: number;
23
63
  }
24
64
  export interface PermissionRulePolicyOptions {
65
+ /** Invalid/unsupported rules: `"throw"`(default — 部署作者写错要立刻知道)aggregates ALL issues
66
+ * into one error; `"skip"` drops them (pair with {@link validatePermissionRules} for a report, and/or
67
+ * supply {@link onIssue}). Exception(codex 实现审 M3):`invalid.cap_exceeded` on the WHOLE rule set
68
+ * (maxRules) throws EVEN under `"skip"` — skipping it would compile an EMPTY table and fail-open. */
25
69
  onInvalidRule?: "throw" | "skip";
70
+ /** Called once per dropped rule under `"skip"` (audit surface — silent drops are how a deployment
71
+ * discovers, months later, that its deny never existed). Default: one aggregated `console.warn`. */
26
72
  onIssue?: (issue: PermissionRuleIssue) => void;
73
+ /** What the policy returns when NO rule matches. Default `"allow"` = 本 policy 无意见(组合语义)。
74
+ * default-closed 部署用 `"ask"`/`"deny"` —— 必须在这 INSIDE the policy(codex 127 审 B3:链尾
75
+ * ask policy 会在 fold 里吞掉本 policy 的显式 allow)。 */
27
76
  defaultAction?: "allow" | "ask" | "deny";
77
+ /** 已知主字段参数规则(`Bash(command:…)` 等)的处置。默认 `"reject"`(整串 lexical ≠ 前缀/AST,
78
+ * 假安全感);`"allow-lexical"` 显式接受并按 generic 语义匹配。 */
28
79
  primaryFieldGeneric?: "reject" | "allow-lexical";
80
+ /**
81
+ * design/179 D7 — where a Bash PREFIX rule (`Bash(npm run:*)`) belongs.
82
+ *
83
+ * This DSL is a pure function with no access to a deployment's wiring, so it cannot discover on its own
84
+ * that a persisted-rule store exists; the choice has to be said out loud. `"reject"` is the default and
85
+ * keeps this file's behavior byte-identical to what it was: a prefix rule is an `unsupported.bash_prefix`
86
+ * issue, because a generic parameter matcher would compile it into a rule that never matches anything.
87
+ * `"rules-store"` says the deployment routes that form through the persisted allow-rule lane instead —
88
+ * the issue is then re-coded to {@link PermissionRuleIssue.code} `unsupported.bash_prefix_rules_store`,
89
+ * which reads as "handled elsewhere" rather than "you wrote something wrong". Either way the rule does
90
+ * NOT enter this policy: the two lanes stay separate, and only the report changes.
91
+ */
29
92
  bashPrefixLane?: "reject" | "rules-store";
30
93
  caps?: Partial<PermissionRuleCaps>;
31
94
  }
95
+ /**
96
+ * Parse one rule string — CC `Lh` :55214 parity, including its lenient downgrades (malformed parens /
97
+ * trailing garbage ⇒ the WHOLE string becomes the bare tool name). The strict complement lives in
98
+ * {@link validatePermissionRules} — use that (or the factory) to refuse the downgrades.
99
+ */
32
100
  export declare function parsePermissionRule(rule: string): ParsedPermissionRule;
101
+ /**
102
+ * Linear-time `*` glob match (design/127 M6: NOT a RegExp — patterns may come from tenant-supplied
103
+ * Settings layers; the classic two-pointer walk has zero ReDoS surface and the same semantics as CC's
104
+ * anchored `^…$`+dotAll construction: every non-`*` char is literal, `*` spans anything incl. newlines).
105
+ */
33
106
  export declare function wildcardMatch(pattern: string, value: string): boolean;
107
+ /** Exported for the lockstep guard only (see {@link FILE_TOOL_PARAMS}) — not part of the rule DSL. */
34
108
  export declare const fileToolParamVocabulary: (canonicalTool: string) => ReadonlySet<string> | undefined;
109
+ /** Dry-run 校验/迁移报告(codex 127 审 B5):不 throw,返回全部 issues(含 `unsupported.*` 分类,
110
+ * 供从 CC settings 迁移的部署逐条对照)。 */
35
111
  export declare function validatePermissionRules(rules: PermissionRule[], opts?: Pick<PermissionRulePolicyOptions, "primaryFieldGeneric" | "caps" | "bashPrefixLane">): PermissionRuleIssue[];
112
+ /**
113
+ * Compile declarative permission rules into ONE {@link ToolPolicy} (design/127). Evaluation order
114
+ * inside the policy (CC `G1e` :595272 isomorph): bare deny → param deny → bare ask → param ask →
115
+ * bare allow → `defaultAction`. `check()` is idempotent and side-effect-free (combinePolicies 契约);
116
+ * all parsing/validation happens HERE, the hot path never re-parses.
117
+ *
118
+ * ⚠️ Composition note (codex 127 审 B3): an `allow` from this policy is "no objection", NOT a
119
+ * cross-policy override — another policy's ask/deny still outranks it in the combinePolicies fold.
120
+ * Express default-closed via `defaultAction`, never via a trailing always-ask policy.
121
+ */
36
122
  export declare function createPermissionRulePolicy(rules: PermissionRule[], opts?: PermissionRulePolicyOptions): NamedToolPolicy;
@@ -1,7 +1,27 @@
1
1
  import type { ToolSpec } from "./types.js";
2
+ /** The first-party plan-review tool's name (design/80 D-B; CC `ExitPlanMode` parity). Reserved when
3
+ * `TaskSpec.enablePlanMode` is set. */
2
4
  export declare const PRESENT_PLAN_TOOL_NAME = "ExitPlanMode";
5
+ /** design/108 — the first-party "enter plan mode" tool's name (CC `EnterPlanMode` parity). Mounted (alongside
6
+ * `present_plan`) when `TaskSpec.enablePlanMode` is set, so the model can self-impose read-only plan mode. */
3
7
  export declare const ENTER_PLAN_MODE_TOOL_NAME = "EnterPlanMode";
8
+ /**
9
+ * design/108 — the first-party `enter_plan_mode` tool (CC `EnterPlanMode` parity). A THIN composition over the
10
+ * general `ctx.enterPlanMode()` primitive: the model calls it to self-impose read-only plan mode for the rest of
11
+ * THIS run. `effect:"read"` (it grants nothing — it RESTRICTS). `executionMode:"sequential"` so that in a batch
12
+ * like `[enter_plan_mode, edit_file]` the whole batch runs sequentially (agent-loop `hasSequentialToolCall`),
13
+ * making enter execute (set the flag) BEFORE the sibling edit is prepared+gated — closing the same-batch window.
14
+ * Exit is via `present_plan` (→ plan_review → human approve-resume), not by this tool.
15
+ */
4
16
  export declare function createEnterPlanModeTool(enterPlanMode: () => void): ToolSpec;
17
+ /**
18
+ * design/80 D-B — the first-party `present_plan` tool (CC `ExitPlanMode` parity). A THIN composition over the
19
+ * general `ctx.requestReview()` primitive: the model calls it with a plan; the tool returns the plan as its
20
+ * content (so it reaches the reviewer via the transcript — the plan is NOT stored on the gate, design/76 §9),
21
+ * and signals the engine to pause with a `plan_review` checkpoint at the next safe turn boundary. The tool has
22
+ * NO side effect (`effect:"read"`); the actual pause/mint is the engine's, gated on a wired `checkpointStore`.
23
+ * `requestReview` is the prepare-task closure (the same primitive `ctx.requestReview` exposes to caller tools).
24
+ */
5
25
  export declare function createPresentPlanTool(requestReview: (opts?: {
6
26
  reason?: string;
7
27
  }) => void): ToolSpec;
@@ -1,10 +1,25 @@
1
+ /**
2
+ * Cost computation (1.37). core never hardcodes provider pricing — a deployment injects it via
3
+ * `RunnerDeps.pricing` or each `Model.cost`. All prices are **absolute per-1M-token USD**, not
4
+ * multipliers: each provider's adapter precomputes its discount into an absolute value
5
+ * (OpenAI/DeepSeek: the cache-hit price; Anthropic: base×0.1 read / ×1.25 5min-write / ×2.0 1h-write).
6
+ */
7
+ /** Per-1M-token absolute prices (USD) for a model. */
1
8
  export interface ModelPricing {
2
9
  inputPer1M: number;
3
10
  outputPer1M: number;
11
+ /** Cache-read (hit) absolute price per 1M. Default 0 (treated as full-price input if absent). */
4
12
  cacheReadPer1M?: number;
13
+ /** Cache-write 5-min-TTL absolute price per 1M (Anthropic ~1.25× base). 0 elsewhere. */
5
14
  cacheWritePer1M?: number;
15
+ /** Cache-write 1-hour-TTL absolute price per 1M (Anthropic ~2.0× base). 0 elsewhere. */
6
16
  cacheWriteLongPer1M?: number;
7
17
  }
18
+ /**
19
+ * Unified token counts for one task/turn, **already normalized** so `totalInputTokens` INCLUDES all
20
+ * cache tokens (matching OTel `gen_ai.usage.input_tokens`). `cacheReadTokens`/`cacheWriteTokens`/
21
+ * `cacheWriteTokensLong` are mutually exclusive subsets of `totalInputTokens`.
22
+ */
8
23
  export interface TokenCounts {
9
24
  totalInputTokens: number;
10
25
  cacheReadTokens: number;
@@ -12,7 +27,18 @@ export interface TokenCounts {
12
27
  cacheWriteTokensLong: number;
13
28
  outputTokens: number;
14
29
  }
30
+ /**
31
+ * Cost in **integer micro-USD** (1e-6 USD) — integer to avoid float-accumulation error in billing
32
+ * reconcile (Stripe/AWS-style). Convergent across providers: full-price input = `totalInputTokens`
33
+ * minus all cache tokens; cache read/write priced at their own absolute rates; output at its rate.
34
+ *
35
+ * DeepSeek (hit price as `cacheReadPer1M`, no cache-write) and OpenAI (no 1h write) fall out by their
36
+ * zero token counts; Anthropic uses all fields. This fixes P2 (cached charged at full price) by
37
+ * pricing the cache subset separately instead of trusting the brain's possibly-overstated cost total.
38
+ */
15
39
  export declare function computeCostMicroUsd(counts: TokenCounts, pricing: ModelPricing): number;
40
+ /** Map a vendor `Model.cost` (already per-1M absolute) to `ModelPricing`. We don't emit 1h cache
41
+ * writes, so `cacheWriteLongPer1M` defaults to the 5-min write price (irrelevant while that count is 0). */
16
42
  export declare function modelCostToPricing(cost: {
17
43
  input?: number;
18
44
  output?: number;
@@ -1,39 +1,125 @@
1
+ /**
2
+ * Property-harness (design/57 §9 / design/58) — the **oracle-free** half of the trusted-oracle problem.
3
+ *
4
+ * From a **trusted contract** (supplied by the spec / leader — NEVER the worker, so it dodges BUG8: a worker
5
+ * can't write `assert(true)` here) this derives executable **invariants** that hold for ANY correct
6
+ * implementation, with **no expected values** (no oracle — dodging the "expected is LLM-computed" trap of a
7
+ * generated test) and **no LLM** (pure deterministic — design/56's "execute > analyze"). Run against an
8
+ * implementation over many generated inputs, they catch the **structural-contract** bug class deterministically
9
+ * at **0 false positives** (probe-13: structural 16/16 caught, FP 0/12).
10
+ *
11
+ * It is a thin **complement** to the mechanical exit gate ({@link runExecGate}), not a replacement: it provably
12
+ * **cannot** catch value-semantic bugs — wrong output that is still structurally valid (`abs → square`,
13
+ * titlecase `don't → Don'T`). Those still need a real test suite (MECH) or the L3 judge. The value is the
14
+ * **sound invariant library + the contract→invariant derivation** centralized here (a profile re-deriving it
15
+ * risks unsound invariants = false positives = the thing that makes a gate harmful).
16
+ *
17
+ * Honest limits (two independent probes converged — core probe-13 + search [52], both FP=0):
18
+ * - **The only false-positive risk is an UNFAITHFUL contract.** Each invariant is sound by construction, so a
19
+ * *correct* impl can't violate one — UNLESS the contract misdescribes the intended behavior (declaring a
20
+ * property the correct impl doesn't have). The contract must faithfully describe intent (it is trusted input).
21
+ * - **Order/positional blindness.** `permutation`/`subset`/multiset-based invariants are order-agnostic, so a
22
+ * wrong-order-but-same-elements result (concat `b+a`, a mis-ordered flatten) passes. That is the value-semantic
23
+ * class — catch it with a positional contract entry, a real test (MECH), or the judge.
24
+ * - **No contract ⇒ no signal.** A function with no declared contract derives zero invariants (zero coverage);
25
+ * the catch comes from the *contract* you declare, not from the type alone — this is not magic from signatures.
26
+ *
27
+ * Scope (design/58 §2): no type→input generation (caller supplies `genInput`), no multi-language rendering
28
+ * (this is the JS/TS reference; other languages render their own from {@link FunctionContract}), no
29
+ * non-termination detection (a sync infinite loop blocks {@link checkInvariants} — gate it with the
30
+ * env/exec timeout via `runExecGate`; `totalNoThrow` only catches throws).
31
+ */
32
+ /** Sound, oracle-free invariant kinds (design/58 §1.3). Each holds for ANY correct implementation. */
1
33
  export type InvariantKind = "permutation" | "lengthPreserving" | "subset" | "distinctOutput" | "idempotent" | "involution" | "outputPredicate" | "rangeBound" | "nonNegative" | "nonEmptyPreserving" | "concatPreserving" | "chunkMaxLen" | "lengthEq" | "roundtrip" | "totalNoThrow";
34
+ /**
35
+ * The TRUSTED contract a function is expected to satisfy — from the spec / leader, **never the worker** (BUG8).
36
+ * The predicate/bound fields carry trusted JS supplied by the spec author (not worker output), so the
37
+ * in-process model is safe for them.
38
+ */
2
39
  export interface FunctionContract {
40
+ /** Output is a permutation (same multiset) of the input collection — sort / shuffle / reverse / rotate. */
3
41
  permutation?: boolean;
42
+ /** `|output| === |input collection|`. */
4
43
  lengthPreserving?: boolean;
44
+ /** Output is a sub-multiset of the input collection — filter / take. */
5
45
  subset?: boolean;
46
+ /** Output has no duplicate elements — dedupe / unique. */
6
47
  distinctOutput?: boolean;
48
+ /** `f(f(x))` deep-equals `f(x)` — normalize / sort / dedupe. (Output type must equal input type.) */
7
49
  idempotent?: boolean;
50
+ /** `f(f(x))` deep-equals `x` — reverse / negate. (Output type must equal input type.) */
8
51
  involution?: boolean;
52
+ /** Numeric output is `>= 0` — abs / length / count. */
9
53
  nonNegative?: boolean;
54
+ /** A non-empty input collection implies a non-empty output — titlecase / dedupe. */
10
55
  nonEmptyPreserving?: boolean;
56
+ /** Concatenating the output groups in order deep-equals the input collection — chunk / split. */
11
57
  concatPreserving?: boolean;
58
+ /** The function is an `{ encode, decode }` pair and `decode(encode(x))` deep-equals `x` — serde / base62. */
12
59
  roundtrip?: boolean;
60
+ /** The function must not throw on any valid-typed input. (Non-termination is NOT covered — see file header.) */
13
61
  totalNoThrow?: boolean;
62
+ /** Every output element satisfies this trusted predicate — filter-by-P. */
14
63
  outputPredicate?: (el: any) => boolean;
64
+ /** Numeric output lies within `[lo, hi]` computed from the input by this trusted fn — clamp. */
15
65
  rangeBound?: (input: any) => readonly [number, number];
66
+ /** Every output group has length in `(0, n]` where `n` is this trusted fn of the input — chunk. */
16
67
  chunkMaxLen?: (input: any) => number;
68
+ /** `|output| === ` this trusted fn of the input — e.g. `countdown(n)` has length `n + 1`. */
17
69
  lengthEq?: (input: any) => number;
70
+ /**
71
+ * Extract the input collection when the input WRAPS it — e.g. `(x) => x.a` for `{ a, k }`. Default: the input
72
+ * IS the collection. 🔴 Required for the collection invariants when the input is a wrapper object, else they
73
+ * compare the output against the wrapper instead of the collection (probe-13 soundness fix).
74
+ */
18
75
  inputCollection?: (input: any) => unknown[];
19
76
  }
77
+ /** One derived, runnable invariant. `check(fn, input)` returns `true` iff the invariant HOLDS. */
20
78
  export interface Invariant {
21
79
  kind: InvariantKind;
80
+ /** Human-readable description (surfaced in a violation). */
22
81
  description: string;
82
+ /** For `roundtrip`, `fn` is the `{ encode, decode }` pair; otherwise a unary function. A throw propagates to the runner. */
23
83
  check: (fn: any, input: any) => boolean;
24
84
  }
85
+ /** A concrete invariant violation found by {@link checkInvariants}. */
25
86
  export interface InvariantViolation {
26
87
  kind: InvariantKind;
27
88
  description: string;
89
+ /** The input that triggered it (the first one observed). */
28
90
  input: unknown;
91
+ /** A-5 fold: the violation was detected via the check THROWING on a structurally wrong return value
92
+ * (e.g. `.length` of undefined) rather than returning false — the impl's output doesn't even have
93
+ * the shape the contract implies. fn itself did NOT throw (that is `totalNoThrow`'s domain). */
29
94
  evaluationThrew?: true;
30
95
  }
96
+ /** The outcome of running invariants over generated inputs. */
31
97
  export interface CheckResult {
98
+ /** True iff no invariant was violated across all trials. */
32
99
  ok: boolean;
100
+ /** One entry per violated invariant (first triggering input). */
33
101
  violations: InvariantViolation[];
102
+ /** How many inputs were tried. */
34
103
  trials: number;
35
104
  }
105
+ /**
106
+ * Derive the sound, oracle-free invariants implied by a trusted {@link FunctionContract}. Pure and
107
+ * deterministic. The collection invariants honor `contract.inputCollection` (default: the input is the
108
+ * collection) so a wrapper-object input (`{ a, k }`) is handled correctly.
109
+ */
36
110
  export declare function deriveInvariants(contract: FunctionContract): Invariant[];
111
+ /**
112
+ * Run derived `invariants` against `fn` over `opts.trials` generated inputs (default 200). Returns the
113
+ * violated invariants (first triggering input each).
114
+ *
115
+ * 🔴 Runs `fn` **in the caller's process** (design/58 §1.2). Pass only a TRUSTED `fn`, or invoke this INSIDE
116
+ * the worker's sandbox (a generated test the leader drops into the env and runs via `runExecGate`, gating on
117
+ * exit code). **Non-termination is NOT caught here** — a sync infinite loop blocks the call; bound it with the
118
+ * env/exec timeout. An impl throw is detected by the self-contained `totalNoThrow` invariant (recorded ONLY
119
+ * when totality was contracted — soundness over recall); the runner's `catch` is just a safety net so one
120
+ * pathological input can't crash the whole run. Note: `fn` is invoked once per invariant per trial (twice for
121
+ * `idempotent`/`involution`) — pass a PURE function (the intended use); a side-effecting `fn` is amplified.
122
+ */
37
123
  export declare function checkInvariants(fn: unknown, genInput: (i: number) => unknown, invariants: Invariant[], opts?: {
38
124
  trials?: number;
39
125
  }): CheckResult;
@@ -1,7 +1,45 @@
1
1
  import type { ProtocolNamespace } from "./protocol-table.js";
2
+ /** The provider's tool-name pattern is `^[a-zA-Z0-9_-]{1,64}$` — the limit applies to the ASSEMBLED name,
3
+ * not to its segments (design/116 W5-5, CC 2.1.187 parity `buildMcpToolName`). */
2
4
  export declare const TOOL_NAME_MAX_CHARS = 64;
5
+ /** Reserved for the tool segment when budgeting the peer segment: a peer kept at the full name budget
6
+ * overflows the assembled name on its own (prefix + 64 + separator = 71 > 64), which is how the tool
7
+ * segment used to be handed a NEGATIVE budget. A tool name shorter than this is not recognizable. */
3
8
  export declare const MINTED_TOOL_SEGMENT_MIN_CHARS = 16;
9
+ /**
10
+ * design/116 W5-5 (CC 2.1.187 parity) — normalize a peer/tool segment to the API tool-name charset by
11
+ * replacing every other character with `_`. CC does exactly this on BOTH segments when composing
12
+ * `mcp__<server>__<tool>` (services/mcp/normalization.ts `normalizeNameForMCP` + mcpStringUtils.ts
13
+ * `buildMcpToolName`), so a peer advertising a dotted/spaced/unicode name can't mint a name the provider
14
+ * rejects. NOTE: only the MODEL-FACING namespaced name is normalized — the raw remote name still goes on
15
+ * the wire and still keys the caller-facing maps (`allowTools`/`toolAxes`). Same known collision property
16
+ * as CC: two remote names that normalize to the same string collide (rare; CC accepts this).
17
+ *
18
+ * RB-83 (2026-07-25, red probe): the pattern this enforces is `{1,64}`, and only the charset half was
19
+ * enforced. Both other halves matter for the same reason the charset does — an over-long or empty segment
20
+ * produces a name the provider rejects, which 400s the WHOLE model request, the exact failure the intake
21
+ * gate exists to contain ("a single misconfigured server never bricks the whole task").
22
+ */
4
23
  export declare function normalizeNameSegment(name: string): string;
24
+ /** RB-83: force a normalized segment into `{1,max}`, keeping long names distinct via a stable digest. */
5
25
  export declare function clampNameSegment(seg: string, max?: number): string;
26
+ /**
27
+ * The registered-name prefix for `peer` in `ns` — i.e. the set `name.startsWith(prefix)` that a consumer
28
+ * uses as its splice domain when swapping one peer's tools wholesale.
29
+ *
30
+ * The peer segment is kept as long as the assembled name allows (it is how an operator recognizes which
31
+ * peer a tool came from) and absorbs the clamp, digest-suffixed, when it does not fit.
32
+ *
33
+ * NOT `ns.makeName`: that leg REFUSES a peer carrying the separator, while this pipeline SANITIZES its
34
+ * inputs (the peer name is deployment/remote data, not a caller-authored identifier) and must not turn a
35
+ * long or exotic peer name into a materialization failure. SANITIZE, however, means the sanitized result
36
+ * must be sound: {@link settlePeerSegment} owes the same round-trip guarantee `makeName` gets by refusing
37
+ * (ticket #10), and the property test holds the two legs to the identical law.
38
+ */
6
39
  export declare function mintNamespacePrefix(ns: ProtocolNamespace, peer: string): string;
40
+ /**
41
+ * The full registered name for `(peer, tool)` in `ns`. Always starts with {@link mintNamespacePrefix}'s
42
+ * answer for the same peer (the invariant ticket #9's pins hold), and never exceeds
43
+ * {@link TOOL_NAME_MAX_CHARS}: whatever the peer segment leaves over is the tool segment's budget.
44
+ */
7
45
  export declare function mintNamespacedToolName(ns: ProtocolNamespace, peer: string, tool: string): string;