@sema-agent/core 5.57.0 → 5.59.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.
- package/CHANGELOG.md +96 -0
- package/dist/agents/cascade.d.ts +1 -1
- package/dist/agents/cumulative-stats.d.ts +1 -1
- package/dist/agents/observer.d.ts +2 -2
- package/dist/agents/peer-admission.d.ts +1 -1
- package/dist/agents/retain-ledger.d.ts +2 -2
- package/dist/agents/roster-store.d.ts +8 -8
- package/dist/agents/send-message-tool.d.ts +2 -2
- package/dist/agents/subagent-steps.d.ts +1 -1
- package/dist/agents/subagent.d.ts +13 -13
- package/dist/agents/team.d.ts +5 -5
- package/dist/agents/tool-filter.d.ts +2 -2
- package/dist/agents/verify.d.ts +1 -1
- package/dist/bench/metrics.d.ts +35 -35
- package/dist/brain/degrading.d.ts +1 -1
- package/dist/brain/errors.d.ts +3 -3
- package/dist/brain/reasoning.d.ts +2 -2
- package/dist/brain/repetition.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +8 -1
- package/dist/brain/route-adjudicator.js +8 -1
- package/dist/brain/status-sink.d.ts +2 -2
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/config/catalog.d.ts +5 -5
- package/dist/core/arg-summary.d.ts +4 -4
- package/dist/core/ask-class.d.ts +2 -2
- package/dist/core/ask-question.d.ts +1 -1
- package/dist/core/auto-compaction.d.ts +15 -15
- package/dist/core/auto-mode.d.ts +5 -5
- package/dist/core/background-agent-store.d.ts +20 -20
- package/dist/core/background-shell.d.ts +4 -4
- package/dist/core/checkpoint-store.d.ts +35 -27
- package/dist/core/context-edit.d.ts +1 -1
- package/dist/core/context-guard.d.ts +1 -1
- package/dist/core/exec-output-tail.d.ts +6 -6
- package/dist/core/file-snapshot-store.d.ts +8 -8
- package/dist/core/git-worktree-env.d.ts +3 -3
- package/dist/core/governance-codes.d.ts +37 -10
- package/dist/core/governance-codes.js +54 -1
- package/dist/core/hooks.d.ts +73 -33
- package/dist/core/hooks.js +87 -25
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/locked-config.d.ts +1 -1
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mailbox-store.d.ts +1 -1
- package/dist/core/mcp.d.ts +3 -3
- package/dist/core/memory-engine/consolidation-driver.d.ts +211 -0
- package/dist/core/memory-engine/consolidation-driver.js +427 -0
- package/dist/core/memory-engine/consolidation.d.ts +119 -3
- package/dist/core/memory-engine/consolidation.js +22 -1
- package/dist/core/memory-engine/data-plane.d.ts +1 -1
- package/dist/core/memory-engine/distiller.d.ts +550 -0
- package/dist/core/memory-engine/distiller.js +598 -0
- package/dist/core/memory-engine/dual-root.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +143 -10
- package/dist/core/memory-engine/engine.js +149 -23
- package/dist/core/memory-engine/file-backend.d.ts +14 -2
- package/dist/core/memory-engine/file-backend.js +3 -0
- package/dist/core/memory-engine/index.d.ts +6 -3
- package/dist/core/memory-engine/index.js +4 -2
- package/dist/core/memory-engine/layout.js +20 -6
- package/dist/core/memory-engine/origin-clearance.d.ts +1 -1
- package/dist/core/memory-engine/scope-contract.d.ts +4 -4
- package/dist/core/memory-engine/sync-client.d.ts +16 -16
- package/dist/core/memory-engine/sync.d.ts +4 -4
- package/dist/core/memory-engine/types.d.ts +17 -0
- package/dist/core/memory-recall.d.ts +1 -1
- package/dist/core/memory.d.ts +2 -2
- package/dist/core/permission-rule-consent.d.ts +185 -36
- package/dist/core/permission-rule-consent.js +219 -44
- package/dist/core/permission-rule-model.d.ts +235 -31
- package/dist/core/permission-rule-model.js +105 -35
- package/dist/core/permission-rules.d.ts +9 -9
- package/dist/core/remote-env.d.ts +8 -8
- package/dist/core/roles.d.ts +3 -3
- package/dist/core/roles.js +1 -0
- package/dist/core/runner/assemble-result.d.ts +2 -2
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/memory-consolidation-driver.d.ts +49 -0
- package/dist/core/runner/memory-consolidation-driver.js +60 -0
- package/dist/core/runner/memory-consolidation.d.ts +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +3 -3
- package/dist/core/runner/prepare-task.d.ts +21 -21
- package/dist/core/runner/prepare-task.js +24 -17
- package/dist/core/runner/prepare-workspace-restore.d.ts +2 -2
- package/dist/core/runner/runtask.d.ts +11 -11
- package/dist/core/runner/runtask.js +4 -4
- package/dist/core/runner/session-rule-policy.d.ts +1 -1
- package/dist/core/runner/teardown-bounded.d.ts +1 -1
- package/dist/core/runner/tool-disclosure.d.ts +2 -2
- package/dist/core/runner/turn-attachments.d.ts +11 -11
- package/dist/core/scheduler.d.ts +5 -5
- package/dist/core/secret-env.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/session-policy-store.d.ts +2 -2
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +3 -3
- package/dist/core/session.d.ts +1 -1
- package/dist/core/shutdown-debug.d.ts +2 -2
- package/dist/core/side-query.d.ts +2 -2
- package/dist/core/spec-contract.d.ts +1 -1
- package/dist/core/store-contracts/contract-harness.d.ts +2 -2
- package/dist/core/store-contracts/contract-kit-version.d.ts +2 -2
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +1 -1
- package/dist/core/store-contracts/mailbox-store-contract.js +1 -1
- package/dist/core/task-notification.d.ts +5 -5
- package/dist/core/task-registry-agent.d.ts +12 -12
- package/dist/core/task-registry-monitor.d.ts +1 -1
- package/dist/core/task-registry-shared.d.ts +41 -41
- package/dist/core/task-registry.d.ts +12 -12
- package/dist/core/tool-detach.d.ts +2 -2
- package/dist/core/tool-errors.d.ts +3 -3
- package/dist/core/tool-policy.d.ts +113 -28
- package/dist/core/tool-policy.js +80 -1
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +2 -2
- package/dist/core/tools.d.ts +1 -1
- package/dist/core/trace.d.ts +26 -23
- package/dist/core/types.d.ts +164 -86
- package/dist/core/types.js +4 -3
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +7 -7
- package/dist/core/wiring-manifest.d.ts +5 -5
- package/dist/core/workflow-journal-store.d.ts +14 -14
- package/dist/core/workflow-run-store-contract.d.ts +1 -1
- package/dist/core/workflow-run-store-contract.js +1 -1
- package/dist/core/workflow-run-store.d.ts +4 -4
- package/dist/engine/compaction/compaction.d.ts +3 -3
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/execution-env/kill-tree.d.ts +1 -1
- package/dist/engine/execution-env/node-execution-env.d.ts +8 -8
- package/dist/engine/harness/agent-harness.d.ts +6 -6
- package/dist/engine/harness/messages.d.ts +1 -1
- package/dist/engine/harness/types.d.ts +10 -10
- package/dist/engine/llm/types.d.ts +14 -14
- package/dist/engine/loop/agent-loop.d.ts +3 -3
- package/dist/engine/loop/types.d.ts +4 -4
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/import-validate.d.ts +1 -1
- package/dist/engine/session/log-digest.d.ts +1 -1
- package/dist/engine/session/memory-repo.d.ts +2 -2
- package/dist/engine/session/session.d.ts +4 -4
- package/dist/fixtures/index.d.ts +4 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.js +5 -4
- package/dist/orchestration/goal.d.ts +1 -1
- package/dist/orchestration/run-spec.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +12 -12
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-observe.d.ts +1 -1
- package/dist/orchestration/workflow-script-runner.d.ts +1 -1
- package/dist/orchestration/workflow-script-store.d.ts +9 -9
- package/dist/orchestration/workflow-size-guideline.d.ts +1 -1
- package/dist/orchestration/workflow-types.d.ts +5 -5
- package/dist/orchestration/workflow.d.ts +10 -10
- package/dist/prompt-assembly/artifact-store.d.ts +1 -1
- package/dist/prompt-assembly/artifact.d.ts +1 -1
- package/dist/prompt-assembly/assemble.d.ts +1 -1
- package/dist/prompt-assembly/composer.d.ts +2 -2
- package/dist/prompt-assembly/epoch.d.ts +2 -2
- package/dist/prompt-assembly/event-registry.d.ts +1 -1
- package/dist/prompt-assembly/explain.d.ts +3 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -4
- package/dist/prompt-assembly/types.d.ts +12 -12
- package/dist/prompts/coordinator.d.ts +1 -1
- package/dist/prompts/default.d.ts +8 -8
- package/dist/prompts/simple-sections.d.ts +3 -3
- package/dist/prompts/supervisor.d.ts +2 -2
- package/dist/scenarios/full-body.d.ts +3 -3
- package/dist/scenarios/scenario-registry.d.ts +1 -1
- package/dist/stores/cc/sidecar-transcript.d.ts +3 -3
- package/dist/stores/file/fs-atomic.d.ts +2 -2
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/session-store.d.ts +2 -2
- package/dist/stores/file/workflow-journal-store.d.ts +4 -4
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/encoding.d.ts +4 -4
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-pdf.d.ts +1 -1
- package/dist/tools/fs/fs-shared.d.ts +6 -6
- package/dist/tools/fs/index.d.ts +2 -2
- package/dist/tools/fs/notebook.d.ts +1 -1
- package/dist/tools/fs/pdf.d.ts +1 -1
- package/dist/tools/fs/read-deny.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +2 -2
- package/dist/tools/monitor.d.ts +3 -3
- package/dist/tools/task-list.d.ts +2 -2
- package/dist/tools/web.d.ts +4 -4
- package/dist/tools/worktree.d.ts +5 -5
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +1826 -3
|
@@ -17,11 +17,13 @@ export const NON_GOVERNANCE_MEMORY_CODES = new Set([
|
|
|
17
17
|
"memory.session_polluted",
|
|
18
18
|
"memory.harvest_quarantined",
|
|
19
19
|
"memory.delegation_static_mark_waived",
|
|
20
|
+
"memory.consolidation_driver_superseded",
|
|
20
21
|
"memory.challenge_sweep_failed",
|
|
21
22
|
"memory.lineage_settle_failed",
|
|
22
23
|
"memory.challenge_ledger_corrupt",
|
|
23
24
|
"memory.consolidation_recommended",
|
|
24
25
|
"memory.consolidation_committed",
|
|
26
|
+
"memory.consolidation_incomplete",
|
|
25
27
|
"memory.consolidation_conflict",
|
|
26
28
|
"memory.consolidation_refused",
|
|
27
29
|
"memory.consolidation_disabled",
|
|
@@ -82,14 +84,65 @@ export const RULE_SYNC_DROP_CODES = {
|
|
|
82
84
|
below_gc_frontier: "local-quarantined",
|
|
83
85
|
server_rejected: "local-quarantined",
|
|
84
86
|
};
|
|
85
|
-
export const
|
|
87
|
+
export const ENGINE_NOTICE_CODES = [
|
|
88
|
+
"config.env_timeout_discarded",
|
|
89
|
+
"config.materialize_env_discarded",
|
|
90
|
+
"config.models_swapped",
|
|
91
|
+
"config.read_face_deployment_clamped",
|
|
92
|
+
"config.tool_model_gate_removed",
|
|
93
|
+
"config.tool_model_gate_unknown_class",
|
|
94
|
+
"config.tool_model_gate_env_invalid",
|
|
95
|
+
"delegation.transcript_integrity",
|
|
96
|
+
"mcp.revocation_probe_failed",
|
|
97
|
+
"workflow.governance_key_stripped",
|
|
98
|
+
"memory.session_polluted",
|
|
99
|
+
"memory.harvest_quarantined",
|
|
100
|
+
"memory.delegation_static_mark_waived",
|
|
101
|
+
"memory.hold_opened",
|
|
102
|
+
"memory.hold_released",
|
|
103
|
+
"memory.hold_disposed",
|
|
104
|
+
"memory.consolidation_recommended",
|
|
105
|
+
"memory.consolidation_committed",
|
|
106
|
+
"memory.consolidation_conflict",
|
|
107
|
+
"memory.consolidation_incomplete",
|
|
108
|
+
"memory.consolidation_refused",
|
|
109
|
+
"route.fallback_to_primary",
|
|
110
|
+
"route.base_url_changed_key_unchanged",
|
|
111
|
+
"task.user_steer_undrained",
|
|
112
|
+
"task.user_followup_undrained",
|
|
113
|
+
"task.injection_priority_unimplemented",
|
|
114
|
+
"tool_result.offload_put_failed",
|
|
115
|
+
];
|
|
116
|
+
const NOTICE_AUDIENCE_TABLE = {
|
|
86
117
|
"memory.session_polluted": "user",
|
|
87
118
|
"memory.harvest_quarantined": "user",
|
|
88
119
|
"memory.delegation_static_mark_waived": "user",
|
|
89
120
|
"memory.hold_opened": "user",
|
|
90
121
|
"memory.hold_released": "user",
|
|
91
122
|
"memory.hold_disposed": "user",
|
|
123
|
+
"task.user_steer_undrained": "user",
|
|
124
|
+
"task.user_followup_undrained": "user",
|
|
125
|
+
"config.env_timeout_discarded": "operator",
|
|
126
|
+
"config.materialize_env_discarded": "operator",
|
|
127
|
+
"config.models_swapped": "operator",
|
|
128
|
+
"config.read_face_deployment_clamped": "operator",
|
|
129
|
+
"config.tool_model_gate_removed": "operator",
|
|
130
|
+
"config.tool_model_gate_unknown_class": "operator",
|
|
131
|
+
"config.tool_model_gate_env_invalid": "operator",
|
|
132
|
+
"delegation.transcript_integrity": "operator",
|
|
133
|
+
"mcp.revocation_probe_failed": "operator",
|
|
134
|
+
"workflow.governance_key_stripped": "operator",
|
|
135
|
+
"memory.consolidation_recommended": "operator",
|
|
136
|
+
"memory.consolidation_committed": "operator",
|
|
137
|
+
"memory.consolidation_conflict": "operator",
|
|
138
|
+
"memory.consolidation_incomplete": "operator",
|
|
139
|
+
"memory.consolidation_refused": "operator",
|
|
140
|
+
"route.fallback_to_primary": "operator",
|
|
141
|
+
"route.base_url_changed_key_unchanged": "operator",
|
|
142
|
+
"task.injection_priority_unimplemented": "operator",
|
|
143
|
+
"tool_result.offload_put_failed": "operator",
|
|
92
144
|
};
|
|
145
|
+
export const NOTICE_AUDIENCE = NOTICE_AUDIENCE_TABLE;
|
|
93
146
|
export function noticeAudienceOf(code) {
|
|
94
147
|
return NOTICE_AUDIENCE[code] ?? "operator";
|
|
95
148
|
}
|
package/dist/core/hooks.d.ts
CHANGED
|
@@ -161,7 +161,7 @@ export interface Hooks {
|
|
|
161
161
|
*/
|
|
162
162
|
stopFailure?(ctx: StopFailureContext): void | Promise<void>;
|
|
163
163
|
/**
|
|
164
|
-
* design/134 R5 (CC PermissionDenied parity, SDK 0.3.202
|
|
164
|
+
* design/134 R5 (CC PermissionDenied parity, SDK 0.3.202): runs when the tool gate's
|
|
165
165
|
* adjudicate chain DENY-SHORT-CIRCUITS a tool call — a ToolPolicy deny, a gate tighten (egress /
|
|
166
166
|
* irreversibility / coarse shellGate) whose `ask` resolved to deny (headless auto-deny included), or the
|
|
167
167
|
* plan-mode write-deny. Closes the observation blind spot where a blocked call fires NEITHER postToolUse
|
|
@@ -525,7 +525,7 @@ export interface StopHookContext {
|
|
|
525
525
|
/** Consecutive blocks so far in this run (resets when a stop() call lets the run proceed). */
|
|
526
526
|
consecutiveBlocks: number;
|
|
527
527
|
/**
|
|
528
|
-
* RB-177 (
|
|
528
|
+
* RB-177 (measured downstream) — a view of the conversation this hook is being asked to judge.
|
|
529
529
|
*
|
|
530
530
|
* Until now a Stop hook received two counters and nothing else. That is enough for a hook that asks
|
|
531
531
|
* "have I blocked too often?", and structurally insufficient for the entire class of hooks that ask
|
|
@@ -732,7 +732,7 @@ export interface HookInvocationIdentity {
|
|
|
732
732
|
* other absence-signaling face this module mints — "absent member" must be a fact about THIS object,
|
|
733
733
|
* and a frozen object with an ordinary prototype still answers `insideFork`/`agentName` reads (and
|
|
734
734
|
* `in` probes) from `Object.prototype`, so a prototype write elsewhere in the process could hand
|
|
735
|
-
* every leg a delegation axis the mint never stamped
|
|
735
|
+
* every leg a delegation axis the mint never stamped. `agentName` is sanitized here — it
|
|
736
736
|
* is the only member whose value a model influences.
|
|
737
737
|
*/
|
|
738
738
|
export declare function mintHookInvocationIdentity(facts: HookInvocationIdentity): HookInvocationIdentity;
|
|
@@ -986,20 +986,33 @@ export type OrgGateVerdict = {
|
|
|
986
986
|
/** The overlay's own disclosure lines (engine/deployment-authored), for the operator channel. */
|
|
987
987
|
disclosures: readonly string[];
|
|
988
988
|
};
|
|
989
|
+
/** One member of a {@link PersistedRuleHit} coverage set: a rule's canonical text plus (optionally)
|
|
990
|
+
* its add-dot identity. */
|
|
991
|
+
export interface PersistedRuleHitRule {
|
|
992
|
+
/** The canonical text of one admitting rule. */
|
|
993
|
+
readonly rule: string;
|
|
994
|
+
/** The rule's LIVE add dots (tombstoned adds already filtered by the store's read). Omitted by a
|
|
995
|
+
* lane that has the text but not the dots; the evidence then reports `"not_reported"`. */
|
|
996
|
+
readonly dots?: readonly import("./permission-rule-model.js").RuleDot[];
|
|
997
|
+
}
|
|
989
998
|
/**
|
|
990
|
-
* design/252 G-2 — the
|
|
991
|
-
*
|
|
999
|
+
* design/252 G-2, re-formed by design/375 (BREAKING) — the structured answer a persisted-rule lane
|
|
1000
|
+
* gives: the COVERAGE SET that admits the call. A single rule admitting the whole command is a
|
|
1001
|
+
* one-element set (the historical case); a compound admitted by the conjunction of per-segment rules
|
|
1002
|
+
* (design/375 §5.1) is the set of those rules, in segment order. `rules` is non-empty by contract —
|
|
1003
|
+
* an empty set covers nothing and is not a hit (the normalizer reads it as a clean negative).
|
|
992
1004
|
*
|
|
993
|
-
* Why
|
|
994
|
-
*
|
|
995
|
-
*
|
|
1005
|
+
* Why dots and not an id: a persisted allow rule HAS no scalar id — it is a (text, scope) group whose
|
|
1006
|
+
* identity is the set of add dots that redeemed it, and two concurrently approved records for one text
|
|
1007
|
+
* each carry their own. The set is the identity; a joined string would not be one.
|
|
1008
|
+
*
|
|
1009
|
+
* The pre-375 single-rule object shape (`{ rule, dots? }`) is NOT accepted: on this loosening seam an
|
|
1010
|
+
* unrecognized answer degrades to a clean negative (more asks), never to a match — the safe failure
|
|
1011
|
+
* shape for a lane that missed the same-window upgrade.
|
|
996
1012
|
*/
|
|
997
1013
|
export interface PersistedRuleHit {
|
|
998
|
-
/** The
|
|
999
|
-
readonly
|
|
1000
|
-
/** The matched rule's LIVE add dots (tombstoned adds already filtered by the store's read). Omitted
|
|
1001
|
-
* by a lane that has the text but not the dots; the evidence then reports `"not_reported"`. */
|
|
1002
|
-
readonly dots?: readonly import("./permission-rule-model.js").RuleDot[];
|
|
1014
|
+
/** The coverage set — every rule the decision stands on. Non-empty. */
|
|
1015
|
+
readonly rules: readonly PersistedRuleHitRule[];
|
|
1003
1016
|
}
|
|
1004
1017
|
/**
|
|
1005
1018
|
* design/252 G-2 — the answer a lane gives when it could not READ its store.
|
|
@@ -1014,8 +1027,20 @@ export interface PersistedRuleHit {
|
|
|
1014
1027
|
export interface PersistedRuleUnreadable {
|
|
1015
1028
|
readonly unreadable: true;
|
|
1016
1029
|
}
|
|
1030
|
+
/**
|
|
1031
|
+
* design/375 §5.2② — the CLEAN NEGATIVE that still carries the per-segment coverage table: no rule
|
|
1032
|
+
* admits the whole call, and THESE segments are the ones an eligible rule already covers. Minted by
|
|
1033
|
+
* the lane from the SAME store read that adjudicated the call (snapshot = adjudication snapshot, no
|
|
1034
|
+
* second read), and consumed only by the suggestion face — which puts on the batch offer exactly the
|
|
1035
|
+
* segments this table calls uncovered. Its DECISION meaning is identical to "no rule": the seat is
|
|
1036
|
+
* advisory, and a lane that omits it (or an unreadable one) degrades to all-uncovered, which merely
|
|
1037
|
+
* over-offers (every offered rule still passes the validator at redemption).
|
|
1038
|
+
*/
|
|
1039
|
+
export interface PersistedRuleCoverage {
|
|
1040
|
+
readonly segmentCoverage: readonly import("./permission-rule-model.js").SegmentCoverage[];
|
|
1041
|
+
}
|
|
1017
1042
|
/** Every shape a lane may answer with. A bare string stays valid and unchanged. */
|
|
1018
|
-
export type PersistedRuleAnswer = string | PersistedRuleHit | PersistedRuleUnreadable | undefined;
|
|
1043
|
+
export type PersistedRuleAnswer = string | PersistedRuleHit | PersistedRuleCoverage | PersistedRuleUnreadable | undefined;
|
|
1019
1044
|
/**
|
|
1020
1045
|
* design/252 review r3 — read a foreign {@link OrgGateVerdict} the way the personal-rule answer is read:
|
|
1021
1046
|
* OWN DATA properties only, never the prototype chain, never an accessor.
|
|
@@ -1044,9 +1069,15 @@ export declare function normalizeOrgGateVerdict(answer: unknown, unreadable: str
|
|
|
1044
1069
|
* Normalize the accepted {@link ToolGateInput.persistedRules} answers into one reading.
|
|
1045
1070
|
*
|
|
1046
1071
|
* `{}` = a clean negative (no rule admits this call). `{ unreadable: true }` = the lane could not read
|
|
1047
|
-
* its source. `{ hit }` = a match
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
1072
|
+
* its source. `{ hit }` = a match, whose `rules` is the non-empty coverage set (design/375). An answer
|
|
1073
|
+
* outside every accepted shape — a number, `null`, an object with neither `rules` nor `unreadable`, an
|
|
1074
|
+
* EMPTY `rules` array, the retired pre-375 `{ rule, dots? }` single-rule object — is read as a clean
|
|
1075
|
+
* negative rather than a match: this is a LOOSENING seam, so an answer nobody can name degrades toward
|
|
1076
|
+
* asking, never toward an allow built on it. All-or-nothing across the set's TEXTS for the same
|
|
1077
|
+
* reason: a set with one unreadable member is a different (smaller) claim than the lane made, and a
|
|
1078
|
+
* decision must not stand on a claim nobody made — one bad member drops the whole answer to the clean
|
|
1079
|
+
* negative. Per-member DOTS stay individually optional (identity lost ⇒ `"not_reported"`, exactly the
|
|
1080
|
+
* single-rule contract).
|
|
1050
1081
|
*
|
|
1051
1082
|
* The hit's dots are COPIED, not aliased. The array travels onto an ask that may sit in front of a
|
|
1052
1083
|
* person for a long time; a lane that retains and mutates its own array would otherwise change what the
|
|
@@ -1055,6 +1086,7 @@ export declare function normalizeOrgGateVerdict(answer: unknown, unreadable: str
|
|
|
1055
1086
|
export declare function normalizePersistedRuleHit(hit: PersistedRuleAnswer): {
|
|
1056
1087
|
hit?: PersistedRuleHit;
|
|
1057
1088
|
unreadable?: true;
|
|
1089
|
+
coverage?: readonly import("./permission-rule-model.js").SegmentCoverage[];
|
|
1058
1090
|
};
|
|
1059
1091
|
/** Inputs to the two-phase tool gate. `adjudicate`/`resolveAsk` are pre-bound to the task abort signal. */
|
|
1060
1092
|
export interface ToolGateInput {
|
|
@@ -1104,7 +1136,7 @@ export interface ToolGateInput {
|
|
|
1104
1136
|
/** The combined tool-policy check (abort-bound), or undefined when no policy is wired (→ allow). */
|
|
1105
1137
|
adjudicate?: (req: ToolCallRequest) => Promise<PermissionResult>;
|
|
1106
1138
|
/** Resolve an `ask` to allow/deny via `onAsk` (abort-bound). Required iff a decision can be `ask`.
|
|
1107
|
-
* G1 three-value
|
|
1139
|
+
* G1 three-value: the result may carry `approverUnavailable` — the live approver affirmed no
|
|
1108
1140
|
* operator is reachable for THIS ask; the gate then re-routes onto the durable park leg (below),
|
|
1109
1141
|
* keeping the carried fail-closed deny when no park is armed. */
|
|
1110
1142
|
resolveAsk: (decision: PermissionResult, req: ToolCallRequest) => Promise<ResolvedAsk>;
|
|
@@ -1163,7 +1195,11 @@ export interface ToolGateInput {
|
|
|
1163
1195
|
probeReason?: string,
|
|
1164
1196
|
/** backlog #239: the STRUCTURED cause (the surviving ask's `probeCause`) — same durable-route errand
|
|
1165
1197
|
* as `probeReason`, already validated at the gate. */
|
|
1166
|
-
probeCause?: import("./checkpoint-store.js").ProbeCause
|
|
1198
|
+
probeCause?: import("./checkpoint-store.js").ProbeCause,
|
|
1199
|
+
/** design/375 §5.2②: the surviving ask's engine-stamped `segmentCoverage` — threaded so the park
|
|
1200
|
+
* mint's offer factory reads the same coverage snapshot on the durable route as the synchronous
|
|
1201
|
+
* mints read off the decision (absent ⇒ all segments uncovered ⇒ over-offer, the safe way). */
|
|
1202
|
+
segmentCoverage?: readonly import("./permission-rule-model.js").SegmentCoverage[]) => Promise<ToolGateResult["suspend"] | ParkAttemptFailed | undefined>;
|
|
1167
1203
|
/**
|
|
1168
1204
|
* design/174 — route a policy `ask` on the reserved question tool to this run's CONTENT-ask channel
|
|
1169
1205
|
* before it can become a park or a refusal. Called in the `ask` branch with the FINAL post-hook,
|
|
@@ -1268,7 +1304,7 @@ export interface ToolGateInput {
|
|
|
1268
1304
|
*/
|
|
1269
1305
|
writeProtectionCheck?: (toolName: string, args: unknown) => import("./write-protect.js").WriteProtectedHit | null;
|
|
1270
1306
|
/**
|
|
1271
|
-
* design/143 批2 (
|
|
1307
|
+
* design/143 批2 (A, CC 2.1.207 auto mode): when present, a surviving `ask` is routed to the
|
|
1272
1308
|
* small-model policy CLASSIFIER before any human/durable resolution:
|
|
1273
1309
|
* - verdict `allow` → the ask resolves to allow (`decisionReason:"classifier"`) — no suspend, no onAsk;
|
|
1274
1310
|
* - verdict `block` → deny (`decisionReason:"classifier"`, `source:"classifier"`; CC `automode-blocked`);
|
|
@@ -1337,22 +1373,26 @@ export interface ToolGateInput {
|
|
|
1337
1373
|
* bullets above are what keep integrity/hook/mandated asks out of that set.
|
|
1338
1374
|
*/
|
|
1339
1375
|
persistedRules?: {
|
|
1340
|
-
/** The rule that admits this call, or `undefined`. Must not throw: a store that cannot
|
|
1341
|
-
* answers "no rule" and discloses on its own channel (fail-closed = more asks).
|
|
1376
|
+
/** The rule COVERAGE that admits this call, or `undefined`. Must not throw: a store that cannot
|
|
1377
|
+
* be read answers "no rule" and discloses on its own channel (fail-closed = more asks).
|
|
1342
1378
|
*
|
|
1343
|
-
* TWO ACCEPTED SHAPES (design/252 G-2
|
|
1344
|
-
*
|
|
1345
|
-
* text plus
|
|
1346
|
-
*
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1379
|
+
* TWO ACCEPTED SHAPES (design/252 G-2 / design/375 BREAKING): the canonical rule TEXT (a
|
|
1380
|
+
* single-rule hit with no identity), or a {@link PersistedRuleHit} carrying the coverage SET —
|
|
1381
|
+
* each member's canonical text plus its add DOTS. A single rule admitting the whole command is a
|
|
1382
|
+
* one-element set; a compound admitted by the per-segment conjunction (design/375 §5.1) is the
|
|
1383
|
+
* set of the covering rules. The dots are a rule's durable identity, and the text is not one (it
|
|
1384
|
+
* reaches a card sanitized and capped); a lane that can name them lets the shadowed-ask evidence
|
|
1385
|
+
* say WHICH stored rules matched rather than merely what they looked like. The retired pre-375
|
|
1386
|
+
* single-rule object shape (`{ rule, dots? }`) is read as a clean negative by the normalizer —
|
|
1387
|
+
* a stale lane degrades toward asking, never toward an allow. */
|
|
1350
1388
|
admits: (req: ToolCallRequest) => Promise<PersistedRuleAnswer>;
|
|
1351
|
-
/** Observation sink for an ask a rule resolved — the allow-side disclosure.
|
|
1389
|
+
/** Observation sink for an ask a rule coverage resolved — the allow-side disclosure. `rules` is
|
|
1390
|
+
* the coverage set's canonical texts in reporting order (design/375: a conjunction names every
|
|
1391
|
+
* rule the decision stands on). Never affects the outcome. */
|
|
1352
1392
|
onResolved?: (info: {
|
|
1353
1393
|
toolName: string;
|
|
1354
1394
|
toolCallId: string;
|
|
1355
|
-
|
|
1395
|
+
rules: readonly string[];
|
|
1356
1396
|
}) => void;
|
|
1357
1397
|
};
|
|
1358
1398
|
/**
|
|
@@ -1380,7 +1420,7 @@ export interface ToolGateInput {
|
|
|
1380
1420
|
/** True iff the reserved question-tool NAME on this leg resolves to the ENGINE's own content-ask
|
|
1381
1421
|
* tool. It is the exemption's real predicate: the name alone is not, because a caller may mount
|
|
1382
1422
|
* its own tool under that name when the first-party one is not mounted, and such a tool has
|
|
1383
|
-
* arbitrary side effects (
|
|
1423
|
+
* arbitrary side effects (confirmed MED). Absent ⇒ `false` ⇒ the call is governed
|
|
1384
1424
|
* like any other, which is the fail-closed default. */
|
|
1385
1425
|
contentAskToolMounted?: boolean;
|
|
1386
1426
|
/** Disclosure sink for the unavailable arm (trace `permission.org_snapshot_unavailable`). Never
|
|
@@ -1398,7 +1438,7 @@ export interface ToolGateInput {
|
|
|
1398
1438
|
* checkpoint store that explicitly declares `redecision.reopen`). Absent ⇒ the whole step does not
|
|
1399
1439
|
* exist and the decision path is byte-identical to a build without it.
|
|
1400
1440
|
*
|
|
1401
|
-
* Semantics (
|
|
1441
|
+
* Semantics (the ruling): inside a declared sandbox, an engine-authored "confirm a potentially
|
|
1402
1442
|
* destructive local action" ask is answered by containment itself — auto-allow + durable
|
|
1403
1443
|
* disclosure (`permission.sandbox_admitted`), never a headless deny that pollutes the model.
|
|
1404
1444
|
* STRICT dominance governs: the leg admits only when EVERY surviving ask on the call is classified
|
package/dist/core/hooks.js
CHANGED
|
@@ -253,17 +253,7 @@ export function normalizeOrgGateVerdict(answer, unreadable) {
|
|
|
253
253
|
return clean({ status: "unavailable", disclosures: [unreadable] });
|
|
254
254
|
return clean({ status: "available", verdict: clean({ behavior: behavior, rule }), ...revisionCell });
|
|
255
255
|
}
|
|
256
|
-
|
|
257
|
-
if (typeof hit === "string")
|
|
258
|
-
return { hit: { rule: hit } };
|
|
259
|
-
if (!isPlainOwnRecord(hit))
|
|
260
|
-
return {};
|
|
261
|
-
if (ownDataValue(hit, "unreadable") === true)
|
|
262
|
-
return { unreadable: true };
|
|
263
|
-
const rule = ownDataValue(hit, "rule");
|
|
264
|
-
if (typeof rule !== "string")
|
|
265
|
-
return {};
|
|
266
|
-
const dots = ownDataValue(hit, "dots");
|
|
256
|
+
function copiedUsableDots(dots) {
|
|
267
257
|
let copied;
|
|
268
258
|
try {
|
|
269
259
|
if (Array.isArray(dots)) {
|
|
@@ -279,7 +269,53 @@ export function normalizePersistedRuleHit(hit) {
|
|
|
279
269
|
copied = undefined;
|
|
280
270
|
}
|
|
281
271
|
const usable = copied?.every((d) => typeof d.actor === "string" && typeof d.counter === "number" && Number.isFinite(d.counter)) === true && copied.length > 0;
|
|
282
|
-
return
|
|
272
|
+
return usable ? { dots: copied } : {};
|
|
273
|
+
}
|
|
274
|
+
export function normalizePersistedRuleHit(hit) {
|
|
275
|
+
if (typeof hit === "string")
|
|
276
|
+
return { hit: { rules: [{ rule: hit }] } };
|
|
277
|
+
if (!isPlainOwnRecord(hit))
|
|
278
|
+
return {};
|
|
279
|
+
if (ownDataValue(hit, "unreadable") === true)
|
|
280
|
+
return { unreadable: true };
|
|
281
|
+
const rulesRaw = ownDataValue(hit, "rules");
|
|
282
|
+
if (rulesRaw === undefined) {
|
|
283
|
+
const coverageRaw = ownDataValue(hit, "segmentCoverage");
|
|
284
|
+
let rows;
|
|
285
|
+
try {
|
|
286
|
+
if (Array.isArray(coverageRaw)) {
|
|
287
|
+
const walked = [];
|
|
288
|
+
for (let i = 0; i < coverageRaw.length; i++) {
|
|
289
|
+
const r = coverageRaw[i];
|
|
290
|
+
walked.push(isPlainOwnRecord(r) ? { segment: ownDataValue(r, "segment"), covered: ownDataValue(r, "covered") } : { segment: undefined, covered: undefined });
|
|
291
|
+
}
|
|
292
|
+
rows = walked.every((r) => typeof r.segment === "string" && typeof r.covered === "boolean") ? walked : undefined;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
rows = undefined;
|
|
297
|
+
}
|
|
298
|
+
return rows !== undefined && rows.length > 0 ? { coverage: rows.map((r) => ({ segment: r.segment, covered: r.covered })) } : {};
|
|
299
|
+
}
|
|
300
|
+
let members;
|
|
301
|
+
try {
|
|
302
|
+
if (Array.isArray(rulesRaw)) {
|
|
303
|
+
const walked = [];
|
|
304
|
+
for (let i = 0; i < rulesRaw.length; i++) {
|
|
305
|
+
const m = rulesRaw[i];
|
|
306
|
+
walked.push(isPlainOwnRecord(m) ? { rule: ownDataValue(m, "rule"), dots: ownDataValue(m, "dots") } : { rule: undefined, dots: undefined });
|
|
307
|
+
}
|
|
308
|
+
members = walked;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
members = undefined;
|
|
313
|
+
}
|
|
314
|
+
if (members === undefined || members.length === 0)
|
|
315
|
+
return {};
|
|
316
|
+
if (!members.every((m) => typeof m.rule === "string"))
|
|
317
|
+
return {};
|
|
318
|
+
return { hit: { rules: members.map((m) => ({ rule: m.rule, ...copiedUsableDots(m.dots) })) } };
|
|
283
319
|
}
|
|
284
320
|
function preToolUseCrashReason(subject, err) {
|
|
285
321
|
const raw = err instanceof Error ? err.message.trim() || err.name : String(err);
|
|
@@ -672,6 +708,7 @@ export async function runToolGate(input) {
|
|
|
672
708
|
}
|
|
673
709
|
const persistedRuleMandate = persistedRuleMandateOf(input);
|
|
674
710
|
let personalEvidence = { dotsAbsent: input.persistedRules === undefined ? "not_wired" : "not_adjudicated" };
|
|
711
|
+
let laneCoverage;
|
|
675
712
|
if (input.persistedRules &&
|
|
676
713
|
!orgRealApprovalRequired &&
|
|
677
714
|
decision.action === "ask" &&
|
|
@@ -689,21 +726,44 @@ export async function runToolGate(input) {
|
|
|
689
726
|
}
|
|
690
727
|
return await settleOrgVerdictWithin(pendingHit.then(normalizePersistedRuleHit).catch(() => ({ unreadable: true })), { unreadable: true }, { ...(input.abortSignal !== undefined ? { signal: input.abortSignal } : {}), timeoutMs: ORG_ADJUDICATION_TIMEOUT_MS });
|
|
691
728
|
})();
|
|
692
|
-
const
|
|
693
|
-
|
|
729
|
+
const hitRules = answer.hit?.rules;
|
|
730
|
+
laneCoverage = answer.coverage;
|
|
694
731
|
personalEvidence = { dotsAbsent: answer.unreadable === true ? "unavailable" : "no_match" };
|
|
695
|
-
|
|
732
|
+
const disclosedRuleSet = (rules) => {
|
|
733
|
+
const shown = rules.slice(0, 5).map((r) => inlineUntrusted(r.rule, 200));
|
|
734
|
+
const rest = rules.length - shown.length;
|
|
735
|
+
return rest > 0 ? `${shown.join(", ")} and ${rest} more` : shown.join(", ");
|
|
736
|
+
};
|
|
737
|
+
const unionDotsOf = (rules) => {
|
|
738
|
+
const seen = new Set();
|
|
739
|
+
const union = [];
|
|
740
|
+
for (const r of rules) {
|
|
741
|
+
if (r.dots === undefined || r.dots.length === 0)
|
|
742
|
+
return { dotsAbsent: "not_reported" };
|
|
743
|
+
for (const d of r.dots) {
|
|
744
|
+
const key = JSON.stringify([d.actor, d.counter]);
|
|
745
|
+
if (!seen.has(key)) {
|
|
746
|
+
seen.add(key);
|
|
747
|
+
union.push(d);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return { dots: union };
|
|
752
|
+
};
|
|
753
|
+
if (hitRules !== undefined && persistedRuleMandate === undefined && decision.matchedAskRule === undefined) {
|
|
696
754
|
decision = {
|
|
697
755
|
action: "allow",
|
|
698
|
-
message:
|
|
756
|
+
message: hitRules.length === 1
|
|
757
|
+
? `a persisted allow rule (${disclosedRuleSet(hitRules)}) covers this call`
|
|
758
|
+
: `persisted allow rules (${disclosedRuleSet(hitRules)}) cover every segment of this call`,
|
|
699
759
|
decisionReason: "persisted_rule",
|
|
700
760
|
...(policyRewrite !== undefined ? { updatedInput: policyRewrite } : {}),
|
|
701
761
|
};
|
|
702
|
-
await notifier.notifyAsync(() => input.persistedRules?.onResolved?.({ toolName: req.toolName, toolCallId,
|
|
762
|
+
await notifier.notifyAsync(() => input.persistedRules?.onResolved?.({ toolName: req.toolName, toolCallId, rules: hitRules.map((r) => r.rule) }), "toolGate.persistedRuleResolved");
|
|
703
763
|
}
|
|
704
|
-
else if (
|
|
705
|
-
personalEvidence =
|
|
706
|
-
const shownRule =
|
|
764
|
+
else if (hitRules !== undefined) {
|
|
765
|
+
personalEvidence = unionDotsOf(hitRules);
|
|
766
|
+
const shownRule = disclosedRuleSet(hitRules);
|
|
707
767
|
const mandateNoun = persistedRuleMandate === "operator_always"
|
|
708
768
|
? "this deployment mandates per-call confirmation for shell commands (shellGate: always)"
|
|
709
769
|
: persistedRuleMandate !== undefined
|
|
@@ -712,12 +772,14 @@ export async function runToolGate(input) {
|
|
|
712
772
|
decision = {
|
|
713
773
|
...decision,
|
|
714
774
|
persistedRuleShadowed: shownRule,
|
|
715
|
-
message:
|
|
775
|
+
message: hitRules.length === 1
|
|
776
|
+
? `${decision.message !== undefined ? `${decision.message} ` : ""}(a persisted allow rule (${shownRule}) matches this call but does not clear the ask — ${mandateNoun})`
|
|
777
|
+
: `${decision.message !== undefined ? `${decision.message} ` : ""}(persisted allow rules (${shownRule}) match this call but do not clear the ask — ${mandateNoun})`,
|
|
716
778
|
};
|
|
717
779
|
}
|
|
718
780
|
}
|
|
719
781
|
if (decision.action === "ask") {
|
|
720
|
-
decision = { ...decision, ruleEvidence: mintRuleEvidence(personalEvidence) };
|
|
782
|
+
decision = { ...decision, ruleEvidence: mintRuleEvidence(personalEvidence), ...(laneCoverage !== undefined ? { segmentCoverage: laneCoverage } : {}) };
|
|
721
783
|
}
|
|
722
784
|
if (input.autoMode &&
|
|
723
785
|
!orgRealApprovalRequired &&
|
|
@@ -779,7 +841,7 @@ export async function runToolGate(input) {
|
|
|
779
841
|
? { origin: orgAskOrigin !== undefined ? `org_${orgAskOrigin}` : "policy" }
|
|
780
842
|
: undefined;
|
|
781
843
|
if (suspendAsk && decision.action === "ask") {
|
|
782
|
-
const suspended = await suspendAsk(req, currentInput, safety, undefined, realApprovalOf(decision), decision.action === "ask" ? decision.persistedRuleShadowed : undefined, decision.action === "ask" ? decision.decisionReason : undefined, decision.action === "ask" ? decision.probeReason : undefined, decision.action === "ask" ? decision.probeCause : undefined);
|
|
844
|
+
const suspended = await suspendAsk(req, currentInput, safety, undefined, realApprovalOf(decision), decision.action === "ask" ? decision.persistedRuleShadowed : undefined, decision.action === "ask" ? decision.decisionReason : undefined, decision.action === "ask" ? decision.probeReason : undefined, decision.action === "ask" ? decision.probeCause : undefined, decision.action === "ask" ? decision.segmentCoverage : undefined);
|
|
783
845
|
if (suspended) {
|
|
784
846
|
if ("parkFailed" in suspended)
|
|
785
847
|
parkFailed = suspended.parkFailed;
|
|
@@ -798,7 +860,7 @@ export async function runToolGate(input) {
|
|
|
798
860
|
req.args = outcome.presentedInput;
|
|
799
861
|
}
|
|
800
862
|
if (suspendAsk && outcome.parkDeclined && parkFailed === undefined) {
|
|
801
|
-
const suspended = await suspendAsk(req, currentInput, safety, true, realApprovalOf(decision), decision.action === "ask" ? decision.persistedRuleShadowed : undefined, decision.action === "ask" ? decision.decisionReason : undefined, decision.action === "ask" ? decision.probeReason : undefined, decision.action === "ask" ? decision.probeCause : undefined);
|
|
863
|
+
const suspended = await suspendAsk(req, currentInput, safety, true, realApprovalOf(decision), decision.action === "ask" ? decision.persistedRuleShadowed : undefined, decision.action === "ask" ? decision.decisionReason : undefined, decision.action === "ask" ? decision.probeReason : undefined, decision.action === "ask" ? decision.probeCause : undefined, decision.action === "ask" ? decision.segmentCoverage : undefined);
|
|
802
864
|
if (suspended) {
|
|
803
865
|
if ("parkFailed" in suspended)
|
|
804
866
|
parkFailed = suspended.parkFailed;
|
|
@@ -830,7 +892,7 @@ export async function runToolGate(input) {
|
|
|
830
892
|
askDenyResolution = resolved.resolution;
|
|
831
893
|
decision = resolved;
|
|
832
894
|
if (resolved.action === "deny" && resolved.approverUnavailable === true && suspendAsk && parkFailed === undefined) {
|
|
833
|
-
const suspended = await suspendAsk(req, currentInput, safety, true, realApprovalOf(askBeforeResolve), askBeforeResolve.action === "ask" ? askBeforeResolve.persistedRuleShadowed : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.decisionReason : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.probeReason : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.probeCause : undefined);
|
|
895
|
+
const suspended = await suspendAsk(req, currentInput, safety, true, realApprovalOf(askBeforeResolve), askBeforeResolve.action === "ask" ? askBeforeResolve.persistedRuleShadowed : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.decisionReason : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.probeReason : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.probeCause : undefined, askBeforeResolve.action === "ask" ? askBeforeResolve.segmentCoverage : undefined);
|
|
834
896
|
if (suspended) {
|
|
835
897
|
if ("parkFailed" in suspended)
|
|
836
898
|
parkFailed = suspended.parkFailed;
|
|
@@ -36,7 +36,7 @@ export declare const IMAGE_MAX_HEIGHT = 2000;
|
|
|
36
36
|
* replaced by an explanatory text block with the size + path; a within-limit image passes through unchanged.
|
|
37
37
|
*/
|
|
38
38
|
/**
|
|
39
|
-
* Optional image-resize seam (design/116 review CONFIRM-1,
|
|
39
|
+
* Optional image-resize seam (design/116 review CONFIRM-1, 裁定 2026-07-02 加 seam 保体验): given an
|
|
40
40
|
* over-limit image, return a smaller re-encoded one — or undefined when it can't. CC resizes with sharp
|
|
41
41
|
* (imageResizer.ts: fit within 2000x2000, JPEG quality ladder) so the model still SEES a degraded image;
|
|
42
42
|
* core must not hard-depend on a native image library, so the capability is injected (or auto-detected).
|
|
@@ -46,7 +46,7 @@ export interface LockedPreflight {
|
|
|
46
46
|
* always enforced, resolved ONCE here. With `toolPolicy` locked, the deployment's own
|
|
47
47
|
* `deps.toolPolicy` is the whole answer (a spec-supplied policy has already been refused). */
|
|
48
48
|
toolPolicy: ToolPolicy | undefined;
|
|
49
|
-
/** F-012
|
|
49
|
+
/** F-012: the effective resume-edit re-adjudication OVERRIDE, resolved lock-aware in
|
|
50
50
|
* the SAME slot as {@link toolPolicy}. With `toolPolicy` locked, a spec-supplied
|
|
51
51
|
* `basePolicyForResumeEdit` has already been refused wholesale, so this is the deployment's own
|
|
52
52
|
* `deps.basePolicyForResumeEdit` (or undefined — the caller-policy fallback then applies at the use
|
package/dist/core/lsp.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface LspSymbolInfo {
|
|
|
50
50
|
positionUnknown?: boolean;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* RB-232
|
|
53
|
+
* RB-232: WHY a "none" result was "none". Absent `reason` = a GENUINE empty answer (the server
|
|
54
54
|
* answered null/[] — today's behavior byte-for-byte, and what an external manager returning bare
|
|
55
55
|
* `{kind:"none"}` keeps getting). The failure reasons exist because one literal "No results." used to cover
|
|
56
56
|
* both real emptiness and every transport-level fault — a findReferences that TIMED OUT read as "no
|
|
@@ -110,7 +110,7 @@ export interface MailboxStore {
|
|
|
110
110
|
maxAgeMs?: number;
|
|
111
111
|
}): Promise<number>;
|
|
112
112
|
}
|
|
113
|
-
/** RB-250② (2026-07-28
|
|
113
|
+
/** RB-250② (2026-07-28) class fix — the box age for `reap` is the MAX `sentAt`, not the
|
|
114
114
|
* last array element: `sentAt` is caller-supplied, so append order need not be time order, and taking
|
|
115
115
|
* the tail let a box whose freshest message was mid-array be swept — both bundled backends discarded
|
|
116
116
|
* a brand-new message while the CC adapter (stores/cc/mailbox-store.ts, the in-package reference)
|
package/dist/core/mcp.d.ts
CHANGED
|
@@ -209,7 +209,7 @@ export interface MaterializedMcp {
|
|
|
209
209
|
*/
|
|
210
210
|
statuses: McpServerStatus[];
|
|
211
211
|
/**
|
|
212
|
-
*
|
|
212
|
+
* RefreshMcpTools (CC 2.1.218 parity, anchored to the CLI form) — re-read the tool list of one server (or
|
|
213
213
|
* every CONNECTED server when `server` is omitted) over the EXISTING connection. NEVER dials or
|
|
214
214
|
* re-dials: a dead/never-connected server reports `not_connected`; a live listTools failure
|
|
215
215
|
* reports `failed` (the connection is left as-is). A refreshed entry carries the NEW intake
|
|
@@ -225,7 +225,7 @@ export interface MaterializedMcp {
|
|
|
225
225
|
refresh: (server?: string) => Promise<McpRefreshResult[]>;
|
|
226
226
|
dispose: () => Promise<void>;
|
|
227
227
|
}
|
|
228
|
-
/**
|
|
228
|
+
/** One per-server entry of {@link MaterializedMcp.refresh}. `added`/`removed` are namespaced
|
|
229
229
|
* (`mcp__<server>__<tool>`) names; `tools`/`axes`/`dropped` are present only on `"refreshed"`.
|
|
230
230
|
* The model-facing refresh receipt renders each `dropped` entry with ITS OWN `reason` (schema
|
|
231
231
|
* gate, same-listing name collision, …) — never a blanket label; a consumer matching that receipt
|
|
@@ -654,7 +654,7 @@ export declare function listEntryFingerprint(entry: unknown): string | undefined
|
|
|
654
654
|
* page cap — a bounded multiplier, not a new unbounded surface. Per-entry admission stays where it
|
|
655
655
|
* already is (the intake schema gate, which also drops a name a later page repeats).
|
|
656
656
|
*
|
|
657
|
-
* TIME, the reason `budgetMs` exists (
|
|
657
|
+
* TIME, the reason `budgetMs` exists (confirmed): the page cap bounds REQUESTS, not
|
|
658
658
|
* latency. Giving every page its own full request timeout would let a server that stalls each page hold
|
|
659
659
|
* a connect (or a refresh) for up to twenty timeouts — twenty minutes at the SDK's 60s default, where
|
|
660
660
|
* an unpaginated listing cost one. So the WALK gets the budget a single listing used to have: page one
|