@sema-agent/core 7.55.0 → 7.56.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 +513 -0
- 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/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-session-drain.js +2 -2
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +4 -4
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +64 -60
- 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 +30 -73
- 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 +13 -26
- package/dist/brain/openai.js +14 -87
- 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 +7 -4
- package/dist/brain/request-params.js +7 -4
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- 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 +20 -13
- package/dist/core/allow-entry.js +26 -22
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/ask-origin.d.ts +64 -18
- 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/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 +13 -1
- package/dist/core/checkpoint-requirements.js +4 -0
- package/dist/core/checkpoint-store.d.ts +88 -24
- package/dist/core/checkpoint-store.js +24 -9
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +1 -3
- 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 +30 -11
- package/dist/core/file-history-store.d.ts +90 -14
- package/dist/core/file-history-store.js +23 -15
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -64
- 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 +17 -16
- 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/mcp.d.ts +5 -1
- package/dist/core/mcp.js +67 -41
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- 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 +65 -6
- 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 +1 -0
- package/dist/core/permission-rule-consent.d.ts +19 -0
- package/dist/core/permission-rule-consent.js +116 -26
- package/dist/core/permission-rule-model.d.ts +14 -3
- package/dist/core/permission-rule-model.js +39 -24
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- 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 +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- 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 +31 -19
- 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/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +28 -25
- 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/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 +4 -4
- package/dist/core/runner/permission-rule-lanes.js +26 -10
- 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-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 +29 -38
- package/dist/core/runner/prepare-config-doors.js +42 -25
- 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 +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -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.js +5 -5
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +65 -72
- 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 +1 -1
- package/dist/core/runner/prepare-task.js +29 -20
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
- 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 +15 -0
- package/dist/core/runner/rewind-files.js +132 -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 +30 -18
- package/dist/core/runner/run-settle-and-teardown.js +2 -1
- package/dist/core/runner/run-turn-boundary.js +1 -10
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- 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/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 +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -7
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- 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 +5 -5
- 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 +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +27 -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.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/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
- package/dist/core/store-contracts/file-history-store-contract.js +31 -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.d.ts +9 -0
- package/dist/core/task-registry.js +11 -1
- 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 +17 -0
- package/dist/core/tool-catalog-entries.js +13 -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 +16 -16
- package/dist/core/tool-name-aliases.js +13 -19
- package/dist/core/tool-name-readings.d.ts +5 -35
- package/dist/core/tool-name-readings.js +1 -9
- package/dist/core/tool-policy.d.ts +68 -198
- package/dist/core/tool-policy.js +149 -198
- 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 +2 -2
- package/dist/core/types.d.ts +1 -1
- 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 +25 -1
- package/dist/engine/harness/agent-harness.js +54 -7
- 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 +22 -0
- package/dist/engine/loop/agent-loop.js +16 -26
- 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 +22 -10
- package/dist/index.js +15 -7
- package/dist/internal/harness-types.d.ts +1 -1
- 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/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 -0
- package/dist/stores/file/checkpoint-store.js +38 -6
- package/dist/stores/file/file-history-store.js +6 -7
- package/dist/stores/file/index.js +2 -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/fs-bash.js +5 -5
- 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 +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -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.js +6 -19
- 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-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 +38 -55
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +143 -5
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
|
@@ -2,7 +2,7 @@ import { webFetchToolSpec, createWebSearchTool } from "../tools/web.js";
|
|
|
2
2
|
import { createTodoWriteTool } from "../tools/todo.js";
|
|
3
3
|
import { createTaskListTools } from "../tools/task-list.js";
|
|
4
4
|
import { createSubagentTool } from "../agents/subagent.js";
|
|
5
|
-
import {
|
|
5
|
+
import { namesRoleBase } from "../prompt-assembly/role-base.js";
|
|
6
6
|
export function assembleCodeTools(cfg = {}) {
|
|
7
7
|
const web = [webFetchToolSpec(cfg.webFetch ?? {})];
|
|
8
8
|
if (cfg.webSearch)
|
|
@@ -19,13 +19,14 @@ export function assembleCodeTools(cfg = {}) {
|
|
|
19
19
|
}
|
|
20
20
|
const tools = [...web];
|
|
21
21
|
if (cfg.subagent) {
|
|
22
|
+
const roleBase = namesRoleBase(cfg.subagent) ? {} : { promptRole: "code" };
|
|
22
23
|
tools.push(createSubagentTool({
|
|
23
24
|
...cfg.subagent,
|
|
24
|
-
|
|
25
|
+
...roleBase,
|
|
25
26
|
inheritedTools: cfg.subagent.inheritedTools ?? [...web, ...scaffolds],
|
|
26
27
|
}));
|
|
27
28
|
}
|
|
28
29
|
tools.push(...scaffolds);
|
|
29
30
|
return tools;
|
|
30
31
|
}
|
|
31
|
-
export const CODE_ROLE = {
|
|
32
|
+
export const CODE_ROLE = { promptRole: "code", thinking: "high" };
|
package/dist/shell/lex.js
CHANGED
|
@@ -1169,6 +1169,7 @@ function scan(source, connectorsAreText, segments, level, list) {
|
|
|
1169
1169
|
let assignmentSeen = false;
|
|
1170
1170
|
let subscriptsClosed = false;
|
|
1171
1171
|
let commandWord;
|
|
1172
|
+
let arithParens = 0;
|
|
1172
1173
|
let w = new WordBuilder();
|
|
1173
1174
|
const next = (j) => past(source, j + 1);
|
|
1174
1175
|
const quotedBy = () => (inSingle || inDouble ? regionBy : undefined);
|
|
@@ -1503,7 +1504,7 @@ function scan(source, connectorsAreText, segments, level, list) {
|
|
|
1503
1504
|
take(ch, i);
|
|
1504
1505
|
continue;
|
|
1505
1506
|
}
|
|
1506
|
-
if (ch === "#" && !w.started) {
|
|
1507
|
+
if (ch === "#" && !w.started && arithParens === 0) {
|
|
1507
1508
|
const nl = source.indexOf("\n", i);
|
|
1508
1509
|
i = nl < 0 ? source.length : nl - 1;
|
|
1509
1510
|
continue;
|
|
@@ -1531,6 +1532,14 @@ function scan(source, connectorsAreText, segments, level, list) {
|
|
|
1531
1532
|
const r = endWord() ?? operandOwed(i);
|
|
1532
1533
|
if (r !== undefined)
|
|
1533
1534
|
return r;
|
|
1535
|
+
if (ch === "(") {
|
|
1536
|
+
if (arithParens > 0)
|
|
1537
|
+
arithParens++;
|
|
1538
|
+
else if (split && source[next(i)] === "(")
|
|
1539
|
+
arithParens = 1;
|
|
1540
|
+
}
|
|
1541
|
+
else if (arithParens > 0)
|
|
1542
|
+
arithParens--;
|
|
1534
1543
|
current().tokens.push({ kind: "group", op: ch });
|
|
1535
1544
|
resetPosition();
|
|
1536
1545
|
continue;
|
|
@@ -8,6 +8,7 @@ import { SessionPolicyError } from "../../../core/session-policy-store.js";
|
|
|
8
8
|
import { thrownText } from "../../../core/thrown-value.js";
|
|
9
9
|
import { AdoptionError, NOT_MIGRATED_BY_DESIGN, readRootAdoptionFile, writeRootAdoptionFile, } from "./marker.js";
|
|
10
10
|
import { readRuleOwner, ruleOwnerText, sameRuleOwner } from "../../../core/rule-owner.js";
|
|
11
|
+
import { principalNameOf } from "../../../core/principal-name.js";
|
|
11
12
|
const CONFIG_ACCOUNT_FILE = "adoption-configs.json";
|
|
12
13
|
function baselineConfigs(toPrincipal) {
|
|
13
14
|
return [
|
|
@@ -333,12 +334,12 @@ function answerFromExisting(root, existing, from, toPrincipal) {
|
|
|
333
334
|
return undefined;
|
|
334
335
|
}
|
|
335
336
|
export async function adoptLocalDataRoot(opts) {
|
|
336
|
-
if (
|
|
337
|
-
throw new AdoptionError("adoption_bad_request", "adoptLocalDataRoot requires the adopting principal — adoption is the act of giving this data root an identity");
|
|
337
|
+
if (principalNameOf(opts.toPrincipal) === undefined) {
|
|
338
|
+
throw new AdoptionError("adoption_bad_request", "adoptLocalDataRoot requires the adopting principal, a principal name — adoption is the act of giving this data root an identity");
|
|
338
339
|
}
|
|
339
340
|
const from = readRuleOwner(opts.from);
|
|
340
341
|
if (from === undefined) {
|
|
341
|
-
throw new AdoptionError("adoption_bad_request", "the adoption source must be the local-owner kind or a principal
|
|
342
|
+
throw new AdoptionError("adoption_bad_request", "the adoption source must be the local-owner kind or a principal owner whose principal is a principal name — local-single-user identity is the local-owner kind, never a blank string");
|
|
342
343
|
}
|
|
343
344
|
if (from.kind === "principal" && from.principal === opts.toPrincipal) {
|
|
344
345
|
throw new AdoptionError("adoption_bad_request", `the data root already belongs to "${opts.toPrincipal}" — there is nothing to adopt`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { readRuleOwner, sameRuleOwner } from "../../../core/rule-owner.js";
|
|
4
|
+
import { principalNameOf } from "../../../core/principal-name.js";
|
|
4
5
|
import { atomicWriteFile, ensureDir } from "../fs-atomic.js";
|
|
5
6
|
export class AdoptionError extends Error {
|
|
6
7
|
code;
|
|
@@ -39,7 +40,7 @@ function isRootAdoptionFileShape(v) {
|
|
|
39
40
|
typeof m !== "object" ||
|
|
40
41
|
typeof m.adoptionId !== "string" ||
|
|
41
42
|
readRuleOwner(m.from) === undefined ||
|
|
42
|
-
|
|
43
|
+
principalNameOf(m.toPrincipal) === undefined ||
|
|
43
44
|
typeof m.phase !== "number" ||
|
|
44
45
|
![2, 3, 4, 5].includes(m.phase)) {
|
|
45
46
|
return false;
|
|
@@ -88,7 +89,7 @@ function isRootAdoptionFileShape(v) {
|
|
|
88
89
|
if (a === null ||
|
|
89
90
|
typeof a !== "object" ||
|
|
90
91
|
from === undefined ||
|
|
91
|
-
|
|
92
|
+
principalNameOf(a.toPrincipal) === undefined ||
|
|
92
93
|
typeof a.atMs !== "number" ||
|
|
93
94
|
a.immutableReport === null ||
|
|
94
95
|
typeof a.immutableReport !== "object") {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ExecutionOutcomeRecordWord } from "../../core/checkpoint-execution-record.js";
|
|
2
|
+
import { type HolderJudge } from "../../core/checkpoint-generation.js";
|
|
2
3
|
import { type Checkpoint, type PendingSteerInput, type CheckpointFaultMode, type CheckpointStore, type CheckpointSummary, type CheckpointToken, type ReopenReason, type ResolveExpectation, type ResumeOutcome } from "../../core/checkpoint-store.js";
|
|
3
4
|
import type { GateOutcome } from "../../core/gate-outcome.js";
|
|
5
|
+
import { type CheckpointDeleteGuard, type CheckpointOverdueCursor, type CheckpointOverdueQuery, type CheckpointPage, type CheckpointRowRead, type CheckpointSessionCursor, type CheckpointSessionQuery } from "../../core/checkpoint-queries.js";
|
|
4
6
|
import { type CorruptReadInfo } from "./corrupt-read-sink.js";
|
|
5
7
|
export interface FileCheckpointStoreOptions {
|
|
6
8
|
/** This store's half of {@link import("./shared-ledger.js").LedgerPaths.onCorruptRead}. */
|
|
@@ -11,6 +13,13 @@ export interface FileCheckpointStoreOptions {
|
|
|
11
13
|
fsync?: boolean;
|
|
12
14
|
/** Compact the ledger into a snapshot once it exceeds this many events (then truncate). Default 1000. */
|
|
13
15
|
compactEvery?: number;
|
|
16
|
+
/** The session head read (a session store's `headOf`) {@link FileCheckpointStore.deleteSessionCheckpoints} judges its guard by;
|
|
17
|
+
* without it the store has no `deleteSessionCheckpoints` member. */
|
|
18
|
+
sessionHeadOf?: (sessionId: string) => Promise<{
|
|
19
|
+
readonly owner: string | null;
|
|
20
|
+
} | undefined>;
|
|
21
|
+
/** The judge of a resolve's claim holder ({@link HolderJudge}); with it the store declares `fence = { holder: true }`. */
|
|
22
|
+
holderIsCurrent?: HolderJudge;
|
|
14
23
|
}
|
|
15
24
|
export declare class FileCheckpointStore implements CheckpointStore {
|
|
16
25
|
/** design/173 §2.3 — honest declaration on the restart-survival axis the vocabulary claims: rows
|
|
@@ -34,6 +43,11 @@ export declare class FileCheckpointStore implements CheckpointStore {
|
|
|
34
43
|
readonly execution: {
|
|
35
44
|
readonly outcome: true;
|
|
36
45
|
};
|
|
46
|
+
/** Declared exactly when the store was built with a `holderIsCurrent` judge. */
|
|
47
|
+
readonly fence?: {
|
|
48
|
+
readonly holder: true;
|
|
49
|
+
};
|
|
50
|
+
private readonly holderIsCurrent;
|
|
37
51
|
private readonly fsyncEnabled;
|
|
38
52
|
private readonly compactEvery;
|
|
39
53
|
/** RB-134: the directory's ONE authority (map + token mutex + append log), joined not rebuilt. */
|
|
@@ -45,6 +59,8 @@ export declare class FileCheckpointStore implements CheckpointStore {
|
|
|
45
59
|
/** The guarded {@link FileCheckpointStoreOptions.onCorruptRead} seat (the ledger's replay and this store's projection share it). */
|
|
46
60
|
private readonly discloseCorrupt;
|
|
47
61
|
private readonly ledgerPath;
|
|
62
|
+
/** Present exactly when the store was built with a session head read (`FileCheckpointStoreOptions.sessionHeadOf`). */
|
|
63
|
+
readonly deleteSessionCheckpoints?: (sessionId: string, guard: CheckpointDeleteGuard) => Promise<number>;
|
|
48
64
|
constructor(root: string, opts?: FileCheckpointStoreOptions);
|
|
49
65
|
/** Serialize an op behind any in-flight op on the same token (the in-process per-token async mutex). */
|
|
50
66
|
private withLock;
|
|
@@ -69,6 +85,11 @@ export declare class FileCheckpointStore implements CheckpointStore {
|
|
|
69
85
|
reap(scope: string, cutoff: number): Promise<number>;
|
|
70
86
|
listByScope(scope: string): Promise<CheckpointSummary[]>;
|
|
71
87
|
listScopes(): Promise<string[]>;
|
|
88
|
+
/** The listing faces' disclosure: a row read past a damage is reported through the corrupt-read seat, named by its non-secret
|
|
89
|
+
* identity (never its token). */
|
|
90
|
+
private listingDisclose;
|
|
91
|
+
listOverdue(query: CheckpointOverdueQuery): Promise<CheckpointPage<CheckpointSummary, CheckpointOverdueCursor>>;
|
|
92
|
+
listBySession(query: CheckpointSessionQuery): Promise<CheckpointPage<CheckpointRowRead, CheckpointSessionCursor>>;
|
|
72
93
|
/** Force a compaction now (test/inspection). The snapshot rewrite + RB-167 closeForSwap swap that
|
|
73
94
|
* makes `replay` read the full state from the snapshot alone is the base's {@link LedgerCore.compact}. */
|
|
74
95
|
compactNow(): void;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { assertAdoptionBootGate } from "./adoption/marker.js";
|
|
3
3
|
import { checkpointExecutionRecorded, executionRecordDisposition, ExecutionOutcomeConflictError, } from "../../core/checkpoint-execution-record.js";
|
|
4
|
-
import {
|
|
4
|
+
import { checkpointHolderMatches, checkpointOccMatches, checkpointRevOf } from "../../core/checkpoint-generation.js";
|
|
5
|
+
import { appendPendingSteer, CheckpointError, checkpointRowMatches, encodeAtFidelity, summarizeCheckpoint, validatePendingSteer, winnerFromOutcome, } from "../../core/checkpoint-store.js";
|
|
6
|
+
import { checkpointDeadlinePassed, deleteSessionRowsAtStart, readCheckpointOverdueQuery, readCheckpointSessionQuery, selectOverduePage, selectSessionPage, } from "../../core/checkpoint-queries.js";
|
|
5
7
|
import { SharedLedgerTable } from "./shared-ledger.js";
|
|
6
8
|
import { guardCorruptSink } from "./corrupt-read-sink.js";
|
|
7
9
|
const CHECKPOINT_LEDGER_EVENT_REGISTRY = {
|
|
@@ -10,6 +12,7 @@ const CHECKPOINT_LEDGER_EVENT_REGISTRY = {
|
|
|
10
12
|
reopen: true,
|
|
11
13
|
execution: true,
|
|
12
14
|
expire: true,
|
|
15
|
+
delete: true,
|
|
13
16
|
steer_append: true,
|
|
14
17
|
};
|
|
15
18
|
const KNOWN_CHECKPOINT_LEDGER_EVENTS = new Set(Object.keys(CHECKPOINT_LEDGER_EVENT_REGISTRY));
|
|
@@ -45,6 +48,9 @@ function applyCheckpointEvent(cps, ev) {
|
|
|
45
48
|
case "expire":
|
|
46
49
|
cp.status = "expired";
|
|
47
50
|
break;
|
|
51
|
+
case "delete":
|
|
52
|
+
cps.delete(ev.token);
|
|
53
|
+
break;
|
|
48
54
|
case "steer_append": {
|
|
49
55
|
const queue = cp.state.pendingSteerQueue ?? [];
|
|
50
56
|
if (!queue.some((e) => e.inputId === ev.entry.inputId))
|
|
@@ -84,6 +90,7 @@ export class FileCheckpointStore {
|
|
|
84
90
|
fidelity = "json";
|
|
85
91
|
redecision = { reopen: true };
|
|
86
92
|
execution = { outcome: true };
|
|
93
|
+
holderIsCurrent;
|
|
87
94
|
fsyncEnabled;
|
|
88
95
|
compactEvery;
|
|
89
96
|
ledger;
|
|
@@ -97,6 +104,9 @@ export class FileCheckpointStore {
|
|
|
97
104
|
constructor(root, opts = {}) {
|
|
98
105
|
assertAdoptionBootGate(root, "FileCheckpointStore");
|
|
99
106
|
this.fsyncEnabled = opts.fsync !== false;
|
|
107
|
+
this.holderIsCurrent = opts.holderIsCurrent;
|
|
108
|
+
if (opts.holderIsCurrent !== undefined)
|
|
109
|
+
this.fence = Object.freeze({ holder: true });
|
|
100
110
|
this.compactEvery = opts.compactEvery ?? 1000;
|
|
101
111
|
this.discloseCorrupt = guardCorruptSink(opts.onCorruptRead);
|
|
102
112
|
const dir = join(root, "checkpoints");
|
|
@@ -108,6 +118,15 @@ export class FileCheckpointStore {
|
|
|
108
118
|
ledgerPath: this.ledgerPath,
|
|
109
119
|
snapshotPath: join(dir, "checkpoints.snapshot.jsonl"),
|
|
110
120
|
});
|
|
121
|
+
const headOf = opts.sessionHeadOf;
|
|
122
|
+
if (headOf !== undefined) {
|
|
123
|
+
this.deleteSessionCheckpoints = (sessionId, guard) => deleteSessionRowsAtStart(this.cps, sessionId, guard, headOf, (token, row) => this.withLock(token, () => {
|
|
124
|
+
if (this.cps.get(token) !== row)
|
|
125
|
+
return false;
|
|
126
|
+
this.commit({ t: "delete", token }, true);
|
|
127
|
+
return true;
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
111
130
|
}
|
|
112
131
|
withLock(token, fn) {
|
|
113
132
|
return this.ledger.withLock(token, fn);
|
|
@@ -144,8 +163,11 @@ export class FileCheckpointStore {
|
|
|
144
163
|
if (!checkpointOccMatches(cp, expect)) {
|
|
145
164
|
return false;
|
|
146
165
|
}
|
|
166
|
+
if (!checkpointHolderMatches(expect, this.holderIsCurrent)) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
147
169
|
const winner = winnerFromOutcome(outcome);
|
|
148
|
-
const rev = (cp
|
|
170
|
+
const rev = checkpointRevOf(cp) + 1;
|
|
149
171
|
this.commit({ t: "resolve", token, rev, resolvedOutcome: winner }, true);
|
|
150
172
|
if (this.fault === "resolve-after-commit") {
|
|
151
173
|
this.fault = null;
|
|
@@ -172,7 +194,7 @@ export class FileCheckpointStore {
|
|
|
172
194
|
if (!checkpointRowMatches(cp, scope, "resolved") || checkpointExecutionRecorded(cp)) {
|
|
173
195
|
return false;
|
|
174
196
|
}
|
|
175
|
-
const rev = (cp
|
|
197
|
+
const rev = checkpointRevOf(cp) + 1;
|
|
176
198
|
this.commit({ t: "reopen", token, rev, reason }, true);
|
|
177
199
|
return true;
|
|
178
200
|
});
|
|
@@ -204,7 +226,7 @@ export class FileCheckpointStore {
|
|
|
204
226
|
}
|
|
205
227
|
async reap(scope, cutoff) {
|
|
206
228
|
let n = 0;
|
|
207
|
-
const deadlinePassed = (deadline) =>
|
|
229
|
+
const deadlinePassed = (deadline) => checkpointDeadlinePassed(deadline, cutoff);
|
|
208
230
|
const candidates = [...this.cps.values()].filter((cp) => cp.scope === scope && cp.status === "pending" && deadlinePassed(cp.deadline));
|
|
209
231
|
for (const cp of candidates) {
|
|
210
232
|
const won = await this.withLock(cp.token, () => {
|
|
@@ -222,8 +244,7 @@ export class FileCheckpointStore {
|
|
|
222
244
|
return n;
|
|
223
245
|
}
|
|
224
246
|
async listByScope(scope) {
|
|
225
|
-
const
|
|
226
|
-
const disclose = sink === undefined ? undefined : (sentence) => sink({ kind: "file", path: this.ledgerPath, reason: sentence });
|
|
247
|
+
const disclose = this.listingDisclose();
|
|
227
248
|
const out = [];
|
|
228
249
|
for (const cp of this.cps.values()) {
|
|
229
250
|
if (cp.scope === scope && cp.status === "pending")
|
|
@@ -238,6 +259,17 @@ export class FileCheckpointStore {
|
|
|
238
259
|
out.add(cp.scope);
|
|
239
260
|
return [...out];
|
|
240
261
|
}
|
|
262
|
+
listingDisclose() {
|
|
263
|
+
const sink = this.discloseCorrupt;
|
|
264
|
+
return sink === undefined ? undefined : (sentence) => sink({ kind: "file", path: this.ledgerPath, reason: sentence });
|
|
265
|
+
}
|
|
266
|
+
async listOverdue(query) {
|
|
267
|
+
const disclose = this.listingDisclose();
|
|
268
|
+
return selectOverduePage(this.cps.entries(), readCheckpointOverdueQuery(query), (cp) => summarizeCheckpoint(cp, disclose), disclose);
|
|
269
|
+
}
|
|
270
|
+
async listBySession(query) {
|
|
271
|
+
return selectSessionPage(this.cps.entries(), readCheckpointSessionQuery(query), (cp) => structuredClone(cp), this.listingDisclose());
|
|
272
|
+
}
|
|
241
273
|
compactNow() {
|
|
242
274
|
this.ledger.compact();
|
|
243
275
|
}
|
|
@@ -2,7 +2,7 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
2
2
|
import { appendFileSync, closeSync, existsSync, fsyncSync, openSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { thrownText } from "../../core/thrown-value.js";
|
|
5
|
-
import { applyFileRestoreViaEnv, boundaryPublishVerdict, worldStillMatchesMint, captureFileBackupViaEnv, modeProvenDifferent, previewFileDelta, describeTrackKey, fileHistoryExportDigest, caughtFault, DAMAGED_RECORD, resolveTrackKey, trackKeyOf, validateFileHistoryExport, } from "../../core/file-history-store.js";
|
|
5
|
+
import { applyFileRestoreViaEnv, boundaryPublishVerdict, worldStillMatchesMint, annulProofFailure, captureFileBackupViaEnv, modeProvenDifferent, previewFileDelta, describeTrackKey, fileHistoryExportDigest, caughtFault, DAMAGED_RECORD, resolveTrackKey, trackKeyOf, validateFileHistoryExport, } from "../../core/file-history-store.js";
|
|
6
6
|
import { fileHistoryBoundariesToKeep, resolveFileHistoryRetention } from "../../core/file-history-retention.js";
|
|
7
7
|
import { atomicWriteFile, ensureDir, sanitizePathComponent, sanitizeScope, writeThenLink } from "./fs-atomic.js";
|
|
8
8
|
import { guardCorruptSink } from "./corrupt-read-sink.js";
|
|
@@ -481,9 +481,8 @@ export class FileFileHistoryStore {
|
|
|
481
481
|
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} has since been served to another edit of the same path — it is that edit's baseline now, not a retractable mint` } };
|
|
482
482
|
}
|
|
483
483
|
const proof = verify === undefined ? undefined : await worldStillMatchesMint(verify.env, absPath, root, rec.baseAvailable, rec.versions[0]?.blobHash ?? null, verify.signal);
|
|
484
|
-
if (proof !== undefined &&
|
|
485
|
-
return
|
|
486
|
-
}
|
|
484
|
+
if (proof !== undefined && proof.verdict !== "unchanged")
|
|
485
|
+
return annulProofFailure(proof, absPath);
|
|
487
486
|
const fresh = this.readTrackedState(scope);
|
|
488
487
|
if (fresh.corrupt)
|
|
489
488
|
return { ok: false, error: { code: "track_failed", message: `file history for scope "${scope}" became unreadable — the record was left in place`, ...fresh.fault } };
|
|
@@ -723,7 +722,7 @@ export class FileFileHistoryStore {
|
|
|
723
722
|
let targetVersion = boundary.get(key);
|
|
724
723
|
if (targetVersion === undefined) {
|
|
725
724
|
if (!rec.baseAvailable) {
|
|
726
|
-
ledger.refused.push({ path: key, reason: "base_unavailable" });
|
|
725
|
+
ledger.refused.push({ path: key, reason: "base_unavailable", class: "base_unavailable" });
|
|
727
726
|
continue;
|
|
728
727
|
}
|
|
729
728
|
targetVersion = 1;
|
|
@@ -735,7 +734,7 @@ export class FileFileHistoryStore {
|
|
|
735
734
|
}
|
|
736
735
|
const resolved = resolveTrackKey(root, key, descriptorOf(rec));
|
|
737
736
|
if (!resolved.ok) {
|
|
738
|
-
ledger.refused.push({ path: key, reason: resolved.reason });
|
|
737
|
+
ledger.refused.push({ path: key, reason: resolved.reason, class: resolved.class });
|
|
739
738
|
continue;
|
|
740
739
|
}
|
|
741
740
|
let target;
|
|
@@ -777,7 +776,7 @@ export class FileFileHistoryStore {
|
|
|
777
776
|
else if (applied.outcome === "identical")
|
|
778
777
|
ledger.identicalSkipped.push(key);
|
|
779
778
|
else if (applied.outcome === "refused")
|
|
780
|
-
ledger.refused.push({ path: key, reason: applied.reason });
|
|
779
|
+
ledger.refused.push({ path: key, reason: applied.reason, class: applied.class });
|
|
781
780
|
else
|
|
782
781
|
ledger.failed.push({ path: key, reason: applied.reason });
|
|
783
782
|
if ((applied.outcome === "applied" || applied.outcome === "identical") && applied.modeNotPreserved === true)
|
|
@@ -62,7 +62,8 @@ export class FileStorageBackend {
|
|
|
62
62
|
this.fileSessions = repo;
|
|
63
63
|
this.ttl = new TtlSessionStore({ repo, evict: opts.evict ?? "forget", durability: "durable", placements: { subagent: { durability: "durable" } } });
|
|
64
64
|
this.sessionStore = this.ttl;
|
|
65
|
-
|
|
65
|
+
const sessionHeadOf = this.ttl.headOf;
|
|
66
|
+
this.fileCheckpoints = new FileCheckpointStore(this.root, { ...opts.checkpoint, ...corruptRead, ...(sessionHeadOf !== undefined ? { sessionHeadOf } : {}) });
|
|
66
67
|
built.push(() => this.fileCheckpoints.close());
|
|
67
68
|
this.checkpointStore = this.fileCheckpoints;
|
|
68
69
|
this.fileMemory = new FileMemoryStore(this.root, opts.embedder ? { embedder: opts.embedder } : {});
|
|
@@ -2,18 +2,19 @@ import { existsSync, renameSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writerOf } from "../../core/permission-rule-store.js";
|
|
4
4
|
import { readRuleOwner, ruleOwnerText, sameRuleOwner } from "../../core/rule-owner.js";
|
|
5
|
+
import { principalNameOf } from "../../core/principal-name.js";
|
|
5
6
|
import { createPermissionRuleStoreProvider } from "../../core/permission-rule-provider.js";
|
|
6
7
|
import { syncPermissionRules } from "../../core/permission-rule-sync.js";
|
|
7
8
|
import { thrownText } from "../../core/thrown-value.js";
|
|
8
9
|
import { FileStoreLockError } from "./fs-atomic.js";
|
|
9
10
|
import { FileDurableRulePartitionProvider, LOCAL_OWNER_FILE, principalRuleFileName, readRuleAdoptionFile, writeRuleAdoptionFile, } from "./permission-rule-store.js";
|
|
10
11
|
export async function adoptFilePermissionRuleStore(opts) {
|
|
11
|
-
if (
|
|
12
|
-
throw new Error("adoptFilePermissionRuleStore requires the adopting principal — adoption is the act of giving this bucket an identity");
|
|
12
|
+
if (principalNameOf(opts.toPrincipal) === undefined) {
|
|
13
|
+
throw new Error("adoptFilePermissionRuleStore requires the adopting principal, a principal name — adoption is the act of giving this bucket an identity");
|
|
13
14
|
}
|
|
14
15
|
const from = readRuleOwner(opts.from);
|
|
15
16
|
if (from === undefined) {
|
|
16
|
-
throw new Error("adoptFilePermissionRuleStore requires a source owner — a principal
|
|
17
|
+
throw new Error("adoptFilePermissionRuleStore requires a source owner — a principal owner whose principal is a principal name, or the local owner");
|
|
17
18
|
}
|
|
18
19
|
if (from.kind === "principal" && from.principal === opts.toPrincipal) {
|
|
19
20
|
throw new Error(`the bucket already belongs to "${opts.toPrincipal}" — there is nothing to adopt`);
|
|
@@ -4,6 +4,7 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
4
4
|
import { isRuleBehavior } from "../../core/permission-rule-model.js";
|
|
5
5
|
import { posixModeBitsMeaningful } from "../../core/posix-mode-face.js";
|
|
6
6
|
import { readRuleOwner } from "../../core/rule-owner.js";
|
|
7
|
+
import { principalNameOf, readPrincipal } from "../../core/principal-name.js";
|
|
7
8
|
import { PERMISSION_RULES_LATER_GRAMMAR_CODE, PERMISSION_RULE_WRITER, applySyncJoin, applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, unknownRuleWriteDeltaError, } from "../../core/permission-rule-store.js";
|
|
8
9
|
import { sameOrgPolicyContent } from "../../core/permission-rule-org.js";
|
|
9
10
|
import { SESSION_RULES_GRAMMAR, readRuleGrammarStamp } from "../../core/session-policy-store.js";
|
|
@@ -66,7 +67,7 @@ function isRuleAdoptionFileShape(v) {
|
|
|
66
67
|
const rec = (hasMarker ? v.marker : v.adopted);
|
|
67
68
|
if (rec === null || typeof rec !== "object")
|
|
68
69
|
return false;
|
|
69
|
-
if (readRuleOwner(rec.from) === undefined ||
|
|
70
|
+
if (readRuleOwner(rec.from) === undefined || principalNameOf(rec.toPrincipal) === undefined)
|
|
70
71
|
return false;
|
|
71
72
|
return hasMarker ? rec.phase === 2 || rec.phase === 3 || rec.phase === 4 || rec.phase === 5 : typeof rec.atMs === "number" && Number.isFinite(rec.atMs);
|
|
72
73
|
}
|
|
@@ -452,17 +453,22 @@ export class FileDurableRulePartitionProvider {
|
|
|
452
453
|
this.lock = lock;
|
|
453
454
|
};
|
|
454
455
|
forPrincipal(principal) {
|
|
455
|
-
|
|
456
|
+
const reading = readPrincipal(principal);
|
|
457
|
+
if (reading.kind === "invalid") {
|
|
458
|
+
throw new Error(`the principal given is not a principal name (got ${reading.fault}) — refusing to resolve a bucket for it; a provided value that names nobody is not "no principal"`);
|
|
459
|
+
}
|
|
460
|
+
if (reading.kind === "absent") {
|
|
456
461
|
return { list: async () => ({ ...EMPTY_READ }), durability: "process-local" };
|
|
457
462
|
}
|
|
463
|
+
const name = reading.name;
|
|
458
464
|
const adoption = this.adoptionMarker();
|
|
459
465
|
if (adoption !== undefined) {
|
|
460
466
|
const rec = "adopted" in adoption ? adoption.adopted : adoption.marker;
|
|
461
|
-
if (rec.from.kind === "principal" && rec.from.principal ===
|
|
462
|
-
return this.readOnlySourceView(principalRuleFileName(
|
|
467
|
+
if (rec.from.kind === "principal" && rec.from.principal === name) {
|
|
468
|
+
return this.readOnlySourceView(principalRuleFileName(name), principalRuleFileName(rec.toPrincipal), "adopted" in adoption || adoption.marker.phase >= 4);
|
|
463
469
|
}
|
|
464
470
|
}
|
|
465
|
-
return new FileDurableRulePartition(this.dir, join(this.dir, principalRuleFileName(
|
|
471
|
+
return new FileDurableRulePartition(this.dir, join(this.dir, principalRuleFileName(name)), this.acquireWriteLock, this.onError, this.vetting);
|
|
466
472
|
}
|
|
467
473
|
readOnlySourceView(sourceName, targetName, flipped) {
|
|
468
474
|
const pick = flipped ? targetName : existsSync(join(this.dir, sourceName)) ? sourceName : targetName;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Session, SessionCreateOptions, SessionForkOptions, SessionHead, SessionMetadata, SessionPlacementRecord, SessionRepo, SessionTreeEntry } from "../../internal/harness.js";
|
|
1
|
+
import type { Session, SessionCreateOptions, SessionForkOptions, SessionHead, SessionMetadata, SessionPlacementRecord, SessionRepo, SessionRow, SessionTreeEntry } from "../../internal/harness.js";
|
|
2
2
|
import type { PlacedSessionRow } from "../../core/session.js";
|
|
3
3
|
import { type CorruptReadInfo } from "./corrupt-read-sink.js";
|
|
4
4
|
export interface FileSessionRepoOptions {
|
|
@@ -8,8 +8,9 @@ export interface FileSessionRepoOptions {
|
|
|
8
8
|
* "corrupt read as missing" are one failure grammar, so they get one seat name.
|
|
9
9
|
*
|
|
10
10
|
* Fires for: an unreadable sessions DIRECTORY (the listing degrades to "no sessions"), a session log
|
|
11
|
-
*
|
|
12
|
-
* record dropped on replay plus that replay's
|
|
11
|
+
* whose header could not be read during a listing (skipped from the result — a listing reads headers,
|
|
12
|
+
* it never replays a log), and each corrupt interior JSONL record dropped on replay plus that replay's
|
|
13
|
+
* tally (turns missing from an otherwise healthy session).
|
|
13
14
|
*
|
|
14
15
|
* Never fires on plain ENOENT / `not_found` — that is honest absence, and the torn TAIL stays silent
|
|
15
16
|
* too (dying mid-write is the append log's documented crash-recovery shape, not corruption).
|
|
@@ -59,6 +60,15 @@ export declare class FileSessionRepo implements SessionRepo {
|
|
|
59
60
|
* head does not see. A leaf entry naming an id the log does not hold is not checked here (a replay refuses that log on open).
|
|
60
61
|
*/
|
|
61
62
|
headOf(sessionId: string): Promise<SessionHead | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* The row's {@link SessionRow} — its header cells and the newest write it holds, the log's modification time (every write to a row
|
|
65
|
+
* is an append to its log; the placed listing's age reads the same time) — in one read of the header, never a replay of the log.
|
|
66
|
+
* `undefined` = no row; a row whose header cannot be read rejects (`corrupt_session`).
|
|
67
|
+
*/
|
|
68
|
+
private rowOf;
|
|
69
|
+
/** The one descriptor a by-id read of the row takes: its size and modification time and its header, from one inode (a file replaced
|
|
70
|
+
* or removed while this reads is still the inode this descriptor opened); `undefined` = no file. */
|
|
71
|
+
private atRow;
|
|
62
72
|
private storage;
|
|
63
73
|
/**
|
|
64
74
|
* RB-437 — release every shared authority this repo joined (LAST holder ⇒ evict + close the append fd).
|
|
@@ -75,12 +85,25 @@ export declare class FileSessionRepo implements SessionRepo {
|
|
|
75
85
|
dispose(): Promise<void>;
|
|
76
86
|
create(options?: SessionCreateOptions): Promise<Session>;
|
|
77
87
|
open(metadata: SessionMetadata): Promise<Session>;
|
|
78
|
-
|
|
88
|
+
/** Record activity on the row now: its log's modification time — the one time a listing reads, which every append moves too — is
|
|
89
|
+
* set to now, the log's bytes untouched. A missing file is nothing to record; any other fault rejects. */
|
|
90
|
+
touch(sessionId: string): Promise<void>;
|
|
91
|
+
/** Every ordinary row with the newest write its log holds ({@link rowOf}): one header read per session file, no replay — what a
|
|
92
|
+
* listing costs grows with the number of sessions, never with their history. Placed rows are the placed listing's. */
|
|
93
|
+
list(): Promise<SessionRow[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Every row of the sessions directory, each read by {@link rowOf}. The listing degrades to "no sessions" so a
|
|
96
|
+
* browse face never throws — but "I could not read the directory" and "there are none" are different facts, and only the sink can
|
|
97
|
+
* tell them apart (ENOENT is honest absence: the constructor creates the directory, so it was removed underneath us). A session
|
|
98
|
+
* whose header cannot be read is skipped and disclosed — it exists and is missing from the listing — while a file that vanished
|
|
99
|
+
* between the directory read and its own is honest absence.
|
|
100
|
+
*/
|
|
101
|
+
private rows;
|
|
79
102
|
/**
|
|
80
103
|
* Subagent transcript persistence — the PLACED partition's own enumeration (the joint reap's
|
|
81
104
|
* partition-leg input; `TtlSessionStore` re-exposes it verbatim). Age (`olderThanMs`) is judged on
|
|
82
|
-
* the session FILE's mtime — the transcript's last append
|
|
83
|
-
*
|
|
105
|
+
* the session FILE's mtime — the transcript's last append, the time the host listing reads too
|
|
106
|
+
* (mtime is also the CC orphan-adoption window's basis, so the age reads agree).
|
|
84
107
|
* Rows missing either `(scope, handle)` join half return the honest `tupleIncomplete` variant
|
|
85
108
|
* (consumers fail closed on it — never age-reaped, see the SessionStore contract).
|
|
86
109
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { closeSync, existsSync, fstatSync, openSync, readdirSync, rmSync,
|
|
1
|
+
import { closeSync, existsSync, fstatSync, openSync, readdirSync, rmSync, utimesSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { BaseSessionStorage, StoredSession, SessionError, assertForkTarget, compareOccupants, forkRowCells, frozenRow, getEntriesToFork, importRowCells, incarnationCell, leafIdAfterEntry, ownerCell, readIncarnationCell, readOwnerCell, uuidv7, validateEntriesForImport, } from "../../internal/harness.js";
|
|
4
4
|
import { canonicalStoreKey, AppendLog, atomicWriteFile, ensureDir, firstJsonlRecord, lastJsonlRecord, readJsonlRecords, sanitizePathComponent, writeThenLink } from "./fs-atomic.js";
|
|
@@ -125,6 +125,15 @@ export class FileSessionRepo {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
async headOf(sessionId) {
|
|
128
|
+
return this.atRow(sessionId, (fd, size, meta) => {
|
|
129
|
+
const last = lastJsonlRecord(fd, size, (r) => r.kind === "entry", SESSION_LINE_JUDGE);
|
|
130
|
+
return { owner: meta.owner ?? null, incarnation: meta.incarnation, leafId: last === undefined ? null : leafIdAfterEntry(last.entry) };
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
rowOf(sessionId) {
|
|
134
|
+
return this.atRow(sessionId, (_fd, _size, meta, mtimeMs) => ({ ...meta, lastActiveAt: Math.trunc(mtimeMs) }));
|
|
135
|
+
}
|
|
136
|
+
atRow(sessionId, read) {
|
|
128
137
|
const path = this.pathFor(sessionId);
|
|
129
138
|
let fd;
|
|
130
139
|
try {
|
|
@@ -136,10 +145,8 @@ export class FileSessionRepo {
|
|
|
136
145
|
throw err;
|
|
137
146
|
}
|
|
138
147
|
try {
|
|
139
|
-
const size = fstatSync(fd)
|
|
140
|
-
|
|
141
|
-
const last = lastJsonlRecord(fd, size, (r) => r.kind === "entry", SESSION_LINE_JUDGE);
|
|
142
|
-
return { owner: meta.owner ?? null, incarnation: meta.incarnation, leafId: last === undefined ? null : leafIdAfterEntry(last.entry) };
|
|
148
|
+
const { size, mtimeMs } = fstatSync(fd);
|
|
149
|
+
return read(fd, size, this.headerOf(sessionId, path, firstJsonlRecord(fd, size, SESSION_LINE_JUDGE)), mtimeMs);
|
|
143
150
|
}
|
|
144
151
|
finally {
|
|
145
152
|
closeSync(fd);
|
|
@@ -201,80 +208,65 @@ export class FileSessionRepo {
|
|
|
201
208
|
const { meta, entries } = this.read(metadata.id);
|
|
202
209
|
return new StoredSession(this.storage(meta, entries));
|
|
203
210
|
}
|
|
204
|
-
async
|
|
205
|
-
|
|
211
|
+
async touch(sessionId) {
|
|
212
|
+
const now = new Date();
|
|
206
213
|
try {
|
|
207
|
-
|
|
214
|
+
utimesSync(this.pathFor(sessionId), now, now);
|
|
208
215
|
}
|
|
209
216
|
catch (err) {
|
|
210
|
-
if (err.code
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
return [];
|
|
214
|
-
}
|
|
215
|
-
const out = [];
|
|
216
|
-
for (const name of names) {
|
|
217
|
-
if (!name.endsWith(SUFFIX))
|
|
218
|
-
continue;
|
|
219
|
-
const id = name.slice(0, -SUFFIX.length);
|
|
220
|
-
try {
|
|
221
|
-
const { createdAt, forkedFrom, placement } = this.read(id).meta;
|
|
222
|
-
if (placement !== undefined)
|
|
223
|
-
continue;
|
|
224
|
-
out.push({ id, createdAt, ...(forkedFrom !== undefined ? { forkedFrom } : {}) });
|
|
225
|
-
}
|
|
226
|
-
catch (err) {
|
|
227
|
-
if (!(err instanceof SessionError && err.code === "not_found")) {
|
|
228
|
-
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from the listing`, id);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
217
|
+
if (err.code === "ENOENT")
|
|
218
|
+
return;
|
|
219
|
+
throw new SessionError("storage", `session ${sessionId}'s activity could not be recorded: ${thrownText(err)}`, err instanceof Error ? err : undefined);
|
|
231
220
|
}
|
|
232
|
-
return out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
233
221
|
}
|
|
234
|
-
async
|
|
222
|
+
async list() {
|
|
223
|
+
return this.rows("the listing")
|
|
224
|
+
.filter((row) => row.placement === undefined)
|
|
225
|
+
.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
226
|
+
}
|
|
227
|
+
rows(listing) {
|
|
235
228
|
let names;
|
|
236
229
|
try {
|
|
237
230
|
names = readdirSync(this.dir);
|
|
238
231
|
}
|
|
239
232
|
catch (err) {
|
|
240
233
|
if (err.code !== "ENOENT") {
|
|
241
|
-
this.disclose(this.dir, `session directory unreadable (${err.code ?? "unknown"}) —
|
|
234
|
+
this.disclose(this.dir, `session directory unreadable (${err.code ?? "unknown"}) — ${listing} degraded to empty`);
|
|
242
235
|
}
|
|
243
236
|
return [];
|
|
244
237
|
}
|
|
245
|
-
const now = Date.now();
|
|
246
238
|
const out = [];
|
|
247
239
|
for (const name of names) {
|
|
248
240
|
if (!name.endsWith(SUFFIX))
|
|
249
241
|
continue;
|
|
250
242
|
const id = name.slice(0, -SUFFIX.length);
|
|
251
|
-
let
|
|
243
|
+
let row;
|
|
252
244
|
try {
|
|
253
|
-
|
|
245
|
+
row = this.rowOf(id);
|
|
254
246
|
}
|
|
255
247
|
catch (err) {
|
|
256
|
-
|
|
257
|
-
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from the placed listing`, id);
|
|
258
|
-
}
|
|
248
|
+
this.disclose(this.pathFor(id), `session log unreadable (${thrownText(err)}) — skipped from ${listing}`, id);
|
|
259
249
|
continue;
|
|
260
250
|
}
|
|
251
|
+
if (row !== undefined)
|
|
252
|
+
out.push(row);
|
|
253
|
+
}
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
async listPlaced(kind, opts) {
|
|
257
|
+
const now = Date.now();
|
|
258
|
+
const out = [];
|
|
259
|
+
for (const row of this.rows("the placed listing")) {
|
|
260
|
+
const placement = row.placement;
|
|
261
261
|
if (placement === undefined || placement.kind !== kind)
|
|
262
262
|
continue;
|
|
263
263
|
if (opts?.scope !== undefined && placement.scope !== opts.scope)
|
|
264
264
|
continue;
|
|
265
|
-
if (opts?.olderThanMs !== undefined)
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
ageAnchor = statSync(this.pathFor(id)).mtimeMs;
|
|
269
|
-
}
|
|
270
|
-
catch {
|
|
271
|
-
}
|
|
272
|
-
if (now - ageAnchor <= opts.olderThanMs)
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
265
|
+
if (opts?.olderThanMs !== undefined && now - row.lastActiveAt <= opts.olderThanMs)
|
|
266
|
+
continue;
|
|
275
267
|
out.push(placement.scope !== undefined && placement.handle !== undefined
|
|
276
|
-
? { sessionId: id, placedAt: placement.placedAt, scope: placement.scope, handle: placement.handle }
|
|
277
|
-
: { sessionId: id, placedAt: placement.placedAt, tupleIncomplete: true });
|
|
268
|
+
? { sessionId: row.id, placedAt: placement.placedAt, scope: placement.scope, handle: placement.handle }
|
|
269
|
+
: { sessionId: row.id, placedAt: placement.placedAt, tupleIncomplete: true });
|
|
278
270
|
}
|
|
279
271
|
return out;
|
|
280
272
|
}
|