@sema-agent/server 7.131.0 → 7.133.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/MIGRATION.md +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +31 -13
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +47 -32
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -28
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +118 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { type HookEntry, type HookEntryType, type HookEventName, type HooksDroppedPiece, type HooksRejection } from "@sema-agent/settings-schema/hooks";
|
|
1
|
+
import { type HookEntry, type HookEntryType, type HookEventName, type HooksDroppedPiece, type HooksDroppedPieceCode, type HooksRejection, type HooksRejectionCode } from "@sema-agent/settings-schema/hooks";
|
|
2
2
|
import { type ConfigPath } from "@sema-agent/settings-schema";
|
|
3
|
-
import
|
|
3
|
+
import { ENGINE_OWNED_HOOK_EVENTS } from "@sema-agent/settings-schema/hooks";
|
|
4
|
+
import type { EngineDollar, ModRegistration } from "@sema-agent/core";
|
|
4
5
|
import type { Logger } from "../observability/logger.js";
|
|
5
|
-
import type { HookNoticeObservation } from "../fleet/fleet-bus.js";
|
|
6
|
+
import type { HookManagedUnrun, HookNoticeObservation } from "../fleet/fleet-bus.js";
|
|
7
|
+
import { LIMIT_REASONS, type LimitMeasure } from "../limit-refusal.js";
|
|
8
|
+
import { type HookGroupSource } from "./hook-source.js";
|
|
9
|
+
import { type RunnableCommandHookEntry } from "./command-spawn.js";
|
|
6
10
|
/** 服务侧防线上限(契约本身不设量纲;不设界=单请求可塞任意大配置/任意长命令)。超界=校验错(fail-loud)。 */
|
|
7
11
|
export declare const MAX_HOOK_ENTRIES_PER_EVENT = 32;
|
|
8
12
|
export declare const MAX_HOOK_COMMAND_CHARS = 8192;
|
|
@@ -21,8 +25,7 @@ export declare const MAX_HOOK_OUTPUT_BYTES: number;
|
|
|
21
25
|
* 一次事件里所有 hook 上下文片段**聚合后**喂给模型的总量上限(字符)。
|
|
22
26
|
*
|
|
23
27
|
* 为什么单条帽不够:一次事件最多 {@link MAX_HOOK_ENTRIES_PER_EVENT} 条(parseHooksConfig 的广度闸),
|
|
24
|
-
* 每条最多推两段(`decision:"block"` 的 reason + `hookSpecificOutput.additionalContext`),
|
|
25
|
-
* {@link composeHooks} 再把部署槽与 task 槽的**成品**拼一次 —— 单条 4096 相乘后一次注入可达 ~256KB,
|
|
28
|
+
* 每条最多推两段(`decision:"block"` 的 reason + `hookSpecificOutput.additionalContext`)—— 单条 4096 相乘后一次注入可达 ~256KB,
|
|
26
29
|
* 而这些字符是**逐次工具调用**进模型可见文本的(core `hooks.js` 的 preToolContext / `prepare-task.js`
|
|
27
30
|
* 的 tool_result 追加 / `runtask.js` 的 Stop follow-up),不是日志。
|
|
28
31
|
*
|
|
@@ -32,6 +35,52 @@ export declare const MAX_HOOK_OUTPUT_BYTES: number;
|
|
|
32
35
|
* 且 4096 的单条帽保证**前两条**钩子的话仍整段进得去(截断是配置广度的代价,不是常态)。
|
|
33
36
|
*/
|
|
34
37
|
export declare const MAX_HOOK_CONTEXT_TOTAL_CHARS = 10000;
|
|
38
|
+
/** 契约里**引擎属主**的 `settings.hooks` 事件(契约包的九员字面量元组;壳属主的事件引擎不跑,owner-single)。 */
|
|
39
|
+
export type EngineOwnedHookEvent = (typeof ENGINE_OWNED_HOOK_EVENTS)[number];
|
|
40
|
+
/**
|
|
41
|
+
* 律二 · **事件对位只有一张表**:引擎属主的每个 `settings.hooks` 事件 → 它挂的 `classic.*` 站。
|
|
42
|
+
* 注册的 `uses.events`、点亮了哪些站,全从这张表派生;契约加一个引擎属主事件 ⇒ 本表缺键 ⇒ tsc 红(那一刻补一行翻译),
|
|
43
|
+
* 所以运行期没有「引擎属主却没点亮」这一臂。每个站名在引擎事件表里都有站(钉从 `MOD_EVENT_TABLE` 派生对拍:只选无站名的注册 prepare 即拒)。
|
|
44
|
+
* `Stop` 挂两站:引擎把委派子代的停车点叫 `classic.SubagentStop`(续跑的子代同读),而旧座在每条腿都跑 ——
|
|
45
|
+
* 挂两个名字使用户的 `Stop` 条目触达不变(契约把 `SubagentStop` 判给壳;两张属主表对齐之前不收窄)。
|
|
46
|
+
*/
|
|
47
|
+
export declare const SETTINGS_HOOK_STATIONS: {
|
|
48
|
+
readonly PreToolUse: readonly ["classic.PreToolUse"];
|
|
49
|
+
readonly PostToolUse: readonly ["classic.PostToolUse"];
|
|
50
|
+
readonly PostToolUseFailure: readonly ["classic.PostToolUseFailure"];
|
|
51
|
+
readonly PostToolBatch: readonly ["classic.PostToolBatch"];
|
|
52
|
+
readonly UserPromptSubmit: readonly ["classic.UserPromptSubmit"];
|
|
53
|
+
readonly Stop: readonly ["classic.Stop", "classic.SubagentStop"];
|
|
54
|
+
readonly StopFailure: readonly ["classic.StopFailure"];
|
|
55
|
+
readonly PreCompact: readonly ["classic.PreCompact"];
|
|
56
|
+
readonly PostCompact: readonly ["classic.PostCompact"];
|
|
57
|
+
};
|
|
58
|
+
/** 这张注册的名字 —— wire 可见(`wiring_manifest.mods[].name`、`allowRuleShadowed[].entries`),也是 handler 失败时引擎拒句点名的扩展名。 */
|
|
59
|
+
export declare const SETTINGS_HOOKS_REGISTRATION = "settings.hooks";
|
|
60
|
+
/**
|
|
61
|
+
* 律四 · `HOOKS_TIMEOUT_MS` 未设时本注册每个 handler 的预算(ms)。
|
|
62
|
+
*
|
|
63
|
+
* **这只数是引擎的钟,不是本服务跑钩子子进程的墙钟。** 引擎对 `budgetMs` 的定义(core `ModRegistration.budgetMs` 的注释,逐字)是
|
|
64
|
+
* "Each handler's own time" —— 每个 handler 自己的时间:一只在 handler 等 `next` / `$` 调用时暂停的钟(core 的 `SelfBudget`),
|
|
65
|
+
* 到点 ⇒ 这个 handler 失败(PreToolUse / UserPromptSubmit 上 fail-closed 拒,其余站跳过)。命令钩子子进程自己的墙钟另有两只,都在本文件:
|
|
66
|
+
* 单条命令的 `timeout`(上限 {@link MAX_HOOK_TIMEOUT_SECONDS})与一个事件里同步条目的总墙钟({@link MAX_HOOK_EVENT_TOTAL_SECONDS},到点不再起下一条)。
|
|
67
|
+
*
|
|
68
|
+
* 缺省取单条命令超时的上限 {@link MAX_HOOK_TIMEOUT_SECONDS} × 1000(两只钟起点不同:引擎的钟在 handler 起跑时就开始走,命令的 `timeout` 钟要等 shell 解析和 spawn 之后,
|
|
69
|
+
* 同一 handler 里串行的几条还共用这一只钟 —— 配到 600 s 的命令跑满时预算会先到)。不是抄引擎缺省(10 s):一条跑 11 s 的 PreToolUse 钩子会因此被 fail-closed 拒。
|
|
70
|
+
*
|
|
71
|
+
* 两只钟的交汇:预算到,与任务被取消一样,引擎对这个 handler 的信号({@link ClassicAnswer} 的 `signal`)触发 ——
|
|
72
|
+
* 在跑的命令钩子的进程组被叫停(SIGTERM → {@link HOOK_KILL_GRACE_MS} → 组长还在则组 SIGKILL),这个 handler 里还没起的条目不再起。
|
|
73
|
+
*/
|
|
74
|
+
export declare const DEFAULT_SETTINGS_HOOKS_BUDGET_MS: number;
|
|
75
|
+
/** 时限的唯一读法:`HOOKS_TIMEOUT_MS` 设了就是它(`0` 按字面 = 零预算);未设 ⇒ {@link DEFAULT_SETTINGS_HOOKS_BUDGET_MS}。 */
|
|
76
|
+
export declare function settingsHooksBudgetMs(config: {
|
|
77
|
+
readonly hooksTimeoutMs?: number | undefined;
|
|
78
|
+
}): number;
|
|
79
|
+
/**
|
|
80
|
+
* 命令钩子的进程组被叫停(预算到 / 任务取消)时,SIGTERM 之后给它收尾的宽限(ms):到点组长还在就补一发组 SIGKILL(组长在宽限内退了则不再发)。
|
|
81
|
+
* 零旋钮 —— 命令要的收尾窗长于此值的,在命令里自己兜(trap 里快速落盘)。
|
|
82
|
+
*/
|
|
83
|
+
export declare const HOOK_KILL_GRACE_MS = 1000;
|
|
35
84
|
/**
|
|
36
85
|
* 本仓对契约每一种 hook 条目类型的表态 —— **一张表**:受理面({@link parseHooksConfig})与执行侧({@link RunnableHookEntry},以及每个按条目类型分派的臂)读的都是它。
|
|
37
86
|
*
|
|
@@ -52,26 +101,38 @@ export type SupportedHookEntryType = {
|
|
|
52
101
|
}[HookEntryType];
|
|
53
102
|
/** 本仓会真跑的条目类型闭集(契约 {@link HOOK_ENTRY_TYPES} 的次序)—— 拒句 `supported: …` 的词表与 {@link RunnableHookEntry} 的类型都出自这一张表。 */
|
|
54
103
|
export declare const SUPPORTED_HOOK_ENTRY_TYPES: readonly SupportedHookEntryType[];
|
|
55
|
-
/** 本 runner 会真跑的条目(契约 `HookEntry` 取表态为 `true`
|
|
56
|
-
export type RunnableHookEntry =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
104
|
+
/** 本 runner 会真跑的条目(契约 `HookEntry` 取表态为 `true` 的那几型;command 条目另带本仓读的两只 wire 键 `args` / `plugin`,见 `command-spawn.ts`)。 */
|
|
105
|
+
export type RunnableHookEntry = {
|
|
106
|
+
[T in SupportedHookEntryType]: T extends "command" ? RunnableCommandHookEntry : Extract<HookEntry, {
|
|
107
|
+
type: T;
|
|
108
|
+
}>;
|
|
109
|
+
}[SupportedHookEntryType];
|
|
110
|
+
/** 一个匹配器组,条目只含 {@link RunnableHookEntry}。`source` = 这一组是谁写的(wire 键,闭集见 `hook-source.ts`;缺席 = 非托管),决定它在哪一相跑。 */
|
|
60
111
|
export interface RunnableMatcherGroup {
|
|
61
112
|
matcher?: string;
|
|
113
|
+
source?: HookGroupSource;
|
|
62
114
|
hooks: RunnableHookEntry[];
|
|
63
115
|
}
|
|
64
|
-
/** 受理面通过后的 hooks 配置:每个事件下的条目都是本仓会跑的型 —— 执行侧({@link
|
|
116
|
+
/** 受理面通过后的 hooks 配置:每个事件下的条目都是本仓会跑的型 —— 执行侧({@link createSettingsHooksRegistration})只收这一型,「不认识的类型」到不了它手里。 */
|
|
65
117
|
export type RunnableHooksConfig = Partial<Record<HookEventName, RunnableMatcherGroup[]>>;
|
|
66
118
|
/** 分类器点名的一块(被剔的块或整份被拒的理由):码 + 坐标 + 坏字段。 */
|
|
67
119
|
export type HooksRefusalPiece = HooksDroppedPiece | HooksRejection;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
120
|
+
/**
|
|
121
|
+
* {@link parseHooksConfig} 的返回:受理 ⇒ `config`;拒 ⇒ `issue`(判决数据,受理门经 {@link buildHooksRefusal} 铸 400 体的句子与机读位)+ `error`(同一只铸点给的句子,
|
|
122
|
+
* resume 防御路径用它 warn)+ 拒因来自**分类器**时的 `pieces`(它点名的每一块,文档序;本仓自己的拒 —— 条目类型 / 服务侧上限 —— 不带这一位。一次性迁移读它按名剥键
|
|
123
|
+
* (`stored-request-hooks-m20.ts`)—— 迁移不另起读者)。
|
|
124
|
+
*/
|
|
125
|
+
export type ParseHooksConfigResult = {
|
|
126
|
+
readonly config: RunnableHooksConfig;
|
|
127
|
+
readonly issue?: undefined;
|
|
128
|
+
readonly error?: undefined;
|
|
129
|
+
readonly pieces?: undefined;
|
|
130
|
+
} | {
|
|
131
|
+
readonly config?: undefined;
|
|
132
|
+
readonly issue: HooksConfigIssue;
|
|
133
|
+
readonly error: string;
|
|
134
|
+
readonly pieces?: readonly HooksRefusalPiece[];
|
|
135
|
+
};
|
|
75
136
|
/**
|
|
76
137
|
* 🔴 **S-924 → S-995(clay [ref] ③;八病审计 SG H6-d;test 7.112.0 验收 OBS ①)—— 工具事件的 matcher 选中了工具**别名**、却选不中它的正名 ⇒ fresh 提交面响亮拒。**
|
|
77
138
|
*
|
|
@@ -80,14 +141,14 @@ export interface ParseHooksConfigResult {
|
|
|
80
141
|
* ⇒ **永不命中、一句话都没有**(post 两事件自 7.107.0 / core 7.36.0 起如此,PreToolUse 一直如此)。静默不命中 = 写的人以为在生效的 hook
|
|
81
142
|
* 其实没跑,硬破坏三句要求的「响亮」没有着落。7.112.0(S-924)只拒**字面**别名;同一个错误写成 `^ListPeers$` / `ListPeers.*` / `(ListPeers)` 照样 200(S-995)。
|
|
82
143
|
*
|
|
83
|
-
* 规则(一条;字面形是它的特例):{@link
|
|
144
|
+
* 规则(一条;字面形是它的特例):{@link hooksMatcherIssue} 对 core 静态目录里**每一条退役别名**问「这只 matcher 选不选它 / 选不选它的正名」:
|
|
84
145
|
* matcher **命中别名 ∧ 不命中它的正名** ⇒ `400 request.field_invalid`(`admission.ts` fresh 门)。「选不选」**只有一只读法**:契约包的 `hookMatcherSelects`
|
|
85
|
-
* (名字表 / 空 / `*` / 正则三形都由它答;正则形**不锚定**,与壳同形;运行期 {@link hookMatcherMatches}
|
|
146
|
+
* (名字表 / 空 / `*` / 正则三形都由它答;正则形**不锚定**,与壳同形;运行期 {@link hookMatcherMatches} 问的也是它 —— 经同一只带预算的求值口,本仓不留副本)。按**一条顺序**判(两档共用,7.114.0 修复轮):
|
|
86
147
|
* ① **长度上限**:超 {@link MAX_MATCHER_EVAL_CHARS} 的 matcher 两档都不读 ⇒ 未判(reason = oversize);
|
|
87
148
|
* ② **形只问契约包的 `hookMatcherForm`**(与 `hookMatcherSelects` 同一只解析步,本仓不留形判),闭集三词、两档一张表:
|
|
88
149
|
* · `literal`(缺席 / 空 / `*` / 名字表形;契约不编、不跑调用方的正则)⇒ 两档都**直接问契约函数**、**不占求值预算**;
|
|
89
150
|
* · `regex` ⇒ **`"regex"` 档**(hooks 会被采纳的车道,`taskHooksHonored`)把**同一只契约函数**经 `node:vm` 的 `timeout` 带**每次求值各一份固定预算**调用({@link matcherSelectsWithin};
|
|
90
|
-
*
|
|
151
|
+
* 每次求值的额度**不共享**、不随同一受理里别的 matcher 缩水、这一份不读钟 —— S-1455;另有一只受理总额度,见下「预算与结局」);**超时 ⇒ 这只 matcher 是灾难回溯 ⇒ `400 request.field_invalid` 拒**(见下「预算与结局」);
|
|
91
152
|
* **`"literal"` 档**(多租户车道:hooks 整只被 resolveSpec 忽略)= **不适用**:该车道没有被守的对象(hooks 不装配),不判、不算未判、不登记 —— **零调用方正则执行**
|
|
92
153
|
* (7.112.0 的字面判保留:裸 `ListPeers` / `Read|ListPeers` 照旧 400);
|
|
93
154
|
* · `invalid`(编不过)⇒ `"regex"` 档 = **`400 request.field_invalid` 拒**(判决 `invalid_regex`,见下「预算与结局」;不进求值 —— 形判已答「读不了」);`"literal"` 档 = 不适用(同上)。
|
|
@@ -111,23 +172,29 @@ export interface ParseHooksConfigResult {
|
|
|
111
172
|
* · **不在本规则内**:两边都选不中的 matcher(大小写错 / 词内空白 / 纯错字;目录之外的 MCP / 嵌入方工具名同样「选不中目录里任何名」,受理面无从区分错字与它们)=
|
|
112
173
|
* **「选不到目录里任何名」另一类,候设计(台账另立号,主会话裁)**。
|
|
113
174
|
*
|
|
114
|
-
* 🔴 **预算与结局(S-1455
|
|
115
|
-
* {@link
|
|
116
|
-
* 同一份设置忙机偶尔被收下、闲机恒 400)
|
|
175
|
+
* 🔴 **预算与结局(S-1455 / S-1503;良性设置的受理结局只取决于配置,不取决于机器忙闲)**:regex 档每一次求值(一只正则形 matcher 对一个名字的一次问)各拿**一份固定的墙钟预算**
|
|
176
|
+
* {@link ADMISSION_MATCHER_BUDGET}`.budgetMs`(vm `timeout`,从这次求值开始计)—— **不共享**(此前一次受理共用 100 ms,忙机上会被吃光 ⇒
|
|
177
|
+
* 同一份设置忙机偶尔被收下、闲机恒 400),额度不随同一受理里 matcher 的个数缩水,这一份**不读钟**(没有「截止线」可被调度停顿越过)。预算只防**灾难回溯**:
|
|
117
178
|
* 良性求值 ~0.1 ms,灾难形(指数级)吃满预算也跑不完 —— 两者相差数个数量级,取值给足余量(1 000 ms),让忙机上的调度停顿也跨不过这条线。
|
|
179
|
+
* **另有一只受理总额度**(S-1503;同一张表的 `.totalMs`,5 000 ms):每次求值的额度界得住「一只 matcher 不会无限算」,界不住「刚好低于它的病态 matcher × 别名数 × 2 × 组数」(3 事件 × 16 组 × 1 别名 × 2 = 96 次,
|
|
180
|
+
* 每次 0.99 s 就是 96 s 的事件循环占用)。一次受理里所有**已完成**的正则形求值的耗时之和(一只单调钟逐次累加;字面形与非工具事件不进 vm、不计)一旦**超过**总额度 ⇒ 同码 `400`,
|
|
181
|
+
* `detail.reason = budget_exceeded`({@link BudgetExceededMatcherIssue},点名越线的那一组与总额度)。单次超时先到、先判 `over_budget`(更具体)。一次受理的最坏占用 ≤ 总额度 + 一次求值的额度。
|
|
182
|
+
* 总额度这一只读钟,但良性设置离它近三个数量级(一份最大的良性配置 —— 3 工具事件 × 16 组 —— 总耗时在毫秒级),所以良性设置的结局仍不随机器忙闲翻转;只有求值总耗时逼近总额度的病态设置才可能落在边界两侧。
|
|
118
183
|
* **超时 ⇒ 确定拒绝**:`400 request.field_invalid`({@link OverBudgetMatcherIssue}),句子点名**哪一只 matcher**(事件 + 组下标,不回显原字节)与**预算**;**按配置顺序遇到的第一只超时 / 命中别名的 matcher 定结局**。
|
|
119
|
-
* 为什么是拒绝而不是放行:运行期 {@link hookMatcherMatches}
|
|
120
|
-
*
|
|
184
|
+
* 为什么是拒绝而不是放行:运行期 {@link hookMatcherMatches} 在**每次工具调用**里问同一只带预算的口(S-1017 起;此前是裸调、无预算)—— 一只在受理面连目录里几个短名字都求不完的 matcher 放进去,
|
|
185
|
+
* 运行期每次调用都要白烧一整份预算(超预算的组按选中处理并登记,守卫不丢,但每次调用卡一份预算);放行 = 把一个确定的坏配置推迟成运行期每次调用的卡顿。这条拒不是「越界即拒」的新检测面:被拒的恰是**无法被求值**的 matcher,与 `hook_matcher_invalid`(编不过 ⇒ 该组不跑)同属「这只 matcher 不可用」,
|
|
121
186
|
* 只是编不过的运行期自己安全地不跑它,跑不完的不行。
|
|
122
|
-
*
|
|
187
|
+
* 总用时的上界:首个超时 / 总额度越线即拒、不再往下求值;未超时的求值各自 < 预算,其和 ≤ 总额度 + 一次求值的额度。regex 档只在单用户车道(`taskHooksHonored`,hooks 会装配的那条;调用方就是进程属主,本来就能配任意 `command` 钩子)运行,
|
|
123
188
|
* 多租户车道走 literal 档、零调用方正则执行 —— 受理面的 DoS 面不因此重开。
|
|
124
189
|
*
|
|
125
190
|
* 🔴 **编不过的正则 = 确定的拒绝**(S-1455 收尾;与超预算同类 —— 确定性的坏配置,结局只取决于配置):`"regex"` 档遇契约 `hookMatcherForm` 答 `invalid`(或求值时契约函数答 `"invalid"`)⇒
|
|
126
|
-
* `400 request.field_invalid`({@link InvalidRegexMatcherIssue}),句子点名**哪一只 matcher**(事件 + 组下标 + 原文〔超 {@link MATCHER_ECHO_CHARS} 字符截断〕)与引擎的编译错误句;机读位 `detail`
|
|
191
|
+
* `400 request.field_invalid`({@link InvalidRegexMatcherIssue}),句子点名**哪一只 matcher**(事件 + 组下标 + 原文〔超 {@link MATCHER_ECHO_CHARS} 字符截断〕)与引擎的编译错误句;机读位 `detail` 只有闭集三键 + 坐标 `path`(那一组的 `matcher`)。
|
|
127
192
|
* 受理面与运行期问**同一只判**:契约把"编不过"答成 `invalid`,运行期 {@link hookMatcherMatches} 因此不跑那一组(并记 `hook_matcher_invalid`),受理面因此拒 —— 本仓不加第二个判官
|
|
128
193
|
* (编译错误句只是诊断文字,见 {@link matcherCompileSentence};拒不拒由契约函数一个人说了算)。为什么是拒绝而不是放行:放行 = 用户以为在生效的钩子(含会真拦的 PreToolUse deny 钩子)
|
|
129
194
|
* 在每次工具调用里都**悄悄不跑**,硬破坏三句要求的「响亮」没有着落;`"literal"` 档(多租户车道,hooks 不装配)= 不适用,与正则形同一行表。resume 重放不判(照旧采纳、该组不跑)。
|
|
130
|
-
* 🔴
|
|
195
|
+
* 🔴 **形判对所有事件同一判**(S-1472;此前只守三个工具事件,写在 `StopFailure` 的 `error` 词 / `PreCompact`·`PostCompact` 的 `trigger` 词上的坏 matcher 受理、运行期该组不跑并记 `hook_matcher_invalid`;壳跑的事件〔如 `SessionStart`〕由壳按同一只契约函数处置):
|
|
196
|
+
* 「这一串是不是一只读得了的 matcher」是**串的形**问题,不是事件的问题 —— `hookMatcherForm` 答 `invalid` ⇒ `400`,**不论写在 33 个契约事件里的哪一个**(含 matcher 被忽略的 `UserPromptSubmit` / `Stop` / `PostToolBatch`:规则里没有「事件类」这个维度,
|
|
197
|
+
* 也就没有一张按事件类分档的表)。死别名问(「选中别名而选不中正名」)只对 matcher 匹配**工具 wire 名**的事件(上面的三个工具事件)才问 —— 别的事件上 matcher 匹配的不是工具名,没有「别名」可言;这一问不占别的事件的求值预算。
|
|
131
198
|
*
|
|
132
199
|
* 🔴 **「未判」臂过 `recordFailOpen`**(F 类 tag `MATCHER_UNJUDGED_TAG`;主会话裁,CLAUDE.md「合法 F 类回退走登记 tag」):一只 matcher 没能被判 ⇒ 照旧受理 + 登记一笔,
|
|
133
200
|
* detail = `event=… reason=… matcherChars=…`(**不带 matcher 原字节**,S-716 姿势)。现在只剩一种 reason:
|
|
@@ -139,32 +206,52 @@ export interface ParseHooksConfigResult {
|
|
|
139
206
|
* 错误句:死别名与超预算两形只回显**目录里的**别名与正名 / 位置(闭集字符串与数字),不回显调用方的原字节(S-716 姿势);编不过一形**点名那只 matcher 的原文**(截断到 {@link MATCHER_ECHO_CHARS} 字符)与引擎的编译错误句 ——
|
|
140
207
|
* 调用方要改的就是这一串,且它本来就是调用方自己送来的;机读位 `detail` 仍不带这两段。
|
|
141
208
|
*
|
|
142
|
-
* 🔴 **判决是数据,句子与体的机读位同出一只铸点**(S-1025;client-core 请托,additive):{@link
|
|
143
|
-
* {@link OverBudgetMatcherIssue} 的 event / groupIndex / budgetMs,{@link InvalidRegexMatcherIssue} 的 event / groupIndex〔+ 句子用的 matcher / compileError〕,以 `reason` 区分)而不是句子;{@link
|
|
209
|
+
* 🔴 **判决是数据,句子与体的机读位同出一只铸点**(S-1025;client-core 请托,additive):{@link hooksMatcherIssue} 回 {@link HooksMatcherIssue}(闭集四形:{@link DeadToolMatcherIssue} 的 event / alias / canonical,
|
|
210
|
+
* {@link OverBudgetMatcherIssue} 的 event / groupIndex / budgetMs,{@link BudgetExceededMatcherIssue} 的 event / groupIndex / totalMs,{@link InvalidRegexMatcherIssue} 的 event / groupIndex〔+ 句子用的 matcher / compileError〕,以 `reason` 区分)而不是句子;{@link buildHooksRefusal} 是**唯一**把它铸成拒句 + `field` + `detail` 的函数(配置读者的拒同经它),
|
|
144
211
|
* 受理门只取它的返回、**不解析句子**。体上多出的两键让三端不必解析英文就能把这只拒与普通提交失败分流、提示用户改 matcher;死别名那一句逐字同 7.114.0、零新码。
|
|
145
212
|
*/
|
|
146
213
|
/** 超此长度的 matcher 不在受理面读(两档同一个上限;未判,reason = oversize)。与 {@link MAX_HOOK_COMMAND_CHARS} 同量纲的服务侧防线:真实 matcher(精确名 / 交替 / `mcp__.*`)远在其内;目录全部工具名交替 ~0.5 KiB。 */
|
|
147
214
|
export declare const MAX_MATCHER_EVAL_CHARS = 8192;
|
|
148
215
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
216
|
+
* 正则形 matcher 的**求值预算表**(毫秒)—— 两个数同出这一张表,判据与测试注入都不另持第二份(名字里的 `ADMISSION` 是历史:`budgetMs` 自 S-1017 起**受理面与运行期共用**,`totalMs` 只属受理面):
|
|
217
|
+
* · `budgetMs` = **每一次**正则形求值各一份的固定墙钟额度(S-1455;vm `timeout`)。**不共享、额度不随受理里别的 matcher 缩水、这一份不读钟**;字面形不占它。
|
|
218
|
+
* **运行期读同一个数**(S-1017;{@link hookMatcherMatches} 每次现读本对象):运行期每次工具调用对正则形 matcher 的每次求值也各拿这一份,超了 ⇒ 该组按选中处理并登记,不另设运行期额度。
|
|
219
|
+
* 良性求值 ~0.1 ms;灾难回溯(指数级)吃满它也跑不完 ⇒ 这只 matcher 被 400 拒(`over_budget`)。取值是「良性求值之上数个数量级」的余量 —— 小了,忙机上的调度停顿会把良性 matcher 读成灾难(受理结局随负载翻转,正是 S-1455 要根除的形)。
|
|
220
|
+
* · `totalMs` = **一次受理**里所有已完成的正则形求值的**耗时之和**的总额度(S-1503):之和一旦超过它 ⇒ `400`,`detail.reason = budget_exceeded`。每次求值的额度只界住「一只 matcher 不会无限算」,
|
|
221
|
+
* 界不住「刚好低于它的病态 matcher × 别名数 × 2 × 组数」—— 今天 3 事件 × 16 组 × 1 别名 × 2 = 96 次,每次 0.99 s 可占住事件循环 96 s(单用户车道上持 token 的调用方)。
|
|
222
|
+
* 总额度读一只单调钟、**只累加已完成求值的耗时**(`performance.now`),求值本身不被它缩短(每次求值的额度仍是固定的 `budgetMs`),所以一次受理最坏占用 ≤ `totalMs` + `budgetMs`。
|
|
223
|
+
* 取值同一条余量律:一份最大的良性配置(3 工具事件 × 16 组)的总耗时实测约 9 ms,离 `totalMs` 近三个数量级 —— 良性设置的结局不随机器忙闲翻转;只有求值总耗时逼近 `totalMs` 的病态设置才可能。
|
|
151
224
|
*/
|
|
152
|
-
export declare const
|
|
153
|
-
|
|
225
|
+
export declare const ADMISSION_MATCHER_BUDGET: {
|
|
226
|
+
readonly budgetMs: 1000;
|
|
227
|
+
readonly totalMs: 5000;
|
|
228
|
+
};
|
|
229
|
+
/** 拒句里回显的 matcher 原文 / 引擎编译错误句、运行期 `hook_matcher_invalid` 日志行的 `matcher` 字段,各自的字符上限(都过回显的一只口径 `echoCallerText`,截断记号 `…`;S-1455 收尾 / S-1735)。真实 matcher 远在其内;上限只防一只 8 KiB 的坏 matcher 把拒句撑成一屏。 */
|
|
154
230
|
export declare const MATCHER_ECHO_CHARS = 200;
|
|
231
|
+
/** 运行期 `hook_entries_skipped` 日志行的 `if` 字段(配置写的权限规则表达式)的字符上限;与 matcher 同口径(`echoCallerText`),截断记号 `…`。 */
|
|
232
|
+
export declare const IF_ECHO_CHARS = 200;
|
|
155
233
|
/** 受理面判据的求值深度(见上头注):`"regex"` = 契约字面形直接问、正则形带预算问同一只契约函数;`"literal"` = 7.112.0 的字面判(只判契约字面形,零调用方正则执行;正则形 / 编不过的形不适用)。 */
|
|
156
234
|
export type MatcherEvalDepth = "regex" | "literal";
|
|
157
235
|
/**
|
|
158
|
-
* **仅供测试注入**的求值预算(生产调用点不传 ⇒
|
|
159
|
-
*
|
|
236
|
+
* **仅供测试注入**的求值预算(生产调用点不传 ⇒ 两个数都读 {@link ADMISSION_MATCHER_BUDGET},钟 = `performance.now`)。让「灾难形被拒」「总额度被推过」这类格子能用小额度或假钟跑,不必等满生产预算。
|
|
237
|
+
* 键名与那张表一致:`budgetMs` = 每次求值的额度,`totalMs` = 受理总额度;`now` = 总额度累加用的钟(缺席 ⇒ `performance.now`)—— 每次求值前后各读一次,差即这次求值的耗时。
|
|
238
|
+
* 每次求值的额度是 vm `timeout`、不读钟;钟只服务总额度。字面形求值与非工具事件不进 vm、**不读钟**。
|
|
160
239
|
*/
|
|
161
240
|
export interface MatcherEvalBudget {
|
|
162
241
|
readonly budgetMs?: number;
|
|
242
|
+
readonly totalMs?: number;
|
|
243
|
+
readonly now?: () => number;
|
|
163
244
|
}
|
|
164
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* 一次 matcher 求值的答案(闭集四词;**受理面与运行期同一张**):`true` 选中 · `false` 不选 · `"invalid"` 契约答编不过 · `"over_budget"` 这一次求值没在预算内结束(灾难回溯)。
|
|
247
|
+
* 处置它的 switch 都是穷举的(加一词 = 这里加、每个处置点编译红)。
|
|
248
|
+
*/
|
|
249
|
+
export type MatcherAnswer = boolean | "invalid" | "over_budget";
|
|
250
|
+
/** 一条受理面判决(纯数据)· 死别名:`event` 事件下第 `groupIndex` 组(从 0 起)的 matcher 选中了退役别名 `alias`、却选不中它的正名 `canonical`。`alias` / `canonical` 恒取自 core 静态目录(闭集字符串,不含调用方原字节)。 */
|
|
165
251
|
export interface DeadToolMatcherIssue {
|
|
166
252
|
readonly reason: "dead_alias";
|
|
167
253
|
readonly event: HookEventName;
|
|
254
|
+
readonly groupIndex: number;
|
|
168
255
|
readonly alias: string;
|
|
169
256
|
readonly canonical: string;
|
|
170
257
|
}
|
|
@@ -175,6 +262,13 @@ export interface OverBudgetMatcherIssue {
|
|
|
175
262
|
readonly groupIndex: number;
|
|
176
263
|
readonly budgetMs: number;
|
|
177
264
|
}
|
|
265
|
+
/** 一条受理面判决(纯数据)· 受理总额度用尽(S-1503):`event` 事件下第 `groupIndex` 组(从 0 起)的 matcher 求完之后,本次受理里所有已完成正则形求值的耗时之和超过了 `totalMs`。三键都是闭集 / 数字,不含调用方原字节。 */
|
|
266
|
+
export interface BudgetExceededMatcherIssue {
|
|
267
|
+
readonly reason: "budget_exceeded";
|
|
268
|
+
readonly event: HookEventName;
|
|
269
|
+
readonly groupIndex: number;
|
|
270
|
+
readonly totalMs: number;
|
|
271
|
+
}
|
|
178
272
|
/**
|
|
179
273
|
* 一条受理面判决(纯数据)· 正则编不过(S-1455 收尾):`event` 事件下第 `groupIndex` 组(从 0 起)的 matcher 在契约包的读法下答 `invalid`。
|
|
180
274
|
* `matcher` = 那只 matcher 的原文、`compileError` = 引擎的编译错误句(各自截到 {@link MATCHER_ECHO_CHARS} 字符):**只供铸拒句用**,机读位 `detail` 不带它们。
|
|
@@ -186,68 +280,175 @@ export interface InvalidRegexMatcherIssue {
|
|
|
186
280
|
readonly matcher: string;
|
|
187
281
|
readonly compileError: string;
|
|
188
282
|
}
|
|
189
|
-
/** 受理面判据的判决(
|
|
190
|
-
export type
|
|
191
|
-
/**
|
|
192
|
-
|
|
283
|
+
/** 受理面判据的判决(闭集四形,`reason` 区分;每一形都是 400 拒):死别名 · 单次求值超预算 · 受理总额度用尽 · 正则编不过。 */
|
|
284
|
+
export type HooksMatcherIssue = DeadToolMatcherIssue | OverBudgetMatcherIssue | BudgetExceededMatcherIssue | InvalidRegexMatcherIssue;
|
|
285
|
+
/**
|
|
286
|
+
* `settings.hooks` 受理面读者({@link parseHooksConfig})的拒判决(纯数据;闭集按 `reason` 分形,与 {@link HooksMatcherIssue} 合起来是这一面**全部**的拒):
|
|
287
|
+
* · 分类器点名的一块({@link HooksPieceIssue}):`reason` = 契约包的码(`HOOKS_REJECTION_CODES` / `HOOKS_DROPPED_PIECE_CODES`,原样、不改拼法)、`path` = 分类器的坐标、`key` = 这一块上让它坏的那个键;
|
|
288
|
+
* · 本仓不执行的条目类型({@link UnsupportedEntryTypeIssue});
|
|
289
|
+
* · 服务侧上限({@link HooksCapIssue}):`reason` = 撞帽的量纲(`over_cap` 条数 / `too_long` 字符数,与请求体其余各处的帽同一张表);
|
|
290
|
+
* · 分类器说拒却一块都没点名({@link UnnamedHooksRefusalIssue}:契约漂移,fail-closed)。
|
|
291
|
+
*/
|
|
292
|
+
export interface HooksPieceIssue {
|
|
293
|
+
readonly reason: HooksDroppedPieceCode | HooksRejectionCode;
|
|
294
|
+
readonly path: ConfigPath;
|
|
295
|
+
readonly key?: string;
|
|
296
|
+
}
|
|
297
|
+
/** 本仓不执行的条目类型(`path` 指那一条的 `type`)。 */
|
|
298
|
+
export interface UnsupportedEntryTypeIssue {
|
|
299
|
+
readonly reason: "unsupported_entry_type";
|
|
300
|
+
readonly path: ConfigPath;
|
|
301
|
+
readonly type: HookEntryType;
|
|
302
|
+
}
|
|
303
|
+
/** hooks 的服务侧上限只有条数与字符数两种量纲(没有字节帽):`reason` 的词随量纲从 {@link LIMIT_REASONS} 取,本面的读者穷举读这两个词。 */
|
|
304
|
+
type HooksCapMeasure = Extract<LimitMeasure, "entries" | "characters">;
|
|
305
|
+
type HooksCapReason = (typeof LIMIT_REASONS)[HooksCapMeasure];
|
|
306
|
+
/** 服务侧上限的哪一条(只供铸句;机读位只出 `reason` / `path` / `count` / `cap`)。帽的量纲与数在 {@link HOOKS_CAPS} 一张表。 */
|
|
307
|
+
type HooksCap = "matcher_groups" | "event_entries" | "command" | "url" | "headers" | "header_chars" | "allowed_env_vars" | "plugin";
|
|
308
|
+
/**
|
|
309
|
+
* 服务侧上限撞帽:`path` = 撞帽处的坐标(组数 ⇒ 那个事件;一个事件的条目总数 ⇒ 第一条超出的条目;命令 / URL ⇒ 那个字段;header 条数 / 总字符数 ⇒ `headers`;
|
|
310
|
+
* `allowedEnvVars` ⇒ 那个字段),`count` = 送来的量,`cap` = 帽,`reason` 由量纲定。
|
|
311
|
+
*/
|
|
312
|
+
export interface HooksCapIssue {
|
|
313
|
+
readonly reason: HooksCapReason;
|
|
314
|
+
readonly limit: HooksCap;
|
|
315
|
+
readonly event: HookEventName;
|
|
316
|
+
readonly path: ConfigPath;
|
|
317
|
+
readonly count: number;
|
|
318
|
+
readonly cap: number;
|
|
319
|
+
}
|
|
320
|
+
/** 分类器说「不是 loaded」却一块都没点名 / `loaded` 却没有 `hooks`:契约漂移 —— 响亮地拒(fail-closed),不把「说不出理由」当受理。 */
|
|
321
|
+
export interface UnnamedHooksRefusalIssue {
|
|
322
|
+
readonly reason: "unnamed_refusal";
|
|
323
|
+
readonly path: ConfigPath;
|
|
324
|
+
}
|
|
325
|
+
/** 本仓读的 wire 键(契约分类器不认、会剥掉的那三只)。 */
|
|
326
|
+
export type HooksWireKey = "source" | "plugin" | "args";
|
|
327
|
+
/**
|
|
328
|
+
* 本仓的 wire 键形错(`path` 指那只键:组的 `source` / command 条目的 `plugin` / `args`)。这三只键分类器不认(它对未知键一律剥除),
|
|
329
|
+
* 由 {@link parseHooksConfig} 在分类器装上的同一坐标上读 —— 形错 = 拒,**不**再被静默剥掉(剥掉 `source` = 托管组落进非托管道;剥掉 `args` = exec 形只剩可执行名)。
|
|
330
|
+
*/
|
|
331
|
+
export interface HooksWireKeyIssue {
|
|
332
|
+
readonly reason: "wire_key_invalid";
|
|
333
|
+
readonly path: ConfigPath;
|
|
334
|
+
readonly key: HooksWireKey;
|
|
335
|
+
}
|
|
336
|
+
/** 受理面 hooks 配置读者的拒判决。 */
|
|
337
|
+
export type HooksConfigIssue = HooksPieceIssue | UnsupportedEntryTypeIssue | HooksCapIssue | UnnamedHooksRefusalIssue | HooksWireKeyIssue;
|
|
338
|
+
/** `settings.hooks` 这一面的全部拒判决:配置读者的({@link HooksConfigIssue})与 fresh 提交面 matcher 判据的({@link HooksMatcherIssue})。 */
|
|
339
|
+
export type HooksIssue = HooksConfigIssue | HooksMatcherIssue;
|
|
340
|
+
/**
|
|
341
|
+
* 400 体上的 `detail`(按 `reason` 分形;每一形都带 `path` —— 判决所在的坐标,契约分类器的段形,相对请求体的 `settings` 对象,用户文本段过 `outgoingPath`)。
|
|
342
|
+
* matcher 四形另带它们各自的键(`event` / `alias` / `canonical`,`event` / `groupIndex` / `budgetMs`,`event` / `groupIndex` / `totalMs`,`event` / `groupIndex`)。
|
|
343
|
+
*/
|
|
344
|
+
export type HooksRefusalDetail = {
|
|
345
|
+
readonly reason: "dead_alias";
|
|
346
|
+
readonly event: HookEventName;
|
|
347
|
+
readonly alias: string;
|
|
348
|
+
readonly canonical: string;
|
|
349
|
+
readonly path: ConfigPath;
|
|
350
|
+
} | {
|
|
351
|
+
readonly reason: "over_budget";
|
|
352
|
+
readonly event: HookEventName;
|
|
353
|
+
readonly groupIndex: number;
|
|
354
|
+
readonly budgetMs: number;
|
|
355
|
+
readonly path: ConfigPath;
|
|
356
|
+
} | {
|
|
357
|
+
readonly reason: "budget_exceeded";
|
|
358
|
+
readonly event: HookEventName;
|
|
359
|
+
readonly groupIndex: number;
|
|
360
|
+
readonly totalMs: number;
|
|
361
|
+
readonly path: ConfigPath;
|
|
362
|
+
} | {
|
|
363
|
+
readonly reason: "invalid_regex";
|
|
364
|
+
readonly event: HookEventName;
|
|
365
|
+
readonly groupIndex: number;
|
|
366
|
+
readonly path: ConfigPath;
|
|
367
|
+
} | {
|
|
368
|
+
readonly reason: HooksDroppedPieceCode | HooksRejectionCode;
|
|
369
|
+
readonly path: ConfigPath;
|
|
370
|
+
readonly key?: string;
|
|
371
|
+
} | {
|
|
372
|
+
readonly reason: "unsupported_entry_type";
|
|
373
|
+
readonly path: ConfigPath;
|
|
374
|
+
readonly type: HookEntryType;
|
|
375
|
+
} | {
|
|
376
|
+
readonly reason: HooksCapReason;
|
|
377
|
+
readonly path: ConfigPath;
|
|
378
|
+
readonly count: number;
|
|
379
|
+
readonly cap: number;
|
|
380
|
+
} | {
|
|
381
|
+
readonly reason: "unnamed_refusal";
|
|
382
|
+
readonly path: ConfigPath;
|
|
383
|
+
} | {
|
|
384
|
+
readonly reason: "wire_key_invalid";
|
|
385
|
+
readonly path: ConfigPath;
|
|
386
|
+
readonly key: HooksWireKey;
|
|
387
|
+
};
|
|
388
|
+
/** {@link buildHooksRefusal} 的返回(纯数据):拒句 + 400 体上的两个机读位。`field` 恒为字面 `"settings.hooks"`。 */
|
|
389
|
+
export interface HooksRefusal {
|
|
193
390
|
readonly message: string;
|
|
194
391
|
readonly field: "settings.hooks";
|
|
195
|
-
readonly detail:
|
|
196
|
-
readonly reason: "dead_alias";
|
|
197
|
-
readonly event: HookEventName;
|
|
198
|
-
readonly alias: string;
|
|
199
|
-
readonly canonical: string;
|
|
200
|
-
} | {
|
|
201
|
-
readonly reason: "over_budget";
|
|
202
|
-
readonly event: HookEventName;
|
|
203
|
-
readonly groupIndex: number;
|
|
204
|
-
readonly budgetMs: number;
|
|
205
|
-
} | {
|
|
206
|
-
readonly reason: "invalid_regex";
|
|
207
|
-
readonly event: HookEventName;
|
|
208
|
-
readonly groupIndex: number;
|
|
209
|
-
};
|
|
392
|
+
readonly detail: HooksRefusalDetail;
|
|
210
393
|
}
|
|
211
394
|
/**
|
|
212
|
-
* 判决 → 拒句 +
|
|
213
|
-
*
|
|
395
|
+
* 判决 → 拒句 + 机读位 —— `settings.hooks` 这一面**拒句与机读位的唯一铸点**(配置读者的拒与 fresh 提交面的 matcher 拒同经这里;受理门 `admission.ts` 用返回值填 400 体,
|
|
396
|
+
* 不从句子里反解字段)。句子:死别名逐字 = 7.114.0 的那一句(`test/hooks-alias-matcher-s995.test.ts` R7 冻结);超预算点名**哪一只**(事件 + 组下标 + `matcher`)与**预算**,不回显 matcher 原字节(S-716 姿势);
|
|
397
|
+
* 分类器的一块 = 坐标 + 码 + 释义(+ 坏键);服务侧上限的几句逐字 = 7.131.0。`reason` 闭集穷举(多一形 = 这里编译红)。
|
|
214
398
|
*/
|
|
215
|
-
export declare function
|
|
399
|
+
export declare function buildHooksRefusal(issue: HooksIssue): HooksRefusal;
|
|
216
400
|
/**
|
|
217
|
-
* fresh 提交面专用判据(S-924 / S-995 / S-1455)
|
|
218
|
-
* 拒句与 400 体的机读位由 {@link
|
|
401
|
+
* fresh 提交面专用判据(S-924 / S-995 / S-1455 / S-1472 / S-1503):配置里第一条「该拒」的 matcher 的判决数据({@link HooksMatcherIssue}):「永远打不中」(死别名,只属工具事件)· 「编不过」(任何事件)· 「单次求值超预算」(灾难回溯)· 「受理总额度用尽」;没有 ⇒ undefined。
|
|
402
|
+
* 拒句与 400 体的机读位由 {@link buildHooksRefusal} 从这份数据铸(S-1025)。**按配置顺序(事件 → 组)遇到的第一条定结局**;良性设置的结局只取决于配置(每次求值的额度固定、不共享;总额度离良性设置近三个数量级,见头注「预算与结局」)。
|
|
219
403
|
* 入参是 {@link parseHooksConfig} 已校验过的配置;`depth` 由调用点按车道定(见头注:`taskHooksHonored(config) ? "regex" : "literal"`)。
|
|
220
404
|
* `budget` **仅供测试注入**({@link MatcherEvalBudget});生产调用点只传前两个实参。
|
|
221
405
|
* **只有 `admission.ts` 的 fresh 提交门调它** —— resume 重放不调(理由见上面的头注)。未判的 matcher 过 `recordFailOpen`(tag `MATCHER_UNJUDGED_TAG`);超预算的不是未判,是拒。
|
|
222
406
|
*/
|
|
223
|
-
export declare function
|
|
224
|
-
/**
|
|
407
|
+
export declare function hooksMatcherIssue(config: RunnableHooksConfig, depth: MatcherEvalDepth, budget?: MatcherEvalBudget): HooksMatcherIssue | undefined;
|
|
408
|
+
/**
|
|
409
|
+
* 坐标的出门段:事件名等键段是用户文本 ⇒ 先过 {@link outgoingPath}(凭据形不原样回显),每个串段再过调用方串的唯一回显口径(`caller-text-echo.ts`:剥控制 / 双向字符、截到 64 字 + …)——
|
|
410
|
+
* 一只 100 KB 的未知键不把拒体撑大、也不在句子里夹看不见的字符。400 体的 `detail.path` 与拒句里的坐标读的都是它。
|
|
411
|
+
*/
|
|
412
|
+
export declare function hooksOutgoingPath(path: ConfigPath): ConfigPath;
|
|
413
|
+
/** 坐标出门形:`settings.` + 契约包唯一的 stringify 点({@link formatConfigPath})作用在 {@link hooksOutgoingPath} 上。 */
|
|
225
414
|
export declare function hooksCoordinate(path: ConfigPath): string;
|
|
226
415
|
/**
|
|
227
416
|
* 把 wire 上的 untrusted `settings.hooks` 判成 {@link RunnableHooksConfig} + 服务侧上限 —— **hooks 配置在本仓的唯一入口**。
|
|
228
417
|
*
|
|
229
418
|
* · **一只读者**:合不合法只问契约包的 {@link classifyHooksConfig}(入参是 `{ hooks: raw }`,与契约 zod 面 `HooksConfig` 是同一读法的投影)。本仓只收 `loaded`:
|
|
230
419
|
* 一块被剔(`loaded-partial`)或整份被拒(`rejected`)都是拒 —— wire 面「剔掉坏块、其余照装」会让写的人以为生效的钩子无声消失(分类器的宽松粒度是读设置文件的宿主用的)。
|
|
231
|
-
*
|
|
420
|
+
* 拒的判决 = 分类器给的**码 + 坐标 + 坏字段**({@link HooksPieceIssue};分类器不写句子,句子与 400 体的机读位由 {@link buildHooksRefusal} 铸)。
|
|
232
421
|
* · **本仓不执行的条目类型整份拒**:分类器受理契约的全部五型,而本仓只跑 {@link SUPPORTED_HOOK_ENTRY_TYPES}。含其余类型的配置整份拒,不留跳过臂。
|
|
233
|
-
* ·
|
|
422
|
+
* · **本仓的 wire 键**(分类器不认、会剥掉的三只):组上的 `source`(来源闭集,`hook-source.ts`)、command 条目上的 `plugin` / `args`(执行上下文,`command-spawn.ts`)——
|
|
423
|
+
* 在分类器装上的**同一坐标**上读原值(分类器只在 `loaded` 时放行,装上的件与原值逐位对齐),形错 ⇒ {@link HooksWireKeyIssue}。
|
|
424
|
+
* `plugin` / `args` 只在 command 条目上有义:别的条目上它们与任何未知键一样被分类器剥掉(CC 同形)。值为 `undefined` 与缺席同读(与分类器读可选字段同一口径)。
|
|
425
|
+
* · **服务侧上限**(广度闸;契约本身不设量纲)。exec 形的命令行(`command` + 各 `args`)计入 `command` 帽;插件上下文一道总字符帽。
|
|
234
426
|
*
|
|
235
|
-
*
|
|
427
|
+
* 拒返回判决(`issue`)与它的句子(`error`)而不 throw —— submit 路径 400 fail-loud(体带 `field: "settings.hooks"` + `detail`)、resume 防御路径 warn-drop(hooks 整只不采纳),由调用方选;
|
|
428
|
+
* **读者、判决与句子两腿同一只**,后果按腿分。
|
|
236
429
|
*/
|
|
237
430
|
export declare function parseHooksConfig(raw: unknown): ParseHooksConfigResult;
|
|
238
431
|
/**
|
|
239
|
-
* 运行期的 matcher 读法席位:**问契约包的 `hookMatcherSelects
|
|
432
|
+
* 运行期的 matcher 读法席位:**问契约包的 `hookMatcherSelects`,经受理面同一只带预算的求值口({@link matcherSelectsBy})**(壳与服务端都问这一只契约函数,谁都不留副本;读法全文见它的头注,这里不重述)。
|
|
240
433
|
* 三形(名字表 / 空 `*` 缺省 / 不锚定的 JS 正则)与「编不过 ⇒ `"invalid"`」都由它答;**对所有带 matcher 的事件同一只读法**(工具事件 / StopFailure 的 `error` 词 /
|
|
241
|
-
* PreCompact·PostCompact 的 `trigger` 词 / `if` 条件的名部)
|
|
242
|
-
*
|
|
434
|
+
* PreCompact·PostCompact 的 `trigger` 词 / `if` 条件的名部),不按事件分档。
|
|
435
|
+
*
|
|
436
|
+
* 🔴 **预算(S-1017)**:求法与受理面 `"regex"` 档同一格表({@link MATCHER_EVALUATION}):字面形(名字表 / 空 / `*` / 缺省)直接问契约函数,不进 vm、不占额度;
|
|
437
|
+
* 正则形**每一次求值**进 vm、各拿一份固定的 {@link ADMISSION_MATCHER_BUDGET}`.budgetMs`(不共享、不读钟、不新造第二只预算常量)。受理面只对 core 目录里的别名 / 正名这几个短名字求过值,
|
|
438
|
+
* 运行期要对**任意别的工具名**求值 —— 受理过了的 matcher 在某个名字上灾难回溯,不能再同步占住事件循环。
|
|
439
|
+
* 四个答案(闭集,{@link MatcherAnswer}),调用方各用一条穷举 switch 处置({@link matcherGroupSelected} / {@link hookIfMatches}):
|
|
440
|
+
* · `true` / `false` —— 选中 / 不选;
|
|
441
|
+
* · `"invalid"` —— 该组不跑(fail-closed 到「不跑」),调用方记账一次(`hook_matcher_invalid`);
|
|
442
|
+
* · `"over_budget"` —— 这一次求值没在预算内结束 ⇒ **按选中处理 + 登记**(`hook_matcher_over_budget` 一行日志 + `matcher_over_budget` 一帧):不选 = 守卫 hook 被静默放过 = fail-open,
|
|
443
|
+
* 所以方向是「多跑」不是「少跑」;不静默 —— 每次发生各登记一次,一直在坏就一直说。
|
|
243
444
|
*/
|
|
244
|
-
export declare function hookMatcherMatches(matcher: string | undefined, value: string):
|
|
445
|
+
export declare function hookMatcherMatches(matcher: string | undefined, value: string): MatcherAnswer;
|
|
245
446
|
/** `if` 条目条件(CC-exact,对照 CC 2.1.187/198 实测行为核验的真语义,两版一致):
|
|
246
447
|
* 值 = permission-rule 模式(`ToolName` 或 `ToolName(arg-模式)`),【不是】表达式语言——按当前工具调用
|
|
247
448
|
* 求值:名部走 permission matcher(交替/正则同 matcher 字段),括号内 arg-模式(`*` 通配)匹配工具输入的
|
|
248
449
|
* 主字符串(Bash=command,文件工具=file_path/path)。CC 行为逐条目:不匹配 → 跳过该条目(记日志);
|
|
249
450
|
* 非工具事件(payload 无 tool_name)→ "cannot be evaluated" 跳过;解析失败 → 跳过。返回:
|
|
250
|
-
* true=跑 / "not_matched" / "unevaluable"(调用方分别记账;跳过永不静默)。
|
|
451
|
+
* true=跑 / "not_matched" / "unevaluable"(调用方分别记账;跳过永不静默)/ "over_budget"(S-1017:名部求值没在预算内结束 ⇒ 调用方按**选中**处理 + 登记,见 {@link hookMatcherMatches})。
|
|
251
452
|
*
|
|
252
453
|
* 2.1.250 复核([ref],2026-08-30;语料=sema-internal `blueprints/cc-decoded/cli250.js`):求值器与 220
|
|
253
454
|
* 逐字同构——五种工具事件之外「cannot be evaluated for non-tool event」跳过、「Skipping hook due to if
|
|
@@ -255,8 +456,8 @@ export declare function hookMatcherMatches(matcher: string | undefined, value: s
|
|
|
255
456
|
* 本实现同向。差异登记(不改行为):①250 证据里名部=**规范化后等值比对**(`vd(toolName)!==o`),
|
|
256
457
|
* 「交替/正则」是 matcher 字段的文法——本实现名部走 hookMatcherMatches 属**超集**(alternation 也认),
|
|
257
458
|
* 如实登记不收窄;②250 的 `if` 已扩到 prompt/agent/http/mcp_tool 条目(本 runner 只翻 command,不涉)。 */
|
|
258
|
-
export declare function hookIfMatches(cond: string, payload: unknown): true | "not_matched" | "unevaluable";
|
|
259
|
-
/**
|
|
459
|
+
export declare function hookIfMatches(cond: string, payload: unknown): true | "not_matched" | "unevaluable" | "over_budget";
|
|
460
|
+
/** createSettingsHooksRegistration 的装配上下文(payload 的 CC-verbatim 字段来源)。 */
|
|
260
461
|
export interface HookRunnerContext {
|
|
261
462
|
logger: Logger;
|
|
262
463
|
sessionId: string;
|
|
@@ -280,7 +481,7 @@ export interface HookRunnerContext {
|
|
|
280
481
|
onHookNotice?: (n: HookNoticeObservation) => void;
|
|
281
482
|
/** Stop × `type:"prompt"` 是否把**会话 transcript** 交给评估者(CC `execPromptHook` 形)。
|
|
282
483
|
* 缺省(undefined)= **开**。`false` ⇒ 整条路不启用(prompt 条目在 Stop 上被跳过并记账)——
|
|
283
|
-
* 部署侧的显式逃生口(`SEMA_STOP_PROMPT_TRANSCRIPT=0`)。见
|
|
484
|
+
* 部署侧的显式逃生口(`SEMA_STOP_PROMPT_TRANSCRIPT=0`)。见 Stop 翻译里那段三问。 */
|
|
284
485
|
stopPromptTranscript?: boolean;
|
|
285
486
|
/** asyncRewake wake 管道(契约:Background + wake the model on exit 2)。部署组装:live 腿=同 session
|
|
286
487
|
* 的 TaskStream.steer(下个 turn 边界注入);返回 false=没有活流可投(任务已结束/挂起/别副本)——
|
|
@@ -314,19 +515,75 @@ export type HookLlmCall = (opts: {
|
|
|
314
515
|
code?: HookLlmFailureCode;
|
|
315
516
|
}>;
|
|
316
517
|
/** 失败判别码(B8:判别一律走码,禁按 error 文案分支——v3.1 批2,统检第二波 high)。error 仍是给人看的
|
|
317
|
-
* 自由文本;code 是给控制流的。缺席=未分类失败(不重试、不特判)。
|
|
318
|
-
|
|
518
|
+
* 自由文本;code 是给控制流的。缺席=未分类失败(不重试、不特判)。
|
|
519
|
+
*
|
|
520
|
+
* 🔴 **一类真因一个码**(S-1635;闭集 —— 消费方的 `switch` 无兜底分支,加一个码而不表态 = 编译错误):码是**成因族**的名字,铸点是直连载体
|
|
521
|
+
* (`hook-llm.ts` 的 `callLlm` / `hookModelFor`)的每一个失败臂,消费方(会话标题器的 fail-open 标签表)据此区分「该改哪里」,不读 `error` 文案:
|
|
522
|
+
* · `model_unresolved`:这只模型在本部署上选不出来 —— 目录里没有 / 条目不可用 / 网关腿解析不出端点(改目录或网关配置)
|
|
523
|
+
* · `route_refused`:路由核验拒发 —— key↔URL 不配对,或 foreign 端点无 per-model key(改路由 / 凭据配置;零请求)
|
|
524
|
+
* · `credential_custody_failed`:per-model key 托管读不出(密封 key 中毒 / 解密失败;不回落共享凭据,零请求)
|
|
525
|
+
* · `redirect_refused`:端点回了 3xx、直连请求按律不跟随(`egress-redirect.ts`;把网关 URL 改成最终地址)
|
|
526
|
+
* · `bad_response`:端点答了,但不是可用的 completion —— 非 2xx 状态,或 2xx 而 body 不是 JSON
|
|
527
|
+
* · `no_content`:端点答了合法 JSON,里面没有文本(CC 评估者路对它重试一次)
|
|
528
|
+
* · `unreachable`:连不上 / 网络层失败 / 超时(没有应答)
|
|
529
|
+
* 载体层面的整体硬顶(`hard_timeout`)不在这里:它由 runner 自己的 `Promise.race` 铸、只在 runner 内部读,不是载体的失败码。 */
|
|
530
|
+
export type HookLlmFailureCode = "model_unresolved" | "route_refused" | "credential_custody_failed" | "redirect_refused" | "bad_response" | "no_content" | "unreachable";
|
|
531
|
+
/** 托管相「未跑成」的原因闭集(= 帧 `hook_managed_unrun.reason`;每个词对应一条既有的跳过 / 故障臂,见 `fleet-bus.ts` 的 {@link HookManagedUnrun})。 */
|
|
532
|
+
export type ManagedUnrunReason = HookManagedUnrun["reason"];
|
|
533
|
+
/**
|
|
534
|
+
* 有放行 / 改写判词的事件(翻译器读 `permissionDecision: "allow"` / `updatedInput` 的那一个:PreToolUse)。判词不可信这条律(否决算数,放行与改写不作数)
|
|
535
|
+
* 只在这里有东西可不采信 ⇒ 只在这里铸 `distrust`;别的事件没有放行词,判词照收,不发「放行与改写不作数」的帧(那会说一件没发生的事)。
|
|
536
|
+
* 按事件名穷举(`satisfies Record<HookEventName, boolean>`,与 `HOOK_EVENT_OWNER` / `HOOK_EVENT_MATCHER_FIELD` 同形):契约加一个事件而这里没表态 = 编译红 ——
|
|
537
|
+
* 不缺省倒向「照收放行」(安全轴的闭集律)。壳属事件不在本服务跑,恒 `false`。
|
|
538
|
+
*/
|
|
539
|
+
export declare const PERMISSIVE_VERDICT_EVENTS: {
|
|
540
|
+
readonly PreToolUse: true;
|
|
541
|
+
readonly PostToolUse: false;
|
|
542
|
+
readonly PostToolUseFailure: false;
|
|
543
|
+
readonly PostToolBatch: false;
|
|
544
|
+
readonly Notification: false;
|
|
545
|
+
readonly UserPromptSubmit: false;
|
|
546
|
+
readonly UserPromptExpansion: false;
|
|
547
|
+
readonly SessionStart: false;
|
|
548
|
+
readonly SessionEnd: false;
|
|
549
|
+
readonly Stop: false;
|
|
550
|
+
readonly StopFailure: false;
|
|
551
|
+
readonly SubagentStart: false;
|
|
552
|
+
readonly SubagentStop: false;
|
|
553
|
+
readonly PreCompact: false;
|
|
554
|
+
readonly PostCompact: false;
|
|
555
|
+
readonly PermissionRequest: false;
|
|
556
|
+
readonly PermissionDenied: false;
|
|
557
|
+
readonly Setup: false;
|
|
558
|
+
readonly TeammateIdle: false;
|
|
559
|
+
readonly TaskCreated: false;
|
|
560
|
+
readonly TaskCompleted: false;
|
|
561
|
+
readonly Elicitation: false;
|
|
562
|
+
readonly ElicitationResult: false;
|
|
563
|
+
readonly ConfigChange: false;
|
|
564
|
+
readonly WorktreeCreate: false;
|
|
565
|
+
readonly WorktreeRemove: false;
|
|
566
|
+
readonly InstructionsLoaded: false;
|
|
567
|
+
readonly CwdChanged: false;
|
|
568
|
+
readonly FileChanged: false;
|
|
569
|
+
readonly MessageDisplay: false;
|
|
570
|
+
readonly DirectoryAdded: false;
|
|
571
|
+
readonly PreModelSwitch: false;
|
|
572
|
+
readonly PostModelSwitch: false;
|
|
573
|
+
};
|
|
319
574
|
/**
|
|
320
575
|
* hook 上下文片段 → 喂给模型的单串。**所有** `additionalContext` 聚合点的唯一属主(此前是同一个
|
|
321
576
|
* `contexts.join("\n")` 表达式抄在二十余处,总量帽无处可挂 —— 那正是漂移成因)。
|
|
322
577
|
*
|
|
323
|
-
*
|
|
578
|
+
* 四条语义,都是承重的:
|
|
324
579
|
* 1. **顺序保留、只截尾**:先来的钩子先说话;一旦装不下就停,后面的条目一律不再挤进来(哪怕更短)。
|
|
325
580
|
* 按长度重排会让"第 3 条钩子的话"随别人的长度忽隐忽现,排障时无从复现。
|
|
326
581
|
* 2. **截断可见**:尾巴挂一行标记说明省了几条、丢了多少字符。静默丢弃会让 hook 作者以为自己的
|
|
327
582
|
* context 生效了,而模型那头根本没见过 —— 这类"以为配好了"的缺席比长文本本身更贵。
|
|
328
583
|
* 3. **标记不计预算**:与 core `truncateError` / CC `A7e` 同姿势(marker 不占那 10k),否则帽值的
|
|
329
584
|
* 含义会随标记文案长度漂。
|
|
585
|
+
* 4. **一片 = 一条钩子发言,标记只写不读**:输入只来自钩子(不可信文本),本函数的成品不会被再聚合一次
|
|
586
|
+
* (跨记录的合成器随 core 7.52.0 退役:部署两张注册是观察者,不出答案)。钩子自己吐出的同形文字就是普通内容。
|
|
330
587
|
*/
|
|
331
588
|
export declare function buildHookContext(parts: readonly string[]): string | undefined;
|
|
332
589
|
/**
|
|
@@ -365,23 +622,20 @@ export interface LlmHookExtra {
|
|
|
365
622
|
transcript?: string;
|
|
366
623
|
}
|
|
367
624
|
/**
|
|
368
|
-
* 把校验过的 {@link RunnableHooksConfig}
|
|
369
|
-
*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
* - preCompact:双跑,block 部署优先,additionalInstructions 拼接。
|
|
382
|
-
* - stopFailure/postCompact(observe-only void):顺序双跑,无返回可折。
|
|
383
|
-
* 单在则透传。
|
|
625
|
+
* 律一 · 把校验过的 {@link RunnableHooksConfig} 铸成**一张** mods 注册 `settings.hooks`(任务座;档缺席 = `user`)。
|
|
626
|
+
* 没有可挂的条目 → undefined(`TaskSpec.mods` 不铸)。`budgetMs` = {@link settingsHooksBudgetMs} 的读数(调用方交)。
|
|
627
|
+
*
|
|
628
|
+
* 构造约束(每一条都有引擎侧的硬理由):
|
|
629
|
+
* · `register` 同步、只读本注册自己的配置、不按腿分支 —— 返回 thenable 即 `config.mods_invalid`;委派子代把父的任务座当自己的派发,
|
|
630
|
+
* 两条腿挂的是同一套 handler,父链才塌进子代的 phase 1(否则多一次约束判定);
|
|
631
|
+
* · `once` 去重集({@link runMatchingEntries} 的 `onceFired`)在铸注册这一层、每请求一份,不放进 `register`(那是每腿一次);
|
|
632
|
+
* · 答案全部由本仓从 CC JSON 铸,引擎在 handler 边界屏(唯一判官),本仓不预屏;
|
|
633
|
+
* · 无意见 ⇒ `next(e)`(链 handler 返回 `undefined` 是站点违约,PreToolUse / UserPromptSubmit 的失败列是 refuse ⇒ 每次都会被拒);
|
|
634
|
+
* 观察站的 handler 恒返回 `undefined` —— 两条都在 {@link hangClassic} 成形;
|
|
635
|
+
* · `uses.calls: []`(必填;本仓的 handler 不调 `$`),`uses.events` 从 {@link SETTINGS_HOOK_STATIONS} 派生;
|
|
636
|
+
* · 每只翻译的第二个入参是引擎的 `next.signal`(这只 handler 的预算 ∪ 这次派发被取消;见 {@link DEFAULT_SETTINGS_HOOKS_BUDGET_MS}):
|
|
637
|
+
* 一路贯穿到命令腿的 spawn({@link runCommandHook}),本仓不自合成第二只、不另设钟。
|
|
384
638
|
*/
|
|
385
|
-
export declare function
|
|
639
|
+
export declare function createSettingsHooksRegistration(config: RunnableHooksConfig, ctx: HookRunnerContext, budgetMs: number): ModRegistration<EngineDollar> | undefined;
|
|
386
640
|
export {};
|
|
387
641
|
//# sourceMappingURL=hook-runner.d.ts.map
|