@sema-agent/core 7.48.0 → 7.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +418 -0
- package/README.md +2 -2
- package/dist/agents/cascade.d.ts +2 -5
- package/dist/agents/child-failure.d.ts +20 -0
- package/dist/agents/child-failure.js +28 -0
- package/dist/agents/cross-session-ref.d.ts +11 -3
- package/dist/agents/cross-session-ref.js +6 -0
- package/dist/agents/cumulative-stats.d.ts +12 -15
- package/dist/agents/cumulative-stats.js +1 -1
- package/dist/agents/extra-tool-names.js +1 -1
- package/dist/agents/inherited-tool-pool.d.ts +17 -13
- package/dist/agents/inherited-tool-pool.js +4 -3
- package/dist/agents/peer-session-drain.d.ts +3 -2
- package/dist/agents/peer-session-drain.js +5 -4
- package/dist/agents/send-message-tool.js +2 -9
- package/dist/agents/subagent.d.ts +10 -29
- package/dist/agents/subagent.js +65 -53
- package/dist/agents/suspend-guard.d.ts +1 -1
- package/dist/agents/tool-filter.d.ts +76 -65
- package/dist/agents/tool-filter.js +122 -92
- package/dist/agents/verify.d.ts +4 -7
- package/dist/agents/verify.js +6 -7
- package/dist/bench/metrics.d.ts +1 -2
- package/dist/brain/anthropic.js +133 -79
- package/dist/brain/errors.d.ts +53 -6
- package/dist/brain/errors.js +22 -2
- package/dist/brain/input-too-long.d.ts +40 -19
- package/dist/brain/input-too-long.js +3 -16
- package/dist/brain/open-responses.js +19 -10
- package/dist/brain/openai.js +123 -32
- package/dist/brain/provider-dialect.d.ts +214 -0
- package/dist/brain/provider-dialect.js +186 -0
- package/dist/brain/request-params.d.ts +27 -8
- package/dist/brain/request-params.js +7 -12
- package/dist/brain/request-route.d.ts +84 -0
- package/dist/brain/request-route.js +41 -0
- package/dist/brain/retry.d.ts +8 -0
- package/dist/brain/retry.js +10 -4
- package/dist/brain/route-adjudicator.d.ts +7 -0
- package/dist/brain/route-adjudicator.js +5 -1
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +11 -0
- package/dist/brain/stream-engine.d.ts +52 -1
- package/dist/brain/stream-engine.js +81 -24
- package/dist/brain/stream-shared.d.ts +57 -11
- package/dist/brain/stream-shared.js +28 -2
- package/dist/core/a2a.d.ts +1 -0
- package/dist/core/agent-config-dir.js +3 -2
- package/dist/core/allow-entry.d.ts +21 -12
- package/dist/core/allow-entry.js +38 -31
- package/dist/core/arg-summary.d.ts +17 -24
- package/dist/core/arg-summary.js +169 -68
- package/dist/core/ask-origin.d.ts +42 -24
- package/dist/core/ask-origin.js +18 -13
- package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/auto-mode-prompt.d.ts +11 -1
- package/dist/core/auto-mode-prompt.js +13 -10
- package/dist/core/auto-mode-rebuild.d.ts +7 -0
- package/dist/core/auto-mode-rebuild.js +4 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.js +2 -1
- package/dist/core/checkpoint-requirements.d.ts +892 -0
- package/dist/core/checkpoint-requirements.js +333 -0
- package/dist/core/checkpoint-store.d.ts +94 -65
- package/dist/core/checkpoint-store.js +14 -26
- package/dist/core/child-clamp-seats.d.ts +228 -69
- package/dist/core/child-clamp-seats.js +211 -17
- package/dist/core/classifier-unavailable-arm.d.ts +5 -1
- package/dist/core/classifier-unavailable-arm.js +3 -3
- package/dist/core/compliance.d.ts +3 -0
- package/dist/core/compliance.js +9 -4
- package/dist/core/credential-vocabulary.d.ts +140 -0
- package/dist/core/credential-vocabulary.js +131 -0
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/effective-path-target.d.ts +73 -16
- package/dist/core/effective-path-target.js +63 -33
- package/dist/core/engine-notice.d.ts +32 -7
- package/dist/core/file-history-store.js +2 -2
- package/dist/core/fs-write-gate-policy.d.ts +4 -0
- package/dist/core/fs-write-gate-policy.js +22 -5
- package/dist/core/gate-bounded-await.d.ts +28 -13
- package/dist/core/gate-bounded-await.js +41 -4
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -25
- package/dist/core/gate-lanes.js +16 -15
- package/dist/core/gate-outcome.d.ts +20 -5
- package/dist/core/gate-outcome.js +5 -0
- package/dist/core/governance-codes.d.ts +11 -4
- package/dist/core/governance-codes.js +14 -3
- package/dist/core/hooks.d.ts +4 -0
- package/dist/core/locked-config.d.ts +8 -0
- package/dist/core/locked-config.js +14 -2
- package/dist/core/lsp.js +3 -5
- package/dist/core/mailbox-store.d.ts +3 -4
- package/dist/core/mcp-connection-pool.d.ts +75 -0
- package/dist/core/mcp-connection-pool.js +128 -0
- package/dist/core/mcp-failure.d.ts +2 -1
- package/dist/core/mcp-failure.js +13 -2
- package/dist/core/mcp.d.ts +4 -0
- package/dist/core/mcp.js +70 -43
- package/dist/core/memory-engine/content-origin.js +2 -14
- package/dist/core/memory-engine/engine.d.ts +32 -22
- package/dist/core/memory-engine/engine.js +103 -55
- package/dist/core/memory-engine/file-backend.d.ts +13 -30
- package/dist/core/memory-engine/file-backend.js +37 -252
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +139 -9
- package/dist/core/memory-engine/layout.js +350 -7
- package/dist/core/memory-engine/scope-contract.d.ts +10 -0
- package/dist/core/memory-engine/scope-contract.js +8 -0
- package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
- package/dist/core/memory-engine/session-incarnation.js +5 -2
- package/dist/core/memory-engine/types.d.ts +10 -1
- package/dist/core/memory.js +5 -17
- package/dist/core/model-seat.d.ts +4 -4
- package/dist/core/model-seat.js +1 -1
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +19 -0
- package/dist/core/namespaced-rule-name.d.ts +29 -0
- package/dist/core/namespaced-rule-name.js +52 -0
- package/dist/core/park-selfcheck.d.ts +1 -1
- package/dist/core/park-selfcheck.js +16 -6
- package/dist/core/path-guard-rows.d.ts +99 -0
- package/dist/core/path-guard-rows.js +45 -0
- package/dist/core/path-identity.d.ts +22 -16
- package/dist/core/path-identity.js +10 -10
- package/dist/core/path-rule-binding.d.ts +2 -1
- package/dist/core/path-rule-binding.js +3 -1
- package/dist/core/pause-registry.d.ts +16 -2
- package/dist/core/pause-registry.js +6 -0
- package/dist/core/permission-rule-consent.js +0 -7
- package/dist/core/permission-rule-model.d.ts +68 -24
- package/dist/core/permission-rule-model.js +105 -24
- package/dist/core/permission-rule-store.js +2 -2
- package/dist/core/permission-rules.d.ts +3 -30
- package/dist/core/permission-rules.js +4 -54
- package/dist/core/read-root-candidate.d.ts +1 -3
- package/dist/core/read-root-candidate.js +4 -15
- package/dist/core/real-approval.d.ts +4 -3
- package/dist/core/retired-keys.d.ts +13 -0
- package/dist/core/retired-keys.js +14 -0
- package/dist/core/roles.d.ts +2 -3
- package/dist/core/roles.js +15 -6
- package/dist/core/runner/assemble-result.d.ts +0 -7
- package/dist/core/runner/assemble-result.js +19 -31
- package/dist/core/runner/caller-roster.d.ts +78 -0
- package/dist/core/runner/caller-roster.js +219 -0
- package/dist/core/runner/checkpoint-scope.d.ts +16 -16
- package/dist/core/runner/checkpoint-scope.js +2 -2
- package/dist/core/runner/child-tree.js +2 -2
- package/dist/core/runner/contracts.d.ts +68 -35
- package/dist/core/runner/decide-continuation.d.ts +51 -3
- package/dist/core/runner/decide-continuation.js +76 -21
- package/dist/core/runner/denial-limit-arms.d.ts +17 -5
- package/dist/core/runner/denial-limit-arms.js +11 -9
- package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
- package/dist/core/runner/extra-body-dropped-seat.js +22 -0
- package/dist/core/runner/finish-reason-seat.d.ts +9 -0
- package/dist/core/runner/finish-reason-seat.js +40 -0
- package/dist/core/runner/gate-exit.d.ts +44 -32
- package/dist/core/runner/gate-exit.js +112 -25
- package/dist/core/runner/inherited-ask-grants.js +6 -4
- package/dist/core/runner/mcp-redial.d.ts +3 -3
- package/dist/core/runner/mcp-redial.js +3 -4
- package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
- package/dist/core/runner/permission-rule-lanes.js +5 -4
- package/dist/core/runner/prepare-artifact.d.ts +4 -0
- package/dist/core/runner/prepare-artifact.js +2 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +12 -6
- package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
- package/dist/core/runner/prepare-boundary-parks.js +4 -7
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
- package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
- package/dist/core/runner/prepare-config-doors.d.ts +9 -9
- package/dist/core/runner/prepare-config-doors.js +10 -5
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-defer-classify.js +5 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-delegation-surface.js +3 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
- package/dist/core/runner/prepare-gate-stations.js +9 -7
- package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
- package/dist/core/runner/prepare-hands-readface.js +7 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
- package/dist/core/runner/prepare-inherited-gate.js +14 -15
- package/dist/core/runner/prepare-listings.d.ts +7 -24
- package/dist/core/runner/prepare-listings.js +4 -5
- package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
- package/dist/core/runner/prepare-memory-engine-session.js +4 -3
- package/dist/core/runner/prepare-memory.d.ts +6 -0
- package/dist/core/runner/prepare-memory.js +13 -13
- package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
- package/dist/core/runner/prepare-offload-wrappers.js +3 -3
- package/dist/core/runner/prepare-park-ask.d.ts +7 -8
- package/dist/core/runner/prepare-park-ask.js +17 -10
- package/dist/core/runner/prepare-policy-chain.js +24 -44
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +3 -4
- package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
- package/dist/core/runner/prepare-protocol-tools.js +3 -4
- package/dist/core/runner/prepare-run-refs.d.ts +3 -0
- package/dist/core/runner/prepare-run-refs.js +2 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
- package/dist/core/runner/prepare-suspend-saga.js +28 -12
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +67 -56
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
- package/dist/core/runner/prepare-wiring-manifest.js +5 -8
- package/dist/core/runner/resume-apply.js +7 -14
- package/dist/core/runner/resume-checkpoint-screen.js +11 -4
- package/dist/core/runner/resume-internals-and-config.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +5 -32
- package/dist/core/runner/resume-review-outcome.js +4 -1
- package/dist/core/runner/retired-runner-deps.d.ts +6 -0
- package/dist/core/runner/retired-runner-deps.js +10 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -0
- package/dist/core/runner/run-brain-sinks.js +5 -2
- package/dist/core/runner/run-harness-handlers.js +27 -34
- package/dist/core/runner/run-leg.d.ts +0 -2
- package/dist/core/runner/run-leg.js +32 -33
- package/dist/core/runner/run-terminal-adoption.js +4 -3
- package/dist/core/runner/runtask.js +8 -8
- package/dist/core/runner/session-rule-policy.js +5 -5
- package/dist/core/runner/stream-settle-backstop.js +7 -4
- package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
- package/dist/core/runner/sub-agent-deny-lists.js +111 -80
- package/dist/core/runner/terminal-account.d.ts +48 -0
- package/dist/core/runner/terminal-account.js +186 -0
- package/dist/core/runner/tool-end-body.d.ts +54 -17
- package/dist/core/runner/tool-end-body.js +27 -2
- package/dist/core/runner/tool-face-overlay.d.ts +3 -1
- package/dist/core/runner/tool-face-overlay.js +6 -4
- package/dist/core/runner/tool-occurrence.d.ts +106 -0
- package/dist/core/runner/tool-occurrence.js +123 -0
- package/dist/core/runner/tool-progress-lane.d.ts +16 -8
- package/dist/core/runner/tool-progress-lane.js +25 -34
- package/dist/core/runner/turn-attachments.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +21 -9
- package/dist/core/runner/write-protection-station.js +20 -17
- package/dist/core/runner-deps.d.ts +12 -22
- package/dist/core/secret-env.d.ts +16 -5
- package/dist/core/secret-env.js +23 -63
- package/dist/core/sensitive-path-policy.d.ts +19 -18
- package/dist/core/sensitive-path-policy.js +73 -49
- package/dist/core/session-reconcile.d.ts +3 -0
- package/dist/core/session-reconcile.js +5 -4
- package/dist/core/session-store.d.ts +5 -0
- package/dist/core/session-store.js +12 -0
- package/dist/core/session.d.ts +13 -0
- package/dist/core/shared-memory/normalize.d.ts +17 -4
- package/dist/core/shared-memory/normalize.js +7 -7
- package/dist/core/shell-lexer.js +5 -4
- package/dist/core/skill-grant.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +2 -2
- package/dist/core/task-event.d.ts +59 -5
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +42 -9
- package/dist/core/terminal-cause.d.ts +94 -11
- package/dist/core/tighten-task-spec.d.ts +5 -4
- package/dist/core/tighten-task-spec.js +20 -25
- package/dist/core/tool-catalog-entries.d.ts +5 -7
- package/dist/core/tool-catalog-entries.js +14 -15
- package/dist/core/tool-face.d.ts +47 -0
- package/dist/core/tool-face.js +5 -0
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +26 -2
- package/dist/core/tool-name-aliases.js +13 -0
- package/dist/core/tool-name-list.d.ts +30 -0
- package/dist/core/tool-name-list.js +55 -0
- package/dist/core/tool-name-readings.d.ts +1 -9
- package/dist/core/tool-name-readings.js +1 -3
- package/dist/core/tool-policy.d.ts +195 -85
- package/dist/core/tool-policy.js +165 -380
- package/dist/core/tool-registry.d.ts +44 -1
- package/dist/core/tool-registry.js +26 -0
- package/dist/core/tool-roster.d.ts +19 -1
- package/dist/core/tool-roster.js +21 -2
- package/dist/core/tool-spec-members.d.ts +45 -0
- package/dist/core/tool-spec-members.js +169 -0
- package/dist/core/tool-spec.d.ts +46 -8
- package/dist/core/tools.d.ts +6 -2
- package/dist/core/tools.js +8 -4
- package/dist/core/untrusted-egress.js +29 -26
- package/dist/core/untrusted-text.d.ts +13 -10
- package/dist/core/untrusted-text.js +6 -44
- package/dist/core/workflow-journal-store.d.ts +4 -1
- package/dist/core/write-protect.d.ts +65 -29
- package/dist/core/write-protect.js +235 -177
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
- package/dist/engine/execution-env/node-execution-env.js +16 -38
- package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
- package/dist/engine/execution-env/symlink-chain.js +32 -0
- package/dist/engine/harness/types.d.ts +7 -0
- package/dist/engine/llm/tool-turns.d.ts +3 -0
- package/dist/engine/llm/tool-turns.js +1 -0
- package/dist/engine/llm/types.d.ts +59 -23
- package/dist/engine/loop/agent-loop.js +16 -2
- package/dist/engine/session/memory-repo.js +11 -3
- package/dist/engine/session/repo-utils.d.ts +8 -0
- package/dist/engine/session/repo-utils.js +13 -0
- package/dist/index.d.ts +20 -23
- package/dist/index.js +17 -20
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/governance-baseline-validity.js +1 -1
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +16 -35
- package/dist/orchestration/run-workflow-tool.js +38 -78
- package/dist/orchestration/workflow-governance.d.ts +21 -25
- package/dist/orchestration/workflow-governance.js +38 -78
- package/dist/orchestration/workflow-primitives.d.ts +7 -22
- package/dist/orchestration/workflow-primitives.js +5 -12
- package/dist/orchestration/workflow-types.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +61 -11
- package/dist/orchestration/workflow.js +189 -117
- package/dist/scenarios/full-body.d.ts +1 -1
- package/dist/shell/lex.d.ts +0 -21
- package/dist/shell/lex.js +250 -68
- package/dist/shell/shell-words.d.ts +35 -0
- package/dist/shell/shell-words.js +65 -0
- package/dist/stores/file/checkpoint-store.d.ts +5 -5
- package/dist/stores/file/checkpoint-store.js +5 -2
- package/dist/stores/file/index.d.ts +0 -8
- package/dist/stores/file/index.js +0 -12
- package/dist/stores/file/session-store.d.ts +3 -0
- package/dist/stores/file/session-store.js +44 -19
- package/dist/tools/artifact/artifact-tool.js +2 -0
- package/dist/tools/fs/bash-program-position.d.ts +10 -3
- package/dist/tools/fs/bash-program-position.js +21 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/bash-readonly-classifier.js +8 -7
- package/dist/tools/fs/containment-face.d.ts +4 -0
- package/dist/tools/fs/containment-face.js +3 -0
- package/dist/tools/fs/fs-shared.d.ts +10 -0
- package/dist/tools/fs/fs-shared.js +18 -0
- package/dist/tools/fs/fs-write.js +4 -2
- package/dist/tools/fs/index.d.ts +1 -1
- package/dist/tools/fs/program-read-model.d.ts +39 -18
- package/dist/tools/fs/program-read-model.js +29 -19
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +5 -5
- package/dist/tools/fs/read-deny-home.d.ts +33 -47
- package/dist/tools/fs/read-deny-home.js +35 -49
- package/dist/tools/fs/read-deny.d.ts +23 -22
- package/dist/tools/fs/read-deny.js +114 -89
- package/dist/tools/fs/removal-targets.d.ts +56 -23
- package/dist/tools/fs/removal-targets.js +65 -87
- package/dist/tools/fs/safety.d.ts +29 -22
- package/dist/tools/fs/safety.js +17 -11
- package/dist/tools/fs/search.js +10 -8
- package/dist/tools/fs/shell-read-argv.js +1 -1
- package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
- package/dist/tools/fs/shell-read-bindings.js +324 -86
- package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
- package/dist/tools/fs/shell-read-builtins.js +43 -0
- package/dist/tools/fs/shell-read-check.d.ts +15 -1
- package/dist/tools/fs/shell-read-check.js +51 -42
- package/dist/tools/fs/shell-read-establish.js +6 -6
- package/dist/tools/fs/shell-read-functions.d.ts +22 -0
- package/dist/tools/fs/shell-read-functions.js +29 -0
- package/dist/tools/fs/shell-read-judge.d.ts +48 -18
- package/dist/tools/fs/shell-read-judge.js +33 -4
- package/dist/tools/fs/shell-read-plan.d.ts +12 -6
- package/dist/tools/fs/shell-read-plan.js +118 -113
- package/dist/tools/fs/shell-read-start.d.ts +29 -6
- package/dist/tools/fs/shell-read-start.js +16 -9
- package/dist/tools/fs/shell-read-word.js +4 -0
- package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
- package/dist/tools/fs/shell-read-workdir.js +281 -0
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
- package/dist/tools/fs/shell-read-write-targets.js +14 -5
- package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
- package/dist/tools/fs/shell-reentry-text.js +3 -11
- package/dist/tools/task-list.d.ts +1 -2
- package/dist/tools/web.js +1 -1
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +107 -143
- package/wire-changes/core@7.49.0.json +4765 -0
- package/dist/agents/teacher.d.ts +0 -159
- package/dist/agents/teacher.js +0 -577
- package/dist/agents/team.d.ts +0 -226
- package/dist/agents/team.js +0 -257
- package/dist/core/strategy-store.d.ts +0 -238
- package/dist/core/strategy-store.js +0 -253
- package/dist/orchestration/builtin-workflows.d.ts +0 -133
- package/dist/orchestration/builtin-workflows.js +0 -159
- package/dist/scenarios/env.d.ts +0 -40
- package/dist/scenarios/env.js +0 -39
- package/dist/scenarios/scenario-registry.d.ts +0 -110
- package/dist/scenarios/scenario-registry.js +0 -140
- package/dist/scenarios/teacher-quickstart.d.ts +0 -40
- package/dist/scenarios/teacher-quickstart.js +0 -12
- package/dist/stores/cc/lockfile.d.ts +0 -10
- package/dist/stores/cc/lockfile.js +0 -98
- package/dist/stores/cc/mailbox-store.d.ts +0 -20
- package/dist/stores/cc/mailbox-store.js +0 -255
- package/dist/stores/cc/roster-adapter.d.ts +0 -12
- package/dist/stores/cc/roster-adapter.js +0 -117
- package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
- package/dist/stores/cc/sidecar-transcript.js +0 -264
- package/dist/stores/cc/task-list-store.d.ts +0 -2
- package/dist/stores/cc/task-list-store.js +0 -125
- package/dist/stores/file/strategy-store.d.ts +0 -97
- package/dist/stores/file/strategy-store.js +0 -341
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { sessionRecordBindsIncarnation, usableSessionIncarnation } from "./layout.js";
|
|
2
2
|
import { thrownText } from "../thrown-value.js";
|
|
3
|
+
export function sessionIncarnationResolver(sessionId, own, lineage) {
|
|
4
|
+
return ({ sessionId: asked }) => (asked === sessionId ? own : lineage.get(asked));
|
|
5
|
+
}
|
|
3
6
|
export function createSessionIncarnationSeat(input) {
|
|
4
7
|
const { resolve, onIncident } = input;
|
|
5
8
|
let faultAnnounced = false;
|
|
@@ -25,7 +28,7 @@ export function createSessionIncarnationSeat(input) {
|
|
|
25
28
|
catch (err) {
|
|
26
29
|
if (!faultAnnounced) {
|
|
27
30
|
faultAnnounced = true;
|
|
28
|
-
disclose("memory.session_incarnation_unreadable", `the session incarnation
|
|
31
|
+
disclose("memory.session_incarnation_unreadable", `the session incarnation read failed (${thrownText(err)}) — this run cannot tell one occupant of a session id from the next, so every durable session record binds by id alone (the conservative reading, and the behavior of a session store that has no incarnation read)`);
|
|
29
32
|
}
|
|
30
33
|
return undefined;
|
|
31
34
|
}
|
|
@@ -40,7 +43,7 @@ export function createSessionIncarnationSeat(input) {
|
|
|
40
43
|
if (separationAnnounced.has(sessionId))
|
|
41
44
|
return;
|
|
42
45
|
separationAnnounced.add(sessionId);
|
|
43
|
-
disclose("memory.session_incarnation_mismatch", `a durable record stands for session ${sessionId} but it was minted by a DIFFERENT occupant of that id (recorded incarnation ${JSON.stringify(recorded)}, this run ${JSON.stringify(incarnation)}) — it does not bind this run and the record is kept where it is. Either the id was recycled after its previous session was deleted, or the
|
|
46
|
+
disclose("memory.session_incarnation_mismatch", `a durable record stands for session ${sessionId} but it was minted by a DIFFERENT occupant of that id (recorded incarnation ${JSON.stringify(recorded)}, this run ${JSON.stringify(incarnation)}) — it does not bind this run and the record is kept where it is. Either the id was recycled after its previous session was deleted, or the session row's incarnation is not stable for the life of one session`);
|
|
44
47
|
},
|
|
45
48
|
};
|
|
46
49
|
},
|
|
@@ -372,8 +372,17 @@ export interface MemoryBackend {
|
|
|
372
372
|
* crash-idempotent retry reads the optional committed-snapshot face (post-update rev + bound
|
|
373
373
|
* projection) — all asserted by the suite's two hold-protocol cases;
|
|
374
374
|
* - conflicts are per-patch and non-fatal: the rest of the batch still applies.
|
|
375
|
+
*
|
|
376
|
+
* `opts.anchoredRoot` is the physical store root the calling session is mounted on (its handle's
|
|
377
|
+
* `memoryDir`; absent for a caller with no session). A backend that anchors its own root reads that
|
|
378
|
+
* anchor inside the transaction's lock, at every act of the batch up to its commit marker, and refuses
|
|
379
|
+
* the whole batch with `memory.target_outside_store` when the anchor is another root (`detail.recorded`
|
|
380
|
+
* = the anchor, `detail.now` = `anchoredRoot`): a session mounted before a re-anchor commits nothing
|
|
381
|
+
* into the re-anchored store. A backend without a directory ignores it.
|
|
375
382
|
*/
|
|
376
|
-
applyPatches(patches: readonly NotePatch[]
|
|
383
|
+
applyPatches(patches: readonly NotePatch[], opts?: {
|
|
384
|
+
readonly anchoredRoot?: string;
|
|
385
|
+
}): Promise<PatchReport>;
|
|
377
386
|
/** design/84 Seam B cursor pair, migrated verbatim onto the entry-id plane (S2 rewires consolidation). */
|
|
378
387
|
getConsolidationCursor(scope: string): Promise<string | undefined>;
|
|
379
388
|
setConsolidationCursor(scope: string, cursor: string): Promise<void>;
|
package/dist/core/memory.js
CHANGED
|
@@ -4,6 +4,7 @@ import { termSet } from "./memory-vector.js";
|
|
|
4
4
|
import { attrEscape } from "./task-notification.js";
|
|
5
5
|
import { sanitizeUntrustedText, ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./untrusted-text.js";
|
|
6
6
|
import { thrownText } from "./thrown-value.js";
|
|
7
|
+
import { CREDENTIAL_VOCABULARY, refuseWriteView } from "./credential-vocabulary.js";
|
|
7
8
|
export function supportsConsolidation(store) {
|
|
8
9
|
return (typeof store.searchScored === "function" &&
|
|
9
10
|
typeof store.update === "function" &&
|
|
@@ -38,26 +39,13 @@ export class MemoryProjectionError extends Error {
|
|
|
38
39
|
function hasPromotableMarker(note) {
|
|
39
40
|
return note.outcomeStats !== undefined;
|
|
40
41
|
}
|
|
41
|
-
const
|
|
42
|
-
{ label: "aws_access_key_id", re: /\bAKIA[0-9A-Z]{16}\b/ },
|
|
43
|
-
{ label: "github_token", re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/ },
|
|
44
|
-
{ label: "github_fine_grained_pat", re: /\bgithub_pat_[A-Za-z0-9_]{60,}\b/ },
|
|
45
|
-
{ label: "openai_api_key", re: /\bsk-(?:ant-(?:api03-)?|proj-)?[A-Za-z0-9_]{20,}\b/ },
|
|
46
|
-
{ label: "stripe_secret_key", re: /\b[sr]k_(?:live|test)_[A-Za-z0-9]{24,}\b/ },
|
|
47
|
-
{ label: "slack_token", re: /\bxox[baprs]-(?:[A-Za-z0-9]+-){1,3}[A-Za-z0-9]{16,}\b/ },
|
|
48
|
-
{ label: "google_api_key", re: /\bAIza[0-9A-Za-z_-]{35}\b/ },
|
|
49
|
-
{ label: "huggingface_token", re: /\bhf_(?=[A-Za-z0-9]*[0-9])[A-Za-z0-9]{20,}\b/ },
|
|
50
|
-
{ label: "private_key", re: /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/ },
|
|
51
|
-
{ label: "jwt", re: /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{16,}\b/ },
|
|
52
|
-
{ label: "azure_storage_account_key", re: /AccountKey=[A-Za-z0-9+/]{40,}={0,2}/ },
|
|
53
|
-
{ label: "bearer_token", re: /\bAuthorization:\s*Bearer\s+(?=[A-Za-z0-9._~+/-]*[0-9])[A-Za-z0-9._~+/-]{20,}=*/ },
|
|
54
|
-
];
|
|
42
|
+
const REFUSE_WRITE_FORMS = refuseWriteView(CREDENTIAL_VOCABULARY);
|
|
55
43
|
export function detectSecret(text) {
|
|
56
44
|
if (!text)
|
|
57
45
|
return null;
|
|
58
|
-
for (const
|
|
59
|
-
if (
|
|
60
|
-
return
|
|
46
|
+
for (const form of REFUSE_WRITE_FORMS) {
|
|
47
|
+
if (form.re.test(text))
|
|
48
|
+
return form.label;
|
|
61
49
|
}
|
|
62
50
|
return null;
|
|
63
51
|
}
|
|
@@ -11,7 +11,8 @@ export type ModelRef = string | Model;
|
|
|
11
11
|
/**
|
|
12
12
|
* Logical model roles, so a deployment declares its models once and every subsystem asks for its
|
|
13
13
|
* role instead of repeating a model name. Resolved against `RunnerDeps.roles` / `TaskSpec.roles`
|
|
14
|
-
* with a fallback chain (e.g. `summarize → default`, `
|
|
14
|
+
* with a fallback chain (e.g. `summarize → default`, `classifier → summarize → default`). A key or a
|
|
15
|
+
* `modelRole` value outside this vocabulary is refused by name (`config.unknown_role`), never ignored.
|
|
15
16
|
* - `default` — the main task model when `TaskSpec.model` is omitted.
|
|
16
17
|
* - `summarize` — between-turn compaction/summarization. Absent = the MAIN task model, which is the
|
|
17
18
|
* correct default baseline: the summary request FORKS the main conversation's already-paid
|
|
@@ -21,8 +22,7 @@ export type ModelRef = string | Model;
|
|
|
21
22
|
* tradeoff (quality for price): an independent model cannot share the main prefix, so it pays the
|
|
22
23
|
* full independent-request serialization every boundary AND summarizes with a weaker model.
|
|
23
24
|
* - `subagent` — delegated sub-runs (`createSubagentTool` without an explicit model).
|
|
24
|
-
* - `
|
|
25
|
-
* - `advisor` — the strong "teacher" a cheap student escalates to (`runWithTeacher`).
|
|
25
|
+
* - `verifier` — the verification gate's verifier leg (falls back to `default`).
|
|
26
26
|
* - `classifier` — the auto-mode permission classifier (a roster-cheap tier; falls back
|
|
27
27
|
* `summarize → default`, tier default `flash` on tier-expanded catalogs).
|
|
28
28
|
* - `consolidate` — the memory-consolidation distillation driver (design/376). Falls back to
|
|
@@ -36,7 +36,7 @@ export type ModelRef = string | Model;
|
|
|
36
36
|
* this role wants (note the summarize DEFAULT rationale — prompt-cache forking — does not
|
|
37
37
|
* apply here: consolidation is an offline independent request with no shared prefix).
|
|
38
38
|
*/
|
|
39
|
-
export declare const MODEL_ROLES: readonly ["default", "summarize", "subagent", "
|
|
39
|
+
export declare const MODEL_ROLES: readonly ["default", "summarize", "subagent", "verifier", "classifier", "consolidate"];
|
|
40
40
|
/** The role vocabulary, derived from {@link MODEL_ROLES} — one source; a consumer that needs the members at
|
|
41
41
|
* runtime (a settings schema, a parity pin, a doctor line) reads the tuple instead of transcribing it. */
|
|
42
42
|
export type ModelRole = (typeof MODEL_ROLES)[number];
|
package/dist/core/model-seat.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const MODEL_ROLES = Object.freeze(["default", "summarize", "subagent", "
|
|
1
|
+
export const MODEL_ROLES = Object.freeze(["default", "summarize", "subagent", "verifier", "classifier", "consolidate"]);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MCP surface a run mounts, as a delegation tool reads it at spawn: per declared server, the tools of it that are mounted
|
|
3
|
+
* right now (the wire name and the name the server itself knows the tool by), and the names of the aggregate tools no server
|
|
4
|
+
* owns (the cross-server resource readers). Read off the run's LIVE roster, so a refresh that added or removed a server's
|
|
5
|
+
* tools is what a child spawned after it inherits.
|
|
6
|
+
*
|
|
7
|
+
* The run fills it on `ToolExecuteContext.mountedMcp`; the delegation tool puts the same universe through the child's lists
|
|
8
|
+
* and declares the child the servers they leave.
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServerSpec } from "./mcp-server-spec.js";
|
|
11
|
+
import type { ToolContentOrigin } from "./tool-spec.js";
|
|
12
|
+
import type { McpConnectionPool } from "./mcp-connection-pool.js";
|
|
13
|
+
/** The two names a server's `allowTools` carries to let the cross-server resource readers reach its resources (a server whose allowlist omits one is left out of that reader). */
|
|
14
|
+
export declare const MCP_RESOURCE_LIST_ALLOW = "list_resources";
|
|
15
|
+
export declare const MCP_RESOURCE_READ_ALLOW = "read_resource";
|
|
16
|
+
/** One declared MCP server and its mounted tools. */
|
|
17
|
+
export interface MountedMcpServer {
|
|
18
|
+
readonly server: McpServerSpec;
|
|
19
|
+
readonly tools: ReadonlyArray<{
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly remoteName: string;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
/** What a run mounts of MCP: its servers, and the aggregate tool names that belong to none of them. */
|
|
25
|
+
export interface MountedMcp {
|
|
26
|
+
readonly servers: ReadonlyArray<MountedMcpServer>;
|
|
27
|
+
readonly aggregate: ReadonlyArray<string>;
|
|
28
|
+
/** The run tree's connection pool: a child that inherits the mount leases its connections from it. */
|
|
29
|
+
readonly pool?: McpConnectionPool;
|
|
30
|
+
}
|
|
31
|
+
/** A roster entry as far as this reading goes. */
|
|
32
|
+
interface RosterEntry {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly mcpRemoteName?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read the run's MCP surface off its roster. `declared` is the run's frozen server declarations; `aggregateNames` the names of the
|
|
38
|
+
* tools its materialization minted that no server owns. A tool is a server's when its wire name sits under the server's prefix
|
|
39
|
+
* domain and carries the remote name the mint recorded on it; a tool of a server that failed to connect is simply not mounted,
|
|
40
|
+
* so that server has no tools here and a child is not declared it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function mountedMcpOf(input: {
|
|
43
|
+
readonly declared: ReadonlyArray<McpServerSpec> | undefined;
|
|
44
|
+
readonly roster: ReadonlyArray<RosterEntry>;
|
|
45
|
+
readonly aggregateNames: ReadonlySet<string>;
|
|
46
|
+
readonly pool?: McpConnectionPool;
|
|
47
|
+
}): MountedMcp;
|
|
48
|
+
/**
|
|
49
|
+
* The MCP tools of a mount as pool rows (name and the server's declared content class) — what the memory content-origin face adds to
|
|
50
|
+
* a delegation tool's pool when its children inherit the mount. The rows are the universe the spawn's lists are read over, so
|
|
51
|
+
* "can the child reach an MCP tool" has one answer.
|
|
52
|
+
*/
|
|
53
|
+
export declare function mountedMcpPoolRows(mounted: MountedMcp): Array<{
|
|
54
|
+
name: string;
|
|
55
|
+
contentOrigin?: ToolContentOrigin;
|
|
56
|
+
}>;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { mintNamespacePrefix } from "./protocol-naming.js";
|
|
2
|
+
import { MCP_NAMESPACE } from "./protocol-table.js";
|
|
3
|
+
export const MCP_RESOURCE_LIST_ALLOW = "list_resources";
|
|
4
|
+
export const MCP_RESOURCE_READ_ALLOW = "read_resource";
|
|
5
|
+
export function mountedMcpOf(input) {
|
|
6
|
+
const servers = (input.declared ?? []).map((server) => {
|
|
7
|
+
const prefix = mintNamespacePrefix(MCP_NAMESPACE, server.name);
|
|
8
|
+
const tools = input.roster.flatMap((t) => (t.name.startsWith(prefix) && typeof t.mcpRemoteName === "string" ? [{ name: t.name, remoteName: t.mcpRemoteName }] : []));
|
|
9
|
+
return { server, tools };
|
|
10
|
+
});
|
|
11
|
+
const aggregate = input.roster.filter((t) => input.aggregateNames.has(t.name)).map((t) => t.name);
|
|
12
|
+
return { servers, aggregate, ...(input.pool !== undefined ? { pool: input.pool } : {}) };
|
|
13
|
+
}
|
|
14
|
+
export function mountedMcpPoolRows(mounted) {
|
|
15
|
+
return [
|
|
16
|
+
...mounted.servers.flatMap((m) => m.tools.map((t) => ({ name: t.name, ...(m.server.contentOrigin !== undefined ? { contentOrigin: m.server.contentOrigin } : {}) }))),
|
|
17
|
+
...mounted.aggregate.map((name) => ({ name })),
|
|
18
|
+
];
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear-time `*` glob match (design/127 M6: NOT a RegExp — patterns may come from tenant-supplied
|
|
3
|
+
* Settings layers; the classic two-pointer walk has zero ReDoS surface and the same semantics as CC's
|
|
4
|
+
* anchored `^…$`+dotAll construction: every non-`*` char is literal, `*` spans anything incl. newlines).
|
|
5
|
+
*/
|
|
6
|
+
export declare function wildcardMatch(pattern: string, value: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Does a namespaced RULE name cover `toolName`? — the tail branch of CC's rule matcher `VRp`
|
|
9
|
+
* (:595780), which is UNCONDITIONAL there (its `globMatching` option gates only the whole-name glob
|
|
10
|
+
* branch, so CC's allow lane — `mVo` :595803, which passes no options — matches MCP segments too).
|
|
11
|
+
* Three covering forms, matching CC's three disjuncts (`<ns>` = any protocol-table prefix):
|
|
12
|
+
* · `<ns>__<peer>` — every tool of that peer (rule tool segment absent);
|
|
13
|
+
* · `<ns>__<peer>__*` — the same set, spelled with the star CC's own settings validator
|
|
14
|
+
* recommends (`"MCP rules do not support patterns in parentheses …
|
|
15
|
+
* use mcp__srv__*"`);
|
|
16
|
+
* · `<ns>__<peer>__get_*` — a glob over the tool segment.
|
|
17
|
+
* A LITERAL tool segment is deliberately NOT covered here: it is an exact tool name, and the exact
|
|
18
|
+
* table already answers it — the same split CC makes with its leading `ruleName === toolName`.
|
|
19
|
+
*
|
|
20
|
+
* Rule and target must be in the SAME namespace, and peer segments compare EXACTLY (CC
|
|
21
|
+
* `s.serverName === a.serverName`). A rule must therefore spell the peer the way the mint does; that
|
|
22
|
+
* is the same string an operator reads off any mounted tool name, and inventing a fuzzier comparison
|
|
23
|
+
* here would let one rule reach a peer — or a protocol — it does not name.
|
|
24
|
+
*/
|
|
25
|
+
export declare function namespacedRuleNameCovers(ruleName: string, toolName: string): boolean;
|
|
26
|
+
/** True ⇔ this rule name is a namespaced name whose reach is a SET of tools rather than one exact tool
|
|
27
|
+
* — i.e. the shapes {@link namespacedRuleNameCovers} answers and an exact name table cannot. Every
|
|
28
|
+
* lane that keys rules by exact tool name needs this to know which entries it must NOT key that way. */
|
|
29
|
+
export declare function isNamespacedCoveringRuleName(name: string): boolean;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { splitNamespacedName } from "./tool-name-aliases.js";
|
|
2
|
+
export function wildcardMatch(pattern, value) {
|
|
3
|
+
let p = 0;
|
|
4
|
+
let v = 0;
|
|
5
|
+
let star = -1;
|
|
6
|
+
let mark = 0;
|
|
7
|
+
while (v < value.length) {
|
|
8
|
+
if (p < pattern.length && pattern[p] === value[v] && pattern[p] !== "*") {
|
|
9
|
+
p++;
|
|
10
|
+
v++;
|
|
11
|
+
}
|
|
12
|
+
else if (p < pattern.length && pattern[p] === "*") {
|
|
13
|
+
star = p++;
|
|
14
|
+
mark = v;
|
|
15
|
+
}
|
|
16
|
+
else if (star >= 0) {
|
|
17
|
+
p = star + 1;
|
|
18
|
+
v = ++mark;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
while (p < pattern.length && pattern[p] === "*")
|
|
25
|
+
p++;
|
|
26
|
+
return p === pattern.length;
|
|
27
|
+
}
|
|
28
|
+
function parseNamespacedRuleName(name) {
|
|
29
|
+
const split = splitNamespacedName(name);
|
|
30
|
+
if (split === undefined || split.peer === "")
|
|
31
|
+
return undefined;
|
|
32
|
+
return split.tool !== undefined ? { protocol: split.ns.id, peer: split.peer, tool: split.tool } : { protocol: split.ns.id, peer: split.peer };
|
|
33
|
+
}
|
|
34
|
+
export function namespacedRuleNameCovers(ruleName, toolName) {
|
|
35
|
+
const rule = parseNamespacedRuleName(ruleName);
|
|
36
|
+
if (rule === undefined)
|
|
37
|
+
return false;
|
|
38
|
+
const target = parseNamespacedRuleName(toolName);
|
|
39
|
+
if (target === undefined)
|
|
40
|
+
return false;
|
|
41
|
+
if (rule.protocol !== target.protocol)
|
|
42
|
+
return false;
|
|
43
|
+
if (rule.peer !== target.peer)
|
|
44
|
+
return false;
|
|
45
|
+
if (rule.tool === undefined || rule.tool === "*")
|
|
46
|
+
return true;
|
|
47
|
+
return target.tool !== undefined && rule.tool.includes("*") && wildcardMatch(rule.tool, target.tool);
|
|
48
|
+
}
|
|
49
|
+
export function isNamespacedCoveringRuleName(name) {
|
|
50
|
+
const parsed = parseNamespacedRuleName(name);
|
|
51
|
+
return parsed !== undefined && (parsed.tool === undefined || parsed.tool.includes("*"));
|
|
52
|
+
}
|
|
@@ -72,7 +72,7 @@ export type ParkProbeFindingCode =
|
|
|
72
72
|
"put_failed"
|
|
73
73
|
/** `get` threw, or answered `null` for a token the store had just accepted. */
|
|
74
74
|
| "row_not_readable"
|
|
75
|
-
/** The row came back, but a load-bearing field did not survive the round
|
|
75
|
+
/** The row came back, but a load-bearing field did not survive the round-trip (see `detail` for which). */
|
|
76
76
|
| "row_not_faithful"
|
|
77
77
|
/** The row came back with a status other than `pending` — a park nobody can resolve. */
|
|
78
78
|
| "row_not_pending"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { boundInputHashOf, canonicalize } from "./canonical-json.js";
|
|
2
|
-
import {
|
|
2
|
+
import { mintCheckpointId, mintCheckpointToken, resolveCheckpointStore, resolveDeclaredFidelity } from "./checkpoint-store.js";
|
|
3
|
+
import { stampCheckpointRequirements } from "./checkpoint-requirements.js";
|
|
3
4
|
import { resolveDeclaredDurability } from "./wiring-manifest.js";
|
|
4
5
|
export const PARK_SELFCHECK_SCOPE_PREFIX = "sema:park-selfcheck:";
|
|
5
6
|
export const PARK_SELFCHECK_STEP_TIMEOUT_MS = 10_000;
|
|
@@ -56,8 +57,8 @@ export function durableParkGapFor(deps, spec = {}) {
|
|
|
56
57
|
sessionDurable: declaresDurable(deps.sessionStore, "sessionStore"),
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
|
-
function syntheticCheckpoint(scope) {
|
|
60
|
-
return {
|
|
60
|
+
function syntheticCheckpoint(scope, fidelity) {
|
|
61
|
+
return stampCheckpointRequirements({
|
|
61
62
|
token: mintCheckpointToken(),
|
|
62
63
|
checkpointId: mintCheckpointId(),
|
|
63
64
|
scope,
|
|
@@ -85,7 +86,6 @@ function syntheticCheckpoint(scope) {
|
|
|
85
86
|
state: { activeTools: ["SelfCheck"], nestedStats: { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0, anyUnpriced: false } },
|
|
86
87
|
status: "pending",
|
|
87
88
|
createdAt: Date.now(),
|
|
88
|
-
version: MAX_SUPPORTED_CHECKPOINT_VERSION,
|
|
89
89
|
suspendCount: 1,
|
|
90
90
|
suspendedAt: Date.now(),
|
|
91
91
|
resourceLedger: { spentMicroUsd: 0, spentTokens: 0, spentTurns: 0, sliceCount: 1 },
|
|
@@ -94,7 +94,7 @@ function syntheticCheckpoint(scope) {
|
|
|
94
94
|
principal: `${scope}:principal`,
|
|
95
95
|
durableApproval: { scope, ttlMs: PARK_SELFCHECK_ROW_TTL_MS },
|
|
96
96
|
deadline: Date.now() + PARK_SELFCHECK_ROW_TTL_MS,
|
|
97
|
-
};
|
|
97
|
+
}, fidelity);
|
|
98
98
|
}
|
|
99
99
|
function faithfulnessDelta(sent, got) {
|
|
100
100
|
const project = (cp) => ({
|
|
@@ -109,6 +109,8 @@ function faithfulnessDelta(sent, got) {
|
|
|
109
109
|
deadline: cp.deadline,
|
|
110
110
|
createdAt: cp.createdAt,
|
|
111
111
|
version: cp.version,
|
|
112
|
+
requires: cp.requires,
|
|
113
|
+
requirementsDigest: cp.requirementsDigest,
|
|
112
114
|
suspendCount: cp.suspendCount,
|
|
113
115
|
suspendedAt: cp.suspendedAt,
|
|
114
116
|
resourceLedger: cp.resourceLedger,
|
|
@@ -134,7 +136,15 @@ export async function probeParkRoundTrip(deps, spec = {}) {
|
|
|
134
136
|
};
|
|
135
137
|
}
|
|
136
138
|
const scope = `${PARK_SELFCHECK_SCOPE_PREFIX}${mintCheckpointToken()}`;
|
|
137
|
-
|
|
139
|
+
let fidelity;
|
|
140
|
+
try {
|
|
141
|
+
fidelity = resolveDeclaredFidelity(store, "checkpointStore");
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
const detail = "the checkpoint backend declares an unrecognized encoding fidelity — a park refuses rather than guess which values survive it";
|
|
145
|
+
return { verdict: "failed", findings: [{ code: "put_failed", detail }], scope, summary: `the park lane failed its round-trip self-check at "put_failed": ${detail}`, ...gapCell };
|
|
146
|
+
}
|
|
147
|
+
const cp = syntheticCheckpoint(scope, fidelity);
|
|
138
148
|
const said = (err) => {
|
|
139
149
|
try {
|
|
140
150
|
const m = err instanceof Error ? err.message : undefined;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { DenyFace, PathRowReach } from "../tools/fs/read-deny.js";
|
|
2
|
+
/** Which reading of a target one view is: the placed spelling, the environment's canonical answer, a hop of the leaf's
|
|
3
|
+
* symlink chain, or the home's own spelling of a canonical key (read-deny-home.ts). */
|
|
4
|
+
export type GuardViewKind = "lexical" | "canonical" | "hop" | "home";
|
|
5
|
+
/** ONE view of a target as the judgment reads it. */
|
|
6
|
+
export interface GuardView {
|
|
7
|
+
/** The view's spelling — absolute, or (for an operand a station could not place) as spelled. */
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly kind: GuardViewKind;
|
|
10
|
+
/** The canonical key's minter reports the real filesystem already collapsed any win32 component alias in it. */
|
|
11
|
+
readonly aliasResolved?: true;
|
|
12
|
+
/** The view's remainder below an exempt root (`""` = the root itself), computed by the reading's owner. */
|
|
13
|
+
readonly exemptRemainder?: string;
|
|
14
|
+
}
|
|
15
|
+
/** A target as a judgment reads it: its present views, and `unreadable` — the call names a target this reading cannot
|
|
16
|
+
* locate, or where the target really lands (its canonical view, its link chain) could not be determined (the reason).
|
|
17
|
+
* `identityExempt`: the reading's OWN canonical key lies inside an exempt root. */
|
|
18
|
+
export interface TargetViews {
|
|
19
|
+
readonly views: readonly GuardView[];
|
|
20
|
+
readonly unreadable?: string;
|
|
21
|
+
readonly identityExempt?: true;
|
|
22
|
+
}
|
|
23
|
+
/** The views' spellings, in order, without repeats — what a reader that only needs the strings reads. */
|
|
24
|
+
export declare function viewSpellings(views: TargetViews): readonly string[];
|
|
25
|
+
/** Views from bare spellings (each read as the kind given, the first as `lexical` when no kind is given). */
|
|
26
|
+
export declare function spelledViews(spellings: readonly string[], kind?: GuardViewKind): TargetViews;
|
|
27
|
+
/** The language a row is written in — a column, not a judgment: every grammar is judged by {@link judgePathRows}. */
|
|
28
|
+
export type PathGuardGrammar =
|
|
29
|
+
/** A literal name (the write-protection table): the target's last segment, any segment, or a consecutive run. */
|
|
30
|
+
{
|
|
31
|
+
readonly kind: "literal-name";
|
|
32
|
+
readonly match: "basename" | "segment" | "segment-run";
|
|
33
|
+
readonly name: string;
|
|
34
|
+
}
|
|
35
|
+
/** A `/`-separated segment glob (`*` the one metacharacter) matched as a contiguous run (the sensitive list, the read
|
|
36
|
+
* deny set's segment rows). */
|
|
37
|
+
| {
|
|
38
|
+
readonly kind: "segment-glob";
|
|
39
|
+
readonly run: string;
|
|
40
|
+
}
|
|
41
|
+
/** A permission rule's path pattern, judged by its own reach (the rule DSL's rows and their twins). */
|
|
42
|
+
| {
|
|
43
|
+
readonly kind: "rule";
|
|
44
|
+
readonly rule: string;
|
|
45
|
+
}
|
|
46
|
+
/** The directories a write may land in, from one SOURCE (the write domains — an ALLOW row): the run's advertised writable
|
|
47
|
+
* roots (frozen canonical keys), the deployment's configured structural domains, the person's session-won grants, a
|
|
48
|
+
* session rule's `allowDirs` confinement. */
|
|
49
|
+
| {
|
|
50
|
+
readonly kind: "domain";
|
|
51
|
+
readonly dirs: readonly string[];
|
|
52
|
+
readonly source: "advertised" | "configured" | "accepted" | "session";
|
|
53
|
+
};
|
|
54
|
+
/** Where a row is placed: anywhere its grammar matches; at a home; at the filesystem root; below a declared root. A placed
|
|
55
|
+
* row is judged in a ROOTED view only, except that a home row in a view that cannot be placed holds wider. */
|
|
56
|
+
export type PathGuardPlacement = "anywhere" | "home" | "rooted" | {
|
|
57
|
+
readonly below: string;
|
|
58
|
+
};
|
|
59
|
+
/** How a row folds case: `protective` (the built-in tables: case, the two confusable letters, the invisible format
|
|
60
|
+
* characters, across every platform reading), `ascii` (the read deny set's contract), `host` (case-insensitive exactly
|
|
61
|
+
* where the host's filesystem is), `exact`. A fold only ever WIDENS what a tightening row matches; no exemption folds. */
|
|
62
|
+
export type PathGuardFold = "protective" | "ascii" | "host" | "exact";
|
|
63
|
+
/** The minimum a row offers the judgment: its reach over one view, and whether the data-root exemption applies to it. */
|
|
64
|
+
export interface GuardRowReach {
|
|
65
|
+
readonly reach: (view: GuardView) => PathRowReach;
|
|
66
|
+
readonly exemptible?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/** ONE guarded path. */
|
|
69
|
+
export interface PathGuardRow extends GuardRowReach {
|
|
70
|
+
/** The row's name wherever a refusal, a card or the classifier cites it (the table name, the glob, the rule text). */
|
|
71
|
+
readonly name: string;
|
|
72
|
+
readonly grammar: PathGuardGrammar;
|
|
73
|
+
readonly polarity: "deny" | "ask" | "allow";
|
|
74
|
+
readonly faces: readonly DenyFace[];
|
|
75
|
+
readonly placement: PathGuardPlacement;
|
|
76
|
+
readonly fold: PathGuardFold;
|
|
77
|
+
readonly exemptible: boolean;
|
|
78
|
+
/** The built-in tier that activates the row (absent on a row no tier selects). */
|
|
79
|
+
readonly tier?: string;
|
|
80
|
+
/** Where the row came from: a built-in default, a deployment REPLACEMENT of a default table, an ADDITION to one, a rule. */
|
|
81
|
+
readonly origin: "builtin" | "replacement" | "addition" | "rule";
|
|
82
|
+
}
|
|
83
|
+
/** What {@link judgePathRows} found: the row, the view it met there (its spelling and kind; absent on an unreadable hold),
|
|
84
|
+
* and — when nothing was reached and some row could not be judged — the reason of the first such row. */
|
|
85
|
+
export interface PathRowsHit<R> {
|
|
86
|
+
readonly row: R;
|
|
87
|
+
readonly view?: string;
|
|
88
|
+
readonly viewKind?: GuardViewKind;
|
|
89
|
+
readonly unreadable?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* THE one judgment of guarded rows over a target's views, for every table and every lane: rows outer, views inner — the
|
|
93
|
+
* first row (in the caller's order) that some view reaches is the answer. `tighten` (deny / ask): any present view reaching
|
|
94
|
+
* the row reaches it; a row that cannot be judged (or a target that cannot be read) is held and answered only when no row
|
|
95
|
+
* reaches. `allow`: a row admits the target only when it admits EVERY view (a link out of an allowed directory is not
|
|
96
|
+
* admitted through its spelling); an unreadable target is admitted by nothing. An exemptible row reads each view through
|
|
97
|
+
* the exemption law (the module header).
|
|
98
|
+
*/
|
|
99
|
+
export declare function judgePathRows<R extends GuardRowReach>(rows: readonly R[], views: TargetViews, direction: "tighten" | "allow"): PathRowsHit<R> | undefined;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function viewSpellings(views) {
|
|
2
|
+
const out = [];
|
|
3
|
+
for (const v of views.views)
|
|
4
|
+
if (!out.includes(v.path))
|
|
5
|
+
out.push(v.path);
|
|
6
|
+
return out;
|
|
7
|
+
}
|
|
8
|
+
export function spelledViews(spellings, kind) {
|
|
9
|
+
return { views: spellings.map((path, i) => ({ path, kind: kind ?? (i === 0 ? "lexical" : "canonical") })) };
|
|
10
|
+
}
|
|
11
|
+
export function judgePathRows(rows, views, direction) {
|
|
12
|
+
if (direction === "allow") {
|
|
13
|
+
if (views.unreadable !== undefined || views.views.length === 0)
|
|
14
|
+
return undefined;
|
|
15
|
+
for (const row of rows)
|
|
16
|
+
if (views.views.every((v) => row.reach(v).reach === "reached"))
|
|
17
|
+
return { row };
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
let held;
|
|
21
|
+
for (const row of rows) {
|
|
22
|
+
if (views.unreadable !== undefined)
|
|
23
|
+
held ??= { row, unreadable: views.unreadable };
|
|
24
|
+
for (const view of views.views) {
|
|
25
|
+
const judged = row.exemptible === true ? exemptReading(view, views) : view;
|
|
26
|
+
if (judged === undefined)
|
|
27
|
+
continue;
|
|
28
|
+
const r = row.reach(judged);
|
|
29
|
+
if (r.reach === "reached")
|
|
30
|
+
return { row, view: view.path, viewKind: view.kind };
|
|
31
|
+
if (r.reach === "unreadable")
|
|
32
|
+
held ??= { row, unreadable: r.reason };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return held;
|
|
36
|
+
}
|
|
37
|
+
function exemptReading(view, views) {
|
|
38
|
+
if (views.identityExempt === true && view.kind !== "canonical")
|
|
39
|
+
return undefined;
|
|
40
|
+
if (view.exemptRemainder === undefined)
|
|
41
|
+
return view;
|
|
42
|
+
if (view.exemptRemainder === "")
|
|
43
|
+
return undefined;
|
|
44
|
+
return { path: view.exemptRemainder, kind: view.kind, ...(view.aliasResolved === true ? { aliasResolved: true } : {}) };
|
|
45
|
+
}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import type { ExecutionEnv } from "../internal/harness-types.js";
|
|
2
2
|
import { type PathFamily } from "../tools/fs/safety.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* empty chain, and the environment answering `ok: false`. An unanswerable chain is never a refusal: this
|
|
9
|
-
* reader's callers are path guards whose own absence law says a view that cannot answer does not vote, and a
|
|
10
|
-
* second refusal law over one target would be a second rule. The spelling is anchored as the canonicalizer
|
|
11
|
-
* anchors it (`baseCwd`). A refused namespace spelling and a win-form UNC spelling are not walked (the reference
|
|
12
|
-
* CLI's variant set stops at a network spelling); the share is recognized by the throat's own `isUncSpelling`.
|
|
13
|
-
*
|
|
14
|
-
* `onUnanswerable` separates ONE of those four from the rest for a caller that DISCLOSES its absent views: the
|
|
15
|
-
* environment was ASKED and could not answer (`ok: false`), which is a fact about that environment. The other
|
|
16
|
-
* three are not failures — nothing was asked, or the answer was genuinely "no hops" — so they stay silent. The
|
|
17
|
-
* verdict is `[]` either way; this sink changes nothing about what is judged, only what is said out loud. A
|
|
18
|
-
* throwing sink is the caller's bug and is not caught here.
|
|
4
|
+
* What the reader learned of a leaf symlink chain: the hops (`ok` — `[]` only when the environment was asked and
|
|
5
|
+
* answered that there are none), or that no hop could be read (`ok: false`). `asked` separates a fact about the
|
|
6
|
+
* environment (it was asked and could not answer) from a chain nobody asked about (no `canonicalChain` declared, or a
|
|
7
|
+
* spelling it does not walk).
|
|
19
8
|
*/
|
|
20
|
-
export
|
|
9
|
+
export type ChainHopsReading = {
|
|
10
|
+
readonly ok: true;
|
|
11
|
+
readonly hops: readonly string[];
|
|
12
|
+
} | {
|
|
13
|
+
readonly ok: false;
|
|
14
|
+
readonly cause: string;
|
|
15
|
+
readonly asked: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The leaf symlink chain of `path` — the ONE place where a chain read becomes "read" or "not read". The spelling is
|
|
19
|
+
* anchored as the canonicalizer anchors it (`baseCwd`). A refused namespace spelling and a win-form UNC spelling are
|
|
20
|
+
* not walked (the reference CLI's variant set stops at a network spelling); the share is recognized by the throat's
|
|
21
|
+
* own `isUncSpelling`. Each caller holds its own posture on `ok: false`: a path guard (deny side) lets a view that
|
|
22
|
+
* cannot answer not vote ({@link chainHopsOrNone}), an allow admits nothing it could not see.
|
|
23
|
+
*/
|
|
24
|
+
export declare function symlinkChainHops(env: ExecutionEnv, path: string, signal: AbortSignal | undefined, family: PathFamily, baseCwd?: string): Promise<ChainHopsReading>;
|
|
25
|
+
/** A path guard's reading of a chain: the hops, or none — a view that cannot answer does not vote (its absence law). */
|
|
26
|
+
export declare function chainHopsOrNone(reading: ChainHopsReading): readonly string[];
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export async function symlinkChainHops(env, path, signal, family, baseCwd
|
|
1
|
+
import { anchorSpelling, isUncSpelling, win32NamespaceScreen } from "../tools/fs/safety.js";
|
|
2
|
+
export async function symlinkChainHops(env, path, signal, family, baseCwd) {
|
|
3
3
|
if (typeof env.canonicalChain !== "function")
|
|
4
|
-
return
|
|
4
|
+
return { ok: false, cause: "the environment declares no symlink-chain reader", asked: false };
|
|
5
5
|
const screened = win32NamespaceScreen(path, family);
|
|
6
6
|
if (!screened.ok)
|
|
7
|
-
return
|
|
7
|
+
return { ok: false, cause: "a namespace spelling the chain reader does not walk", asked: false };
|
|
8
8
|
const spelled = screened.spelled;
|
|
9
9
|
if (family === "win" && isUncSpelling(spelled))
|
|
10
|
-
return
|
|
11
|
-
const target = baseCwd !== undefined && baseCwd.length > 0
|
|
10
|
+
return { ok: false, cause: "a network share spelling the chain reader does not walk", asked: false };
|
|
11
|
+
const target = baseCwd !== undefined && baseCwd.length > 0 ? anchorSpelling(family, baseCwd, spelled) : spelled;
|
|
12
12
|
const chain = await env.canonicalChain(target, signal);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return [];
|
|
13
|
+
return chain.ok ? { ok: true, hops: chain.value.hops } : { ok: false, cause: chain.error.message, asked: true };
|
|
14
|
+
}
|
|
15
|
+
export function chainHopsOrNone(reading) {
|
|
16
|
+
return reading.ok ? reading.hops : [];
|
|
17
17
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type PathRuleBase, type PathRuleBases, type PersistedRule, type RuleBehavior, type RuleScope, type ScopeRootIdentity } from "./permission-rule-model.js";
|
|
2
2
|
import { type DenyFace, type JudgedPathRow, type PathRowReach } from "../tools/fs/read-deny.js";
|
|
3
3
|
import { type ToolPolicy } from "./tool-policy.js";
|
|
4
|
-
export {
|
|
4
|
+
export { judgeRuleRows, rowsWhereTheyLead } from "../tools/fs/read-deny.js";
|
|
5
|
+
export type { PathRowsHit, TargetViews } from "./path-guard-rows.js";
|
|
5
6
|
/** One path rule as a binding reads it: the parsed rule, its text, and — for a deny rule that guards a face of the
|
|
6
7
|
* engine's deny tables — those faces (absent: the rule is judged on its own tool's calls only). */
|
|
7
8
|
export interface PathRuleSpec {
|
|
@@ -4,7 +4,8 @@ import { pathFamilyOf, spellingOfIdentity } from "../tools/fs/safety.js";
|
|
|
4
4
|
import { absoluteTargetIdentityOf } from "./effective-path-target.js";
|
|
5
5
|
import { locationLeadsTo, ruleHeadParts } from "../tools/fs/read-deny.js";
|
|
6
6
|
import { carriedMembersOf } from "./tool-policy.js";
|
|
7
|
-
|
|
7
|
+
import { assertNoRetiredToolPolicyKeys } from "./retired-keys.js";
|
|
8
|
+
export { judgeRuleRows, rowsWhereTheyLead } from "../tools/fs/read-deny.js";
|
|
8
9
|
const NOT_REACHED = { reach: "not_reached" };
|
|
9
10
|
export function bindPathRules(specs, anchors) {
|
|
10
11
|
return specs.map((spec) => {
|
|
@@ -71,6 +72,7 @@ const INSTALLATIONS = new WeakMap();
|
|
|
71
72
|
export function installPolicyAnchors(policy, anchors) {
|
|
72
73
|
if (policy === undefined)
|
|
73
74
|
return undefined;
|
|
75
|
+
assertNoRetiredToolPolicyKeys(policy);
|
|
74
76
|
const from = INSTALLED.get(policy)?.from ?? policy;
|
|
75
77
|
const rules = from.pathRules;
|
|
76
78
|
if (rules === undefined)
|