@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,84 +1,240 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The TIGHTEN-ONLY
|
|
3
|
-
*
|
|
2
|
+
* The TIGHTEN-ONLY SEATS of a TaskSpec — the ONE table that says which seats only tighten, which value of each is the
|
|
3
|
+
* restricting one, how two declarations of a seat compose, and which carrier hands it to an engine-built child. Every
|
|
4
|
+
* reader reads the table: the public merge ({@link import("./tighten-task-spec.js").tightenTaskSpec}), the child-spec
|
|
5
|
+
* carrier ({@link childClampSeats}), the run's trusted ctx seats and the workflow mount (one {@link ChildClampSource}
|
|
6
|
+
* minted per prepare), and a revival's fold of the waker's restrictions ({@link clampValuesOf}). A row added here
|
|
7
|
+
* reaches all of them; a reader that spells a seat by hand is named by `scripts/verify-child-clamp-seats.mjs`.
|
|
4
8
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Two mechanical halves keep it whole:
|
|
10
|
+
* · the COMPILER — {@link ChildClampSource} requires every clamp-carrier row as a PRESENT key, so a site that builds a
|
|
11
|
+
* source by hand cannot drop a row;
|
|
12
|
+
* · the SCAN — the gate reads this table literally, requires each registered constructor to go through the carrier,
|
|
13
|
+
* requires the published carriers (`ToolExecuteContext`, `ParentSpecSeat`) to declare exactly the rows they carry,
|
|
14
|
+
* and names any hand-written restricting projection outside the carriers.
|
|
10
15
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* is fine; a missing key is not), so adding a member to {@link CHILD_CLAMP_SEATS} reds `tsc` at every
|
|
14
|
-
* construction site until each one says what it carries there;
|
|
15
|
-
* · the SCAN — `scripts/verify-child-clamp-seats.mjs` reads {@link ENGINE_CHILD_SPEC_CONSTRUCTORS} and
|
|
16
|
-
* requires each registered constructor to go through this carrier, requires the carrier's own source
|
|
17
|
-
* to cover every seat, and requires every tighten-only seat `tightenTaskSpec` governs to be either
|
|
18
|
-
* carried here or listed in {@link CHILD_CLAMP_SEATS_NOT_CARRIED} with a reason.
|
|
19
|
-
*
|
|
20
|
-
* What "tighten-only" means for this seat list: the value that travels is the RESTRICTING one and only
|
|
21
|
-
* that one, so a parent that clamped nothing changes nothing about its children, and nothing a child can
|
|
22
|
-
* author lifts a clamp its parent ran under. That is why the carrier omits a key rather than writing a
|
|
23
|
-
* loosening value — a constructor may state its own stricter default and spread this after it.
|
|
16
|
+
* "Tighten-only" here: the value that travels is the RESTRICTING one and only that one, so a parent that clamped nothing
|
|
17
|
+
* changes nothing about its children, and nothing a child can author lifts a clamp its parent ran under.
|
|
24
18
|
*/
|
|
25
|
-
import type
|
|
19
|
+
import { readDenyEntryProblem, type ReadDenyEntry } from "../tools/fs/read-deny.js";
|
|
20
|
+
import { complianceCapabilityProblem, type ComplianceCapability } from "./compliance.js";
|
|
26
21
|
import type { TaskSpec } from "./types.js";
|
|
22
|
+
import { writeProtectedEntryIdentity, writeProtectedEntryProblem } from "./write-protect.js";
|
|
23
|
+
/** Which carrier hands a row to an engine-built child: the child-spec carrier ({@link childClampSeats}, ctx seats of the
|
|
24
|
+
* same names) or the parent spec seat (`ParentSpecSeat`, applied by `applyParentSpecSeat`). */
|
|
25
|
+
export type ClampCarrier = "clamp" | "specSeat";
|
|
26
|
+
/** The identity an add-only list folds by — case-insensitive unless the entry says otherwise (the deny matcher's reading). */
|
|
27
|
+
declare function readDenyIdentity(entry: ReadDenyEntry): string;
|
|
28
|
+
/** A capability is its own identity (a closed word). */
|
|
29
|
+
declare function complianceIdentity(cap: ComplianceCapability): string;
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
31
|
+
* How a governed workflow SCRIPT's untrusted list for an add-only row is read before the row's `entry` law judges it —
|
|
32
|
+
* the untrusted layer is bounded where the deployment and task layers are not. `atMost` is refused before any element is
|
|
33
|
+
* read (`why` says what each entry costs); `entry` reads ONE element, each of its properties exactly once, rebuilds it
|
|
34
|
+
* from the keys it recognizes (an element's extra own keys never ride along) and throws, naming `at`, on a shape it
|
|
35
|
+
* refuses. `shape` names the list's element grammar for the not-a-list refusal.
|
|
30
36
|
*/
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
export interface ScriptListLaw<E> {
|
|
38
|
+
readonly atMost: number;
|
|
39
|
+
readonly shape: string;
|
|
40
|
+
readonly why: string;
|
|
41
|
+
readonly entry: (el: unknown, at: string) => E;
|
|
42
|
+
}
|
|
34
43
|
/**
|
|
35
|
-
*
|
|
36
|
-
* — the
|
|
37
|
-
*
|
|
44
|
+
* THE CLAMP TABLE. Two laws:
|
|
45
|
+
* · `restricting` — the seat has ONE restricting `value`. Either side carrying it wins; a side that carries a different
|
|
46
|
+
* value cannot replace it (the public merge refuses that as a loosening); a seat with nothing restricting keeps what was
|
|
47
|
+
* authored.
|
|
48
|
+
* · `addOnly` — the seat is a list that only grows: every two of its lists meet in {@link unionAddOnly} (in order, folded
|
|
49
|
+
* by `identity`; `[]` erases nothing), and the run's effective list is that union taken with the deployment's own list
|
|
50
|
+
* (`deploymentLayer`, the `RunnerDeps` member it arrives through) — so the task layer can add entries and never remove
|
|
51
|
+
* one. `entry` is the seat's own entry law (its compiler's, never a copy); the task layer's lists meet it at the one
|
|
52
|
+
* door ({@link assertAddOnlySeats}), and an entry it refuses never folds into another. `script` bounds a governed
|
|
53
|
+
* workflow script's untrusted list for the seat before `entry` judges it.
|
|
54
|
+
* `script` also says whether a governed workflow SCRIPT may declare the seat for its child, under the row's law: a
|
|
55
|
+
* restricting row with `script: true` only as its restricting value (`false` = inherited only); an add-only row through its
|
|
56
|
+
* `script` list law, then `entry`. The script whitelist reads its tighten-only keys off this table ({@link SCRIPT_SEATS}),
|
|
57
|
+
* never off a list of its own.
|
|
58
|
+
* Rows are literals (the gate reads them as written).
|
|
38
59
|
*/
|
|
39
|
-
export declare const
|
|
60
|
+
export declare const CLAMP_SET: Readonly<{
|
|
61
|
+
handsReadOnly: Readonly<{
|
|
62
|
+
readonly law: "restricting";
|
|
63
|
+
readonly value: true;
|
|
64
|
+
readonly script: true;
|
|
65
|
+
readonly carrier: "clamp";
|
|
66
|
+
}>;
|
|
67
|
+
interactiveTools: Readonly<{
|
|
68
|
+
readonly law: "restricting";
|
|
69
|
+
readonly value: false;
|
|
70
|
+
readonly script: true;
|
|
71
|
+
readonly carrier: "clamp";
|
|
72
|
+
}>;
|
|
73
|
+
approvalReach: Readonly<{
|
|
74
|
+
readonly law: "restricting";
|
|
75
|
+
readonly value: "none";
|
|
76
|
+
readonly script: true;
|
|
77
|
+
readonly carrier: "clamp";
|
|
78
|
+
}>;
|
|
79
|
+
readFace: Readonly<{
|
|
80
|
+
readonly law: "restricting";
|
|
81
|
+
readonly value: "roots";
|
|
82
|
+
readonly script: true;
|
|
83
|
+
readonly carrier: "clamp";
|
|
84
|
+
}>;
|
|
85
|
+
writeFace: Readonly<{
|
|
86
|
+
readonly law: "restricting";
|
|
87
|
+
readonly value: "roots";
|
|
88
|
+
readonly script: true;
|
|
89
|
+
readonly carrier: "clamp";
|
|
90
|
+
}>;
|
|
91
|
+
readDenyPatterns: Readonly<{
|
|
92
|
+
readonly law: "addOnly";
|
|
93
|
+
readonly identity: typeof readDenyIdentity;
|
|
94
|
+
readonly entry: typeof readDenyEntryProblem;
|
|
95
|
+
readonly script: ScriptListLaw<ReadDenyEntry>;
|
|
96
|
+
readonly deploymentLayer: "readDenyPatterns";
|
|
97
|
+
readonly carrier: "clamp";
|
|
98
|
+
}>;
|
|
99
|
+
writeProtectedAdditions: Readonly<{
|
|
100
|
+
readonly law: "addOnly";
|
|
101
|
+
readonly identity: typeof writeProtectedEntryIdentity;
|
|
102
|
+
readonly entry: typeof writeProtectedEntryProblem;
|
|
103
|
+
readonly script: ScriptListLaw<import("./write-protect.js").WriteProtectedEntry>;
|
|
104
|
+
readonly deploymentLayer: "writeProtectedPaths";
|
|
105
|
+
readonly carrier: "clamp";
|
|
106
|
+
}>;
|
|
107
|
+
complianceAdditionalDenies: Readonly<{
|
|
108
|
+
readonly law: "addOnly";
|
|
109
|
+
readonly identity: typeof complianceIdentity;
|
|
110
|
+
readonly entry: typeof complianceCapabilityProblem;
|
|
111
|
+
readonly script: ScriptListLaw<ComplianceCapability>;
|
|
112
|
+
readonly deploymentLayer: "compliancePostureResolver";
|
|
113
|
+
readonly carrier: "clamp";
|
|
114
|
+
}>;
|
|
115
|
+
oneShot: Readonly<{
|
|
116
|
+
readonly law: "restricting";
|
|
117
|
+
readonly value: true;
|
|
118
|
+
readonly script: true;
|
|
119
|
+
readonly carrier: "specSeat";
|
|
120
|
+
}>;
|
|
121
|
+
memoryPersistenceCapable: Readonly<{
|
|
122
|
+
readonly law: "restricting";
|
|
123
|
+
readonly value: false;
|
|
124
|
+
readonly script: true;
|
|
125
|
+
readonly carrier: "specSeat";
|
|
126
|
+
}>;
|
|
127
|
+
fileHistory: Readonly<{
|
|
128
|
+
readonly law: "restricting";
|
|
129
|
+
readonly value: "disabled";
|
|
130
|
+
readonly script: false;
|
|
131
|
+
readonly carrier: "specSeat";
|
|
132
|
+
}>;
|
|
133
|
+
}>;
|
|
134
|
+
/** One row's seat name. */
|
|
135
|
+
export type ClampSeat = keyof typeof CLAMP_SET;
|
|
136
|
+
/** The add-only rows' seats. */
|
|
137
|
+
export type AddOnlySeat = {
|
|
138
|
+
[K in ClampSeat]: (typeof CLAMP_SET)[K]["law"] extends "addOnly" ? K : never;
|
|
139
|
+
}[ClampSeat];
|
|
140
|
+
/** One entry of an add-only seat's list. */
|
|
141
|
+
export type AddOnlyEntry<S extends AddOnlySeat> = NonNullable<TaskSpec[S]> extends ReadonlyArray<infer E> ? E : never;
|
|
142
|
+
/** The seats the child-spec carrier hands on. */
|
|
143
|
+
export type ChildClampSeat = {
|
|
144
|
+
[K in ClampSeat]: (typeof CLAMP_SET)[K]["carrier"] extends "clamp" ? K : never;
|
|
145
|
+
}[ClampSeat];
|
|
146
|
+
/** Every row's value as some record carries it — present keys, `undefined` where the record has none. */
|
|
147
|
+
export type ClampSource = {
|
|
148
|
+
[K in ClampSeat]: TaskSpec[K] | undefined;
|
|
149
|
+
};
|
|
150
|
+
/** The clamp source a construction site hands the carrier: EVERY clamp-carrier row as a PRESENT key. */
|
|
151
|
+
export type ChildClampSource = Pick<ClampSource, ChildClampSeat>;
|
|
152
|
+
/** Only the restricting values (add-only rows: a non-empty list) — the shape a waker's clamp seat and a projection take. */
|
|
153
|
+
export type ClampValues = {
|
|
154
|
+
readonly [K in ClampSeat]?: (typeof CLAMP_SET)[K] extends {
|
|
155
|
+
readonly value: infer V;
|
|
156
|
+
} ? V : NonNullable<TaskSpec[K]>;
|
|
157
|
+
};
|
|
158
|
+
/** Every row's seat name, in table order. */
|
|
159
|
+
export declare const CLAMP_SEATS: readonly ClampSeat[];
|
|
160
|
+
/** The rows a governed workflow script may declare for its child (every row whose `script` is not `false`). */
|
|
161
|
+
export type ScriptSeat = {
|
|
162
|
+
[K in ClampSeat]: (typeof CLAMP_SET)[K]["script"] extends false ? never : K;
|
|
163
|
+
}[ClampSeat];
|
|
164
|
+
/** {@link ScriptSeat}, in table order — the script whitelist's tighten-only half. */
|
|
165
|
+
export declare const SCRIPT_SEATS: readonly ScriptSeat[];
|
|
166
|
+
/** Two declarations of one seat under its row's law (`b` is the later one): the restricting value if either carries it,
|
|
167
|
+
* else what was authored (`b` over `a`); an add-only list is the union of both, in order, by the row's identity. */
|
|
168
|
+
export declare function composeClampSeat(seat: ClampSeat, a: unknown, b: unknown): unknown;
|
|
169
|
+
/**
|
|
170
|
+
* THE union of an add-only seat's lists — the ONE merge every add-only row reads, wherever two of its lists meet: two
|
|
171
|
+
* declarations of the seat (the public merge, a fold of records) and the run's EFFECTIVE list (the deployment's list
|
|
172
|
+
* first, then every task-layer list). In order; a lawful entry folds into an earlier one with the same `identity`; `[]`
|
|
173
|
+
* and absent add nothing, and nothing here removes an entry — so a later layer can only add. An entry the row's entry
|
|
174
|
+
* law refuses is kept as it is, never folded into a lawful one: it reaches the door or the compiler that refuses it
|
|
175
|
+
* instead of vanishing behind a namesake. A list that is not a list refuses here (it would be read letter by letter).
|
|
176
|
+
*/
|
|
177
|
+
export declare function unionAddOnly<S extends AddOnlySeat>(seat: S, ...lists: ReadonlyArray<ReadonlyArray<AddOnlyEntry<S>> | undefined>): AddOnlyEntry<S>[];
|
|
40
178
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
179
|
+
* THE task layer's door for the add-only rows: every add-only seat a spec carries is a list of entries its row's entry
|
|
180
|
+
* law accepts, or the prepare refuses — one code (`config.invalid_argument`, the table's own refusal), one sentence for a
|
|
181
|
+
* value that is not a list, and the seat's own entry law (labelled `TaskSpec.<seat>`) for a bad entry. Runs before any
|
|
182
|
+
* list is folded or compiled, so a task-layer value is judged as the caller wrote it. Absent ⇒ nothing to judge.
|
|
183
|
+
*/
|
|
184
|
+
export declare function assertAddOnlySeats(spec: object): void;
|
|
185
|
+
/** Would `override` LOOSEN `base` on this seat? Only a restricting row can be loosened: a base carrying the restricting
|
|
186
|
+
* value meeting an override that states a different one. */
|
|
187
|
+
export declare function loosensClampSeat(seat: ClampSeat, base: unknown, override: unknown): boolean;
|
|
188
|
+
/** Read every row (`carrier`: that carrier's rows only) off a record that carries the seats under their own names (a spec, a ctx, a seat). */
|
|
189
|
+
export declare function clampSourceOf(record: object | undefined): ClampSource;
|
|
190
|
+
export declare function clampSourceOf(record: object | undefined, carrier: "clamp"): ChildClampSource;
|
|
191
|
+
/** Fold several records' declarations of every row, in order, under each row's law — "either side restricting wins",
|
|
192
|
+
* add-only lists unioned. The fold of a spawn snapshot and its waker, of a workflow child's own spec and its host's
|
|
193
|
+
* clamps, of a ctx and its spec seat. */
|
|
194
|
+
export declare function foldClampSources(...records: ReadonlyArray<object | undefined>): ClampSource;
|
|
195
|
+
/** The restricting values of every row (`carrier` narrows it to one carrier's rows): a row with nothing restricting adds
|
|
196
|
+
* NO KEY, so the result spreads onto a spec without ever writing a loosening value. */
|
|
197
|
+
export declare function clampSeatsOf(source: Partial<Record<ClampSeat, unknown>>, carrier?: ClampCarrier): ClampValues;
|
|
198
|
+
/** The coded refusal of a clamp record a caller handed in (`config.invalid_argument`). */
|
|
199
|
+
export declare function clampRecordError(message: string): Error & {
|
|
200
|
+
code: "config.invalid_argument";
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Refuse a caller-supplied clamp record that names a seat the table does not have (or, with `carrier`, a row another
|
|
204
|
+
* carrier hands on): a name nobody reads would sit on the record as if wired — the silent drop the retired-key door
|
|
205
|
+
* exists to prevent. `extra` names the record's own members that are not rows. Absent ⇒ nothing to judge; a member
|
|
206
|
+
* whose value is `undefined` carries nothing and is read as absent (the retired-key door's presence rule).
|
|
207
|
+
*/
|
|
208
|
+
export declare function assertClampRecord(record: unknown, owner: string, carrier?: ClampCarrier, extra?: readonly string[]): void;
|
|
209
|
+
/** The restricting values of every row that ANY of `records` carries — the clamp seat a waker hands a revival. */
|
|
210
|
+
export declare function clampValuesOf(...records: ReadonlyArray<object | undefined>): ClampValues;
|
|
211
|
+
/**
|
|
212
|
+
* Project a parent's clamps onto a child spec — the clamp-carrier rows of the table, the ONE place a source becomes the
|
|
213
|
+
* seats a child spec carries. Spread the result onto the child spec; a seat with nothing to clamp contributes NO KEY, so
|
|
214
|
+
* a constructor may state its own stricter value above the spread and keep it (a `false` from the parent can never lift it).
|
|
44
215
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
216
|
+
* @contract child_spec.clamps_travel_whole — every child spec the ENGINE builds carries the whole of its parent's
|
|
217
|
+
* tighten-only clamp seats (the `CLAMP_SET` rows whose carrier is `"clamp"`) through this one carrier: only the
|
|
218
|
+
* restricting value of each seat travels, arrays are copied at spawn, and a seat the parent did not clamp adds no key —
|
|
219
|
+
* so a clamp can never end one level deep, and a new seat cannot reach some constructors and not others.
|
|
49
220
|
*/
|
|
50
|
-
export declare
|
|
221
|
+
export declare function childClampSeats(source: ChildClampSource): Pick<ClampValues, ChildClampSeat>;
|
|
51
222
|
/**
|
|
52
|
-
* The
|
|
53
|
-
*
|
|
54
|
-
*
|
|
223
|
+
* The seats `tightenTaskSpec` governs OUTSIDE the table, each with the reason it is not a row — the "forgot" / "decided"
|
|
224
|
+
* distinction, kept where a new reader will trip over it. The scan requires every seat `tightenTaskSpec` names to be a
|
|
225
|
+
* row or listed here.
|
|
55
226
|
*/
|
|
56
|
-
export
|
|
57
|
-
/** The write-hands clamp: only `true` travels. */
|
|
58
|
-
handsReadOnly: boolean | undefined;
|
|
59
|
-
/** The hard-headless clamp: only `false` travels. */
|
|
60
|
-
interactiveTools: boolean | undefined;
|
|
61
|
-
/** The declaration that nobody on the run can be asked to approve: only `"none"` travels. */
|
|
62
|
-
approvalReach: TaskSpec["approvalReach"] | undefined;
|
|
63
|
-
/** The read containment face: only `"roots"` travels. */
|
|
64
|
-
readFace: TaskSpec["readFace"] | undefined;
|
|
65
|
-
/** The write containment face: only `"roots"` travels. */
|
|
66
|
-
writeFace: TaskSpec["writeFace"] | undefined;
|
|
67
|
-
/** The deny-set additions: an add-only axis, so a non-empty list travels as a spawn-time copy. */
|
|
68
|
-
readDenyPatterns: readonly ReadDenyEntry[] | undefined;
|
|
69
|
-
}
|
|
227
|
+
export declare const CHILD_CLAMP_SEATS_NOT_CARRIED: Readonly<Record<string, string>>;
|
|
70
228
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* it (a `false` from the parent can never lift it).
|
|
229
|
+
* The engine-built child-spec constructors, as `<repo-relative file>#<name>` — the closed registry the scan enumerates.
|
|
230
|
+
* A constructor that builds a spec for a child RUN belongs here; the scan requires each row to resolve to exactly one
|
|
231
|
+
* declaration IN ITS OWN FILE that calls {@link childClampSeats}.
|
|
75
232
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* — so a clamp can never end one level deep, and a new seat cannot reach some constructors and not others.
|
|
233
|
+
* Why the file is half the key, and why a shape the scan cannot read is a RED rather than an absence: a registry keyed
|
|
234
|
+
* on a bare NAME asks a syntactic scan to enumerate every shape that binds a callable, and that list has no end — every
|
|
235
|
+
* shape it misses leaves the real constructor invisible while a namesake answers for it.
|
|
80
236
|
*/
|
|
81
|
-
export declare
|
|
237
|
+
export declare const ENGINE_CHILD_SPEC_CONSTRUCTORS: readonly ["src/agents/subagent.ts#buildChildSpec", "src/agents/subagent.ts#observerSpec", "src/agents/subagent.ts#resumeSpec", "src/agents/verify.ts#verifierSpec", "src/agents/verify.ts#fixLegSpec", "src/orchestration/workflow-primitives.ts#workflowChildClamps"];
|
|
82
238
|
/**
|
|
83
239
|
* The interaction posture a leg keeps under the clamps it inherited: `"interactive"` promises a person on the leg, and a
|
|
84
240
|
* leg that inherited the hard-headless clamp (`interactiveTools: false`) or the declaration that nobody can be asked
|
|
@@ -92,13 +248,16 @@ export declare function postureUnderClamps(posture: "interactive" | "headless" |
|
|
|
92
248
|
readonly approvalReach: TaskSpec["approvalReach"] | undefined;
|
|
93
249
|
}): "interactive" | "headless" | undefined;
|
|
94
250
|
/**
|
|
95
|
-
* The OWN
|
|
96
|
-
* human-facing tool is mounted
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
251
|
+
* The OWN seats of an engine-built leg that never asks the person (the observer sidecar, the verifier) — ONE declaration
|
|
252
|
+
* the leg's own resolutions read: no human-facing tool is mounted, the leg is headless, and nobody on it can be asked to
|
|
253
|
+
* approve (the approval seat resolves without the deployment's live approver: refused, or parked where the deployment's
|
|
254
|
+
* park facility is armed). The spec's posture outranks the one a leg inherits, and the prepare door refuses an
|
|
255
|
+
* "interactive" posture beside either clamp, so the three travel together. Spread ABOVE {@link childClampSeats}: a caller
|
|
256
|
+
* clamp can only tighten it.
|
|
100
257
|
*/
|
|
101
258
|
export declare function engineHeadlessLegSeats(): {
|
|
102
259
|
interactiveTools: false;
|
|
260
|
+
approvalReach: "none";
|
|
103
261
|
interactionPosture: "headless";
|
|
104
262
|
};
|
|
263
|
+
export {};
|
|
@@ -1,37 +1,231 @@
|
|
|
1
|
-
|
|
1
|
+
import { readDenyEntryProblem } from "../tools/fs/read-deny.js";
|
|
2
|
+
import { COMPLIANCE_CAPABILITIES, complianceCapabilityProblem } from "./compliance.js";
|
|
3
|
+
import { writeProtectedEntryIdentity, writeProtectedEntryProblem } from "./write-protect.js";
|
|
4
|
+
function readDenyIdentity(entry) {
|
|
5
|
+
return typeof entry === "string" ? `i:${entry}` : `${entry.caseSensitive === true ? "s" : "i"}:${entry.pattern}`;
|
|
6
|
+
}
|
|
7
|
+
function complianceIdentity(cap) {
|
|
8
|
+
return cap;
|
|
9
|
+
}
|
|
10
|
+
const MAX_SCRIPT_LIST_ENTRIES = 16;
|
|
11
|
+
const MAX_SCRIPT_ENTRY_CHARS = 256;
|
|
12
|
+
const MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT = 1;
|
|
13
|
+
function assertScriptEntryLength(text, at, what, why) {
|
|
14
|
+
if (text.length > MAX_SCRIPT_ENTRY_CHARS)
|
|
15
|
+
throw new Error(`${at} is ${text.length} characters — a workflow script's ${what} is limited to ${MAX_SCRIPT_ENTRY_CHARS} (${why}).`);
|
|
16
|
+
}
|
|
17
|
+
function assertScriptDenyPatternBounded(pattern, at) {
|
|
18
|
+
assertScriptEntryLength(pattern, at, "deny pattern", "the matcher runs on every read of the child's run");
|
|
19
|
+
for (const segment of pattern.split("/")) {
|
|
20
|
+
const wildcards = segment.split("*").length - 1;
|
|
21
|
+
if (wildcards > MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT) {
|
|
22
|
+
throw new Error(`${at} has a path segment with ${wildcards} \`*\` wildcards — a workflow script's deny pattern allows at most ` +
|
|
23
|
+
`${MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT} per path segment (the same expressiveness the engine's built-in deny table ` +
|
|
24
|
+
`uses). Each \`*\` compiles to a greedy match, and more than one in a single segment makes the judgment cost grow ` +
|
|
25
|
+
`superlinearly with the path length, on every read the child performs. Write the intent as separate entries ` +
|
|
26
|
+
`(the set is a union, so more entries deny strictly more) or anchor it with literal segments.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function readDenyScriptEntry(el, at) {
|
|
31
|
+
if (typeof el === "string") {
|
|
32
|
+
if (el.length === 0)
|
|
33
|
+
throw new Error(`${at} must be a non-empty pattern string`);
|
|
34
|
+
assertScriptDenyPatternBounded(el, at);
|
|
35
|
+
return el;
|
|
36
|
+
}
|
|
37
|
+
if (typeof el !== "object" || el === null || Array.isArray(el))
|
|
38
|
+
throw new Error(`${at} must be a pattern string or an object { pattern, caseSensitive? }`);
|
|
39
|
+
const o = el;
|
|
40
|
+
const pattern = o.pattern;
|
|
41
|
+
const caseSensitive = o.caseSensitive;
|
|
42
|
+
if (typeof pattern !== "string" || pattern.length === 0)
|
|
43
|
+
throw new Error(`${at}.pattern must be a non-empty string, e.g. ".ssh" or "secrets/*.json"`);
|
|
44
|
+
if (caseSensitive !== undefined && typeof caseSensitive !== "boolean")
|
|
45
|
+
throw new Error(`${at}.caseSensitive must be a boolean`);
|
|
46
|
+
assertScriptDenyPatternBounded(pattern, at);
|
|
47
|
+
return caseSensitive === undefined ? { pattern } : { pattern, caseSensitive };
|
|
48
|
+
}
|
|
49
|
+
function writeProtectedScriptEntry(el, at) {
|
|
50
|
+
const why = "the judge runs on every write the child names";
|
|
51
|
+
if (typeof el === "string") {
|
|
52
|
+
if (el.length === 0)
|
|
53
|
+
throw new Error(`${at} must be a non-empty name string`);
|
|
54
|
+
assertScriptEntryLength(el, at, "write-protected name", why);
|
|
55
|
+
return el;
|
|
56
|
+
}
|
|
57
|
+
if (typeof el !== "object" || el === null || Array.isArray(el))
|
|
58
|
+
throw new Error(`${at} must be a name string or an object { name, kind }`);
|
|
59
|
+
const o = el;
|
|
60
|
+
const name = o.name;
|
|
61
|
+
const kind = o.kind;
|
|
62
|
+
if (typeof name !== "string" || name.length === 0)
|
|
63
|
+
throw new Error(`${at}.name must be a non-empty string, e.g. ".npmrc" or ".config/app"`);
|
|
64
|
+
if (typeof kind !== "string")
|
|
65
|
+
throw new Error(`${at}.kind must be a string ("basename", "segment" or "segment-run")`);
|
|
66
|
+
assertScriptEntryLength(name, at, "write-protected name", why);
|
|
67
|
+
return { name, kind };
|
|
68
|
+
}
|
|
69
|
+
function complianceScriptEntry(el, at) {
|
|
70
|
+
if (typeof el !== "string")
|
|
71
|
+
throw new Error(`${at} must be a capability word (${COMPLIANCE_CAPABILITIES.join(", ")})`);
|
|
72
|
+
return el;
|
|
73
|
+
}
|
|
74
|
+
const READ_DENY_SCRIPT_LAW = Object.freeze({
|
|
75
|
+
atMost: MAX_SCRIPT_LIST_ENTRIES,
|
|
76
|
+
shape: 'deny entries (a "/"-separated segment run such as ".ssh", or { pattern, caseSensitive? })',
|
|
77
|
+
why: "Every entry is judged against every path the child reads, for the child's whole run; the deployment's own entries, and whichever built-in tiers the deployment has on (by default the credentials and home agent-config tiers), are in force on top of these.",
|
|
78
|
+
entry: readDenyScriptEntry,
|
|
79
|
+
});
|
|
80
|
+
const WRITE_PROTECTED_SCRIPT_LAW = Object.freeze({
|
|
81
|
+
atMost: MAX_SCRIPT_LIST_ENTRIES,
|
|
82
|
+
shape: 'write-protected names (a literal name such as ".npmrc", a "/"-separated run such as ".config/app", or { name, kind })',
|
|
83
|
+
why: "Every row is judged against every write the child names, for the child's whole run; the deployment's own table is in force beside these.",
|
|
84
|
+
entry: writeProtectedScriptEntry,
|
|
85
|
+
});
|
|
86
|
+
const COMPLIANCE_SCRIPT_LAW = Object.freeze({
|
|
87
|
+
atMost: MAX_SCRIPT_LIST_ENTRIES,
|
|
88
|
+
shape: `capability words (${COMPLIANCE_CAPABILITIES.join(", ")})`,
|
|
89
|
+
why: "The capability set is closed; a longer list can only repeat it.",
|
|
90
|
+
entry: complianceScriptEntry,
|
|
91
|
+
});
|
|
92
|
+
export const CLAMP_SET = Object.freeze({
|
|
93
|
+
handsReadOnly: Object.freeze({ law: "restricting", value: true, script: true, carrier: "clamp" }),
|
|
94
|
+
interactiveTools: Object.freeze({ law: "restricting", value: false, script: true, carrier: "clamp" }),
|
|
95
|
+
approvalReach: Object.freeze({ law: "restricting", value: "none", script: true, carrier: "clamp" }),
|
|
96
|
+
readFace: Object.freeze({ law: "restricting", value: "roots", script: true, carrier: "clamp" }),
|
|
97
|
+
writeFace: Object.freeze({ law: "restricting", value: "roots", script: true, carrier: "clamp" }),
|
|
98
|
+
readDenyPatterns: Object.freeze({ law: "addOnly", identity: readDenyIdentity, entry: readDenyEntryProblem, script: READ_DENY_SCRIPT_LAW, deploymentLayer: "readDenyPatterns", carrier: "clamp" }),
|
|
99
|
+
writeProtectedAdditions: Object.freeze({ law: "addOnly", identity: writeProtectedEntryIdentity, entry: writeProtectedEntryProblem, script: WRITE_PROTECTED_SCRIPT_LAW, deploymentLayer: "writeProtectedPaths", carrier: "clamp" }),
|
|
100
|
+
complianceAdditionalDenies: Object.freeze({ law: "addOnly", identity: complianceIdentity, entry: complianceCapabilityProblem, script: COMPLIANCE_SCRIPT_LAW, deploymentLayer: "compliancePostureResolver", carrier: "clamp" }),
|
|
101
|
+
oneShot: Object.freeze({ law: "restricting", value: true, script: true, carrier: "specSeat" }),
|
|
102
|
+
memoryPersistenceCapable: Object.freeze({ law: "restricting", value: false, script: true, carrier: "specSeat" }),
|
|
103
|
+
fileHistory: Object.freeze({ law: "restricting", value: "disabled", script: false, carrier: "specSeat" }),
|
|
104
|
+
});
|
|
105
|
+
const ROWS = Object.freeze(Object.entries(CLAMP_SET));
|
|
106
|
+
export const CLAMP_SEATS = Object.freeze(ROWS.map(([seat]) => seat));
|
|
107
|
+
export const SCRIPT_SEATS = Object.freeze(ROWS.filter(([, row]) => row.script !== false).map(([seat]) => seat));
|
|
108
|
+
export function composeClampSeat(seat, a, b) {
|
|
109
|
+
const row = CLAMP_SET[seat];
|
|
110
|
+
if (row.law === "restricting")
|
|
111
|
+
return a === row.value || b === row.value ? row.value : (b ?? a);
|
|
112
|
+
const lists = [a, b];
|
|
113
|
+
return unionAddOnly(seat, ...lists);
|
|
114
|
+
}
|
|
115
|
+
function notAListSentence(owner, value) {
|
|
116
|
+
return `${owner} must be an array or absent (got ${value === null ? "null" : typeof value}) — a non-array here would be iterated character by character, so it refuses loudly instead.`;
|
|
117
|
+
}
|
|
118
|
+
export function unionAddOnly(seat, ...lists) {
|
|
119
|
+
const row = CLAMP_SET[seat];
|
|
120
|
+
const identity = row.identity;
|
|
121
|
+
const seen = new Set();
|
|
122
|
+
const out = [];
|
|
123
|
+
for (const list of lists) {
|
|
124
|
+
if (list === undefined)
|
|
125
|
+
continue;
|
|
126
|
+
if (!Array.isArray(list))
|
|
127
|
+
throw clampRecordError(notAListSentence(seat, list));
|
|
128
|
+
for (const e of list) {
|
|
129
|
+
if (row.entry(e, seat) !== undefined) {
|
|
130
|
+
out.push(e);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const key = identity(e);
|
|
134
|
+
if (!seen.has(key))
|
|
135
|
+
(seen.add(key), out.push(e));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
export function assertAddOnlySeats(spec) {
|
|
141
|
+
for (const [seat, row] of ROWS) {
|
|
142
|
+
if (row.law !== "addOnly")
|
|
143
|
+
continue;
|
|
144
|
+
const value = spec[seat];
|
|
145
|
+
if (value === undefined)
|
|
146
|
+
continue;
|
|
147
|
+
const owner = `TaskSpec.${seat}`;
|
|
148
|
+
if (!Array.isArray(value))
|
|
149
|
+
throw clampRecordError(notAListSentence(owner, value));
|
|
150
|
+
const entries = value;
|
|
151
|
+
for (const e of entries) {
|
|
152
|
+
const problem = row.entry(e, owner);
|
|
153
|
+
if (problem !== undefined)
|
|
154
|
+
throw clampRecordError(problem);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function loosensClampSeat(seat, base, override) {
|
|
159
|
+
const row = CLAMP_SET[seat];
|
|
160
|
+
return row.law === "restricting" && base === row.value && override !== undefined && override !== row.value;
|
|
161
|
+
}
|
|
162
|
+
function projected(seat, v) {
|
|
163
|
+
const row = CLAMP_SET[seat];
|
|
164
|
+
if (row.law === "restricting")
|
|
165
|
+
return v === row.value ? row.value : undefined;
|
|
166
|
+
return Array.isArray(v) && v.length > 0 ? Object.freeze(v.map((e) => (typeof e === "object" && e !== null ? { ...e } : e))) : undefined;
|
|
167
|
+
}
|
|
168
|
+
export function clampSourceOf(record, carrier) {
|
|
169
|
+
const r = (record ?? {});
|
|
170
|
+
return Object.fromEntries(ROWS.filter(([, row]) => carrier === undefined || row.carrier === carrier).map(([seat]) => [seat, r[seat]]));
|
|
171
|
+
}
|
|
172
|
+
export function foldClampSources(...records) {
|
|
173
|
+
return Object.fromEntries(CLAMP_SEATS.map((seat) => [seat, records.reduce((acc, rec) => composeClampSeat(seat, acc, rec?.[seat]), undefined)]));
|
|
174
|
+
}
|
|
175
|
+
export function clampSeatsOf(source, carrier) {
|
|
176
|
+
const out = {};
|
|
177
|
+
for (const [seat, row] of ROWS) {
|
|
178
|
+
if (carrier !== undefined && row.carrier !== carrier)
|
|
179
|
+
continue;
|
|
180
|
+
const v = projected(seat, source[seat]);
|
|
181
|
+
if (v !== undefined)
|
|
182
|
+
out[seat] = v;
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
export function clampRecordError(message) {
|
|
187
|
+
const e = new Error(message);
|
|
188
|
+
e.code = "config.invalid_argument";
|
|
189
|
+
return e;
|
|
190
|
+
}
|
|
191
|
+
export function assertClampRecord(record, owner, carrier, extra = []) {
|
|
192
|
+
if (record === undefined)
|
|
193
|
+
return;
|
|
194
|
+
if (record === null || typeof record !== "object")
|
|
195
|
+
throw clampRecordError(`${owner} must be a record of clamp seats, got ${record === null ? "null" : typeof record}`);
|
|
196
|
+
const legal = [...ROWS.filter(([, row]) => carrier === undefined || row.carrier === carrier).map(([seat]) => seat), ...extra];
|
|
197
|
+
const unknown = Object.keys(record).filter((k) => record[k] !== undefined && !legal.includes(k));
|
|
198
|
+
if (unknown.length > 0) {
|
|
199
|
+
throw clampRecordError(`${owner} names ${unknown.map((k) => JSON.stringify(k)).join(", ")}, which the clamp table does not carry there — the legal seats are ${legal.join(", ")}. Refused rather than ignored: a seat nobody reads would read to the caller as wired.`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export function clampValuesOf(...records) {
|
|
203
|
+
return clampSeatsOf(foldClampSources(...records));
|
|
204
|
+
}
|
|
205
|
+
export function childClampSeats(source) {
|
|
206
|
+
return clampSeatsOf(source, "clamp");
|
|
207
|
+
}
|
|
2
208
|
export const CHILD_CLAMP_SEATS_NOT_CARRIED = Object.freeze({
|
|
3
209
|
toolPolicy: "not a clamp a child spec copies: a parent's denies reach its children through the ancestor-constraint chain the child's own prepare folds, not by putting the parent's policy object on the child seat",
|
|
4
210
|
shellGate: "travels on the inherited-gate lane (`InheritedGate.shellGate`, a trusted internals seat), not on the child spec — a spec-level copy would be a second source for the same clamp",
|
|
5
211
|
permissionMode: "travels on the inherited-gate lane (`InheritedGate.permissionMode` / `permissionModeCeiling` — the parent's declared word and its LIVE seat): a child with no word of its own inherits that ceiling on every read, and a word it does declare is clamped under it; a spec-level copy would freeze the parent's word at spawn and be a second source for the same clamp",
|
|
6
212
|
onAsk: "per-lane by construction: the delegation lane wraps the parent's approver with spawn provenance before it becomes the child's seat, and a lane with no approver must hand down none (a parent that declared nobody can be asked hands down no approver — its frozen seat is empty — and the declaration rides `approvalReach`)",
|
|
7
213
|
hooks: "a deployment seat, not an inherited clamp — `tightenTaskSpec` refuses to merge two hook sets rather than composing them, so there is no tightening value to carry",
|
|
8
|
-
|
|
9
|
-
|
|
214
|
+
allowTools: "the tool selector's own layer — a parent bounds its children through the selector's ceiling (`RunInternals.toolCeiling`, a trusted internals seat every engine lane fills), not by copying its own list onto the child seat, which would be a second source for the same bound",
|
|
215
|
+
excludeTools: "the deny half of the same layer as `allowTools` above, same reading: the parent's reaches its children through the ceiling",
|
|
216
|
+
deferTools: "roster disclosure control rather than containment: the lanes that copy it do so beside these seats, and the workflow lane authors its child roster from the governance baseline instead of the host's",
|
|
10
217
|
});
|
|
11
218
|
export const ENGINE_CHILD_SPEC_CONSTRUCTORS = Object.freeze([
|
|
12
219
|
"src/agents/subagent.ts#buildChildSpec",
|
|
13
220
|
"src/agents/subagent.ts#observerSpec",
|
|
14
221
|
"src/agents/subagent.ts#resumeSpec",
|
|
15
|
-
"src/agents/teacher.ts#inheritedDeploymentConfig",
|
|
16
222
|
"src/agents/verify.ts#verifierSpec",
|
|
17
223
|
"src/agents/verify.ts#fixLegSpec",
|
|
18
224
|
"src/orchestration/workflow-primitives.ts#workflowChildClamps",
|
|
19
225
|
]);
|
|
20
|
-
export function childClampSeats(source) {
|
|
21
|
-
return {
|
|
22
|
-
...(source.handsReadOnly === true ? { handsReadOnly: true } : {}),
|
|
23
|
-
...(source.interactiveTools === false ? { interactiveTools: false } : {}),
|
|
24
|
-
...(source.approvalReach === "none" ? { approvalReach: "none" } : {}),
|
|
25
|
-
...(source.readFace === "roots" ? { readFace: "roots" } : {}),
|
|
26
|
-
...(source.writeFace === "roots" ? { writeFace: "roots" } : {}),
|
|
27
|
-
...(source.readDenyPatterns !== undefined && source.readDenyPatterns.length > 0
|
|
28
|
-
? { readDenyPatterns: [...source.readDenyPatterns] }
|
|
29
|
-
: {}),
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
226
|
export function postureUnderClamps(posture, clamps) {
|
|
33
227
|
return posture === "interactive" && (clamps.interactiveTools === false || clamps.approvalReach === "none") ? "headless" : posture;
|
|
34
228
|
}
|
|
35
229
|
export function engineHeadlessLegSeats() {
|
|
36
|
-
return { interactiveTools: false, interactionPosture: "headless" };
|
|
230
|
+
return { interactiveTools: false, approvalReach: "none", interactionPosture: "headless" };
|
|
37
231
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { type AutoModeClassifierRound, type AutoModeDenialTracker, type AutoModeFallbackCause, type UnarmedDenialLimitFallback } from "./auto-mode.js";
|
|
19
19
|
import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "./tool-policy.js";
|
|
20
|
+
import type { Settlement } from "./gate-outcome.js";
|
|
20
21
|
/** Where a classification that did not rule sent the call: `asked` = on to the approval seat, `denied` = refused. */
|
|
21
22
|
export type ClassifierUnavailableDisposition = "asked" | "denied";
|
|
22
23
|
/** What the stations' observer receives — the facts the `classifier.unavailable` notice is composed from. `cause` is why
|
|
@@ -71,6 +72,9 @@ export declare function classifierNoRulingArm<A extends Extract<PermissionResult
|
|
|
71
72
|
export declare function settleNoRulingAsk(opts: {
|
|
72
73
|
ask: PermissionResult;
|
|
73
74
|
mintedHere: boolean;
|
|
74
|
-
resolved:
|
|
75
|
+
resolved: {
|
|
76
|
+
action: ResolvedAsk["action"];
|
|
77
|
+
settlement?: Settlement;
|
|
78
|
+
};
|
|
75
79
|
tracker: AutoModeDenialTracker | undefined;
|
|
76
80
|
}): UnarmedDenialLimitFallback | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { classifierNoRulingAskMessage, classifierUnavailableDenyMessage } from "./auto-mode.js";
|
|
2
|
-
import {
|
|
2
|
+
import { attest } from "./tool-policy.js";
|
|
3
3
|
export function classifierNoRulingArm(args) {
|
|
4
4
|
const { ask, req, cause } = args;
|
|
5
5
|
const seated = args.seat?.approvalSeat === true;
|
|
@@ -11,11 +11,11 @@ export function classifierNoRulingArm(args) {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
if (seated)
|
|
14
|
-
return { kind: "asked", ask:
|
|
14
|
+
return { kind: "asked", ask: { ...ask, message: classifierNoRulingAskMessage(ask.message ?? `approval required for "${req.toolName}"`, cause), requiresRealApproval: true, classifierNoRuling: cause } };
|
|
15
15
|
if (cause === "parse_error")
|
|
16
16
|
return { kind: "counted" };
|
|
17
17
|
const deny = { action: "deny", message: classifierUnavailableDenyMessage(req.toolName, cause, args.attribution), decisionReason: "classifier" };
|
|
18
|
-
return { kind: "denied", deny:
|
|
18
|
+
return { kind: "denied", deny: attest(deny, req, { classifierCause: "unavailable" }) };
|
|
19
19
|
}
|
|
20
20
|
export function settleNoRulingAsk(opts) {
|
|
21
21
|
const { ask, resolved } = opts;
|