@sema-agent/core 7.55.0 → 7.57.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 +1054 -0
- package/LICENSE +1 -1
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.js +1 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +7 -7
- package/dist/agents/org-delivery-gate.js +3 -4
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-held-queue.d.ts +69 -49
- package/dist/agents/peer-held-queue.js +255 -106
- package/dist/agents/peer-session-drain.js +65 -45
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +7 -6
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +72 -68
- package/dist/agents/tool-filter.d.ts +7 -5
- package/dist/agents/tool-filter.js +12 -9
- package/dist/agents/verify.d.ts +3 -2
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +45 -80
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +2 -8
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +23 -34
- package/dist/brain/openai.js +25 -96
- package/dist/brain/provider-dialect.d.ts +3 -2
- package/dist/brain/provider-dialect.js +2 -2
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +11 -11
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +13 -4
- package/dist/brain/request-params.js +21 -5
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.d.ts +9 -0
- package/dist/brain/stream-engine.js +24 -10
- package/dist/brain/stream-shared.d.ts +5 -4
- package/dist/brain/stream-shared.js +4 -4
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/allow-entry.d.ts +23 -23
- package/dist/core/allow-entry.js +42 -46
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/approval-object.d.ts +21 -5
- package/dist/core/approval-object.js +44 -17
- package/dist/core/ask-origin.d.ts +66 -20
- package/dist/core/ask-origin.js +63 -23
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +3 -4
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +71 -6
- package/dist/core/auto-compaction.js +42 -26
- package/dist/core/background-agent-store.d.ts +6 -2
- package/dist/core/background-agent-store.js +1 -1
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -1
- package/dist/core/checkpoint-requirements.js +6 -0
- package/dist/core/checkpoint-store.d.ts +105 -53
- package/dist/core/checkpoint-store.js +43 -20
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +5 -5
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +17 -17
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +32 -12
- package/dist/core/engine-notice.js +6 -0
- package/dist/core/file-history-store.d.ts +104 -22
- package/dist/core/file-history-store.js +37 -19
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -65
- package/dist/core/gate-outcome.d.ts +26 -5
- package/dist/core/gate-outcome.js +26 -0
- package/dist/core/governance-codes.d.ts +5 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +19 -18
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +38 -3
- package/dist/core/host-target.js +38 -5
- package/dist/core/mailbox-store.d.ts +62 -1
- package/dist/core/mailbox-store.js +59 -0
- package/dist/core/mcp-name-judge.d.ts +46 -0
- package/dist/core/mcp-name-judge.js +61 -0
- package/dist/core/mcp-probe.d.ts +1 -1
- package/dist/core/mcp-probe.js +2 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +70 -64
- package/dist/core/memory-engine/consolidation-driver.js +4 -3
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/distiller.js +26 -17
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +70 -8
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +32 -38
- package/dist/core/namespaced-rule-name.js +29 -36
- package/dist/core/parent-spec-seat.d.ts +6 -1
- package/dist/core/parent-spec-seat.js +2 -0
- package/dist/core/park-selfcheck.js +3 -0
- package/dist/core/permission-rule-consent.d.ts +24 -3
- package/dist/core/permission-rule-consent.js +136 -41
- package/dist/core/permission-rule-model.d.ts +57 -5
- package/dist/core/permission-rule-model.js +90 -31
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +8 -4
- package/dist/core/permission-rule-provider.d.ts +5 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +3 -2
- package/dist/core/permission-rule-store.js +11 -2
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +4 -4
- package/dist/core/permission-rules.js +11 -20
- package/dist/core/persisted-rule-arms.d.ts +2 -2
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +40 -5
- package/dist/core/protocol-http-auth.js +168 -4
- package/dist/core/protocol-naming.d.ts +20 -0
- package/dist/core/protocol-naming.js +20 -3
- package/dist/core/read-only-shell.d.ts +20 -5
- package/dist/core/read-only-shell.js +29 -14
- package/dist/core/remote-env.d.ts +37 -1
- package/dist/core/remote-env.js +11 -0
- package/dist/core/resume-startup-cause.d.ts +24 -2
- package/dist/core/resume-startup-cause.js +20 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +28 -1
- package/dist/core/roles.js +81 -26
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-owner.d.ts +3 -3
- package/dist/core/rule-owner.js +3 -2
- package/dist/core/runner/announce-once-ledger.d.ts +14 -0
- package/dist/core/runner/announce-once-ledger.js +5 -0
- package/dist/core/runner/assemble-result.d.ts +1 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +16 -4
- package/dist/core/runner/caller-roster.js +33 -6
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +7 -9
- package/dist/core/runner/classifier-ladder.js +3 -3
- package/dist/core/runner/compact-session.d.ts +10 -0
- package/dist/core/runner/compact-session.js +202 -0
- package/dist/core/runner/compaction-call-options.d.ts +2 -2
- package/dist/core/runner/compaction-seams.d.ts +21 -1
- package/dist/core/runner/compaction-seams.js +11 -8
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +50 -40
- package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
- package/dist/core/runner/cross-boundary-lane.js +40 -27
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +13 -0
- package/dist/core/runner/derived-route-fallback.js +6 -0
- package/dist/core/runner/env-capability-census.d.ts +3 -2
- package/dist/core/runner/env-capability-census.js +9 -3
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +3 -3
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
- package/dist/core/runner/permission-rule-lanes.js +39 -17
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +18 -7
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
- package/dist/core/runner/prepare-config-doors.d.ts +35 -38
- package/dist/core/runner/prepare-config-doors.js +46 -28
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +7 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
- package/dist/core/runner/prepare-gate-stations.js +10 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
- package/dist/core/runner/prepare-hands-readface.js +17 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.d.ts +2 -0
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +67 -76
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +3 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
- package/dist/core/runner/prepare-protocol-tools.js +3 -3
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-safety-scan.js +0 -17
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +5 -2
- package/dist/core/runner/prepare-task.js +48 -43
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/retired-runner-deps.js +1 -0
- package/dist/core/runner/rewind-files.d.ts +12 -0
- package/dist/core/runner/rewind-files.js +90 -0
- package/dist/core/runner/run-attachment-seats.js +2 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-harness-handlers.js +12 -4
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +40 -39
- package/dist/core/runner/run-notification-lane.d.ts +2 -0
- package/dist/core/runner/run-notification-lane.js +2 -2
- package/dist/core/runner/run-recovery-lanes.js +3 -4
- package/dist/core/runner/run-settle-and-teardown.js +7 -12
- package/dist/core/runner/run-terminal-adoption.js +3 -4
- package/dist/core/runner/run-turn-boundary.js +4 -15
- package/dist/core/runner/runtask.d.ts +10 -0
- package/dist/core/runner/runtask.js +35 -42
- package/dist/core/runner/send-message-continuation.js +1 -1
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.js +4 -3
- package/dist/core/runner/session-verb-doors.d.ts +28 -0
- package/dist/core/runner/session-verb-doors.js +48 -0
- package/dist/core/runner/session-write-ledger.d.ts +30 -0
- package/dist/core/runner/session-write-ledger.js +101 -0
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +12 -15
- package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
- package/dist/core/runner/sub-agent-deny-lists.js +25 -17
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/teardown-bounded.d.ts +1 -0
- package/dist/core/runner/teardown-bounded.js +1 -0
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +1 -3
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/turn-attachments.d.ts +33 -15
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +7 -7
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +11 -3
- package/dist/core/secret-env.d.ts +30 -3
- package/dist/core/secret-env.js +47 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +32 -15
- package/dist/core/session-policy-store.js +156 -36
- package/dist/core/session-store.d.ts +29 -10
- package/dist/core/session-store.js +51 -19
- package/dist/core/session.d.ts +82 -16
- package/dist/core/session.js +53 -0
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.d.ts +1 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.js +10 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
- package/dist/core/store-contracts/file-history-store-contract.js +40 -1
- package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-repo-contract.js +51 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
- package/dist/core/store-contracts/session-store-contract.js +150 -14
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +32 -4
- package/dist/core/task-notification.d.ts +16 -12
- package/dist/core/task-registry-agent.d.ts +8 -4
- package/dist/core/task-registry-agent.js +14 -8
- package/dist/core/task-registry-shared.d.ts +35 -6
- package/dist/core/task-registry-shared.js +11 -0
- package/dist/core/task-registry.d.ts +10 -1
- package/dist/core/task-registry.js +12 -2
- package/dist/core/task-result.d.ts +18 -0
- package/dist/core/task-spec.d.ts +18 -13
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +23 -0
- package/dist/core/tool-catalog-entries.js +14 -2
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-model-gate.d.ts +2 -2
- package/dist/core/tool-name-aliases.d.ts +48 -18
- package/dist/core/tool-name-aliases.js +36 -19
- package/dist/core/tool-name-readings.d.ts +6 -32
- package/dist/core/tool-name-readings.js +2 -9
- package/dist/core/tool-policy.d.ts +78 -204
- package/dist/core/tool-policy.js +152 -204
- package/dist/core/tool-result-store.js +3 -0
- package/dist/core/tool-roster.d.ts +14 -19
- package/dist/core/tool-roster.js +11 -44
- package/dist/core/tool-spec-members.js +7 -2
- package/dist/core/tool-spec.d.ts +19 -11
- package/dist/core/tools.js +49 -9
- package/dist/core/trace.d.ts +6 -3
- package/dist/core/trace.js +2 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +20 -0
- package/dist/core/untrusted-egress.js +77 -3
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/wiring-manifest.d.ts +9 -0
- package/dist/core/wiring-manifest.js +1 -0
- package/dist/core/workflow-journal-store.js +1 -1
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
- package/dist/engine/execution-env/node-execution-env.js +11 -2
- package/dist/engine/harness/agent-harness.d.ts +32 -6
- package/dist/engine/harness/agent-harness.js +65 -9
- package/dist/engine/harness/types.d.ts +29 -2
- package/dist/engine/llm/types.d.ts +28 -11
- package/dist/engine/loop/agent-loop.d.ts +23 -4
- package/dist/engine/loop/agent-loop.js +42 -30
- package/dist/engine/loop/types.d.ts +16 -6
- package/dist/engine/session/memory-repo.d.ts +9 -2
- package/dist/engine/session/memory-repo.js +11 -1
- package/dist/engine/session/repo-utils.d.ts +6 -5
- package/dist/engine/session/repo-utils.js +14 -6
- package/dist/index.d.ts +34 -17
- package/dist/index.js +22 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +2 -1
- package/dist/internal/harness.js +1 -0
- package/dist/internal/llm.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +6 -4
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +36 -18
- package/dist/primitives/credential-ref.d.ts +89 -0
- package/dist/primitives/credential-ref.js +125 -0
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.js +1 -0
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
- package/dist/prompt-assembly/tool-catalog.js +114 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/scenarios/full-body.d.ts +11 -11
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.js +4 -3
- package/dist/stores/file/adoption/marker.js +3 -2
- package/dist/stores/file/checkpoint-store.d.ts +21 -4
- package/dist/stores/file/checkpoint-store.js +38 -7
- package/dist/stores/file/file-history-store.js +18 -11
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +2 -1
- package/dist/stores/file/mailbox-store.js +26 -1
- package/dist/stores/file/permission-rule-adopt.js +4 -3
- package/dist/stores/file/permission-rule-store.js +11 -5
- package/dist/stores/file/session-store.d.ts +29 -6
- package/dist/stores/file/session-store.js +42 -50
- package/dist/tools/artifact/artifact-tool.js +3 -2
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
- package/dist/tools/fs/bash-readonly-classifier.js +5 -10
- package/dist/tools/fs/fs-bash.js +15 -8
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
- package/dist/tools/fs/pattern-kill-guard.js +429 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/removal-targets.d.ts +17 -7
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/search.d.ts +10 -0
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.d.ts +10 -0
- package/dist/tools/fs/shell-read-check.js +13 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-identity.d.ts +12 -9
- package/dist/tools/fs/shell-read-identity.js +9 -4
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/todo.js +63 -63
- package/dist/tools/web.d.ts +19 -14
- package/dist/tools/web.js +46 -61
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +221 -7
- package/wire-changes/core-stores-sql@7.57.0.json +29 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/core@7.57.0.json +1487 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/wire-changes/mods-kernel@7.57.0.json +29 -0
- package/wire-changes/primitives@7.57.0.json +245 -0
package/dist/core/session.js
CHANGED
|
@@ -4,9 +4,62 @@ export { BaseSessionStorage, leafIdAfterEntry, } from "../internal/harness.js";
|
|
|
4
4
|
export { SessionError } from "../internal/harness.js";
|
|
5
5
|
import { SessionError } from "../internal/harness.js";
|
|
6
6
|
import { readMember, thrownIs } from "./thrown-value.js";
|
|
7
|
+
import { receiptRefusal, receiveOwnProperties } from "./own-property-receipt.js";
|
|
8
|
+
import { principalNameFault, principalNameOf } from "./principal-name.js";
|
|
7
9
|
export function isSessionConflict(err) {
|
|
8
10
|
return thrownIs(err, SessionError) && readMember(err, "code") === "conflict";
|
|
9
11
|
}
|
|
12
|
+
export const SESSION_LIST_LIMITS = Object.freeze({ default: 50, max: 1000 });
|
|
13
|
+
const LIST_QUERY_MEMBERS = ["owner", "includeUnowned", "after", "limit"];
|
|
14
|
+
export function readSessionListQuery(raw, extensions = []) {
|
|
15
|
+
if (raw === undefined)
|
|
16
|
+
return { includeUnowned: false, limit: SESSION_LIST_LIMITS.default, extensions: {} };
|
|
17
|
+
if (typeof raw !== "object" || raw === null)
|
|
18
|
+
throw receiptRefusal(`SessionStore.list: the query must be an object, got ${raw === null ? "null" : typeof raw}`);
|
|
19
|
+
const got = receiveOwnProperties(raw, { subject: "SessionListQuery", unit: "member", moment: "at SessionStore.list" });
|
|
20
|
+
const extended = {};
|
|
21
|
+
for (const name of Object.keys(got)) {
|
|
22
|
+
if (LIST_QUERY_MEMBERS.includes(name))
|
|
23
|
+
continue;
|
|
24
|
+
if (!extensions.includes(name))
|
|
25
|
+
throw receiptRefusal(`SessionStore.list: this store does not filter by "${name}" — refused rather than listing the rows that filter would exclude`);
|
|
26
|
+
extended[name] = got[name];
|
|
27
|
+
}
|
|
28
|
+
const { owner: ownerGiven, includeUnowned, after, limit } = got;
|
|
29
|
+
const owner = ownerGiven === undefined ? undefined : principalNameOf(ownerGiven);
|
|
30
|
+
if (ownerGiven !== undefined && owner === undefined) {
|
|
31
|
+
throw receiptRefusal(`SessionListQuery.owner must be a principal name (a string with a visible character, no control or separator character, and no format character but a joiner) when present, got ${principalNameFault(ownerGiven)}`);
|
|
32
|
+
}
|
|
33
|
+
if (includeUnowned !== undefined && typeof includeUnowned !== "boolean")
|
|
34
|
+
throw receiptRefusal(`SessionListQuery.includeUnowned must be a boolean when present, got ${typeof includeUnowned}`);
|
|
35
|
+
if (includeUnowned !== undefined && owner === undefined)
|
|
36
|
+
throw receiptRefusal("SessionListQuery.includeUnowned is a member of the owner filter and was given without owner — refused rather than read as every owner's list");
|
|
37
|
+
if (limit !== undefined && !(typeof limit === "number" && Number.isSafeInteger(limit) && limit >= 1 && limit <= SESSION_LIST_LIMITS.max)) {
|
|
38
|
+
throw receiptRefusal(`SessionListQuery.limit must be an integer in 1..${SESSION_LIST_LIMITS.max} when present`);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...(owner !== undefined ? { owner } : {}),
|
|
42
|
+
includeUnowned: includeUnowned === true,
|
|
43
|
+
...(after !== undefined ? { after: readListCursor(after) } : {}),
|
|
44
|
+
limit: limit ?? SESSION_LIST_LIMITS.default,
|
|
45
|
+
extensions: extended,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function readListCursor(raw) {
|
|
49
|
+
if (typeof raw !== "object" || raw === null)
|
|
50
|
+
throw receiptRefusal(`SessionListQuery.after must be an object when present, got ${raw === null ? "null" : typeof raw}`);
|
|
51
|
+
const got = receiveOwnProperties(raw, { subject: "SessionListQuery.after", unit: "member", moment: "at SessionStore.list" });
|
|
52
|
+
for (const name of Object.keys(got)) {
|
|
53
|
+
if (name !== "lastActiveAt" && name !== "sessionId")
|
|
54
|
+
throw receiptRefusal(`SessionListQuery.after carries "${name}" — a cursor is a lastActiveAt and a sessionId`);
|
|
55
|
+
}
|
|
56
|
+
const { lastActiveAt, sessionId } = got;
|
|
57
|
+
if (typeof lastActiveAt !== "number" || !Number.isFinite(lastActiveAt))
|
|
58
|
+
throw receiptRefusal("SessionListQuery.after.lastActiveAt must be a finite number");
|
|
59
|
+
if (typeof sessionId !== "string")
|
|
60
|
+
throw receiptRefusal(`SessionListQuery.after.sessionId must be a string, got ${typeof sessionId}`);
|
|
61
|
+
return { lastActiveAt, sessionId };
|
|
62
|
+
}
|
|
10
63
|
export function hasSessionFork(store) {
|
|
11
64
|
return typeof store.fork === "function";
|
|
12
65
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ShellReadVerdict } from "../tools/fs/shell-read-check.js";
|
|
2
2
|
import { type ShellReadDisposition } from "../tools/fs/shell-read-judge.js";
|
|
3
3
|
import type { GatePass } from "./runner/gate-exit.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { PermissionResult } from "./tool-policy.js";
|
|
5
5
|
/** One station answer, received and read: what a reader acts on (`kind`) and the answer it acts on (`verdict` — the engine's own
|
|
6
6
|
* copy, received once). `unbelieved`: the station's answer was not received or contradicted its own finding, and `verdict` is the
|
|
7
7
|
* engine's refusal of it (its sentence names the station's words only where they are words of the closed sets — nothing a station
|
|
@@ -35,17 +35,16 @@ export interface StationAnswerCall {
|
|
|
35
35
|
* ({@link silencedBy}).
|
|
36
36
|
*/
|
|
37
37
|
export declare function readStationAnswer(answer: ShellReadVerdict, call: StationAnswerCall): StationAnswerReading;
|
|
38
|
-
/**
|
|
39
|
-
* not be read (the rule lane's class); the finding `unanswered` is, unless rows are unread, the environment's silence —
|
|
40
|
-
* engine cannot read (a guard
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
};
|
|
38
|
+
/** The ask `d` with the silence a station's answer carries, each its own class on the question it keeps or mints: unread rows are a
|
|
39
|
+
* rule that could not be read (the rule lane's class); the finding `unanswered` is, unless rows are unread, the environment's silence —
|
|
40
|
+
* shell text the engine cannot read (a guard, attested on the ask's record for `call` beside the guards it already carries) — and the
|
|
41
|
+
* marks only pick whose. Either is a question only a person answers; `probe` follows the finding. No silence ⇒ `d` itself. */
|
|
42
|
+
export declare function silencedBy<D extends Extract<PermissionResult, {
|
|
43
|
+
action: "ask";
|
|
44
|
+
}>>(d: D, verdict: ShellReadVerdict, call: {
|
|
45
|
+
readonly toolCallId: string;
|
|
46
|
+
readonly toolName: string;
|
|
47
|
+
}): D;
|
|
49
48
|
/** The station's SILENCE ({@link readStationAnswer}), applied once, before any disposition arm: a station — a host-mounted one
|
|
50
49
|
* included — may spell `vouch`, `mandated` or `ordinary` beside it, and no word vouches for what nobody judged. A deny stands; an
|
|
51
50
|
* ask keeps its words and gains the silence's class; an allow becomes the silence's question (`ask.message`), one only a person
|
|
@@ -3,6 +3,7 @@ import { dispositionsOfRow, SHELL_READ_FINDINGS } from "../tools/fs/shell-read-j
|
|
|
3
3
|
import { receiveContract } from "./decision-receipt.js";
|
|
4
4
|
import { egressThrownText } from "./untrusted-egress.js";
|
|
5
5
|
import { receive } from "./mods/kernel/receive.js";
|
|
6
|
+
import { attest, attestationOf } from "./engine-attestation.js";
|
|
6
7
|
const DISPOSITIONS = ["refuse", "mandated", "ordinary", "vouch"];
|
|
7
8
|
const MEMBER_KINDS = {
|
|
8
9
|
disposition: "word",
|
|
@@ -71,21 +72,24 @@ export function readStationAnswer(answer, call) {
|
|
|
71
72
|
call.report?.(new Error(`shell read station answered out of its contract for tool "${call.toolName}"${call.toolCallId !== undefined ? ` (toolCallId ${call.toolCallId})` : ""} — ${sentence}`));
|
|
72
73
|
return { kind: "refuse", verdict: { disposition: "refuse", finding: "none", sentence }, unbelieved: true };
|
|
73
74
|
}
|
|
74
|
-
export function silencedBy(verdict,
|
|
75
|
+
export function silencedBy(d, verdict, call) {
|
|
75
76
|
const environment = verdict.environmentSilent === true || (verdict.finding === "unanswered" && verdict.rowsUnread !== true);
|
|
77
|
+
if (!environment && verdict.rowsUnread !== true)
|
|
78
|
+
return d;
|
|
76
79
|
const rows = verdict.rowsUnread === true && d.ruleUnreadable === undefined ? { ruleUnreadable: "persisted_rows" } : {};
|
|
77
|
-
const
|
|
78
|
-
|
|
80
|
+
const out = { ...d, ...rows, requiresRealApproval: true };
|
|
81
|
+
const held = attestationOf(d, call)?.guards ?? [];
|
|
82
|
+
return environment && !held.includes("unverifiable_shell_text") ? attest(out, call, { guards: [...held, "unverifiable_shell_text"] }) : out;
|
|
79
83
|
}
|
|
80
84
|
export function applyUnansweredSilence(pass, verdict, ask) {
|
|
81
85
|
if (verdict.details !== undefined)
|
|
82
86
|
pass.shellReadDetails = verdict.details;
|
|
83
87
|
if (pass.decision.action === "ask") {
|
|
84
|
-
pass.decision =
|
|
88
|
+
pass.decision = silencedBy(pass.decision, verdict, pass.req);
|
|
85
89
|
return;
|
|
86
90
|
}
|
|
87
91
|
if (pass.decision.action !== "allow")
|
|
88
92
|
return;
|
|
89
|
-
pass.decision = { action: "ask", message: ask.message, decisionReason: "safety", ...
|
|
93
|
+
pass.decision = silencedBy({ action: "ask", message: ask.message, decisionReason: "safety", ...(ask.account !== undefined ? { probeReason: ask.account } : {}) }, verdict, pass.req);
|
|
90
94
|
pass.tightenedBy = ask.tightenedBy;
|
|
91
95
|
}
|
|
@@ -276,7 +276,7 @@ function unwrap(words) {
|
|
|
276
276
|
if (row.viaShell === true)
|
|
277
277
|
return `\`${name}\` evaluates its operands as shell input this reader does not read`;
|
|
278
278
|
if (row.executes !== undefined) {
|
|
279
|
-
const hit = words.slice(1).find((w) => w.expands !== false || row.executes.
|
|
279
|
+
const hit = words.slice(1).find((w) => w.expands !== false || row.executes.some((x) => w.text === x || (x.length === 2 && /^-[^-]/.test(w.text) && w.text.includes(x[1]))));
|
|
280
280
|
return hit === undefined ? words : hit.expands !== false ? `an expansion where \`${name}\` reads its arguments` : `\`${name} ${hit.text}\` runs a command this reader does not read`;
|
|
281
281
|
}
|
|
282
282
|
const valueFlags = new Set(row.valueFlags);
|
|
@@ -394,6 +394,8 @@ function unwrap(words) {
|
|
|
394
394
|
if (r !== true)
|
|
395
395
|
return r;
|
|
396
396
|
i++;
|
|
397
|
+
if (durationTaken && positionalTaken)
|
|
398
|
+
break;
|
|
397
399
|
}
|
|
398
400
|
if (i >= words.length)
|
|
399
401
|
return words;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ShellWrapperRow } from "./shell-wrapper-table.js";
|
|
2
2
|
/**
|
|
3
|
-
* The PROJECTION {@link import("./shell-wrapper-table.js").SHELL_WRAPPER_TABLE} is: the
|
|
3
|
+
* The PROJECTION {@link import("./shell-wrapper-table.js").SHELL_WRAPPER_TABLE} is: the tightening reader's peel view of the program read model's rows (`program-read-model.ts`
|
|
4
4
|
* — one table of program facts, read through the binary gate). A launcher row's options by arity (a value word, a
|
|
5
5
|
* switch or an attached-only value, a command string), its required operand (a duration, or the spelling it must have),
|
|
6
6
|
* its bare-dash switch and its `NAME=value` operands; a row that runs its operands, or a code body, as shell input
|
|
@@ -30,7 +30,7 @@ const runsCommand = (spec) => spec.effect === "executes" || spec.value?.kind ===
|
|
|
30
30
|
function projectRow(row) {
|
|
31
31
|
const sorted = (xs) => [...new Set(xs)].sort();
|
|
32
32
|
const all = spellings(row);
|
|
33
|
-
const viaShell = row.reentry?.kind === "shell" || row.launcher?.shellText !== undefined || row.body === "first-operand" || row.body === "assignment-values" || (row.operands?.rest?.kind === "program-text" && row.operands.rest.language === "arithmetic");
|
|
33
|
+
const viaShell = (row.reentry?.kind === "shell" && row.reentry.text !== "history") || row.launcher?.shellText !== undefined || row.body === "first-operand" || row.body === "assignment-values" || (row.operands?.rest?.kind === "program-text" && row.operands.rest.language === "arithmetic");
|
|
34
34
|
if (row.launcher === undefined) {
|
|
35
35
|
if (viaShell)
|
|
36
36
|
return { valueFlags: [], flags: [], commandString: [], viaShell: true };
|
|
@@ -181,6 +181,12 @@ export declare const SHELL_WRAPPER_TABLE: {
|
|
|
181
181
|
readonly commandString: readonly [];
|
|
182
182
|
readonly viaShell: true;
|
|
183
183
|
};
|
|
184
|
+
readonly fc: {
|
|
185
|
+
readonly valueFlags: readonly [];
|
|
186
|
+
readonly flags: readonly [];
|
|
187
|
+
readonly commandString: readonly [];
|
|
188
|
+
readonly executes: readonly ["-e", "-s"];
|
|
189
|
+
};
|
|
184
190
|
readonly source: {
|
|
185
191
|
readonly valueFlags: readonly [];
|
|
186
192
|
readonly flags: readonly [];
|
|
@@ -289,14 +295,14 @@ export declare const SHELL_WRAPPER_TABLE: {
|
|
|
289
295
|
readonly viaShell: true;
|
|
290
296
|
};
|
|
291
297
|
readonly chroot: {
|
|
292
|
-
readonly valueFlags: readonly [];
|
|
293
|
-
readonly flags: readonly [];
|
|
298
|
+
readonly valueFlags: readonly ["--groups", "--userspec", "-G", "-g", "-u"];
|
|
299
|
+
readonly flags: readonly ["--help", "--skip-chdir", "--version"];
|
|
294
300
|
readonly commandString: readonly [];
|
|
295
301
|
readonly positional: RegExp;
|
|
296
302
|
};
|
|
297
303
|
readonly setpriv: {
|
|
298
|
-
readonly valueFlags: readonly [];
|
|
299
|
-
readonly flags: readonly [];
|
|
304
|
+
readonly valueFlags: readonly ["--ambient-caps", "--apparmor-profile", "--bounding-set", "--egid", "--euid", "--groups", "--inh-caps", "--pdeathsig", "--regid", "--reuid", "--rgid", "--ruid", "--securebits", "--selinux-label"];
|
|
305
|
+
readonly flags: readonly ["--clear-groups", "--dump", "--help", "--init-groups", "--keep-groups", "--nnp", "--no-new-privs", "--reset-env", "--version", "-V", "-d", "-h"];
|
|
300
306
|
readonly commandString: readonly [];
|
|
301
307
|
};
|
|
302
308
|
readonly numactl: {
|
|
@@ -305,8 +311,9 @@ export declare const SHELL_WRAPPER_TABLE: {
|
|
|
305
311
|
readonly commandString: readonly [];
|
|
306
312
|
};
|
|
307
313
|
readonly prlimit: {
|
|
308
|
-
readonly valueFlags: readonly [];
|
|
309
|
-
readonly flags: readonly [];
|
|
314
|
+
readonly valueFlags: readonly ["--output", "--pid", "-o", "-p"];
|
|
315
|
+
readonly flags: readonly ["--as", "--core", "--cpu", "--data", "--fsize", "--help", "--locks", "--memlock", "--msgqueue", "--nice", "--nofile", "--noheadings", "--nproc", "--raw", "--rss", "--rtprio", "--rttime", "--sigpending", "--stack", "--verbose", "--version", "-V", "-h"];
|
|
316
|
+
readonly attached: readonly ["-c", "-d", "-e", "-f", "-i", "-l", "-m", "-n", "-q", "-r", "-s", "-t", "-u", "-v", "-x", "-y"];
|
|
310
317
|
readonly commandString: readonly [];
|
|
311
318
|
};
|
|
312
319
|
readonly "systemd-run": {
|
|
@@ -316,7 +323,7 @@ export declare const SHELL_WRAPPER_TABLE: {
|
|
|
316
323
|
};
|
|
317
324
|
readonly valgrind: {
|
|
318
325
|
readonly valueFlags: readonly [];
|
|
319
|
-
readonly flags: readonly [];
|
|
326
|
+
readonly flags: readonly ["--alignment", "--allow-mismatched-debuginfo", "--avg-transtab-entry-size", "--cachegrind-out-file", "--callgrind-out-file", "--child-silent-after-fork", "--default-suppressions", "--demangle", "--dhat-out-file", "--dsymutil", "--error-exitcode", "--error-limit", "--error-markers", "--errors-for-leak-kinds", "--exit-on-first-error", "--expensive-definedness-checks", "--fair-sched", "--free-fill", "--freelist-big-blocks", "--freelist-vol", "--fullpath-after", "--gen-suppressions", "--help", "--help-debug", "--help-dyn-options", "--ignore-range-below-sp", "--ignore-ranges", "--input-fd", "--keep-debuginfo", "--keep-stacktraces", "--kernel-variant", "--leak-check", "--leak-check-heuristics", "--leak-resolution", "--log-fd", "--log-file", "--main-stacksize", "--malloc-fill", "--massif-out-file", "--max-stackframe", "--max-threads", "--merge-recursive-frames", "--num-callers", "--num-transtab-sectors", "--partial-loads-ok", "--quiet", "--read-inline-info", "--read-var-info", "--redzone-size", "--resync-filter", "--run-cxx-freeres", "--run-libc-freeres", "--show-below-main", "--show-emwarns", "--show-error-list", "--show-leak-kinds", "--show-mismatched-frees", "--show-possibly-lost", "--show-reachable", "--sigill-diagnostics", "--sim-hints", "--smc-check", "--soname-synonyms", "--suppressions", "--time-stamp", "--tool", "--trace-children", "--trace-children-skip", "--trace-children-skip-by-arg", "--track-fds", "--track-origins", "--undef-value-errors", "--unw-stack-scan-frames", "--unw-stack-scan-thresh", "--valgrind-stacksize", "--verbose", "--version", "--vgdb", "--vgdb-error", "--vgdb-poll", "--vgdb-shadow-registers", "--vgdb-stop-at", "--workaround-gcc296-bugs", "--xml", "--xml-fd", "--xml-file", "--xml-user-comment", "--xtree-leak", "--xtree-leak-file", "--xtree-memory", "--xtree-memory-file", "-h", "-q", "-s", "-v"];
|
|
320
327
|
readonly commandString: readonly [];
|
|
321
328
|
};
|
|
322
329
|
readonly firejail: {
|
|
@@ -27,6 +27,7 @@ export const SHELL_WRAPPER_TABLE = {
|
|
|
27
27
|
unshare: { valueFlags: ["--boottime", "--map-group", "--map-user", "--monotonic", "--propagation", "--root", "--setgid", "--setgroups", "--setuid", "--wd", "-G", "-R", "-S", "-w"], flags: ["--cgroup", "--fork", "--help", "--ipc", "--keep-caps", "--kill-child", "--map-current-user", "--map-root-user", "--mount", "--mount-proc", "--net", "--pid", "--time", "--user", "--uts", "--version", "-C", "-T", "-U", "-c", "-f", "-i", "-m", "-n", "-p", "-r", "-u"], commandString: [] },
|
|
28
28
|
nsenter: { valueFlags: ["--setgid", "--setuid", "--target", "-G", "-S", "-t"], flags: ["--all", "--cgroup", "--help", "--ipc", "--mount", "--net", "--no-fork", "--pid", "--preserve-credentials", "--root", "--time", "--user", "--uts", "--version", "--wd", "-C", "-F", "-T", "-U", "-Z", "-a", "-i", "-m", "-n", "-p", "-u"], attached: ["-r", "-w"], commandString: [] },
|
|
29
29
|
eval: { valueFlags: [], flags: [], commandString: [], viaShell: true },
|
|
30
|
+
fc: { valueFlags: [], flags: [], commandString: [], executes: ["-e", "-s"] },
|
|
30
31
|
source: { valueFlags: [], flags: [], commandString: [], viaShell: true },
|
|
31
32
|
".": { valueFlags: [], flags: [], commandString: [], viaShell: true },
|
|
32
33
|
trap: { valueFlags: [], flags: [], commandString: [], viaShell: true },
|
|
@@ -45,12 +46,12 @@ export const SHELL_WRAPPER_TABLE = {
|
|
|
45
46
|
busybox: { valueFlags: [], flags: [], commandString: [] },
|
|
46
47
|
su: { valueFlags: ["--group", "--shell", "--supp-group", "--whitelist-environment", "-G", "-g", "-s", "-w"], flags: ["--fast", "--help", "--login", "--no-pty", "--preserve-environment", "--pty", "--version", "-P", "-T", "-V", "-f", "-h", "-l", "-m", "-p"], commandString: ["--command", "--session-command", "-c"], viaShell: true },
|
|
47
48
|
runuser: { valueFlags: ["--group", "--shell", "--supp-group", "--user", "--whitelist-environment", "-G", "-g", "-s", "-u", "-w"], flags: ["--fast", "--help", "--login", "--no-pty", "--preserve-environment", "--pty", "--version", "-P", "-T", "-V", "-f", "-h", "-l", "-m", "-p"], commandString: ["--command", "--session-command", "-c"], viaShell: true },
|
|
48
|
-
chroot: { valueFlags: [], flags: [], commandString: [], positional: /^/ },
|
|
49
|
-
setpriv: { valueFlags: [], flags: [], commandString: [] },
|
|
49
|
+
chroot: { valueFlags: ["--groups", "--userspec", "-G", "-g", "-u"], flags: ["--help", "--skip-chdir", "--version"], commandString: [], positional: /^/ },
|
|
50
|
+
setpriv: { valueFlags: ["--ambient-caps", "--apparmor-profile", "--bounding-set", "--egid", "--euid", "--groups", "--inh-caps", "--pdeathsig", "--regid", "--reuid", "--rgid", "--ruid", "--securebits", "--selinux-label"], flags: ["--clear-groups", "--dump", "--help", "--init-groups", "--keep-groups", "--nnp", "--no-new-privs", "--reset-env", "--version", "-V", "-d", "-h"], commandString: [] },
|
|
50
51
|
numactl: { valueFlags: [], flags: [], commandString: [] },
|
|
51
|
-
prlimit: { valueFlags: [], flags: [], commandString: [] },
|
|
52
|
+
prlimit: { valueFlags: ["--output", "--pid", "-o", "-p"], flags: ["--as", "--core", "--cpu", "--data", "--fsize", "--help", "--locks", "--memlock", "--msgqueue", "--nice", "--nofile", "--noheadings", "--nproc", "--raw", "--rss", "--rtprio", "--rttime", "--sigpending", "--stack", "--verbose", "--version", "-V", "-h"], attached: ["-c", "-d", "-e", "-f", "-i", "-l", "-m", "-n", "-q", "-r", "-s", "-t", "-u", "-v", "-x", "-y"], commandString: [] },
|
|
52
53
|
"systemd-run": { valueFlags: [], flags: [], commandString: [] },
|
|
53
|
-
valgrind: { valueFlags: [], flags: [], commandString: [] },
|
|
54
|
+
valgrind: { valueFlags: [], flags: ["--alignment", "--allow-mismatched-debuginfo", "--avg-transtab-entry-size", "--cachegrind-out-file", "--callgrind-out-file", "--child-silent-after-fork", "--default-suppressions", "--demangle", "--dhat-out-file", "--dsymutil", "--error-exitcode", "--error-limit", "--error-markers", "--errors-for-leak-kinds", "--exit-on-first-error", "--expensive-definedness-checks", "--fair-sched", "--free-fill", "--freelist-big-blocks", "--freelist-vol", "--fullpath-after", "--gen-suppressions", "--help", "--help-debug", "--help-dyn-options", "--ignore-range-below-sp", "--ignore-ranges", "--input-fd", "--keep-debuginfo", "--keep-stacktraces", "--kernel-variant", "--leak-check", "--leak-check-heuristics", "--leak-resolution", "--log-fd", "--log-file", "--main-stacksize", "--malloc-fill", "--massif-out-file", "--max-stackframe", "--max-threads", "--merge-recursive-frames", "--num-callers", "--num-transtab-sectors", "--partial-loads-ok", "--quiet", "--read-inline-info", "--read-var-info", "--redzone-size", "--resync-filter", "--run-cxx-freeres", "--run-libc-freeres", "--show-below-main", "--show-emwarns", "--show-error-list", "--show-leak-kinds", "--show-mismatched-frees", "--show-possibly-lost", "--show-reachable", "--sigill-diagnostics", "--sim-hints", "--smc-check", "--soname-synonyms", "--suppressions", "--time-stamp", "--tool", "--trace-children", "--trace-children-skip", "--trace-children-skip-by-arg", "--track-fds", "--track-origins", "--undef-value-errors", "--unw-stack-scan-frames", "--unw-stack-scan-thresh", "--valgrind-stacksize", "--verbose", "--version", "--vgdb", "--vgdb-error", "--vgdb-poll", "--vgdb-shadow-registers", "--vgdb-stop-at", "--workaround-gcc296-bugs", "--xml", "--xml-fd", "--xml-file", "--xml-user-comment", "--xtree-leak", "--xtree-leak-file", "--xtree-memory", "--xtree-memory-file", "-h", "-q", "-s", "-v"], commandString: [] },
|
|
54
55
|
firejail: { valueFlags: [], flags: [], commandString: [] },
|
|
55
56
|
bwrap: { valueFlags: [], flags: [], commandString: [] },
|
|
56
57
|
ash: { valueFlags: [], flags: [], commandString: [], viaShell: true },
|
package/dist/core/side-query.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ensureToolTurnInvariants } from "../internal/llm.js";
|
|
2
2
|
import { resolveTaskModel } from "./roles.js";
|
|
3
|
+
import { runRenderer } from "../prompt-assembly/renderers.js";
|
|
4
|
+
import { roleBaseOf } from "../prompt-assembly/role-base.js";
|
|
5
|
+
import { effectiveTraitsOf, readModelPromptTraits, selectorsOf } from "../prompt-assembly/select.js";
|
|
3
6
|
import { readDegradation } from "../brain/degrading.js";
|
|
4
7
|
import { extractErrorCode } from "../brain/errors.js";
|
|
5
8
|
import { cacheFamilyOf, uncachedInputTokensOf } from "./runner/usage-accounting.js";
|
|
@@ -9,6 +12,11 @@ function normalizeSideQueryUsage(model, u) {
|
|
|
9
12
|
const input = uncachedInputTokensOf(cacheFamilyOf(model), u);
|
|
10
13
|
return input === u.input ? u : { ...u, input };
|
|
11
14
|
}
|
|
15
|
+
const NO_RUN_FACTS = Object.freeze({ policyEnabled: false, hooksEnabled: false, isolationEnabled: false, withinTaskCompactionEnabled: false, supervisorEnabled: false, orchestrationEnabled: false, awarenessEnabled: false, goalEnabled: false, worktreeIsolated: false, teammateEnabled: false });
|
|
16
|
+
function sideQueryRoleBase(role, model, tools) {
|
|
17
|
+
const selectors = selectorsOf(NO_RUN_FACTS, { role }, undefined, effectiveTraitsOf(readModelPromptTraits(model), undefined));
|
|
18
|
+
return runRenderer("role-base", { facts: NO_RUN_FACTS, toolNames: (tools ?? []).map((t) => t.name) }, selectors)?.text;
|
|
19
|
+
}
|
|
12
20
|
export async function runSideQuery(spec, deps) {
|
|
13
21
|
if (!Array.isArray(spec.messages) || spec.messages.length === 0) {
|
|
14
22
|
throw new Error("sideQuery requires a non-empty messages array");
|
|
@@ -40,7 +48,8 @@ export async function runSideQuery(spec, deps) {
|
|
|
40
48
|
}
|
|
41
49
|
return { role: "user", content: m.content, timestamp };
|
|
42
50
|
};
|
|
43
|
-
const
|
|
51
|
+
const decided = roleBaseOf([spec.systemPrompt !== undefined ? { systemPrompt: spec.systemPrompt } : undefined, resolved]);
|
|
52
|
+
const effectiveSystemPrompt = decided?.systemPrompt ?? (decided?.promptRole !== undefined ? sideQueryRoleBase(decided.promptRole, resolved.model, spec.tools) : undefined);
|
|
44
53
|
const context = {
|
|
45
54
|
...(effectiveSystemPrompt !== undefined ? { systemPrompt: effectiveSystemPrompt } : {}),
|
|
46
55
|
messages: ensureToolTurnInvariants(spec.messages.map(normalize)).messages,
|
|
@@ -199,6 +199,10 @@ export declare class SkillGrantTable {
|
|
|
199
199
|
private readonly rowKeys;
|
|
200
200
|
private mounted;
|
|
201
201
|
private activations;
|
|
202
|
+
private scopes;
|
|
203
|
+
/** State the leg's skill scopes (the mods bus's record): every activation this table writes opens its skill's scope there. A
|
|
204
|
+
* table never told opens nothing (the resume's pre-claim probe). */
|
|
205
|
+
bindScopes(scopes: Pick<import("./mods/spec-seats.js").SkillScopes, "open">): void;
|
|
202
206
|
/** State where the run's mounted names are read (prepare, once the roster is assembled): a skill's entries are read against
|
|
203
207
|
* them when seeded and whenever the skill is activated. A table never told reads the grammar alone. */
|
|
204
208
|
bindMountedNames(mounted: MountedToolNames): void;
|
|
@@ -211,8 +215,9 @@ export declare class SkillGrantTable {
|
|
|
211
215
|
* capture re-supplied beside the frozen rows that already carry it. Keyed on the ROW, not the skill: a definition that
|
|
212
216
|
* changed across a park writes its new rows when it is activated again. */
|
|
213
217
|
private hold;
|
|
214
|
-
/** Write a skill's rows (rows already held are not held twice) — or
|
|
215
|
-
* when its `disallowed-tools` holds an entry that reads as nothing. Returns the allow
|
|
218
|
+
/** Write a skill's rows (rows already held are not held twice) and open its scope — or neither, refused with
|
|
219
|
+
* {@link SKILL_DENY_UNREADABLE_CODE}, when its `disallowed-tools` holds an entry that reads as nothing. Returns the allow
|
|
220
|
+
* entries that read as nothing. */
|
|
216
221
|
activate(skill: SkillGrantSource, origin: SkillGrantOrigin): readonly SkillInertEntry[];
|
|
217
222
|
/** Seed portable records (a delegated child's capture, a resumed leg's frozen rows): a record the model wrote keeps that
|
|
218
223
|
* word, every other record seeds under `origin` — `user` is written only from this leg's own spec, never seeded. Each
|
package/dist/core/skill-grant.js
CHANGED
|
@@ -180,6 +180,10 @@ export class SkillGrantTable {
|
|
|
180
180
|
rowKeys = new Set();
|
|
181
181
|
mounted;
|
|
182
182
|
activations;
|
|
183
|
+
scopes;
|
|
184
|
+
bindScopes(scopes) {
|
|
185
|
+
this.scopes = scopes;
|
|
186
|
+
}
|
|
183
187
|
bindMountedNames(mounted) {
|
|
184
188
|
this.mounted = mounted;
|
|
185
189
|
}
|
|
@@ -203,6 +207,7 @@ export class SkillGrantTable {
|
|
|
203
207
|
throw skillDenyUnreadable(skill.name, unreadDeny, "activation");
|
|
204
208
|
for (const row of rows)
|
|
205
209
|
this.hold(row);
|
|
210
|
+
this.scopes?.open(skill.name);
|
|
206
211
|
return inert;
|
|
207
212
|
}
|
|
208
213
|
seed(records, origin) {
|
|
@@ -23,13 +23,15 @@ const SEQUENCE_NOT_AN_ENTRY = "its `- name` entries are not indented alike";
|
|
|
23
23
|
const SEQUENCE_NOT_A_NAME = "an entry is not a plain or quoted name (nested, mapping, anchor, tag, flow and block-scalar entries, and number, boolean and null entries, are not read)";
|
|
24
24
|
const VALUE_IS_A_MAPPING = "its value is a mapping or holds one (`key: value` or `{…}`), not a list of names";
|
|
25
25
|
const VALUE_NOT_A_STRING = "its value is a number or a boolean, not a list of names";
|
|
26
|
+
const YAML_ALIAS = 'it holds a YAML alias (an unquoted `*<name>`), which the reader does not resolve — quote a value or entry that is meant as a tool-name pattern ("*Edit")';
|
|
27
|
+
const YAML_ALIAS_START = /^\*[^\s,[\]{}]/;
|
|
26
28
|
const QUOTE_NOT_CLOSED = "a quote in it does not close";
|
|
27
29
|
const flowNotClosed = (opener) => `its \`${opener}\` does not close within its lines`;
|
|
28
30
|
const strayLine = (line) => `a flush-left line that is no key follows it (line ${line})`;
|
|
29
31
|
const NOT_A_KEY_LINE = "a flush-left frontmatter line is a key — letters, digits, `_` and `-`, or one quoted scalar — then `:` and a blank or nothing; a comment starts with `#`";
|
|
30
32
|
const PARENS_NOT_ONE_ZONE = "an entry's parentheses are not one group that closes it (a `(` that does not close, a `)` with no `(`, or text after the closing `)` — `\\(` / `\\)` are a rule's own text)";
|
|
31
33
|
const KEY_REPEATED = "the key is written more than once";
|
|
32
|
-
const notARule = (position) => `entry ${position} is no rule spelling (a tool name of ASCII letters, digits and \`_ - . : *\`, starting with a letter, a digit
|
|
34
|
+
const notARule = (position) => `entry ${position} is no rule spelling (a tool name of ASCII letters, digits and \`_ - . : *\`, starting with a letter, a digit, \`_\` or \`*\`, then at most one parenthesized rule)`;
|
|
33
35
|
const keyInsideValue = (inner) => `an indented line under its value is a mapping key, \`${inlineUntrusted(inner, 64)}\` — YAML reads no key there (under a value that is not a mapping, or indented less than the nested block it follows)`;
|
|
34
36
|
const toolListOutOfPlace = (inner) => `it holds the tool-list key \`${inner}\` — a tool list is read only as a key of the frontmatter, written flush left; anywhere else its list would be lost`;
|
|
35
37
|
const isBlank = (ch) => ch === " " || ch === "\t";
|
|
@@ -434,7 +436,9 @@ function scanValue(text, seat) {
|
|
|
434
436
|
const written = trimBlanks(plain);
|
|
435
437
|
plain = "";
|
|
436
438
|
breaks = 0;
|
|
437
|
-
if (
|
|
439
|
+
if (YAML_ALIAS_START.test(written))
|
|
440
|
+
cut.fail(YAML_ALIAS);
|
|
441
|
+
else if (opened.length > 0 || seat === "item") {
|
|
438
442
|
if (YAML_NULL.test(written) || YAML_BOOL_OR_NUMBER.test(written))
|
|
439
443
|
cut.fail(SEQUENCE_NOT_A_NAME);
|
|
440
444
|
}
|
|
@@ -39,7 +39,17 @@ export declare const POLICY_ALLOW: Extract<ResumeOutcome, {
|
|
|
39
39
|
* The full cross-backend contract for {@link CheckpointStore} — the SAME assertions for every
|
|
40
40
|
* backend. Entries are a 1:1 port of the vitest originals (assertion semantics unchanged).
|
|
41
41
|
*/
|
|
42
|
-
export declare function checkpointStoreContract(make: () => CheckpointStore, runAssertion?: ContractAssertionRunner
|
|
42
|
+
export declare function checkpointStoreContract(make: () => CheckpointStore, runAssertion?: ContractAssertionRunner,
|
|
43
|
+
/** `sessionHeads` = the map the binding's stores read their session heads from (their `deleteSessionCheckpoints` guard): the kit writes
|
|
44
|
+
* the heads its delete case needs into it. Required only to judge a store that offers `deleteSessionCheckpoints`.
|
|
45
|
+
* `holders` = the set of current claim holders the binding's store judges by (its `holderIsCurrent`, or the claim table it
|
|
46
|
+
* reads): the kit adds and removes holders in it. Required only to judge a store that declares `fence.holder`. */
|
|
47
|
+
options?: {
|
|
48
|
+
readonly sessionHeads?: Map<string, {
|
|
49
|
+
readonly owner: string | null;
|
|
50
|
+
}>;
|
|
51
|
+
readonly holders?: Set<string>;
|
|
52
|
+
}): Promise<void>;
|
|
43
53
|
/** Seed the canonical listByScope fixture into `store` and return the sorted summaries. Compare the
|
|
44
54
|
* result against {@link EXPECTED_LISTBYSCOPE_SUMMARIES} (deep equality) to prove the backend's
|
|
45
55
|
* summary projection matches the reference — the caller owns the comparison (harness-specific). */
|
|
@@ -48,7 +48,7 @@ export const POLICY_ALLOWED = Object.freeze({
|
|
|
48
48
|
origin: "policy",
|
|
49
49
|
});
|
|
50
50
|
export const POLICY_ALLOW = { ...ALLOW, hostDecision: { decidedBy: "policy", approver: "unattended_class_answer" }, gateOutcome: POLICY_ALLOWED };
|
|
51
|
-
export async function checkpointStoreContract(make, runAssertion) {
|
|
51
|
+
export async function checkpointStoreContract(make, runAssertion, options = {}) {
|
|
52
52
|
const { run, settle } = beginContract(runAssertion);
|
|
53
53
|
run("kit prerequisites: reopen/setPendingSteer/listByScope are implemented (REQUIRED by this kit)", async () => {
|
|
54
54
|
const probe = make();
|
|
@@ -308,7 +308,7 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
308
308
|
const stored = (await store.get(bitless.token)).pendingAction;
|
|
309
309
|
assert.equal("hasBidiControls" in stored, false, "projection backfill must not write back to the row");
|
|
310
310
|
});
|
|
311
|
-
run("the approval object's members: a row's identity + face group and its targets (capabilityId/contractId/shapeDigest/implementationRevision + family/pathTarget/hostTarget/names + targets) survive the round-trip verbatim; an absent group stays absent", async () => {
|
|
311
|
+
run("the approval object's members: a row's identity + face group and its targets (capabilityId/contractId/shapeDigest/implementationRevision + family/pathTarget/hostTarget/names + targets + targetReads + engineMounted) survive the round-trip verbatim; an absent group stays absent", async () => {
|
|
312
312
|
const store = make();
|
|
313
313
|
const carried = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-carried" });
|
|
314
314
|
const group = {
|
|
@@ -320,6 +320,8 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
320
320
|
pathTarget: { param: "destination", aliases: ["path"], access: "create", skillScopeEligible: true },
|
|
321
321
|
names: ["AcmeWrite", "acme_write"],
|
|
322
322
|
targets: { protective: "/srv/work/out.txt", declared: "/srv/work/out.txt" },
|
|
323
|
+
targetReads: { ["0123456789abcdef".repeat(4)]: "fedcba9876543210".repeat(4) },
|
|
324
|
+
engineMounted: true,
|
|
323
325
|
};
|
|
324
326
|
Object.assign(carried.pendingAction, group);
|
|
325
327
|
const bare = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-bare" });
|
|
@@ -463,6 +465,143 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
463
465
|
assert.deepEqual(checkpointIndexFacts(back), checkpointIndexFacts(cp), `the index facts of the row ${cp.gate.kind} came back different`);
|
|
464
466
|
}
|
|
465
467
|
});
|
|
468
|
+
run("listOverdue (when offered): pending rows of every scope past the cutoff, one facet per call (facetOf, the question card included), deadline-then-token order, the bound cut with a cursor that resumes without a gap or a repeat, a bad query refused", async () => {
|
|
469
|
+
const store = make();
|
|
470
|
+
if (store.listOverdue === undefined)
|
|
471
|
+
return;
|
|
472
|
+
const human = (over) => createCheckpointFixture(over);
|
|
473
|
+
const question = createCheckpointFixture({ token: "ov-q", deadline: 1_000, gate: { kind: "human", reason: "ask", toolName: "Write", approvalCard: "question" } });
|
|
474
|
+
const rows = [
|
|
475
|
+
human({ token: "ov-a2", deadline: 1_500 }),
|
|
476
|
+
human({ token: "ov-a1", deadline: 1_000, scope: "tenant-b" }),
|
|
477
|
+
human({ token: "ov-a0", deadline: 1_000 }),
|
|
478
|
+
question,
|
|
479
|
+
createCheckpointFixture({ token: "ov-r", deadline: 900, gate: { kind: "resource_limit", reason: "turns" }, pendingAction: { kind: "resource_limit", reason: "turns" } }),
|
|
480
|
+
createCheckpointFixture({ token: "ov-t", deadline: 900, gate: { kind: "task_done" }, pendingAction: { kind: "task_done" } }),
|
|
481
|
+
human({ token: "ov-late", deadline: 5_000 }),
|
|
482
|
+
human({ token: "ov-none" }),
|
|
483
|
+
human({ token: "ov-done", deadline: 1_000 }),
|
|
484
|
+
];
|
|
485
|
+
for (const cp of rows)
|
|
486
|
+
await store.put(cp.token, cp);
|
|
487
|
+
await store.resolve("ov-done", "tenant-a", ALLOW);
|
|
488
|
+
const tokensOf = (page) => page.rows.map((r) => r.token);
|
|
489
|
+
assert.deepEqual(tokensOf(await store.listOverdue({ cutoff: 2_000, facet: "A" })), ["ov-a0", "ov-a1", "ov-a2"], "facet A = the approval rows past the cutoff, every scope, (deadline, token) ascending");
|
|
490
|
+
assert.deepEqual(tokensOf(await store.listOverdue({ cutoff: 2_000, facet: "B" })), ["ov-r", "ov-q"], "facet B = the abandonment rows, the question parked under an approval gate kind among them");
|
|
491
|
+
assert.deepEqual(tokensOf(await store.listOverdue({ cutoff: 2_000, facet: "-" })), ["ov-t"], "facet - = the non-gate park");
|
|
492
|
+
const first = await store.listOverdue({ cutoff: 2_000, facet: "A", limit: 2 });
|
|
493
|
+
assert.deepEqual(tokensOf(first), ["ov-a0", "ov-a1"], "the bound cuts the page");
|
|
494
|
+
assert.ok(first.next !== undefined, "a cut page carries the next cursor");
|
|
495
|
+
const second = await store.listOverdue({ cutoff: 2_000, facet: "A", limit: 2, after: first.next });
|
|
496
|
+
assert.deepEqual(tokensOf(second), ["ov-a2"], "the cursor resumes after the last row of the page before");
|
|
497
|
+
assert.equal(second.next, undefined, "the last page carries no cursor");
|
|
498
|
+
assert.equal((await store.get(question.token)).status, "pending", "read-only: the listing mutates nothing");
|
|
499
|
+
for (const bad of [{ cutoff: 2_000, facet: "A", limit: 0 }, { cutoff: 2_000, facet: "A", limit: 501 }, { cutoff: 2_000, facet: "A", limit: 1.5 }, { cutoff: Number.NaN, facet: "A" }, { cutoff: 2_000, facet: "C" }, { cutoff: 2_000, facet: "A", scope: "tenant-a" }]) {
|
|
500
|
+
await assert.rejects(store.listOverdue(bad), (e) => e.code === "config.invalid_argument", `refused loudly: ${JSON.stringify(bad)}`);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
run("listBySession (when offered): one session's rows in any status narrowed by status / gate kinds / tool call / scope / createdSince, oldest or newest first, the bound cut with a resuming cursor, an empty gate-kind list matching nothing, a bad query refused", async () => {
|
|
504
|
+
const store = make();
|
|
505
|
+
if (store.listBySession === undefined)
|
|
506
|
+
return;
|
|
507
|
+
const s = "sess-list";
|
|
508
|
+
const rows = [
|
|
509
|
+
createCheckpointFixture({ token: "ls-1", sessionId: s, createdAt: 1 }),
|
|
510
|
+
createCheckpointFixture({ token: "ls-2", sessionId: s, createdAt: 2, pendingAction: { kind: "tool_approval", origin: "policy", toolCallId: "call-9", toolName: "Write", args: {}, boundInputHash: "h9", boundGrantAbsence: "not_bindable", batchToolCallIds: ["call-9"], completedCallIds: [] } }),
|
|
511
|
+
createCheckpointFixture({ token: "ls-3", sessionId: s, createdAt: 3, gate: { kind: "resource_limit", reason: "turns" }, pendingAction: { kind: "resource_limit", reason: "turns" } }),
|
|
512
|
+
createCheckpointFixture({ token: "ls-4", sessionId: s, createdAt: 4, scope: "tenant-b" }),
|
|
513
|
+
createCheckpointFixture({ token: "ls-x", sessionId: "another-session", createdAt: 1 }),
|
|
514
|
+
];
|
|
515
|
+
for (const cp of rows)
|
|
516
|
+
await store.put(cp.token, cp);
|
|
517
|
+
await store.resolve("ls-1", "tenant-a", ALLOW);
|
|
518
|
+
await store.expire("ls-3", "tenant-a");
|
|
519
|
+
const tokensOf = (page) => page.rows.map((r) => {
|
|
520
|
+
const read = r;
|
|
521
|
+
assert.equal(read.kind, "row", "a readable row is answered as a row");
|
|
522
|
+
return read.checkpoint.token;
|
|
523
|
+
});
|
|
524
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s })), ["ls-1", "ls-2", "ls-3", "ls-4"], "every status, every scope, oldest first; another session's row never");
|
|
525
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, order: "newest" })), ["ls-4", "ls-3", "ls-2", "ls-1"]);
|
|
526
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, status: "pending", gateKinds: ["human"], order: "newest", limit: 1 })), ["ls-4"], "the session's newest pending row of a gate kind");
|
|
527
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, status: "pending", gateKinds: ["human"], scope: "tenant-a" })), ["ls-2"]);
|
|
528
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, gateKinds: [] })), [], "an empty gate-kind list matches no row");
|
|
529
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, status: "expired", limit: 1 })), ["ls-3"]);
|
|
530
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, toolCallId: "call-3" })), ["ls-1", "ls-4"], "the rows that parked this tool call (a park with no tool call never matches)");
|
|
531
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, toolCallId: "call-9", status: "pending" })), ["ls-2"]);
|
|
532
|
+
assert.deepEqual(tokensOf(await store.listBySession({ sessionId: s, createdSince: 3 })), ["ls-3", "ls-4"]);
|
|
533
|
+
const first = await store.listBySession({ sessionId: s, limit: 3, order: "newest" });
|
|
534
|
+
assert.deepEqual(tokensOf(first), ["ls-4", "ls-3", "ls-2"]);
|
|
535
|
+
assert.ok(first.next !== undefined, "a cut page carries the next cursor");
|
|
536
|
+
const second = await store.listBySession({ sessionId: s, limit: 3, order: "newest", after: first.next });
|
|
537
|
+
assert.deepEqual(tokensOf(second), ["ls-1"]);
|
|
538
|
+
assert.equal(second.next, undefined);
|
|
539
|
+
const read = (await store.listBySession({ sessionId: s, toolCallId: "call-9" })).rows[0];
|
|
540
|
+
read.checkpoint.status = "expired";
|
|
541
|
+
assert.equal((await store.get("ls-2")).status, "pending", "a listed row is a copy: mutating it changes nothing stored");
|
|
542
|
+
for (const bad of [{ sessionId: "" }, { sessionId: s, limit: 101 }, { sessionId: s, limit: 0 }, { sessionId: s, status: "done" }, { sessionId: s, gateKinds: ["nope"] }, { sessionId: s, order: "latest" }, { sessionId: s, createdSince: Number.POSITIVE_INFINITY }, { sessionId: s, owner: "x" }]) {
|
|
543
|
+
await assert.rejects(store.listBySession(bad), (e) => e.code === "config.invalid_argument", `refused loudly: ${JSON.stringify(bad)}`);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
run("deleteSessionCheckpoints (when offered): every row of the session, in any status, only when the session row exists and its owner equals the guard's (null-safe); otherwise nothing is deleted and the answer is 0", async () => {
|
|
547
|
+
const store = make();
|
|
548
|
+
if (store.deleteSessionCheckpoints === undefined)
|
|
549
|
+
return;
|
|
550
|
+
const heads = options.sessionHeads;
|
|
551
|
+
assert.ok(heads !== undefined, "a store offering deleteSessionCheckpoints is judged with the binding's `sessionHeads` (the map its session head read reads)");
|
|
552
|
+
heads.set("del-owned", { owner: "alice" });
|
|
553
|
+
heads.set("del-anon", { owner: null });
|
|
554
|
+
const owned = [
|
|
555
|
+
createCheckpointFixture({ sessionId: "del-owned" }),
|
|
556
|
+
createCheckpointFixture({ sessionId: "del-owned" }),
|
|
557
|
+
createCheckpointFixture({ sessionId: "del-owned" }),
|
|
558
|
+
createCheckpointFixture({ sessionId: "del-owned", scope: "tenant-b" }),
|
|
559
|
+
];
|
|
560
|
+
const anon = createCheckpointFixture({ sessionId: "del-anon" });
|
|
561
|
+
const orphan = createCheckpointFixture({ sessionId: "del-no-row" });
|
|
562
|
+
const bystander = createCheckpointFixture({ sessionId: "del-other" });
|
|
563
|
+
for (const cp of [...owned, anon, orphan, bystander])
|
|
564
|
+
await store.put(cp.token, cp);
|
|
565
|
+
await store.resolve(owned[1].token, owned[1].scope, ALLOW);
|
|
566
|
+
await store.expire(owned[2].token, owned[2].scope);
|
|
567
|
+
assert.equal(await store.deleteSessionCheckpoints("del-owned", { owner: "bob" }), 0, "another owner deletes nothing");
|
|
568
|
+
assert.equal(await store.deleteSessionCheckpoints("del-owned", { owner: null }), 0, "the anonymous guard does not match an owned session");
|
|
569
|
+
assert.equal(await store.deleteSessionCheckpoints("del-no-row", { owner: null }), 0, "no session row deletes nothing");
|
|
570
|
+
assert.ok((await store.get(orphan.token)) !== null && (await store.get(owned[0].token)) !== null, "a refused guard leaves every row");
|
|
571
|
+
assert.equal(await store.deleteSessionCheckpoints("del-owned", { owner: "alice" }), 4, "the owner's guard deletes the session's rows — pending, resolved, expired, in every scope");
|
|
572
|
+
for (const cp of owned)
|
|
573
|
+
assert.equal(await store.get(cp.token), null);
|
|
574
|
+
assert.equal(await store.deleteSessionCheckpoints("del-anon", { owner: null }), 1, "the anonymous guard deletes an anonymous session's rows");
|
|
575
|
+
assert.ok((await store.get(bystander.token)) !== null, "another session's row stays");
|
|
576
|
+
assert.equal(await store.deleteSessionCheckpoints("del-owned", { owner: "alice" }), 0, "a second delete finds nothing");
|
|
577
|
+
const deleteWith = store.deleteSessionCheckpoints;
|
|
578
|
+
for (const guard of [{}, { owner: undefined }, { owner: 7 }]) {
|
|
579
|
+
const call = () => Reflect.apply(deleteWith, store, ["del-other", guard]);
|
|
580
|
+
await assert.rejects(call, (e) => e.code === "config.invalid_argument", `refused loudly: ${JSON.stringify(guard)}`);
|
|
581
|
+
}
|
|
582
|
+
assert.ok((await store.get(bystander.token)) !== null, "a refused guard deletes nothing");
|
|
583
|
+
});
|
|
584
|
+
run("claim holder (when declared `fence.holder`): a resolve carrying `expect.holder` wins only while the holder is current; a superseded holder loses with the row pending at the same rev (claimTerminal, when offered, answers that reading); no holder is unchanged", async () => {
|
|
585
|
+
const store = make();
|
|
586
|
+
if (store.fence?.holder !== true)
|
|
587
|
+
return;
|
|
588
|
+
const holders = options.holders;
|
|
589
|
+
assert.ok(holders !== undefined, "a store declaring `fence.holder` is judged with the binding's `holders` (the set its holder judge reads)");
|
|
590
|
+
holders.add("kit-holder-current");
|
|
591
|
+
const [a, b, c] = [createCheckpointFixture(), createCheckpointFixture(), createCheckpointFixture()];
|
|
592
|
+
for (const cp of [a, b, c])
|
|
593
|
+
await store.put(cp.token, cp);
|
|
594
|
+
assert.equal(await store.resolve(a.token, a.scope, ALLOW, { rev: 0, holder: "kit-holder-gone" }), false, "a holder that is not current loses");
|
|
595
|
+
const after = (await store.get(a.token));
|
|
596
|
+
assert.deepEqual([after.status, after.rev ?? 0], ["pending", 0], "the row is untouched by the lost CAS");
|
|
597
|
+
if (store.claimTerminal !== undefined) {
|
|
598
|
+
assert.deepEqual(await store.claimTerminal(a.token, a.scope, { kind: "resolve", outcome: ALLOW, expect: { rev: 0, holder: "kit-holder-gone" } }), { claimed: false, current: { status: "pending", rev: 0 } });
|
|
599
|
+
}
|
|
600
|
+
assert.equal(await store.resolve(a.token, a.scope, ALLOW, { rev: 0, holder: "kit-holder-current" }), true, "the current holder wins");
|
|
601
|
+
holders.delete("kit-holder-current");
|
|
602
|
+
assert.equal(await store.resolve(b.token, b.scope, ALLOW, { rev: 0, holder: "kit-holder-current" }), false, "a holder released after an earlier win is judged afresh");
|
|
603
|
+
assert.equal(await store.resolve(c.token, c.scope, ALLOW, { rev: 0 }), true, "no holder: the CAS is as before");
|
|
604
|
+
});
|
|
466
605
|
await settle();
|
|
467
606
|
}
|
|
468
607
|
const sortByToken = (a, b) => a.token.localeCompare(b.token);
|