@sema-agent/core 7.48.0 → 7.49.1
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 +457 -0
- package/README.md +2 -2
- package/dist/agents/cascade.d.ts +2 -5
- package/dist/agents/child-failure.d.ts +20 -0
- package/dist/agents/child-failure.js +28 -0
- package/dist/agents/cross-session-ref.d.ts +11 -3
- package/dist/agents/cross-session-ref.js +6 -0
- package/dist/agents/cumulative-stats.d.ts +12 -15
- package/dist/agents/cumulative-stats.js +1 -1
- package/dist/agents/extra-tool-names.js +1 -1
- package/dist/agents/inherited-tool-pool.d.ts +17 -13
- package/dist/agents/inherited-tool-pool.js +4 -3
- package/dist/agents/peer-session-drain.d.ts +3 -2
- package/dist/agents/peer-session-drain.js +5 -4
- package/dist/agents/send-message-tool.js +2 -9
- package/dist/agents/subagent.d.ts +10 -29
- package/dist/agents/subagent.js +65 -53
- package/dist/agents/suspend-guard.d.ts +1 -1
- package/dist/agents/tool-filter.d.ts +76 -65
- package/dist/agents/tool-filter.js +122 -92
- package/dist/agents/verify.d.ts +4 -7
- package/dist/agents/verify.js +6 -7
- package/dist/bench/metrics.d.ts +1 -2
- package/dist/brain/anthropic.js +133 -79
- package/dist/brain/errors.d.ts +53 -6
- package/dist/brain/errors.js +22 -2
- package/dist/brain/input-too-long.d.ts +40 -19
- package/dist/brain/input-too-long.js +3 -16
- package/dist/brain/open-responses.js +19 -10
- package/dist/brain/openai.js +123 -32
- package/dist/brain/provider-dialect.d.ts +214 -0
- package/dist/brain/provider-dialect.js +186 -0
- package/dist/brain/request-params.d.ts +27 -8
- package/dist/brain/request-params.js +7 -12
- package/dist/brain/request-route.d.ts +84 -0
- package/dist/brain/request-route.js +41 -0
- package/dist/brain/retry.d.ts +8 -0
- package/dist/brain/retry.js +10 -4
- package/dist/brain/route-adjudicator.d.ts +7 -0
- package/dist/brain/route-adjudicator.js +5 -1
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +11 -0
- package/dist/brain/stream-engine.d.ts +52 -1
- package/dist/brain/stream-engine.js +81 -24
- package/dist/brain/stream-shared.d.ts +57 -11
- package/dist/brain/stream-shared.js +28 -2
- package/dist/core/a2a.d.ts +1 -0
- package/dist/core/agent-config-dir.js +3 -2
- package/dist/core/allow-entry.d.ts +21 -12
- package/dist/core/allow-entry.js +38 -31
- package/dist/core/arg-summary.d.ts +21 -28
- package/dist/core/arg-summary.js +235 -88
- package/dist/core/ask-origin.d.ts +42 -24
- package/dist/core/ask-origin.js +18 -13
- package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/auto-mode-prompt.d.ts +11 -1
- package/dist/core/auto-mode-prompt.js +13 -10
- package/dist/core/auto-mode-rebuild.d.ts +7 -0
- package/dist/core/auto-mode-rebuild.js +4 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.js +2 -1
- package/dist/core/checkpoint-requirements.d.ts +892 -0
- package/dist/core/checkpoint-requirements.js +333 -0
- package/dist/core/checkpoint-store.d.ts +94 -65
- package/dist/core/checkpoint-store.js +14 -26
- package/dist/core/child-clamp-seats.d.ts +228 -69
- package/dist/core/child-clamp-seats.js +211 -17
- package/dist/core/classifier-unavailable-arm.d.ts +5 -1
- package/dist/core/classifier-unavailable-arm.js +3 -3
- package/dist/core/compliance.d.ts +3 -0
- package/dist/core/compliance.js +9 -4
- package/dist/core/credential-vocabulary.d.ts +140 -0
- package/dist/core/credential-vocabulary.js +131 -0
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/effective-path-target.d.ts +73 -16
- package/dist/core/effective-path-target.js +63 -33
- package/dist/core/engine-notice.d.ts +43 -11
- package/dist/core/file-history-store.js +2 -2
- package/dist/core/fs-write-gate-policy.d.ts +4 -0
- package/dist/core/fs-write-gate-policy.js +22 -5
- package/dist/core/gate-bounded-await.d.ts +28 -13
- package/dist/core/gate-bounded-await.js +41 -4
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -25
- package/dist/core/gate-lanes.js +16 -15
- package/dist/core/gate-outcome.d.ts +20 -5
- package/dist/core/gate-outcome.js +5 -0
- package/dist/core/governance-codes.d.ts +11 -4
- package/dist/core/governance-codes.js +14 -3
- package/dist/core/hooks.d.ts +21 -0
- package/dist/core/locked-config.d.ts +8 -0
- package/dist/core/locked-config.js +14 -2
- package/dist/core/lsp.js +3 -5
- package/dist/core/mailbox-store.d.ts +3 -4
- package/dist/core/mcp-connection-pool.d.ts +75 -0
- package/dist/core/mcp-connection-pool.js +128 -0
- package/dist/core/mcp-failure.d.ts +2 -1
- package/dist/core/mcp-failure.js +13 -2
- package/dist/core/mcp.d.ts +4 -0
- package/dist/core/mcp.js +70 -43
- package/dist/core/memory-engine/content-origin.js +2 -14
- package/dist/core/memory-engine/engine.d.ts +32 -22
- package/dist/core/memory-engine/engine.js +103 -55
- package/dist/core/memory-engine/file-backend.d.ts +13 -30
- package/dist/core/memory-engine/file-backend.js +37 -252
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +139 -9
- package/dist/core/memory-engine/layout.js +350 -7
- package/dist/core/memory-engine/scope-contract.d.ts +10 -0
- package/dist/core/memory-engine/scope-contract.js +8 -0
- package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
- package/dist/core/memory-engine/session-incarnation.js +5 -2
- package/dist/core/memory-engine/types.d.ts +10 -1
- package/dist/core/memory.js +5 -17
- package/dist/core/model-seat.d.ts +4 -4
- package/dist/core/model-seat.js +1 -1
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +19 -0
- package/dist/core/namespaced-rule-name.d.ts +29 -0
- package/dist/core/namespaced-rule-name.js +52 -0
- package/dist/core/park-selfcheck.d.ts +1 -1
- package/dist/core/park-selfcheck.js +16 -6
- package/dist/core/path-guard-rows.d.ts +99 -0
- package/dist/core/path-guard-rows.js +45 -0
- package/dist/core/path-identity.d.ts +22 -16
- package/dist/core/path-identity.js +10 -10
- package/dist/core/path-rule-binding.d.ts +2 -1
- package/dist/core/path-rule-binding.js +3 -1
- package/dist/core/pause-registry.d.ts +16 -2
- package/dist/core/pause-registry.js +6 -0
- package/dist/core/permission-rule-consent.js +0 -7
- package/dist/core/permission-rule-model.d.ts +68 -24
- package/dist/core/permission-rule-model.js +105 -24
- package/dist/core/permission-rule-store.js +2 -2
- package/dist/core/permission-rules.d.ts +3 -30
- package/dist/core/permission-rules.js +4 -54
- package/dist/core/read-root-candidate.d.ts +1 -3
- package/dist/core/read-root-candidate.js +4 -15
- package/dist/core/real-approval.d.ts +4 -3
- package/dist/core/retired-keys.d.ts +13 -0
- package/dist/core/retired-keys.js +14 -0
- package/dist/core/roles.d.ts +2 -3
- package/dist/core/roles.js +15 -6
- package/dist/core/runner/assemble-result.d.ts +0 -7
- package/dist/core/runner/assemble-result.js +19 -31
- package/dist/core/runner/caller-roster.d.ts +78 -0
- package/dist/core/runner/caller-roster.js +219 -0
- package/dist/core/runner/checkpoint-scope.d.ts +16 -16
- package/dist/core/runner/checkpoint-scope.js +2 -2
- package/dist/core/runner/child-tree.js +2 -2
- package/dist/core/runner/contracts.d.ts +68 -35
- package/dist/core/runner/decide-continuation.d.ts +51 -3
- package/dist/core/runner/decide-continuation.js +76 -21
- package/dist/core/runner/denial-limit-arms.d.ts +17 -5
- package/dist/core/runner/denial-limit-arms.js +11 -9
- package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
- package/dist/core/runner/extra-body-dropped-seat.js +22 -0
- package/dist/core/runner/finish-reason-seat.d.ts +9 -0
- package/dist/core/runner/finish-reason-seat.js +40 -0
- package/dist/core/runner/gate-exit.d.ts +44 -32
- package/dist/core/runner/gate-exit.js +112 -25
- package/dist/core/runner/inherited-ask-grants.js +6 -4
- package/dist/core/runner/mcp-redial.d.ts +3 -3
- package/dist/core/runner/mcp-redial.js +3 -4
- package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
- package/dist/core/runner/permission-rule-lanes.js +5 -4
- package/dist/core/runner/prepare-artifact.d.ts +4 -0
- package/dist/core/runner/prepare-artifact.js +2 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +12 -6
- package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
- package/dist/core/runner/prepare-boundary-parks.js +4 -7
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
- package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
- package/dist/core/runner/prepare-config-doors.d.ts +9 -9
- package/dist/core/runner/prepare-config-doors.js +10 -5
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-defer-classify.js +5 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-delegation-surface.js +3 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
- package/dist/core/runner/prepare-gate-stations.js +9 -7
- package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
- package/dist/core/runner/prepare-hands-readface.js +7 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
- package/dist/core/runner/prepare-inherited-gate.js +14 -15
- package/dist/core/runner/prepare-listings.d.ts +7 -24
- package/dist/core/runner/prepare-listings.js +4 -5
- package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
- package/dist/core/runner/prepare-memory-engine-session.js +4 -3
- package/dist/core/runner/prepare-memory.d.ts +6 -0
- package/dist/core/runner/prepare-memory.js +13 -13
- package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
- package/dist/core/runner/prepare-offload-wrappers.js +3 -3
- package/dist/core/runner/prepare-park-ask.d.ts +7 -8
- package/dist/core/runner/prepare-park-ask.js +17 -10
- package/dist/core/runner/prepare-policy-chain.js +24 -44
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +3 -4
- package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
- package/dist/core/runner/prepare-protocol-tools.js +3 -4
- package/dist/core/runner/prepare-run-refs.d.ts +3 -0
- package/dist/core/runner/prepare-run-refs.js +2 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
- package/dist/core/runner/prepare-suspend-saga.js +28 -12
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +67 -56
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
- package/dist/core/runner/prepare-wiring-manifest.js +5 -8
- package/dist/core/runner/resume-apply.js +7 -14
- package/dist/core/runner/resume-checkpoint-screen.js +11 -4
- package/dist/core/runner/resume-internals-and-config.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +5 -32
- package/dist/core/runner/resume-review-outcome.js +4 -1
- package/dist/core/runner/retired-runner-deps.d.ts +6 -0
- package/dist/core/runner/retired-runner-deps.js +10 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -0
- package/dist/core/runner/run-brain-sinks.js +5 -2
- package/dist/core/runner/run-harness-handlers.js +29 -36
- package/dist/core/runner/run-leg.d.ts +0 -2
- package/dist/core/runner/run-leg.js +32 -33
- package/dist/core/runner/run-terminal-adoption.js +4 -3
- package/dist/core/runner/runtask.js +8 -8
- package/dist/core/runner/session-rule-policy.js +5 -5
- package/dist/core/runner/stream-settle-backstop.js +7 -4
- package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
- package/dist/core/runner/sub-agent-deny-lists.js +111 -80
- package/dist/core/runner/terminal-account.d.ts +48 -0
- package/dist/core/runner/terminal-account.js +186 -0
- package/dist/core/runner/tool-end-body.d.ts +54 -17
- package/dist/core/runner/tool-end-body.js +27 -2
- package/dist/core/runner/tool-face-overlay.d.ts +3 -1
- package/dist/core/runner/tool-face-overlay.js +6 -4
- package/dist/core/runner/tool-occurrence.d.ts +106 -0
- package/dist/core/runner/tool-occurrence.js +123 -0
- package/dist/core/runner/tool-progress-lane.d.ts +16 -8
- package/dist/core/runner/tool-progress-lane.js +25 -34
- package/dist/core/runner/tool-turn-repair-seat.d.ts +28 -4
- package/dist/core/runner/tool-turn-repair-seat.js +36 -13
- package/dist/core/runner/turn-attachments.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +21 -9
- package/dist/core/runner/write-protection-station.js +20 -17
- package/dist/core/runner-deps.d.ts +12 -22
- package/dist/core/secret-env.d.ts +16 -5
- package/dist/core/secret-env.js +23 -63
- package/dist/core/sensitive-path-policy.d.ts +19 -18
- package/dist/core/sensitive-path-policy.js +73 -49
- package/dist/core/session-reconcile.d.ts +3 -0
- package/dist/core/session-reconcile.js +5 -4
- package/dist/core/session-store.d.ts +5 -0
- package/dist/core/session-store.js +12 -0
- package/dist/core/session.d.ts +13 -0
- package/dist/core/shared-memory/normalize.d.ts +17 -4
- package/dist/core/shared-memory/normalize.js +7 -7
- package/dist/core/shell-lexer.js +5 -4
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/skill-grant.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +2 -2
- package/dist/core/task-event.d.ts +59 -5
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +42 -9
- package/dist/core/terminal-cause.d.ts +94 -11
- package/dist/core/tighten-task-spec.d.ts +5 -4
- package/dist/core/tighten-task-spec.js +20 -25
- package/dist/core/tool-catalog-entries.d.ts +5 -7
- package/dist/core/tool-catalog-entries.js +14 -15
- package/dist/core/tool-face.d.ts +47 -0
- package/dist/core/tool-face.js +5 -0
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +26 -2
- package/dist/core/tool-name-aliases.js +13 -0
- package/dist/core/tool-name-list.d.ts +30 -0
- package/dist/core/tool-name-list.js +55 -0
- package/dist/core/tool-name-readings.d.ts +1 -9
- package/dist/core/tool-name-readings.js +1 -3
- package/dist/core/tool-policy.d.ts +195 -85
- package/dist/core/tool-policy.js +165 -380
- package/dist/core/tool-registry.d.ts +44 -1
- package/dist/core/tool-registry.js +26 -0
- package/dist/core/tool-roster.d.ts +19 -1
- package/dist/core/tool-roster.js +21 -2
- package/dist/core/tool-spec-members.d.ts +45 -0
- package/dist/core/tool-spec-members.js +169 -0
- package/dist/core/tool-spec.d.ts +46 -8
- package/dist/core/tools.d.ts +6 -2
- package/dist/core/tools.js +8 -4
- package/dist/core/untrusted-egress.js +29 -26
- package/dist/core/untrusted-text.d.ts +13 -10
- package/dist/core/untrusted-text.js +6 -44
- package/dist/core/workflow-journal-store.d.ts +4 -1
- package/dist/core/write-protect.d.ts +65 -29
- package/dist/core/write-protect.js +235 -177
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
- package/dist/engine/execution-env/node-execution-env.js +16 -38
- package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
- package/dist/engine/execution-env/symlink-chain.js +32 -0
- package/dist/engine/harness/types.d.ts +7 -0
- package/dist/engine/llm/tool-turns.d.ts +3 -0
- package/dist/engine/llm/tool-turns.js +1 -0
- package/dist/engine/llm/types.d.ts +59 -23
- package/dist/engine/loop/agent-loop.js +16 -2
- package/dist/engine/session/memory-repo.js +11 -3
- package/dist/engine/session/repo-utils.d.ts +8 -0
- package/dist/engine/session/repo-utils.js +13 -0
- package/dist/index.d.ts +20 -23
- package/dist/index.js +17 -20
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/governance-baseline-validity.js +1 -1
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +16 -35
- package/dist/orchestration/run-workflow-tool.js +38 -78
- package/dist/orchestration/workflow-governance.d.ts +21 -25
- package/dist/orchestration/workflow-governance.js +38 -78
- package/dist/orchestration/workflow-primitives.d.ts +7 -22
- package/dist/orchestration/workflow-primitives.js +5 -12
- package/dist/orchestration/workflow-types.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +61 -11
- package/dist/orchestration/workflow.js +189 -117
- package/dist/scenarios/full-body.d.ts +1 -1
- package/dist/shell/lex.d.ts +0 -21
- package/dist/shell/lex.js +250 -68
- package/dist/shell/shell-words.d.ts +35 -0
- package/dist/shell/shell-words.js +65 -0
- package/dist/stores/file/checkpoint-store.d.ts +5 -5
- package/dist/stores/file/checkpoint-store.js +5 -2
- package/dist/stores/file/index.d.ts +0 -8
- package/dist/stores/file/index.js +0 -12
- package/dist/stores/file/session-store.d.ts +3 -0
- package/dist/stores/file/session-store.js +44 -19
- package/dist/tools/artifact/artifact-tool.js +2 -0
- package/dist/tools/fs/bash-program-position.d.ts +12 -4
- package/dist/tools/fs/bash-program-position.js +32 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/bash-readonly-classifier.js +8 -7
- package/dist/tools/fs/containment-face.d.ts +4 -0
- package/dist/tools/fs/containment-face.js +3 -0
- package/dist/tools/fs/fs-shared.d.ts +10 -0
- package/dist/tools/fs/fs-shared.js +18 -0
- package/dist/tools/fs/fs-write.js +4 -2
- package/dist/tools/fs/index.d.ts +1 -1
- package/dist/tools/fs/program-read-model.d.ts +46 -20
- package/dist/tools/fs/program-read-model.js +50 -20
- package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
- package/dist/tools/fs/program-read-model.rows.js +16 -15
- package/dist/tools/fs/read-deny-home.d.ts +33 -47
- package/dist/tools/fs/read-deny-home.js +35 -49
- package/dist/tools/fs/read-deny.d.ts +23 -22
- package/dist/tools/fs/read-deny.js +114 -89
- package/dist/tools/fs/removal-targets.d.ts +56 -23
- package/dist/tools/fs/removal-targets.js +65 -87
- package/dist/tools/fs/safety.d.ts +29 -22
- package/dist/tools/fs/safety.js +17 -11
- package/dist/tools/fs/search.js +10 -8
- package/dist/tools/fs/shell-read-argv.js +1 -1
- package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
- package/dist/tools/fs/shell-read-bindings.js +324 -86
- package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
- package/dist/tools/fs/shell-read-builtins.js +43 -0
- package/dist/tools/fs/shell-read-check.d.ts +15 -1
- package/dist/tools/fs/shell-read-check.js +67 -43
- package/dist/tools/fs/shell-read-establish.js +6 -6
- package/dist/tools/fs/shell-read-functions.d.ts +22 -0
- package/dist/tools/fs/shell-read-functions.js +29 -0
- package/dist/tools/fs/shell-read-judge.d.ts +51 -18
- package/dist/tools/fs/shell-read-judge.js +40 -4
- package/dist/tools/fs/shell-read-plan.d.ts +12 -6
- package/dist/tools/fs/shell-read-plan.js +118 -113
- package/dist/tools/fs/shell-read-start.d.ts +29 -6
- package/dist/tools/fs/shell-read-start.js +16 -9
- package/dist/tools/fs/shell-read-word.js +4 -0
- package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
- package/dist/tools/fs/shell-read-workdir.js +281 -0
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
- package/dist/tools/fs/shell-read-write-targets.js +14 -5
- package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
- package/dist/tools/fs/shell-reentry-text.js +3 -11
- package/dist/tools/task-list.d.ts +1 -2
- package/dist/tools/web.js +1 -1
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +107 -143
- package/wire-changes/core@7.49.0.json +4765 -0
- package/dist/agents/teacher.d.ts +0 -159
- package/dist/agents/teacher.js +0 -577
- package/dist/agents/team.d.ts +0 -226
- package/dist/agents/team.js +0 -257
- package/dist/core/strategy-store.d.ts +0 -238
- package/dist/core/strategy-store.js +0 -253
- package/dist/orchestration/builtin-workflows.d.ts +0 -133
- package/dist/orchestration/builtin-workflows.js +0 -159
- package/dist/scenarios/env.d.ts +0 -40
- package/dist/scenarios/env.js +0 -39
- package/dist/scenarios/scenario-registry.d.ts +0 -110
- package/dist/scenarios/scenario-registry.js +0 -140
- package/dist/scenarios/teacher-quickstart.d.ts +0 -40
- package/dist/scenarios/teacher-quickstart.js +0 -12
- package/dist/stores/cc/lockfile.d.ts +0 -10
- package/dist/stores/cc/lockfile.js +0 -98
- package/dist/stores/cc/mailbox-store.d.ts +0 -20
- package/dist/stores/cc/mailbox-store.js +0 -255
- package/dist/stores/cc/roster-adapter.d.ts +0 -12
- package/dist/stores/cc/roster-adapter.js +0 -117
- package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
- package/dist/stores/cc/sidecar-transcript.js +0 -264
- package/dist/stores/cc/task-list-store.d.ts +0 -2
- package/dist/stores/cc/task-list-store.js +0 -125
- package/dist/stores/file/strategy-store.d.ts +0 -97
- package/dist/stores/file/strategy-store.js +0 -341
|
@@ -18,7 +18,7 @@ import { landedUndecided, layerDigest, layerObservationLookup, readOnlyLayerCand
|
|
|
18
18
|
import { markOriginClearanceTombstoned, openOriginClearance, readOriginClearances, settleOriginClearance } from "./origin-clearance.js";
|
|
19
19
|
import { DEFAULT_MAX_ENTRY_DEPTH, MEMORY_INDEX_FILENAME, canonicalJsonStringify, captureErasureInput, erasureRequestInvalid, erasureSelectHash, scanEntryFiles, } from "./file-backend.js";
|
|
20
20
|
import { assembleMemoryExportBundle, computeMemoryBundleHash, memoryBundleInvalid, } from "./export-bundle.js";
|
|
21
|
-
import { QUARANTINE_DIR, SCAN_FUSE_THRESHOLD, quarantineAndTombstone, restoreContainedBaseline, indexLineIsStale, readIndexRevs, writeIndexRevs, bumpScanFuse, scanFuseKey, canonicalize, landingPathOf, landsOutsideStore, storeActRefusal, storeRootMovedRefusal, adoptRootScopeLayout, clearScanFuse,
|
|
21
|
+
import { QUARANTINE_DIR, SCAN_FUSE_THRESHOLD, quarantineAndTombstone, restoreContainedBaseline, indexLineIsStale, readIndexRevs, writeIndexRevs, bumpScanFuse, scanFuseKey, canonicalize, anchorStoreRoot, landingPathOf, landsOutsideStore, storeActRefusal, storeRootMovedRefusal, adoptRootScopeLayout, clearScanFuse, effectiveControlRootOf, drainMemoryAnnouncements, enqueueMemoryAnnouncement, ensureDirExists, markSessionPolluted, readSessionPollution, fileSessionCaptureRecordStore, recordRetrievedAccount, writeFileNoFollow, withPermissionRemedy, permissionRemedyOf, readRetrievedAccount, registerScope, registeredScopes, scopeDirFor, appendChallengeEvents, appendLineageAudit, rebuildStrictControlPlaneLedger, isStrictControlPlaneLedgerCorrupt, CHALLENGE_LEDGER_MAX_EVENTS, adjudicateLineagePending, challengedEntryIds, clearLineageForEntries, discardLineagePending, lineageAccountOfEntry, lineageContributionsOfSession, lineageLatchedIds, promoteLineagePending, readChallengeEvents, readChallengedHistory, readLineageRecord, recordChallengedHistory, recordLineageCredential, reconcileLineage, readProjectionDebts, resolveChallengeEvent, settleProjectionDebts, stageLineagePending, stageProjectionDebts, } from "./layout.js";
|
|
22
22
|
import { createSessionIncarnationSeat, recalledForAnyIdentity, recalledForIdentity, rememberForIdentity } from "./session-incarnation.js";
|
|
23
23
|
import { scanMemoryFileName, scanMemoryWrite, scanRemediation } from "./scan.js";
|
|
24
24
|
import { writableRootOf } from "./types.js";
|
|
@@ -311,7 +311,6 @@ const STALE_LEG_NOTE = "memory session account: this harvest belongs to an earli
|
|
|
311
311
|
export class MemoryEngine {
|
|
312
312
|
backend;
|
|
313
313
|
memoryDir;
|
|
314
|
-
mountedRoot;
|
|
315
314
|
controlDir;
|
|
316
315
|
now;
|
|
317
316
|
perScopeBudgetBytes;
|
|
@@ -324,7 +323,7 @@ export class MemoryEngine {
|
|
|
324
323
|
provenance;
|
|
325
324
|
onIncident;
|
|
326
325
|
unsettleableDisclosed = false;
|
|
327
|
-
|
|
326
|
+
zeroCopy;
|
|
328
327
|
constructor(opts) {
|
|
329
328
|
if (opts.provenance !== undefined && opts.provenance !== "off" && opts.provenance !== "carry") {
|
|
330
329
|
const got = typeof opts.provenance === "string" ? JSON.stringify(opts.provenance) : opts.provenance === null ? "null" : typeof opts.provenance;
|
|
@@ -336,13 +335,13 @@ export class MemoryEngine {
|
|
|
336
335
|
this.backend = opts.backend;
|
|
337
336
|
this.memoryDir = opts.memoryDir;
|
|
338
337
|
const pinned = opts.backend.directoryRoot;
|
|
339
|
-
if (typeof pinned === "string" && pinned)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
338
|
+
if (typeof pinned === "string" && pinned !== "" && landingPathOf(pinned) !== landingPathOf(opts.memoryDir)) {
|
|
339
|
+
const e = new Error(`MemoryEngineOptions.memoryDir must be the File backend's own directory (the backend is pinned to ${pinned}, memoryDir is ${opts.memoryDir}) — a copy-out projection over a File backend is not supported; pass the backend's directoryRoot as memoryDir.`);
|
|
340
|
+
e.code = "config.memory_dir_not_backend_root";
|
|
341
|
+
throw e;
|
|
342
|
+
}
|
|
343
|
+
this.zeroCopy = typeof pinned === "string" && pinned !== "";
|
|
344
|
+
this.controlDir = effectiveControlRootOf(opts.memoryDir, { pinnedBy: opts.backend, controlDir: opts.controlDir, onIncident: opts.onIncident });
|
|
346
345
|
this.now = opts.now ?? Date.now;
|
|
347
346
|
this.perScopeBudgetBytes = opts.perScopeBudgetBytes ?? Number.MAX_SAFE_INTEGER;
|
|
348
347
|
this.perFileBytes = opts.perFileBytes ?? MAX_MEMORY_BYTES;
|
|
@@ -416,8 +415,7 @@ export class MemoryEngine {
|
|
|
416
415
|
return candidates;
|
|
417
416
|
}
|
|
418
417
|
async committedContentUnadopted(id) {
|
|
419
|
-
const
|
|
420
|
-
const view = zeroCopy ? undefined : this.backend.restrictedAdoptionView?.({ audit: false });
|
|
418
|
+
const view = this.zeroCopy ? undefined : this.backend.restrictedAdoptionView?.({ audit: false });
|
|
421
419
|
if (view === undefined)
|
|
422
420
|
return this.committedContentFor(id);
|
|
423
421
|
try {
|
|
@@ -429,7 +427,7 @@ export class MemoryEngine {
|
|
|
429
427
|
}
|
|
430
428
|
return this.backend.readCommittedShadow?.(id) ?? readSafe(join(this.controlDir, "shadow", `${id}.md`));
|
|
431
429
|
}
|
|
432
|
-
async restoreReadOnlyLayers(candidates, report, selfLeg,
|
|
430
|
+
async restoreReadOnlyLayers(candidates, report, selfLeg, handle) {
|
|
433
431
|
let writers;
|
|
434
432
|
for (const c of candidates) {
|
|
435
433
|
const text = readSafe(c.path);
|
|
@@ -452,7 +450,7 @@ export class MemoryEngine {
|
|
|
452
450
|
continue;
|
|
453
451
|
}
|
|
454
452
|
try {
|
|
455
|
-
this.refuseOutsideStore(
|
|
453
|
+
this.refuseOutsideStore(c.path, "restoring the read-only layer file", handle);
|
|
456
454
|
writeFileNoFollow(c.path, committed);
|
|
457
455
|
report.restored.push(c.relPath);
|
|
458
456
|
}
|
|
@@ -754,11 +752,12 @@ export class MemoryEngine {
|
|
|
754
752
|
const writableRoot = handle.writableRoot;
|
|
755
753
|
if (handle.writeScope === null || writableRoot === null || !existsSync(writableRoot))
|
|
756
754
|
return out;
|
|
755
|
+
this.assertRootAnchored(handle);
|
|
757
756
|
{
|
|
758
757
|
const indexPath = join(writableRoot, MEMORY_INDEX_FILENAME);
|
|
759
758
|
const baseline = handle.planeBaseline !== undefined ? handle.planeBaseline.index : handle.indexText;
|
|
760
759
|
try {
|
|
761
|
-
this.refuseOutsideStore(
|
|
760
|
+
this.refuseOutsideStore(indexPath, "sweeping the index", handle);
|
|
762
761
|
const first = existsSync(indexPath) ? readSafe(indexPath) : undefined;
|
|
763
762
|
if (first !== undefined && first !== baseline) {
|
|
764
763
|
const onDisk = readSafe(indexPath);
|
|
@@ -839,6 +838,11 @@ export class MemoryEngine {
|
|
|
839
838
|
}
|
|
840
839
|
text2 = fresh;
|
|
841
840
|
}
|
|
841
|
+
const refusedHere = this.storeActRefusedText(canonical, "sweeping a residue file", handle);
|
|
842
|
+
if (refusedHere !== undefined) {
|
|
843
|
+
out.failures.push({ path: rel, detail: `${refusedHere} — not swept` });
|
|
844
|
+
continue;
|
|
845
|
+
}
|
|
842
846
|
const q = quarantineAndTombstone(canonical, text2, join(this.controlDir, QUARANTINE_DIR), this.now);
|
|
843
847
|
let contained = q.removed;
|
|
844
848
|
if (committed !== undefined) {
|
|
@@ -1092,7 +1096,7 @@ export class MemoryEngine {
|
|
|
1092
1096
|
if (kept.length === lines.length)
|
|
1093
1097
|
continue;
|
|
1094
1098
|
try {
|
|
1095
|
-
this.refuseOutsideStore(
|
|
1099
|
+
this.refuseOutsideStore(indexPath, "rewriting the index");
|
|
1096
1100
|
writeFileNoFollow(indexPath, kept.join("\n"));
|
|
1097
1101
|
}
|
|
1098
1102
|
catch {
|
|
@@ -1395,10 +1399,11 @@ export class MemoryEngine {
|
|
|
1395
1399
|
}
|
|
1396
1400
|
async adoptLayoutBeforeMount(writeScope) {
|
|
1397
1401
|
const adopt = this.backend.adoptRootScopeLayout;
|
|
1398
|
-
|
|
1399
|
-
if (adopt !== undefined)
|
|
1402
|
+
if (adopt !== undefined) {
|
|
1400
1403
|
await adopt.call(this.backend, { ownerCandidate: writeScope, onIncident: this.onIncident });
|
|
1401
|
-
|
|
1404
|
+
this.assertRootAnchored();
|
|
1405
|
+
}
|
|
1406
|
+
if (adopt === undefined || !this.zeroCopy)
|
|
1402
1407
|
adoptRootScopeLayout(this.memoryDir, this.controlDir, { ownerCandidate: writeScope, onIncident: this.onIncident, convertSidecars: convertV1SidecarKeys });
|
|
1403
1408
|
}
|
|
1404
1409
|
async materialize(scopes, writeScope, opts) {
|
|
@@ -1413,13 +1418,11 @@ export class MemoryEngine {
|
|
|
1413
1418
|
}
|
|
1414
1419
|
}
|
|
1415
1420
|
async materializeCore(scopes, writeScope, opts, legSeat) {
|
|
1421
|
+
this.assertRootAnchored();
|
|
1416
1422
|
ensureDirExists(this.memoryDir);
|
|
1417
|
-
const physicalRoot = landingPathOf(this.memoryDir);
|
|
1418
|
-
this.mountedRoot ??= physicalRoot;
|
|
1419
|
-
if (physicalRoot !== this.mountedRoot)
|
|
1420
|
-
throw storeRootMovedRefusal("engine", this.memoryDir);
|
|
1421
1423
|
ensureDirExists(this.controlDir);
|
|
1422
1424
|
await this.adoptLayoutBeforeMount(writeScope);
|
|
1425
|
+
this.assertRootAnchored();
|
|
1423
1426
|
const restricted = opts?.adoptionRestricted === true;
|
|
1424
1427
|
let sessionAccountFailed = false;
|
|
1425
1428
|
let accountLeg;
|
|
@@ -1433,7 +1436,7 @@ export class MemoryEngine {
|
|
|
1433
1436
|
scopeDirs.set(writeScope, registerScope(this.memoryDir, this.controlDir, writeScope));
|
|
1434
1437
|
for (const dir of scopeDirs.values())
|
|
1435
1438
|
this.censusScopeTree(dir);
|
|
1436
|
-
const layerBaseline = this.
|
|
1439
|
+
const layerBaseline = this.zeroCopy
|
|
1437
1440
|
? readOnlyLayerCensus([...scopeDirs].filter(([scope]) => scope !== writeScope).map(([, dir]) => dir))
|
|
1438
1441
|
: undefined;
|
|
1439
1442
|
if (layerBaseline !== undefined)
|
|
@@ -1509,6 +1512,7 @@ export class MemoryEngine {
|
|
|
1509
1512
|
const stagingName = `${captureName}.staging`;
|
|
1510
1513
|
const stagingPath = stagingPathBeside(canonical, stagingName);
|
|
1511
1514
|
try {
|
|
1515
|
+
this.refuseOutsideStore(canonical, "containing session residue");
|
|
1512
1516
|
renameSync(canonical, stagingPath);
|
|
1513
1517
|
if (readFileSync(stagingPath, "utf8") === text) {
|
|
1514
1518
|
writeFileNoFollow(canonical, committed);
|
|
@@ -1599,10 +1603,11 @@ export class MemoryEngine {
|
|
|
1599
1603
|
...(layerBaseline !== undefined ? { layerBaseline } : {}),
|
|
1600
1604
|
...(accountLeg !== undefined ? { accountLeg } : {}),
|
|
1601
1605
|
};
|
|
1602
|
-
if (handle.writableRoot !== null)
|
|
1606
|
+
if (handle.writableRoot !== null) {
|
|
1607
|
+
this.refuseOutsideStore(join(handle.writableRoot, MEMORY_INDEX_FILENAME), "creating the write home", handle);
|
|
1603
1608
|
ensureDirExists(handle.writableRoot);
|
|
1604
|
-
|
|
1605
|
-
const
|
|
1609
|
+
}
|
|
1610
|
+
const zeroCopy = this.zeroCopy;
|
|
1606
1611
|
for (const [scope, dir] of scopeDirs) {
|
|
1607
1612
|
const scopeEntries = (byScope.get(scope) ?? []).slice();
|
|
1608
1613
|
scopeEntries.sort((a, b) => (mtimeById.get(b.id) ?? 0) - (mtimeById.get(a.id) ?? 0));
|
|
@@ -1612,8 +1617,10 @@ export class MemoryEngine {
|
|
|
1612
1617
|
handle.repoIndexTargets?.set(entry.id, entry.frontmatter.provenance.path);
|
|
1613
1618
|
const stale = join(dir, `${entry.slug}.md`);
|
|
1614
1619
|
const staleText = readSafe(stale);
|
|
1615
|
-
if (staleText !== undefined && parseEntryFile(staleText).id === entry.id)
|
|
1620
|
+
if (staleText !== undefined && parseEntryFile(staleText).id === entry.id) {
|
|
1621
|
+
this.refuseOutsideStore(stale, "removing a stale projection", handle);
|
|
1616
1622
|
rmSync(stale, { force: true });
|
|
1623
|
+
}
|
|
1617
1624
|
continue;
|
|
1618
1625
|
}
|
|
1619
1626
|
const fullText = serializeEntryFile(entry);
|
|
@@ -1624,8 +1631,8 @@ export class MemoryEngine {
|
|
|
1624
1631
|
const { deleted: _stubDrop, ...stubFm } = entry.frontmatter;
|
|
1625
1632
|
const text = stub ? serializeEntryFile({ id: entry.id, frontmatter: stubFm, body: STUB_ARCHIVED_LINE }) : fullText;
|
|
1626
1633
|
const target = join(dir, `${entry.slug}.md`);
|
|
1627
|
-
if (
|
|
1628
|
-
this.writeIfChanged(target, text,
|
|
1634
|
+
if (!zeroCopy)
|
|
1635
|
+
this.writeIfChanged(target, text, handle);
|
|
1629
1636
|
const onDiskRev = stub ? revOfText(text, entry.id) : entry.rev;
|
|
1630
1637
|
const path = canonicalize(target);
|
|
1631
1638
|
handle.materialized.push({
|
|
@@ -1908,6 +1915,14 @@ export class MemoryEngine {
|
|
|
1908
1915
|
restored: [],
|
|
1909
1916
|
warnings: [],
|
|
1910
1917
|
};
|
|
1918
|
+
try {
|
|
1919
|
+
this.assertRootAnchored(handle);
|
|
1920
|
+
}
|
|
1921
|
+
catch (err) {
|
|
1922
|
+
report.ok = false;
|
|
1923
|
+
report.incident = { kind: "sidecar_corrupt", detail: `memory control plane refused: ${this.writeFailureText(err)}` };
|
|
1924
|
+
return report;
|
|
1925
|
+
}
|
|
1911
1926
|
const writeScope = handle.writeScope;
|
|
1912
1927
|
const captureRead = opts?.sessionId !== undefined ? await this.sessionCaptureOptOutOrFault(opts.sessionId) : { fault: false };
|
|
1913
1928
|
const captureOptOut = captureRead.record;
|
|
@@ -1962,6 +1977,7 @@ export class MemoryEngine {
|
|
|
1962
1977
|
return report;
|
|
1963
1978
|
}
|
|
1964
1979
|
try {
|
|
1980
|
+
this.assertRootAnchored(handle);
|
|
1965
1981
|
this.backend.checkControlPlane?.();
|
|
1966
1982
|
}
|
|
1967
1983
|
catch (err) {
|
|
@@ -1977,6 +1993,7 @@ export class MemoryEngine {
|
|
|
1977
1993
|
await this.settleUndecidedObservations(handle, report, landedUndecided(observed));
|
|
1978
1994
|
try {
|
|
1979
1995
|
if (carry) {
|
|
1996
|
+
this.assertRootAnchored(handle);
|
|
1980
1997
|
reconcileHolds(this.controlDir, { homeOf: (scope) => scopeDirFor(this.memoryDir, this.controlDir, scope), now: this.now });
|
|
1981
1998
|
const newlyExpired = expireOverdueSettlements(this.controlDir, { timeoutMs: this.holdSettleTimeoutMs, now: this.now });
|
|
1982
1999
|
if (newlyExpired.length > 0) {
|
|
@@ -2077,6 +2094,11 @@ export class MemoryEngine {
|
|
|
2077
2094
|
report.rejections.push({ path: rel, code: "outside_root", reason: "file resolves outside the writable memory root (containment gate, fail-closed)" });
|
|
2078
2095
|
return;
|
|
2079
2096
|
}
|
|
2097
|
+
const refusedHere = this.storeActRefusedText(f.canonical, "containing a withheld file", handle);
|
|
2098
|
+
if (refusedHere !== undefined) {
|
|
2099
|
+
report.rejections.push({ path: rel, code: "outside_root", reason: `containment refused (fail-closed): ${refusedHere}` });
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2080
2102
|
const baseId = handle.baseIds.get(f.canonical);
|
|
2081
2103
|
if (baseId !== undefined && !pollutedStubs.has(f.canonical) && revOfText(f.text, baseId) === handle.baseRevs.get(f.canonical))
|
|
2082
2104
|
return;
|
|
@@ -2106,7 +2128,10 @@ export class MemoryEngine {
|
|
|
2106
2128
|
if (priorId !== undefined) {
|
|
2107
2129
|
const committed = await this.committedContentFor(priorId);
|
|
2108
2130
|
if (committed !== undefined) {
|
|
2109
|
-
const
|
|
2131
|
+
const refusedRestore = this.storeActRefusedText(f.canonical, "restoring a contained file's baseline", handle);
|
|
2132
|
+
if (refusedRestore !== undefined)
|
|
2133
|
+
report.warnings.push(`${rel}: the committed baseline was not restored — ${refusedRestore}`);
|
|
2134
|
+
const put = refusedRestore === undefined ? restoreContainedBaseline(f.canonical, committed, q.leftOnPlane) : undefined;
|
|
2110
2135
|
if (put === "written") {
|
|
2111
2136
|
report.restored.push(rel);
|
|
2112
2137
|
contained = true;
|
|
@@ -2151,6 +2176,7 @@ export class MemoryEngine {
|
|
|
2151
2176
|
catch {
|
|
2152
2177
|
}
|
|
2153
2178
|
try {
|
|
2179
|
+
this.refuseOutsideStore(pollutedIndexPath, "restoring the index", handle);
|
|
2154
2180
|
writeFileNoFollow(pollutedIndexPath, handle.indexText);
|
|
2155
2181
|
report.warnings.push(`memory index restored to its pre-session state — this session's index additions were not retained (session polluted; ${indexCaptureLanded ? "the removed text was captured to quarantine" : "the quarantine capture did NOT land — the removed text is gone"})`);
|
|
2156
2182
|
return true;
|
|
@@ -2186,7 +2212,7 @@ export class MemoryEngine {
|
|
|
2186
2212
|
signalContainment((c) => (c.indexRolledBack = true));
|
|
2187
2213
|
report.warnings.push(`memory harvest refused by an incident while this session is marked externally exposed — no entries were committed; instruction-form files were withheld and the derived index rolled back: ${inlineUntrusted(pollutedReason, 200)}`);
|
|
2188
2214
|
};
|
|
2189
|
-
await this.restoreReadOnlyLayers(readOnlyRestorable, report, handle.accountLeg, handle
|
|
2215
|
+
await this.restoreReadOnlyLayers(readOnlyRestorable, report, handle.accountLeg, handle);
|
|
2190
2216
|
const missingWritable = writable.filter((m) => !recordByPath.has(m.path) && !existsSync(m.path) && !presentIds.has(m.id));
|
|
2191
2217
|
report.missing.push(...missingWritable.map((m) => m.relPath));
|
|
2192
2218
|
if (writable.length > 0 && missingWritable.length / writable.length > MASS_DELETION_FUSE_RATIO) {
|
|
@@ -2213,7 +2239,7 @@ export class MemoryEngine {
|
|
|
2213
2239
|
if (content === undefined)
|
|
2214
2240
|
continue;
|
|
2215
2241
|
try {
|
|
2216
|
-
this.refuseOutsideStore(
|
|
2242
|
+
this.refuseOutsideStore(m.path, "restoring a memory file", handle);
|
|
2217
2243
|
mkdirSync(dirname(m.path), { recursive: true });
|
|
2218
2244
|
writeFileNoFollow(m.path, content);
|
|
2219
2245
|
report.restored.push(m.relPath);
|
|
@@ -2281,7 +2307,7 @@ export class MemoryEngine {
|
|
|
2281
2307
|
if (fastBaseId !== undefined && !stubByPath.has(f.canonical) && revOfText(f.text, fastBaseId) === revByBasePath.get(f.canonical)) {
|
|
2282
2308
|
const fastDebt = projectionDebts.get(debtSeat(writeScope, homeRel(writableRoot, f.canonical)));
|
|
2283
2309
|
if (fastDebt !== undefined && fastDebt.entryId === fastBaseId)
|
|
2284
|
-
await this.repairProjectionSeat(seatOf(f.canonical), f.canonical, fastBaseId, debtClears, report.warnings);
|
|
2310
|
+
await this.repairProjectionSeat(seatOf(f.canonical), f.canonical, fastBaseId, debtClears, report.warnings, handle);
|
|
2285
2311
|
continue;
|
|
2286
2312
|
}
|
|
2287
2313
|
processed++;
|
|
@@ -2307,13 +2333,15 @@ export class MemoryEngine {
|
|
|
2307
2333
|
scanFindings.push(...scanMemoryWrite(f.text));
|
|
2308
2334
|
const finding = scanFindings[0];
|
|
2309
2335
|
if (finding !== undefined) {
|
|
2310
|
-
const
|
|
2336
|
+
const refusedHere = this.storeActRefusedText(f.canonical, "quarantining a rejected file", handle);
|
|
2337
|
+
const q = refusedHere === undefined ? quarantineAndTombstone(f.canonical, f.text, join(this.controlDir, QUARANTINE_DIR), this.now) : { removed: false, leftOnPlane: f.text, detail: refusedHere };
|
|
2311
2338
|
let contained = q.removed;
|
|
2312
2339
|
const priorId = idByBasePath.get(f.canonical);
|
|
2313
2340
|
if (priorId !== undefined) {
|
|
2314
2341
|
const committed = await this.committedContentFor(priorId);
|
|
2315
2342
|
if (committed !== undefined) {
|
|
2316
2343
|
try {
|
|
2344
|
+
this.refuseOutsideStore(f.canonical, "restoring a rejected file's committed content", handle);
|
|
2317
2345
|
writeFileNoFollow(f.canonical, committed);
|
|
2318
2346
|
report.restored.push(rel);
|
|
2319
2347
|
contained = true;
|
|
@@ -2415,7 +2443,8 @@ export class MemoryEngine {
|
|
|
2415
2443
|
continue;
|
|
2416
2444
|
}
|
|
2417
2445
|
if (instructionForm && sessionPending && lineageSessionId !== undefined) {
|
|
2418
|
-
const
|
|
2446
|
+
const holdRefused = this.storeActRefusedText(f.canonical, "holding an instruction-form file", handle);
|
|
2447
|
+
const held = holdRefused !== undefined ? { ok: false, reason: holdRefused } : openInstructionHold(this.controlDir, {
|
|
2419
2448
|
sessionId: lineageSessionId,
|
|
2420
2449
|
rel: homeRel(writableRoot, f.canonical),
|
|
2421
2450
|
absPath: f.canonical,
|
|
@@ -2438,6 +2467,7 @@ export class MemoryEngine {
|
|
|
2438
2467
|
const committed = await this.committedContentFor(committedIdHere);
|
|
2439
2468
|
if (committed !== undefined) {
|
|
2440
2469
|
try {
|
|
2470
|
+
this.refuseOutsideStore(f.canonical, "restoring a held entry's committed content", handle);
|
|
2441
2471
|
writeFileNoFollow(f.canonical, committed);
|
|
2442
2472
|
report.restored.push(rel);
|
|
2443
2473
|
}
|
|
@@ -2489,7 +2519,7 @@ export class MemoryEngine {
|
|
|
2489
2519
|
if (revOfText(f.text, id) === revByBasePath.get(f.canonical)) {
|
|
2490
2520
|
const seatDebt = projectionDebts.get(debtSeat(writeScope, homeRel(writableRoot, f.canonical)));
|
|
2491
2521
|
if (seatDebt !== undefined && seatDebt.entryId === id)
|
|
2492
|
-
await this.repairProjectionSeat(seatOf(f.canonical), f.canonical, id, debtClears, report.warnings);
|
|
2522
|
+
await this.repairProjectionSeat(seatOf(f.canonical), f.canonical, id, debtClears, report.warnings, handle);
|
|
2493
2523
|
continue;
|
|
2494
2524
|
}
|
|
2495
2525
|
pendingProjections.push({ path: f.canonical, entry, needed: minted || parsed.id !== id || needsCompletion(parsed, fm), ...(debtReconciled ? { idCompletion: true } : {}) });
|
|
@@ -2507,6 +2537,7 @@ export class MemoryEngine {
|
|
|
2507
2537
|
reboundId = parsed.id;
|
|
2508
2538
|
const idless = serializeEntryFile({ id: "", frontmatter: fm, body: parsed.body }).replace(/^id:[ \t]*$\r?\n/m, "");
|
|
2509
2539
|
try {
|
|
2540
|
+
this.refuseOutsideStore(f.canonical, "stripping a copied id", handle);
|
|
2510
2541
|
writeFileNoFollow(f.canonical, idless);
|
|
2511
2542
|
}
|
|
2512
2543
|
catch (err) {
|
|
@@ -2526,6 +2557,7 @@ export class MemoryEngine {
|
|
|
2526
2557
|
if (fm.origin !== undefined && parsed.id !== undefined && reboundId === undefined) {
|
|
2527
2558
|
const idless = serializeEntryFile({ id: "", frontmatter: fm, body: parsed.body }).replace(/^id:[ \t]*$\r?\n/m, "");
|
|
2528
2559
|
try {
|
|
2560
|
+
this.refuseOutsideStore(f.canonical, "stripping a model-written id", handle);
|
|
2529
2561
|
writeFileNoFollow(f.canonical, idless);
|
|
2530
2562
|
}
|
|
2531
2563
|
catch (err) {
|
|
@@ -2648,6 +2680,7 @@ export class MemoryEngine {
|
|
|
2648
2680
|
}
|
|
2649
2681
|
const idless = serializeEntryFile({ id: "", frontmatter: p.entry.frontmatter, body: p.entry.body }).replace(/^id:[ \t]*$\r?\n/m, "");
|
|
2650
2682
|
try {
|
|
2683
|
+
this.refuseOutsideStore(flipRec.canonical, "re-minting a marked commit's id", handle);
|
|
2651
2684
|
writeFileNoFollow(flipRec.canonical, idless);
|
|
2652
2685
|
}
|
|
2653
2686
|
catch (err) {
|
|
@@ -2760,7 +2793,7 @@ export class MemoryEngine {
|
|
|
2760
2793
|
}
|
|
2761
2794
|
}
|
|
2762
2795
|
try {
|
|
2763
|
-
patchReport = await this.backend.applyPatches(patches);
|
|
2796
|
+
patchReport = await this.backend.applyPatches(patches, { anchoredRoot: handle.memoryDir });
|
|
2764
2797
|
}
|
|
2765
2798
|
catch (err) {
|
|
2766
2799
|
if (lineageArmed) {
|
|
@@ -2827,14 +2860,14 @@ export class MemoryEngine {
|
|
|
2827
2860
|
}
|
|
2828
2861
|
}
|
|
2829
2862
|
const appliedIds = new Set(patchReport.applied.filter((a) => a.op !== "delete").map((a) => a.id));
|
|
2830
|
-
const planeAfterFailedWriteBack = this.
|
|
2863
|
+
const planeAfterFailedWriteBack = this.zeroCopy
|
|
2831
2864
|
? "this plane is the store itself: the next read adopts them as an out-of-session edit unless the committed copy is put back first"
|
|
2832
2865
|
: "the next materialize re-projects the committed copy over them";
|
|
2833
2866
|
for (const p of pendingProjections) {
|
|
2834
2867
|
const pRel = relative(handle.memoryDir, p.path);
|
|
2835
2868
|
const pSeat = seatOf(p.path);
|
|
2836
2869
|
if (appliedIds.has(p.entry.id)) {
|
|
2837
|
-
const writeBackFailure = this.writeBackProjection(p.path, p.entry, p.needed);
|
|
2870
|
+
const writeBackFailure = this.writeBackProjection(p.path, p.entry, p.needed, handle);
|
|
2838
2871
|
if (p.idCompletion !== true) {
|
|
2839
2872
|
if (writeBackFailure !== undefined)
|
|
2840
2873
|
report.warnings.push(`${pRel}: the entry committed but its projection write-back FAILED — the plane keeps this session's bytes (${planeAfterFailedWriteBack}): ${writeBackFailure}`);
|
|
@@ -2855,6 +2888,7 @@ export class MemoryEngine {
|
|
|
2855
2888
|
let planeHoldsCommitted = false;
|
|
2856
2889
|
if (committed !== undefined && readNoFollowSafe(p.path) !== committed) {
|
|
2857
2890
|
try {
|
|
2891
|
+
this.refuseOutsideStore(p.path, "writing a CAS winner's committed copy back", handle);
|
|
2858
2892
|
writeFileNoFollow(p.path, committed);
|
|
2859
2893
|
planeHoldsCommitted = true;
|
|
2860
2894
|
}
|
|
@@ -3069,7 +3103,7 @@ export class MemoryEngine {
|
|
|
3069
3103
|
}
|
|
3070
3104
|
let patchReport;
|
|
3071
3105
|
try {
|
|
3072
|
-
patchReport = await this.backend.applyPatches([patch]);
|
|
3106
|
+
patchReport = await this.backend.applyPatches([patch], { anchoredRoot: handle.memoryDir });
|
|
3073
3107
|
}
|
|
3074
3108
|
catch (err) {
|
|
3075
3109
|
try {
|
|
@@ -4832,7 +4866,7 @@ export class MemoryEngine {
|
|
|
4832
4866
|
if (opts.write) {
|
|
4833
4867
|
let wrote = false;
|
|
4834
4868
|
try {
|
|
4835
|
-
this.refuseOutsideStore(
|
|
4869
|
+
this.refuseOutsideStore(indexPath, "writing the index", handle);
|
|
4836
4870
|
mkdirSync(dirname(indexPath), { recursive: true });
|
|
4837
4871
|
if (readNoFollowSafe(indexPath) !== text)
|
|
4838
4872
|
writeFileNoFollow(indexPath, text);
|
|
@@ -4852,8 +4886,7 @@ export class MemoryEngine {
|
|
|
4852
4886
|
}
|
|
4853
4887
|
async committedContentOrFault(id) {
|
|
4854
4888
|
let fault = false;
|
|
4855
|
-
|
|
4856
|
-
if (!zeroCopy) {
|
|
4889
|
+
if (!this.zeroCopy) {
|
|
4857
4890
|
try {
|
|
4858
4891
|
const [entry] = await this.backend.getByIds([id]);
|
|
4859
4892
|
if (entry !== undefined && entry.id === id)
|
|
@@ -4872,8 +4905,7 @@ export class MemoryEngine {
|
|
|
4872
4905
|
return { fault };
|
|
4873
4906
|
}
|
|
4874
4907
|
async committedFrontmatterFor(id) {
|
|
4875
|
-
|
|
4876
|
-
if (!zeroCopy) {
|
|
4908
|
+
if (!this.zeroCopy) {
|
|
4877
4909
|
const face = this.backend.retrievalView?.() ?? this.backend;
|
|
4878
4910
|
try {
|
|
4879
4911
|
const [entry] = await face.getByIds([id]);
|
|
@@ -4923,7 +4955,7 @@ export class MemoryEngine {
|
|
|
4923
4955
|
}
|
|
4924
4956
|
let cleared = false;
|
|
4925
4957
|
try {
|
|
4926
|
-
this.refuseOutsideStore(
|
|
4958
|
+
this.refuseOutsideStore(indexPath, "clearing the index", handle);
|
|
4927
4959
|
writeFileNoFollow(indexPath, "");
|
|
4928
4960
|
cleared = true;
|
|
4929
4961
|
}
|
|
@@ -4943,25 +4975,41 @@ export class MemoryEngine {
|
|
|
4943
4975
|
contained: cleared,
|
|
4944
4976
|
};
|
|
4945
4977
|
}
|
|
4946
|
-
refuseOutsideStore(
|
|
4947
|
-
if (landsOutsideStore(
|
|
4978
|
+
refuseOutsideStore(path, act, handle) {
|
|
4979
|
+
if (landsOutsideStore(this.assertRootAnchored(handle), path))
|
|
4948
4980
|
throw storeActRefusal(act, path);
|
|
4949
4981
|
}
|
|
4950
|
-
|
|
4951
|
-
|
|
4982
|
+
storeActRefusedText(path, act, handle) {
|
|
4983
|
+
try {
|
|
4984
|
+
this.refuseOutsideStore(path, act, handle);
|
|
4985
|
+
return undefined;
|
|
4986
|
+
}
|
|
4987
|
+
catch (err) {
|
|
4988
|
+
return this.writeFailureText(err);
|
|
4989
|
+
}
|
|
4990
|
+
}
|
|
4991
|
+
assertRootAnchored(handle) {
|
|
4992
|
+
const root = anchorStoreRoot(this.memoryDir, this.controlDir, { onIncident: this.onIncident, now: this.now });
|
|
4993
|
+
if (handle !== undefined && handle.memoryDir !== root)
|
|
4994
|
+
throw storeRootMovedRefusal(this.memoryDir, { controlDir: this.controlDir, recorded: root, now: handle.memoryDir });
|
|
4995
|
+
return root;
|
|
4996
|
+
}
|
|
4997
|
+
writeIfChanged(target, text, handle) {
|
|
4998
|
+
this.refuseOutsideStore(target, "the projection write", handle);
|
|
4952
4999
|
const current = readNoFollowSafe(target);
|
|
4953
5000
|
if (current === text)
|
|
4954
5001
|
return;
|
|
4955
5002
|
mkdirSync(dirname(target), { recursive: true });
|
|
4956
5003
|
writeFileNoFollow(target, text);
|
|
4957
5004
|
}
|
|
4958
|
-
writeBackProjection(path, entry, needed) {
|
|
5005
|
+
writeBackProjection(path, entry, needed, handle) {
|
|
4959
5006
|
if (!needed)
|
|
4960
5007
|
return undefined;
|
|
4961
5008
|
const text = serializeEntryFile(entry);
|
|
4962
5009
|
if (readNoFollowSafe(path) === text)
|
|
4963
5010
|
return undefined;
|
|
4964
5011
|
try {
|
|
5012
|
+
this.refuseOutsideStore(path, "the projection write-back", handle);
|
|
4965
5013
|
writeFileNoFollow(path, text);
|
|
4966
5014
|
return undefined;
|
|
4967
5015
|
}
|
|
@@ -4969,12 +5017,13 @@ export class MemoryEngine {
|
|
|
4969
5017
|
return this.writeFailureText(err);
|
|
4970
5018
|
}
|
|
4971
5019
|
}
|
|
4972
|
-
async repairProjectionSeat(seat, canonical, entryId, debtClears, warnings) {
|
|
5020
|
+
async repairProjectionSeat(seat, canonical, entryId, debtClears, warnings, handle) {
|
|
4973
5021
|
const committed = await this.committedContentFor(entryId);
|
|
4974
5022
|
if (committed === undefined)
|
|
4975
5023
|
return;
|
|
4976
5024
|
if (readNoFollowSafe(canonical) !== committed) {
|
|
4977
5025
|
try {
|
|
5026
|
+
this.refuseOutsideStore(canonical, "repairing a projection seat", handle);
|
|
4978
5027
|
writeFileNoFollow(canonical, committed);
|
|
4979
5028
|
}
|
|
4980
5029
|
catch (err) {
|
|
@@ -4985,8 +5034,7 @@ export class MemoryEngine {
|
|
|
4985
5034
|
debtClears.push({ ...seat, entryId });
|
|
4986
5035
|
}
|
|
4987
5036
|
async debtCommittedProjection(entryId) {
|
|
4988
|
-
|
|
4989
|
-
if (zeroCopy)
|
|
5037
|
+
if (this.zeroCopy)
|
|
4990
5038
|
return { state: "stale" };
|
|
4991
5039
|
const face = this.backend.retrievalView?.() ?? this.backend;
|
|
4992
5040
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { scopeDirName, type ChallengeEvent, type MemoryPartitionIncidentSink } from "./layout.js";
|
|
1
|
+
import { scopeDirName, type TxnLockTimings, type ChallengeEvent, type MemoryPartitionIncidentSink } from "./layout.js";
|
|
2
2
|
import type { MemoryBundleImportPlan, MemoryImportReport } from "./export-bundle.js";
|
|
3
3
|
import type { HarvestRejection, MemoryBackend, MemoryEntry, MemoryEntryHeader, MemoryScopeEnumeration, NotePatch, PatchReport, ScoredMemoryEntry } from "./types.js";
|
|
4
4
|
export { DEFAULT_MAX_ENTRY_DEPTH, MEMORY_INDEX_FILENAME, scanEntryFiles, type ScannedEntryFile } from "./entry-scan.js";
|
|
@@ -312,12 +312,6 @@ export interface MemoryExportSnapshot {
|
|
|
312
312
|
quarantined: string[];
|
|
313
313
|
quarantineOpaque: number;
|
|
314
314
|
}
|
|
315
|
-
/** Test hook (证伪式复审 L3): small constants so the crash-window leg does not really wait 15-30s. */
|
|
316
|
-
interface TxnLockTimings {
|
|
317
|
-
staleMs?: number;
|
|
318
|
-
waitMs?: number;
|
|
319
|
-
stealGraceMs?: number;
|
|
320
|
-
}
|
|
321
315
|
/** Construction options for {@link FileMemoryEngineBackend}. */
|
|
322
316
|
export interface FileMemoryEngineBackendOptions {
|
|
323
317
|
/** ⚠️ 分家坑(service 报告 2026-07-09):不显式传时,控制平面按无参 `resolveMemoryEngineRoot()`
|
|
@@ -353,8 +347,6 @@ export declare class FileMemoryEngineBackend implements MemoryBackend {
|
|
|
353
347
|
* NEVER under {@link directoryRoot}, always on the config-root side even for an in-repo memory dir.
|
|
354
348
|
* The engine picks this up (like `directoryRoot`) so both sides share ONE control plane. */
|
|
355
349
|
readonly controlPlaneRoot: string;
|
|
356
|
-
/** {@link directoryRoot}'s physical form at construction — the root every act on a store path is judged against. */
|
|
357
|
-
private readonly physicalRoot;
|
|
358
350
|
/** Injected clock (opus 1.258 LOW: match the engine's `this.now` determinism discipline). */
|
|
359
351
|
private readonly now;
|
|
360
352
|
/** The construction-time incident sink (partition adoption, layout adoption on the standalone faces). */
|
|
@@ -687,13 +679,16 @@ export declare class FileMemoryEngineBackend implements MemoryBackend {
|
|
|
687
679
|
* first op that would land outside the store, naming the op (its path on `detail.path`). Runs over a
|
|
688
680
|
* whole batch before its commit marker (no journal is written; a caller that staged files removes
|
|
689
681
|
* them) and per op at the act itself; past the marker a refusal keeps the journal, which replays
|
|
690
|
-
* once the path resolves inside the store again.
|
|
682
|
+
* once the path resolves inside the store again. The root judged against is the anchored one, read at
|
|
683
|
+
* this call ({@link assertRootAnchored}); with `anchoredRoot` (the caller's session root) it must be that one.
|
|
691
684
|
*/
|
|
692
685
|
private refuseEscapingTargets;
|
|
693
|
-
/** At the head of every face (both recovery legs, the lock-free faces' layout seat,
|
|
694
|
-
* the
|
|
695
|
-
* carry every read, adoption, sweep and restore — not only
|
|
696
|
-
|
|
686
|
+
/** At construction and at the head of every face (both recovery legs, the lock-free faces' layout seat,
|
|
687
|
+
* the adoption face): the store root against its anchor ({@link anchorStoreRoot}); answers the anchored
|
|
688
|
+
* physical root. A root re-pointed since would carry every read, adoption, sweep and restore — not only
|
|
689
|
+
* the journal's acts — into another directory. Read every time, never kept. With `expected` (a caller
|
|
690
|
+
* session's root) the anchor must be that root too — the engine's handle comparison, at this act. */
|
|
691
|
+
private assertRootAnchored;
|
|
697
692
|
/** Remove orphaned `.stage-*` files (a crash BEFORE the journal rename = clean rollback: nothing
|
|
698
693
|
* was committed, the staged tmps are litter). Dotfiles are invisible to entry scans regardless. */
|
|
699
694
|
private sweepStagedFiles;
|
|
@@ -978,23 +973,11 @@ export declare class FileMemoryEngineBackend implements MemoryBackend {
|
|
|
978
973
|
* 5. EXECUTE: atomic renames / deletes / shadow updates.
|
|
979
974
|
* 6. Persist the ledger (atomic, fail-closed) and drop the journal.
|
|
980
975
|
*/
|
|
981
|
-
applyPatches(patches: readonly NotePatch[]
|
|
976
|
+
applyPatches(patches: readonly NotePatch[], opts?: {
|
|
977
|
+
readonly anchoredRoot?: string;
|
|
978
|
+
}): Promise<PatchReport>;
|
|
982
979
|
private txnLockDir;
|
|
983
|
-
/**
|
|
984
|
-
* 证伪式复审 L1/L2/L3 — the mkdir mutex, hardened (same shape as layout.ts' acquireSidecarLock, but
|
|
985
|
-
* fail-closed timings and an async wait):
|
|
986
|
-
* - L2: every acquisition writes an OWNER TOKEN (`<lock>/owner`, crypto-random — never a
|
|
987
|
-
* timestamp) immediately after mkdir. Release only removes the lock while the token is still
|
|
988
|
-
* ours; {@link assertTxnLockOwnership} re-verifies it at the commit point.
|
|
989
|
-
* - L1: the stale steal is SINGLE-WINNER — atomic rename of the stale lock dir to a unique
|
|
990
|
-
* tombstone (exactly one racer's rename succeeds; losers ENOENT back into the wait loop), then
|
|
991
|
-
* the winner removes the tombstone and re-acquires through a NORMAL mkdir. Never a bare
|
|
992
|
-
* rmSync+mkdir (two same-window stealers would force-rm each other's FRESH lock = double hold).
|
|
993
|
-
* - L2 (steal side): only a lock that is BOTH past its stale line AND carries an owner token is
|
|
994
|
-
* stealable (a tokenless dir is a mid-acquisition, not a crashed holder).
|
|
995
|
-
* - L3: the wait deadline is `max(waitMs, observed lock's stale line + grace)` — a holder that
|
|
996
|
-
* crashed with `remaining stale > waitMs` no longer strands every waiter in an all-throw window.
|
|
997
|
-
*/
|
|
980
|
+
/** The store's transaction lock, waited for ({@link acquireStoreTxnLock} — the one mkdir mutex, shared with a re-anchor of the root). */
|
|
998
981
|
private acquireTxnLock;
|
|
999
982
|
/** 证伪式复审 L2 — 提交点归属复验: called immediately before the JOURNAL write (the persistent commit
|
|
1000
983
|
* point). A holder that stalled past the stale deadline (slow disk / GC pause / long txn) and was
|