@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.js +2 -1
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +43 -9
- package/dist/agents/peer-directory.js +66 -23
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +8 -1
- package/dist/core/parent-spec-seat.js +4 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +28 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +2 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +3 -1
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function conversationSegmentOf(branch) {
|
|
2
|
+
for (let i = branch.length - 1; i >= 0; i--)
|
|
3
|
+
if (branch[i].type === "compaction")
|
|
4
|
+
return branch[i].id;
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
export const DATE_ANCHOR_CUSTOM_TYPE = "engine:date-anchor";
|
|
8
|
+
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
9
|
+
function normalizeDateAnchor(v) {
|
|
10
|
+
if (typeof v !== "object" || v === null)
|
|
11
|
+
return undefined;
|
|
12
|
+
const { prefixDate, announcedDate, segment } = v;
|
|
13
|
+
if (typeof prefixDate !== "string" || !ISO_DATE.test(prefixDate) || typeof announcedDate !== "string" || !ISO_DATE.test(announcedDate))
|
|
14
|
+
return undefined;
|
|
15
|
+
if (segment !== null && (typeof segment !== "string" || segment.length > 200))
|
|
16
|
+
return undefined;
|
|
17
|
+
return { prefixDate, announcedDate, segment };
|
|
18
|
+
}
|
|
19
|
+
export async function readDateAnchor(session) {
|
|
20
|
+
let branch;
|
|
21
|
+
try {
|
|
22
|
+
branch = await session.getBranch();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
let found;
|
|
28
|
+
for (let i = branch.length - 1; i >= 0 && branch[i].type !== "compaction"; i--) {
|
|
29
|
+
const e = branch[i];
|
|
30
|
+
if (found === undefined && e.type === "custom" && e.customType === DATE_ANCHOR_CUSTOM_TYPE)
|
|
31
|
+
found = normalizeDateAnchor(e.data);
|
|
32
|
+
}
|
|
33
|
+
const segment = conversationSegmentOf(branch);
|
|
34
|
+
return { current: found !== undefined && found.segment === segment ? { prefixDate: found.prefixDate, announcedDate: found.announcedDate } : undefined, segment };
|
|
35
|
+
}
|
|
36
|
+
export function owedDateAnchor(session, seat, state) {
|
|
37
|
+
const read = seat?.anchor;
|
|
38
|
+
if (read === undefined || state === undefined || read.current?.announcedDate === state.announcedDate)
|
|
39
|
+
return undefined;
|
|
40
|
+
const data = { prefixDate: seat.legDate, announcedDate: state.announcedDate, segment: read.segment };
|
|
41
|
+
return () => session.appendCustomEntry(DATE_ANCHOR_CUSTOM_TYPE, data).then(() => undefined, () => undefined);
|
|
42
|
+
}
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* WHERE THE STATE LIVES. The tree's state is one object, reached from the tree's opaque token (`RunInternals.crossBoundaryTree`,
|
|
6
6
|
* `ToolExecuteContext.crossBoundaryTreeForChildren`) through this module alone; each leg joins into it what it knows at prepare (its
|
|
7
7
|
* environment's declaration, its session's newest record, its posture) and every bit an exit sets lands there before the call
|
|
8
|
-
* runs
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* governed
|
|
8
|
+
* runs — after the record that carries it, so a call the exit refuses sets nothing. Each leg's session holds a record
|
|
9
|
+
* (`CROSS_BOUNDARY_RECORD_TYPE`) of the state its content was produced under — written only for an armed tree: at prepare and at an
|
|
10
|
+
* exit (before the call runs) when the state grew past what the session already says, and at a leg's end (before a suspend's row is
|
|
11
|
+
* put, when the leg settles) also when conversation content follows the newest record. A write that fails refuses its call (or its
|
|
12
|
+
* row) on a governed tree; a prepare's or a settle's, and any write on a tree that is not governed, mints
|
|
13
|
+
* `config.cross_boundary_record_unwritten`, once per state. A record covers the content before it: a leg that takes over a session
|
|
13
14
|
* whose content no record covers (none on the branch, or after the newest), on an armed tree, reads that content as off-target.
|
|
14
15
|
*
|
|
15
16
|
* THE OBLIGATION of a call is read off three things at the moment it is asked ({@link crossBoundaryObligation}): the legs the
|
|
@@ -70,16 +70,22 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
70
70
|
tree = joinCrossBoundaryTree(tree, { offTargetReadObserved: true });
|
|
71
71
|
ref.current = tree;
|
|
72
72
|
const stationEngaged = posture !== undefined || externalContentTargetActive || crossBoundaryTreeGoverned(tree);
|
|
73
|
-
|
|
73
|
+
let reported;
|
|
74
|
+
const unwritten = (phase, state, catchUp, err) => {
|
|
75
|
+
if (reported !== undefined && crossBoundaryTreeCovers(reported, state))
|
|
76
|
+
return;
|
|
77
|
+
reported = state;
|
|
78
|
+
deliverEngineNotice(deps.onNotice, crossBoundaryRecordUnwrittenNotice({ sessionId, runId, phase, governed: crossBoundaryTreeGoverned(ref.current), catchUp, cause: thrownText(err) }));
|
|
79
|
+
};
|
|
74
80
|
let writing = Promise.resolve();
|
|
75
81
|
let storeWaits = 0;
|
|
76
|
-
const write = (phase, atLeaf) => {
|
|
82
|
+
const write = (phase, atLeaf, adds = {}) => {
|
|
77
83
|
const next = writing.then(async () => {
|
|
78
84
|
let leafAt = atLeaf;
|
|
79
85
|
let cover = phase === "suspend" || phase === "settle";
|
|
80
86
|
let written;
|
|
81
87
|
for (;;) {
|
|
82
|
-
const state = ref.current;
|
|
88
|
+
const state = joinCrossBoundaryTree(ref.current, adds);
|
|
83
89
|
if (state.targetExecutionArmed !== true)
|
|
84
90
|
return written;
|
|
85
91
|
const grown = !crossBoundaryTreeCovers(recorded, state);
|
|
@@ -112,10 +118,12 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
112
118
|
cover = false;
|
|
113
119
|
}
|
|
114
120
|
catch (err) {
|
|
115
|
-
|
|
121
|
+
const governed = crossBoundaryTreeGoverned(ref.current);
|
|
122
|
+
if (governed && (phase === "exit" || phase === "suspend"))
|
|
116
123
|
throw err;
|
|
117
|
-
unwritten(phase, err);
|
|
118
|
-
|
|
124
|
+
unwritten(phase, state, written !== undefined, err);
|
|
125
|
+
if (!governed)
|
|
126
|
+
recorded = state;
|
|
119
127
|
return written;
|
|
120
128
|
}
|
|
121
129
|
}
|
|
@@ -124,12 +132,13 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
124
132
|
return next;
|
|
125
133
|
};
|
|
126
134
|
const owe = (atLeaf) => write(atLeaf !== undefined ? "suspend" : "exit", atLeaf);
|
|
135
|
+
const OBSERVED = Object.freeze({ offTargetReadObserved: true });
|
|
127
136
|
const trace = (phase, call) => emitTrace(deps.tracer, () => ({ kind: "permission.cross_boundary_taint", version: 1, taskId: hostTaskId, runId, phase, taint: bitsOf(ref.current), governed: ref.current.governed === true, ...(call !== undefined ? { toolName: call.toolName, ...(call.toolCallId !== undefined ? { toolCallId: call.toolCallId } : {}) } : {}), ts: Date.now() }));
|
|
128
137
|
if (tree.targetExecutionArmed === true) {
|
|
129
138
|
trace(resumeLeg ? "resume" : "prepare");
|
|
130
139
|
if (posture === undefined && tree.governed !== true)
|
|
131
140
|
deliverEngineNotice(deps.onNotice, crossBoundaryPostureUndeclaredNotice({ sessionId, runId, tree }));
|
|
132
|
-
await write("prepare")
|
|
141
|
+
await write("prepare");
|
|
133
142
|
}
|
|
134
143
|
let check;
|
|
135
144
|
const lane = {
|
|
@@ -163,19 +172,21 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
163
172
|
message: `tool "${call.toolName}" needs a person's confirmation: this run executes on a target device${ref.current.offTargetReadObserved === true ? " and has since let content from beyond it in, so a call that reaches beyond the device or back into it" : ", so a call that writes beyond the device"} is put to a person — this call was allowed by a configuration, not a person, and was not executed`,
|
|
164
173
|
};
|
|
165
174
|
}
|
|
166
|
-
|
|
167
|
-
ref.current = joinCrossBoundaryTree(ref.current, { offTargetReadObserved: true });
|
|
168
|
-
trace("observed", call);
|
|
169
|
-
}
|
|
175
|
+
const adds = now.record && ref.current.offTargetReadObserved !== true ? OBSERVED : undefined;
|
|
170
176
|
const judged = ref.current;
|
|
171
177
|
try {
|
|
172
|
-
await
|
|
178
|
+
await write("exit", undefined, adds);
|
|
173
179
|
}
|
|
174
180
|
catch (err) {
|
|
175
181
|
return { kind: "unrecorded", message: `tool "${call.toolName}" was not executed: the session's cross-boundary record could not be written before it ran (${thrownText(err)}) — on a governed tree a call that owes its record does not run without it; refused fail-closed` };
|
|
176
182
|
}
|
|
177
|
-
if (ref.current
|
|
178
|
-
|
|
183
|
+
if (ref.current !== judged)
|
|
184
|
+
continue;
|
|
185
|
+
if (adds !== undefined) {
|
|
186
|
+
ref.current = joinCrossBoundaryTree(ref.current, adds);
|
|
187
|
+
trace("observed", call);
|
|
188
|
+
}
|
|
189
|
+
return undefined;
|
|
179
190
|
}
|
|
180
191
|
},
|
|
181
192
|
};
|
|
@@ -184,7 +195,7 @@ export async function prepareCrossBoundaryLane(input) {
|
|
|
184
195
|
owe,
|
|
185
196
|
storeWaits: () => storeWaits,
|
|
186
197
|
recorded: () => ref.current.targetExecutionArmed === true,
|
|
187
|
-
settle: () => write("settle").then(() => undefined
|
|
198
|
+
settle: () => write("settle").then(() => undefined),
|
|
188
199
|
};
|
|
189
200
|
return lane;
|
|
190
201
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { type AskOrigin } from "../ask-origin.js";
|
|
19
19
|
import { type OnQuestion, type QuestionAnswer } from "../ask-question.js";
|
|
20
|
-
import { type Checkpoint, type ResolvedOutcome, type ResumeOutcome } from "../checkpoint-store.js";
|
|
20
|
+
import { type Checkpoint, type CheckpointErrorField, type ResolvedOutcome, type ResumeOutcome } from "../checkpoint-store.js";
|
|
21
21
|
import { type GateOutcome, type HostDecisionFacts } from "../gate-outcome.js";
|
|
22
22
|
import type { ResumeRun } from "./contracts.js";
|
|
23
23
|
/**
|
|
@@ -130,10 +130,13 @@ export declare function mintDecideRecord(cp: Checkpoint, facts: HostDecisionFact
|
|
|
130
130
|
* answer differently each time — the check passing on text it never inspected. Refused pre-CAS so the
|
|
131
131
|
* row stays `pending` for a well-formed decide, exactly like the other capture-time domain refusals,
|
|
132
132
|
* and BEFORE the hygiene check so no guard ever consults a value outside the domain. The rejected field
|
|
133
|
-
* is named in the message
|
|
134
|
-
*
|
|
133
|
+
* is named in the message, and in `detail` where the caller hands the closed set's word for the cell
|
|
134
|
+
* (`CheckpointErrorField`: `feedback` has one; `reason` and `editedPlan` have none, and widening the set is a
|
|
135
|
+
* wire-surface change of its own).
|
|
135
136
|
*/
|
|
136
|
-
export declare function assertOutcomeText(value: string | undefined, field: "editedPlan" | "reason" | "feedback"
|
|
137
|
+
export declare function assertOutcomeText(value: string | undefined, field: "editedPlan" | "reason" | "feedback", detail?: {
|
|
138
|
+
field: CheckpointErrorField;
|
|
139
|
+
}): void;
|
|
137
140
|
/**
|
|
138
141
|
* The continuation prompt for a resumed run. The vendored harness only exposes
|
|
139
142
|
* `prompt(text)` (it always appends a user message — there is no "continue from tool results" entry), so
|
|
@@ -123,9 +123,9 @@ export function mintDecideRecord(cp, facts, verdict) {
|
|
|
123
123
|
const settlement = settlementOfHostDecision(facts, verdict.allowed ? "allowed" : "refused", verdict.note);
|
|
124
124
|
return mintGateOutcome({ ...(verdict.allowed ? {} : { deniedBy: "ask_resolution" }), settled: { settlement, origin } });
|
|
125
125
|
}
|
|
126
|
-
export function assertOutcomeText(value, field) {
|
|
126
|
+
export function assertOutcomeText(value, field, detail) {
|
|
127
127
|
if (value !== undefined && typeof value !== "string") {
|
|
128
|
-
throw new CheckpointError("checkpoint.invalid_outcome", `resume \`${field}\` is not a plain string (got ${typeof value}) — a decide's text payload is an operator's plain data, not a live object; refusing pre-CAS, the checkpoint stays pending
|
|
128
|
+
throw new CheckpointError("checkpoint.invalid_outcome", `resume \`${field}\` is not a plain string (got ${typeof value}) — a decide's text payload is an operator's plain data, not a live object; refusing pre-CAS, the checkpoint stays pending`, detail);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
function reorientClause(fullShellReachable) {
|
|
@@ -170,13 +170,13 @@ export type InheritedClassifierJudgment<A extends InheritedAsk> =
|
|
|
170
170
|
};
|
|
171
171
|
/**
|
|
172
172
|
* The ancestor's frozen classifier, run BEFORE its frozen approver in the ancestor's own gate order,
|
|
173
|
-
* with the denial-limit count folded in (
|
|
173
|
+
* with the denial-limit count folded in (count-then-judge): `allow` ⇒ the classifier's
|
|
174
174
|
* auto-allow (and the streak resets); `block` below the bound ⇒ deny, the exact verdict the ancestor's
|
|
175
175
|
* gate would have produced; `block` AT the bound ⇒ the ask is re-spoken in the classifier's voice as
|
|
176
176
|
* the fallback (`decisionReason:"classifier"`, `requiresRealApproval`, the member carrying counts +
|
|
177
177
|
* window) for the arm to resolve at the frozen approver; a classification that did not rule (`unavailable`, or a reply
|
|
178
178
|
* with no verdict) ⇒ the gate's own exit (`classifierNoRulingArm`) on the frozen approver — a live one resolves the incoming
|
|
179
|
-
* ask carrying why (never counted); none ⇒ the unavailable form is a DENY that says so (
|
|
179
|
+
* ask carrying why (never counted); none ⇒ the unavailable form is a DENY that says so (never counted) and
|
|
180
180
|
* a reply with no verdict takes the block path with the CC parse-failure sentence (counted); a CONFLICTING reply takes the
|
|
181
181
|
* block path too; excluded / no classifier ⇒ the incoming ask, unchanged. The member may ALREADY be on the incoming
|
|
182
182
|
* ask (a deeper ancestor's fallback, minted inside the nested fold — the case the exclusion names):
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The derived-leg route pre-flight shared by prepareTask's
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* spelling it twice. The judgment law and both announcements live in the brain's route adjudicator; this is the one
|
|
6
|
-
* guarded seat around them.
|
|
2
|
+
* The derived-leg route pre-flight shared by prepareTask's derived seats: the compaction-summary model, the auto-mode
|
|
3
|
+
* classifier model and the advisor model. One guarded seat, reached DOWN for by each phase instead of spelled again; the
|
|
4
|
+
* judgment law and the announcements live in the brain's route adjudicator.
|
|
7
5
|
*/
|
|
8
|
-
import type { Model } from "../../internal/llm.js";
|
|
6
|
+
import type { Model, RouteRefusalCode } from "../../internal/llm.js";
|
|
9
7
|
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
8
|
+
/** What the pre-flight decided: keep the seat's model (same route as the primary, the pairing holds, the judge abstained, or
|
|
9
|
+
* the deployment declined a fallback — the seat is kept and its calls refused), swap it for the primary, or take the seat
|
|
10
|
+
* off this run. A move carries the refusal that caused it. */
|
|
11
|
+
export type DerivedSeatOutcome = {
|
|
12
|
+
readonly action: "keep";
|
|
13
|
+
} | {
|
|
14
|
+
readonly action: "fall_back" | "detach";
|
|
15
|
+
readonly cause: RouteRefusalCode;
|
|
16
|
+
};
|
|
10
17
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* failed": at the compaction seat the session is already acquired and the throw-cleanup contract
|
|
17
|
-
* is not yet armed, so a throw here would leak the acquired session view, and the garbage value
|
|
18
|
-
* still earns its loud refusal at the request gate the moment the derived leg is actually used.
|
|
19
|
-
* Returns whether the seat should fall back to the primary model.
|
|
18
|
+
* Judge the derived model where its route differs from the primary's, announce what a broken pairing means for THIS seat
|
|
19
|
+
* (`onBrokenPairing`), and ABSTAIN (keep) on ANY throw. The pre-flight is advisory — the brain's request gate re-runs the
|
|
20
|
+
* same law — so neither a throwing judge face nor a garbage catalog value may widen into "task preparation failed": at the
|
|
21
|
+
* compaction seat the session is already acquired and the throw-cleanup contract is not yet armed, and the garbage value
|
|
22
|
+
* still earns its loud refusal at the request gate the moment the derived leg is used.
|
|
20
23
|
*/
|
|
21
24
|
export declare function derivedRouteFallsBack(args: {
|
|
22
25
|
seat: string;
|
|
@@ -25,14 +28,11 @@ export declare function derivedRouteFallsBack(args: {
|
|
|
25
28
|
brain: RunnerDeps["brain"];
|
|
26
29
|
getApiKeyAndHeaders: TaskSpec["getApiKeyAndHeaders"];
|
|
27
30
|
onNotice: RunnerDeps["onNotice"];
|
|
28
|
-
/** The
|
|
29
|
-
* (the audience stays operator: correlation, not entitlement). Absent ⇒ nothing is fabricated. */
|
|
31
|
+
/** The session / INVOCATION this resolution belongs to: correlation keys on the notice (the audience stays operator). */
|
|
30
32
|
sessionId?: string;
|
|
31
|
-
/** The INVOCATION this seat resolution belongs to. The session cannot stand in for it: two
|
|
32
|
-
* runs of one session that both fall back on the same seat mint otherwise byte-identical lines. */
|
|
33
33
|
runId?: string;
|
|
34
|
-
/**
|
|
35
|
-
* (the
|
|
36
|
-
*
|
|
37
|
-
onBrokenPairing?: "fall_back" | "refuse";
|
|
38
|
-
}): Promise<
|
|
34
|
+
/** Absent / `"fall_back"`: swap and announce `route.fallback_to_primary`. `"refuse"`: keep the seat and announce
|
|
35
|
+
* `route.classifier_unroutable` (the deployment declined a fallback — never granted quietly). `"detach"`: take the seat
|
|
36
|
+
* off the run and announce `route.seat_detached` (a seat the primary model cannot stand in for). */
|
|
37
|
+
onBrokenPairing?: "fall_back" | "refuse" | "detach";
|
|
38
|
+
}): Promise<DerivedSeatOutcome>;
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { adjudicateDerivedRoute, fallbackToPrimaryNotice, sameRouteIdentity, unroutableSeatNotice } from "../../brain/route-adjudicator.js";
|
|
1
|
+
import { adjudicateDerivedRoute, fallbackToPrimaryNotice, sameRouteIdentity, seatDetachedNotice, unroutableSeatNotice } from "../../brain/route-adjudicator.js";
|
|
2
2
|
import { deliverEngineNotice } from "../types.js";
|
|
3
3
|
export async function derivedRouteFallsBack(args) {
|
|
4
4
|
try {
|
|
5
5
|
if (sameRouteIdentity(args.derived, args.primary))
|
|
6
|
-
return
|
|
6
|
+
return { action: "keep" };
|
|
7
7
|
const verdict = await adjudicateDerivedRoute({ brain: args.brain, model: args.derived, getApiKeyAndHeaders: args.getApiKeyAndHeaders });
|
|
8
8
|
if (verdict === undefined || verdict.ok)
|
|
9
|
-
return
|
|
9
|
+
return { action: "keep" };
|
|
10
10
|
const shared = { seat: args.seat, from: args.derived.id, verdict, ...(args.sessionId !== undefined ? { sessionId: args.sessionId } : {}), ...(args.runId !== undefined ? { runId: args.runId } : {}) };
|
|
11
|
-
const
|
|
12
|
-
if (refuse)
|
|
11
|
+
const posture = args.onBrokenPairing ?? "fall_back";
|
|
12
|
+
if (posture === "refuse")
|
|
13
13
|
deliverEngineNotice(args.onNotice, unroutableSeatNotice({ ...shared, primary: args.primary.id }));
|
|
14
|
+
else if (posture === "detach")
|
|
15
|
+
deliverEngineNotice(args.onNotice, seatDetachedNotice(shared));
|
|
14
16
|
else
|
|
15
17
|
deliverEngineNotice(args.onNotice, fallbackToPrimaryNotice({ ...shared, to: args.primary.id }));
|
|
16
|
-
return
|
|
18
|
+
return posture === "refuse" ? { action: "keep" } : { action: posture, cause: verdict.code };
|
|
17
19
|
}
|
|
18
20
|
catch {
|
|
19
|
-
return
|
|
21
|
+
return { action: "keep" };
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* contract (`ToolGateInput`, `ToolGateResult`, the observer payload), which stays declared there.
|
|
23
23
|
*/
|
|
24
24
|
import { type ClassifierDenyCause, type DeniedBy, type GateOutcome, type ModeRefusal, type ModeRelease, type Settlement } from "../gate-outcome.js";
|
|
25
|
+
import type { AllowRuleClearance } from "../allow-rule-shadow.js";
|
|
25
26
|
import type { AutoModeClassifierRound } from "../auto-mode.js";
|
|
26
27
|
import { type Arbitration, type AskClassification, type AskFace, type AskOrigin, type AskOriginFacts } from "../ask-origin.js";
|
|
27
28
|
import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "../tool-policy.js";
|
|
@@ -49,6 +50,8 @@ export interface GateExitFacts {
|
|
|
49
50
|
classifier?: AutoModeClassifierRound;
|
|
50
51
|
/** The permission mode RELEASED the surviving ask (the allow exit's account of it); never beside `deniedBy`. */
|
|
51
52
|
released?: ModeRelease;
|
|
53
|
+
/** An allow-layer member CLEARED the standing ask (the allow exit's account of it); never beside `deniedBy`, a settlement or a release. */
|
|
54
|
+
clearedBy?: AllowRuleClearance;
|
|
52
55
|
/** The permission mode REFUSED the surviving ask — only beside `deniedBy: "mode"`. */
|
|
53
56
|
modeRefusal?: ModeRefusal;
|
|
54
57
|
}
|
|
@@ -333,6 +336,9 @@ export interface GatePass {
|
|
|
333
336
|
arbitration?: Exclude<Arbitration, {
|
|
334
337
|
kind: "ask";
|
|
335
338
|
}>;
|
|
339
|
+
/** borrowed-mutable — the allow-layer member that CLEARED the standing ask and the entries it stood on (the allow exit projects
|
|
340
|
+
* it onto the disposition when nobody answered an ask on this pass). Writer: the lanes' allow layer. */
|
|
341
|
+
clearedBy?: AllowRuleClearance;
|
|
336
342
|
}
|
|
337
343
|
/**
|
|
338
344
|
* The engine's fail-closed block of phase 1 — the PreToolUse face THREW or never ANSWERED, so the engine
|
|
@@ -23,7 +23,12 @@ export function mintGateOutcome(facts) {
|
|
|
23
23
|
...(attribution !== undefined ? { classifier: attribution } : {}),
|
|
24
24
|
...(facts.modeRefusal !== undefined ? { mode: facts.modeRefusal.mode, askClass: facts.modeRefusal.askClass, classes: Object.freeze([...facts.modeRefusal.classes]) } : {}),
|
|
25
25
|
}
|
|
26
|
-
: {
|
|
26
|
+
: {
|
|
27
|
+
kind: "allowed",
|
|
28
|
+
...(attribution !== undefined ? { classifier: attribution } : {}),
|
|
29
|
+
...(facts.released !== undefined ? { released: Object.freeze({ ...facts.released, classes: Object.freeze([...facts.released.classes]) }) } : {}),
|
|
30
|
+
...(facts.clearedBy !== undefined ? { clearedBy: Object.freeze({ ...facts.clearedBy, entries: Object.freeze([...facts.clearedBy.entries]), ...(facts.clearedBy.positions !== undefined ? { positions: Object.freeze([...facts.clearedBy.positions]) } : {}) }) } : {}),
|
|
31
|
+
}),
|
|
27
32
|
...(facts.settled !== undefined ? { settlement: settlement, origin: facts.settled.origin } : {}),
|
|
28
33
|
});
|
|
29
34
|
const defects = screenGateOutcome(outcome, { reading: "producer" });
|
|
@@ -315,7 +320,7 @@ export async function exitGate(pass) {
|
|
|
315
320
|
return undefined; const a = pass.arbitration === undefined ? input.ancestorArbitrationOf?.(toolCallId) : undefined; return a?.kind === "released" ? a : undefined; })();
|
|
316
321
|
return {
|
|
317
322
|
updatedInput: pass.currentInput,
|
|
318
|
-
gate: mintGateOutcome({ ...(ledger.settled !== undefined ? { settled: ledger.settled } : {}), ...(pass.classifierRound !== undefined ? { classifier: pass.classifierRound } : {}), ...(release !== undefined ? { released: releaseRecordOf(release) } : {}) }),
|
|
323
|
+
gate: mintGateOutcome({ ...(ledger.settled !== undefined ? { settled: ledger.settled } : {}), ...(pass.classifierRound !== undefined ? { classifier: pass.classifierRound } : {}), ...(release !== undefined ? { released: releaseRecordOf(release) } : {}), ...(pass.clearedBy !== undefined && ledger.settled === undefined && release === undefined ? { clearedBy: pass.clearedBy } : {}) }),
|
|
319
324
|
finalInput: frozenInputSnapshot(pass.currentInput),
|
|
320
325
|
preToolContext: pass.preToolContext,
|
|
321
326
|
};
|
|
@@ -4,7 +4,7 @@ export function createRunState() {
|
|
|
4
4
|
degrade: { degradeToModel: undefined, degraded: undefined, outputErrorStreak: 0, outputInvalid: false, recordDegraded: () => { } },
|
|
5
5
|
limits: { turnsExceeded: false, budgetHit: undefined, budgetAxis: undefined, platformTerminal: undefined, outputRetryCap: 0, effectiveMaxTurns: undefined },
|
|
6
6
|
budget: { remainingMicroUsd: undefined, maxCostMicroUsd: undefined, remainingTokens: undefined, maxTokensWindow: undefined, overBudget: () => undefined, streamCancel: false, callOutputChars: 0, lastStreamBudgetCheck: 0, projectedOverBudget: () => undefined },
|
|
7
|
-
turn: { callStartAt: undefined, firstTokenAt: undefined, turnUsage: undefined, turnUsageMissing: false, turnStopReason: undefined, turnResponseModel: undefined,
|
|
7
|
+
turn: { callStartAt: undefined, firstTokenAt: undefined, turnUsage: undefined, turnUsageMissing: false, turnStopReason: undefined, turnResponseModel: undefined, toolBatch: [] },
|
|
8
8
|
counters: { approachNoticesSent: 0, walltimeSyncBackstopFired: false, compactionFloor: 0, trimForceBackoff: false, compactionPasses: 0, repetitionCuts: 0, repetitionSpared: 0, repetitionEvents: [], REPETITION_EVENTS_CAP: 0, preemptIgnoredReported: false, wroteThisRun: false, finalVerifyInjections: 0, groundingSignalPreR9: false, groundingSignalPostR9: false, cadenceTurns: 0 },
|
|
9
9
|
attach: { attachmentsCfg: undefined, agentListingOn: false, skillsListingOn: false, attachState: undefined, dateState: undefined, instrProbe: undefined, instrState: undefined, sizeGuidelineState: undefined, attachmentsInjected: 0 },
|
|
10
10
|
};
|
|
@@ -32,7 +32,7 @@ import { type HeadLeads } from "../path-rule-binding.js";
|
|
|
32
32
|
import type { ToolCallLike } from "../tool-registry.js";
|
|
33
33
|
import { type OrgRuleResolution } from "../permission-rule-org.js";
|
|
34
34
|
import { type EffectivePermissionRules, type PermissionRuleStoreProvider, type PersonRowsRead } from "../permission-rule-provider.js";
|
|
35
|
-
/** The one SHELL tool the persisted-rule lane's COMMAND grammar speaks for (the rule-offer face mints for it and the
|
|
35
|
+
/** The one SHELL tool the persisted-rule lane's COMMAND grammar speaks for (the rule-offer face mints for it, the name tools and the host tools); the other grammars' tools are derived (`ruleToolGrammarOf`). */
|
|
36
36
|
export declare const PERSISTED_RULE_TOOL = "Bash";
|
|
37
37
|
/**
|
|
38
38
|
* The evidence an INHERITED-lane ask carries.
|
|
@@ -225,7 +225,7 @@ interface RuleOffersAskFacts extends RuleClearanceFacts {
|
|
|
225
225
|
* "stop asking me this" on a card that will keep asking lets a person mint a rule that never
|
|
226
226
|
* takes effect where they minted it.
|
|
227
227
|
*
|
|
228
|
-
* (
|
|
228
|
+
* (toolPolicy 对表, F11: "wildcard `ask` … keeps every matching tool behind a
|
|
229
229
|
* per-call prompt (no persistent always-allow)") — `matchedAskRule` was the one conjunct of the
|
|
230
230
|
* lane's own clearing predicate this door did not mirror, and the asymmetry was live: the
|
|
231
231
|
* persisted-rule lane refuses to clear ANY ask carrying it (`hooks.ts`, the
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { persistedRuleMandateOf, ruleClearanceOf } from "../ask-origin.js";
|
|
2
2
|
import {} from "../hooks.js";
|
|
3
|
-
import { adjudicatePersistedDomainRules, adjudicatePersistedNameRules, adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf,
|
|
3
|
+
import { adjudicatePersistedDomainRules, adjudicatePersistedNameRules, adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf, escapeForDisclosure, faceRowsSpeakFor, laneToolNamesOf, nameRuleSubjectOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForHost, suggestRuleForName, suggestRulesForCommand } from "../permission-rule-model.js";
|
|
4
|
+
import { callHostTargetOf } from "../host-target.js";
|
|
4
5
|
import { callTargetViewsOf, validatePath } from "../effective-path-target.js";
|
|
5
6
|
import { bindPathRules, persistedRowAnchors, projectScopeIdentity } from "../path-rule-binding.js";
|
|
6
7
|
import { heldBy, seatOf, wireOf } from "../tool-name-readings.js";
|
|
@@ -120,9 +121,9 @@ export function createPermissionRuleLanes(cfg) {
|
|
|
120
121
|
const judged = laneToolNamesOf(req).map((n) => [n, ruleToolGrammarOf(n)]);
|
|
121
122
|
if (!judged.some(([, g]) => g === "path") && faceRowsSpeakFor(callPathFaceOf(req)))
|
|
122
123
|
judged.push([req.toolName, "path"]);
|
|
123
|
-
if (judged.length === 0)
|
|
124
|
-
return undefined;
|
|
125
124
|
const view = await reader.pin(req.toolCallId);
|
|
125
|
+
if (judged.length === 0)
|
|
126
|
+
return view.unreadable !== undefined ? { unreadable: true } : undefined;
|
|
126
127
|
try {
|
|
127
128
|
const table = view.rules.filter((r) => r.behavior !== "allow" || cfg.stripsAllow?.(r, req) !== true);
|
|
128
129
|
const leads = judged.some(([, g]) => g === "path") ? await cfg.leads.resolve(bindPathRules(table.filter((r) => r.match === "path" || r.match === "subpath").map((r) => ({ parsed: r, ruleText: r.rule, rule: r })), (spec) => anchorsOf(spec.rule))) : NO_LEADS;
|
|
@@ -144,9 +145,9 @@ export function createPermissionRuleLanes(cfg) {
|
|
|
144
145
|
if (grammar === "path")
|
|
145
146
|
return pathRuleLaneAnswer(table, req, { root: cfg.root, sessionId: cfg.sessionId, anchorsOf, leads, ...scope });
|
|
146
147
|
if (grammar === "name")
|
|
147
|
-
return persistedRuleAnswerOf(adjudicatePersistedNameRules(table, { tool: req.toolName,
|
|
148
|
+
return persistedRuleAnswerOf(adjudicatePersistedNameRules(table, { tool: req.toolName, request: req, cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
|
|
148
149
|
if (grammar === "domain")
|
|
149
|
-
return persistedRuleAnswerOf(adjudicatePersistedDomainRules(table, { tool: req.toolName,
|
|
150
|
+
return persistedRuleAnswerOf(adjudicatePersistedDomainRules(table, { tool: req.toolName, hosts: { tighten: callHostTargetOf(req, "tighten"), grant: callHostTargetOf(req, "grant") }, cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
|
|
150
151
|
const command = req.args?.command;
|
|
151
152
|
if (typeof command !== "string")
|
|
152
153
|
return undefined;
|
|
@@ -163,7 +164,8 @@ export function createPermissionRuleLanes(cfg) {
|
|
|
163
164
|
export function createRuleOffersOf(cfg) {
|
|
164
165
|
return (call, args, ask) => {
|
|
165
166
|
const toolName = wireOf("offer.laneTool", call);
|
|
166
|
-
|
|
167
|
+
const grammar = ruleToolGrammarOf(toolName);
|
|
168
|
+
if (!cfg.laneArmed || (toolName !== PERSISTED_RULE_TOOL && grammar !== "name" && grammar !== "domain"))
|
|
167
169
|
return {};
|
|
168
170
|
if ((cfg.principal === undefined || cfg.principal === "") && !cfg.localOwnerDeclared)
|
|
169
171
|
return {};
|
|
@@ -175,10 +177,15 @@ export function createRuleOffersOf(cfg) {
|
|
|
175
177
|
}).word;
|
|
176
178
|
if (closedDoor !== undefined)
|
|
177
179
|
return { ruleOffersAbsence: closedDoor };
|
|
178
|
-
if (
|
|
180
|
+
if (grammar === "name") {
|
|
179
181
|
const offer = suggestRuleForName(toolName, nameRuleSubjectOf(toolName, args) ?? "");
|
|
180
182
|
return offer !== undefined ? { ruleOffers: [offer] } : { ruleOffersAbsence: "lane_cannot_speak" };
|
|
181
183
|
}
|
|
184
|
+
if (grammar === "domain") {
|
|
185
|
+
const host = callHostTargetOf({ toolName: call.toolName, args, face: call.face }, "grant");
|
|
186
|
+
const offer = host !== undefined && "host" in host ? suggestRuleForHost(toolName, host.host) : undefined;
|
|
187
|
+
return offer !== undefined ? { ruleOffers: [offer] } : { ruleOffersAbsence: "lane_cannot_speak" };
|
|
188
|
+
}
|
|
182
189
|
const command = args?.command;
|
|
183
190
|
if (typeof command !== "string")
|
|
184
191
|
return { ruleOffersAbsence: "lane_cannot_speak" };
|
|
@@ -367,7 +367,7 @@ export function ruleStoreUnreadableNotice(onNotice, ids) {
|
|
|
367
367
|
const which = sources !== undefined && sources.length > 0 ? `your persisted permission rules from the ${sourcesWord(sources)} sources` : "your persisted permission rules";
|
|
368
368
|
deliverEngineNotice(onNotice, {
|
|
369
369
|
code: "permission.rule_store_unavailable",
|
|
370
|
-
message: `${which} could not be read ${at === "prepare" ? "when this run started" : "for a call on this run"}. Until a read of them succeeds, none of their allow rows (Read directory rows included) applies, while the deny and ask rows most recently read from them this run still apply — a deny row you removed since that read keeps refusing until then. While they cannot be read, every call
|
|
370
|
+
message: `${which} could not be read ${at === "prepare" ? "when this run started" : "for a call on this run"}. Until a read of them succeeds, none of their allow rows (Read directory rows included) applies, while the deny and ask rows most recently read from them this run still apply — a deny row you removed since that read keeps refusing until then. While they cannot be read, every call is asked about rather than allowed, whatever its tool (rules nobody can read may name any), until a read of them succeeds. Every later check reads them again.`,
|
|
371
371
|
detail: { at, sessionId: ids.sessionId, runId: ids.runId },
|
|
372
372
|
});
|
|
373
373
|
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrepareTask's ADVISOR phase: whether this leg mounts the `advisor` tool, and what it owes the model about it. In order —
|
|
3
|
+
* the deployment switch (`RunnerDeps.advisorTool: "disabled"` ignores the spec's advisor model unread); the static verdict
|
|
4
|
+
* (`advisorAttachVerdict`, the one answer a host's advisor query reads too); then the mount chain — the reserved name, the
|
|
5
|
+
* leg's tool selector (its valve's own predicate, asked of the tool's name), the conversation's hold (the transcript), the
|
|
6
|
+
* advisor route (the shared derived-seat pre-flight, posture `detach`) — and the mount. Its answer is the manifest fact,
|
|
7
|
+
* the person's notice for a reason they are told (root legs only, once per conversation per pair), and the leg's
|
|
8
|
+
* instruction seat (what the model is owed, against what it was told in the conversation's current segment).
|
|
9
|
+
*
|
|
10
|
+
* Runs after the scaffold mounts and before the tool-face fold, so the deferred classification, the prompt and the
|
|
11
|
+
* manifest see the roster the leg runs with. A leg whose spec names no advisor model and whose conversation never told
|
|
12
|
+
* the model about one does nothing here and reads nothing.
|
|
13
|
+
*/
|
|
14
|
+
import type { SessionTreeEntry } from "../../internal/harness-types.js";
|
|
15
|
+
import type { Model } from "../../internal/llm.js";
|
|
16
|
+
import type { CompactionForkContext } from "../auto-compaction.js";
|
|
17
|
+
import type { ToolSelector } from "../tool-face.js";
|
|
18
|
+
import type { RosterBuilder } from "../tool-roster.js";
|
|
19
|
+
import { type RunnerDeps, type TaskSpec } from "../types.js";
|
|
20
|
+
import type { WiringAdvisorFact } from "../wiring-manifest.js";
|
|
21
|
+
import { type AdvisorInstructionSeat } from "./advisor-instructions.js";
|
|
22
|
+
import { type AnnounceOnceLedger } from "./announce-once-ledger.js";
|
|
23
|
+
import type { Prepared } from "./contracts.js";
|
|
24
|
+
export interface PrepareAdvisorInput {
|
|
25
|
+
/** borrowed-readonly — the REBOUND spec: the advisor model, the caller's tools (the reserved name), the whole-face switch, the auth hook. */
|
|
26
|
+
spec: Pick<TaskSpec, "advisorModel" | "tools" | "excludeAllTools" | "getApiKeyAndHeaders">;
|
|
27
|
+
/** borrowed-readonly — the deployment switch as the value door screened it. */
|
|
28
|
+
advisorTool: "disabled" | undefined;
|
|
29
|
+
/** borrowed-readonly — the catalog and tiers the verdict reads, the brain the advisor lane books, the notice sink. */
|
|
30
|
+
deps: Pick<RunnerDeps, "models" | "tiers" | "brain" | "onNotice">;
|
|
31
|
+
/** borrowed-readonly — the leg's resolved main model. */
|
|
32
|
+
model: Model;
|
|
33
|
+
/** borrowed-mutable — the mount array (the advisor tool is mounted on it). */
|
|
34
|
+
roster: RosterBuilder;
|
|
35
|
+
/** borrowed-readonly — the leg's frozen tool selector (the valve's predicate). */
|
|
36
|
+
selector: ToolSelector;
|
|
37
|
+
/** borrowed-readonly — the acquired session: its branch (the hold, the segment). */
|
|
38
|
+
session: {
|
|
39
|
+
getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>;
|
|
40
|
+
};
|
|
41
|
+
/** borrowed-readonly — the once-per-session ledger: what the model was told (`arms().advisor`), and the notice's dedupe. */
|
|
42
|
+
onceLedger: Pick<AnnounceOnceLedger, "arms" | "oncePerSession">;
|
|
43
|
+
/** borrowed-readonly — a leg the person reads (not a delegated child): only such a leg tells them. */
|
|
44
|
+
rootLeg: boolean;
|
|
45
|
+
/** borrowed-readonly — the acquired session's id (the notice's routing key). */
|
|
46
|
+
sessionId: string;
|
|
47
|
+
/** borrowed-readonly — this invocation's id (the notices' correlation key). */
|
|
48
|
+
runId: string | undefined;
|
|
49
|
+
/** borrowed-readonly — the leg's usage-account door (the run body binds it before any tool call). */
|
|
50
|
+
sideCallBookRef: Prepared["sideCallBookRef"];
|
|
51
|
+
/** borrowed-readonly — the request the main lane last sent (read at each call). */
|
|
52
|
+
lastSentRequest: () => CompactionForkContext | undefined;
|
|
53
|
+
/** borrowed-readonly — the leg's resolved brain-call guardrail (the value doors' answer; `undefined` = off). */
|
|
54
|
+
brainCallGuardrailMs: number | undefined;
|
|
55
|
+
}
|
|
56
|
+
export interface PrepareAdvisorResult {
|
|
57
|
+
/** The manifest's `advisor` fact; absent ⇔ the spec names no advisor model. */
|
|
58
|
+
manifest: WiringAdvisorFact | undefined;
|
|
59
|
+
/** The leg's instruction seat; absent when there is nothing to tell and nothing told. */
|
|
60
|
+
instruction: AdvisorInstructionSeat | undefined;
|
|
61
|
+
}
|
|
62
|
+
/** The phase body — see the module header. Throws only `config.reserved_tool_name` (a caller tool named `advisor` on a leg that mounts it). */
|
|
63
|
+
export declare function prepareAdvisor(input: PrepareAdvisorInput): Promise<PrepareAdvisorResult>;
|