@sema-agent/core 7.52.0 → 7.54.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 +470 -0
- package/LICENSE +3 -1
- package/README.md +3 -1
- package/dist/agents/cross-session-envelope.d.ts +8 -0
- package/dist/agents/cross-session-envelope.js +6 -0
- package/dist/agents/cross-session-judge.d.ts +21 -1
- package/dist/agents/cross-session-judge.js +8 -0
- package/dist/agents/cross-session-ref.d.ts +5 -0
- package/dist/agents/cross-session-ref.js +1 -0
- package/dist/agents/org-delivery-gate.d.ts +122 -0
- package/dist/agents/org-delivery-gate.js +69 -0
- package/dist/agents/peer-held-queue.d.ts +9 -4
- package/dist/agents/peer-held-queue.js +6 -5
- package/dist/agents/peer-session-drain.d.ts +35 -6
- package/dist/agents/peer-session-drain.js +271 -182
- package/dist/agents/read-inbox-tool.d.ts +7 -0
- package/dist/agents/read-inbox-tool.js +5 -1
- package/dist/agents/send-message-tool.js +3 -4
- package/dist/agents/subagent.d.ts +6 -5
- package/dist/agents/subagent.js +117 -83
- package/dist/agents/tool-filter.d.ts +25 -4
- package/dist/agents/tool-filter.js +13 -3
- package/dist/brain/anthropic.d.ts +6 -1
- package/dist/brain/anthropic.js +4 -4
- package/dist/brain/model-presets.js +2 -1
- package/dist/brain/route-adjudicator.d.ts +6 -0
- package/dist/brain/routing.d.ts +24 -1
- package/dist/brain/routing.js +54 -19
- package/dist/brain/timeout.js +5 -4
- package/dist/core/a2a.d.ts +5 -2
- package/dist/core/a2a.js +33 -14
- package/dist/core/allow-entry.d.ts +3 -1
- package/dist/core/allow-entry.js +3 -2
- package/dist/core/approval-object.d.ts +87 -0
- package/dist/core/approval-object.js +85 -0
- package/dist/core/arg-summary.d.ts +3 -2
- package/dist/core/arg-summary.js +17 -11
- package/dist/core/ask-origin.d.ts +43 -27
- package/dist/core/ask-origin.js +20 -11
- package/dist/core/ask-question.d.ts +0 -1
- package/dist/core/ask-question.js +4 -67
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/auto-compaction.d.ts +106 -50
- package/dist/core/auto-compaction.js +69 -53
- package/dist/core/auto-mode-prompt.d.ts +4 -2
- package/dist/core/auto-mode-prompt.js +4 -3
- package/dist/core/canonical-json.d.ts +69 -0
- package/dist/core/canonical-json.js +130 -8
- package/dist/core/checkpoint-requirements.d.ts +13 -7
- package/dist/core/checkpoint-requirements.js +4 -1
- package/dist/core/checkpoint-store.d.ts +60 -36
- package/dist/core/checkpoint-store.js +7 -6
- package/dist/core/child-clamp-seats.d.ts +45 -6
- package/dist/core/child-clamp-seats.js +56 -4
- package/dist/core/compliance.js +3 -1
- package/dist/core/consolidate-scope.d.ts +1 -1
- package/dist/core/cross-boundary-taint.d.ts +213 -0
- package/dist/core/cross-boundary-taint.js +196 -0
- package/dist/core/decision-receipt.d.ts +44 -1
- package/dist/core/decision-receipt.js +16 -0
- package/dist/core/effective-path-target.d.ts +28 -6
- package/dist/core/effective-path-target.js +28 -2
- package/dist/core/engine-notice.d.ts +47 -4
- package/dist/core/engine-notice.js +17 -1
- package/dist/core/engine-storage-backend.d.ts +73 -0
- package/dist/core/engine-storage-backend.js +1 -0
- package/dist/core/file-history-store.d.ts +6 -2
- package/dist/core/file-history-store.js +1 -0
- package/dist/core/gate-fold.js +13 -4
- package/dist/core/gate-lanes.js +41 -34
- package/dist/core/gate-outcome.d.ts +18 -9
- package/dist/core/governance-codes.d.ts +9 -2
- package/dist/core/governance-codes.js +9 -0
- package/dist/core/hands-band-screen.d.ts +7 -0
- package/dist/core/hands-band-screen.js +32 -0
- package/dist/core/hooks.d.ts +21 -19
- package/dist/core/hooks.js +6 -5
- package/dist/core/locked-config.d.ts +110 -31
- package/dist/core/locked-config.js +155 -42
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp-probe.js +1 -1
- package/dist/core/mcp-server-spec.d.ts +152 -17
- package/dist/core/mcp-server-spec.js +223 -40
- package/dist/core/mcp.d.ts +21 -14
- package/dist/core/mcp.js +59 -54
- package/dist/core/memory-engine/engine.d.ts +14 -19
- package/dist/core/memory-engine/engine.js +9 -6
- package/dist/core/memory-engine/export-bundle.d.ts +1 -1
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/file-backend.d.ts +2 -6
- package/dist/core/memory-engine/file-backend.js +1 -12
- package/dist/core/memory.d.ts +3 -3
- package/dist/core/mode-policy.d.ts +16 -26
- package/dist/core/mode-policy.js +5 -18
- package/dist/core/mods/kernel/dispatch.js +13 -15
- package/dist/core/mods/kernel/events.d.ts +9 -6
- package/dist/core/mods/kernel/events.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +41 -11
- package/dist/core/mods/kernel/receive.js +124 -54
- package/dist/core/mods/kernel/site-rules.d.ts +80 -15
- package/dist/core/mods/kernel/site-rules.js +232 -40
- package/dist/core/mods/stations.d.ts +0 -6
- package/dist/core/mods/stations.js +0 -7
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +71 -2
- package/dist/core/own-property-receipt.d.ts +13 -0
- package/dist/core/own-property-receipt.js +3 -1
- package/dist/core/parent-spec-seat.d.ts +12 -15
- package/dist/core/parent-spec-seat.js +14 -6
- package/dist/core/pause-registry.d.ts +35 -1
- package/dist/core/pause-registry.js +10 -0
- package/dist/core/permission-rule-consent.d.ts +18 -5
- package/dist/core/permission-rule-consent.js +13 -8
- package/dist/core/permission-rule-model.d.ts +87 -15
- package/dist/core/permission-rule-model.js +87 -8
- package/dist/core/permission-rule-org.d.ts +200 -33
- package/dist/core/permission-rule-org.js +217 -91
- package/dist/core/permission-rule-session.js +2 -2
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +1 -0
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +37 -8
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/read-only-shell.js +30 -9
- package/dist/core/remote-env.d.ts +41 -1
- package/dist/core/remote-env.js +18 -0
- package/dist/core/resume-startup-cause.d.ts +18 -0
- package/dist/core/resume-startup-cause.js +12 -0
- package/dist/core/retention.js +7 -2
- package/dist/core/retired-keys.d.ts +8 -2
- package/dist/core/retired-keys.js +12 -1
- package/dist/core/roles.js +60 -10
- package/dist/core/rule-lane-reads.js +1 -1
- package/dist/core/runner/approval-feedback.d.ts +46 -0
- package/dist/core/runner/approval-feedback.js +41 -0
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.js +2 -2
- package/dist/core/runner/contracts.d.ts +34 -41
- package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
- package/dist/core/runner/cross-boundary-lane.js +190 -0
- package/dist/core/runner/decide-continuation.d.ts +4 -4
- package/dist/core/runner/decide-continuation.js +3 -1
- package/dist/core/runner/gate-exit.d.ts +32 -12
- package/dist/core/runner/gate-exit.js +77 -34
- package/dist/core/runner/inherited-ask-grants.js +2 -2
- package/dist/core/runner/mcp-redial.d.ts +52 -10
- package/dist/core/runner/mcp-redial.js +38 -9
- package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
- package/dist/core/runner/permission-rule-lanes.js +22 -10
- package/dist/core/runner/person-path-rows.d.ts +5 -3
- package/dist/core/runner/person-path-rows.js +2 -2
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
- package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
- package/dist/core/runner/prepare-config-doors.d.ts +58 -15
- package/dist/core/runner/prepare-config-doors.js +167 -146
- package/dist/core/runner/prepare-context-lane.js +6 -3
- package/dist/core/runner/prepare-defer-classify.js +4 -7
- package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
- package/dist/core/runner/prepare-delegation-surface.js +8 -7
- package/dist/core/runner/prepare-execution-env.d.ts +1 -2
- package/dist/core/runner/prepare-execution-env.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
- package/dist/core/runner/prepare-gate-stations.js +4 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +3 -3
- package/dist/core/runner/prepare-hands-readface.js +3 -2
- package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
- package/dist/core/runner/prepare-inherited-gate.js +3 -2
- package/dist/core/runner/prepare-listings.d.ts +1 -1
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
- package/dist/core/runner/prepare-memory-engine-session.js +19 -6
- package/dist/core/runner/prepare-memory.d.ts +3 -2
- package/dist/core/runner/prepare-memory.js +6 -2
- package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
- package/dist/core/runner/prepare-offload-wrappers.js +2 -1
- package/dist/core/runner/prepare-park-ask.d.ts +1 -1
- package/dist/core/runner/prepare-park-ask.js +9 -3
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +14 -19
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +6 -4
- package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
- package/dist/core/runner/prepare-prompt-assembly.js +20 -16
- package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
- package/dist/core/runner/prepare-prompt-inputs.js +6 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
- package/dist/core/runner/prepare-protocol-tools.js +19 -12
- package/dist/core/runner/prepare-question-face.d.ts +4 -2
- package/dist/core/runner/prepare-question-face.js +4 -3
- package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
- package/dist/core/runner/prepare-safety-scan.js +34 -27
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.js +6 -2
- package/dist/core/runner/prepare-task.js +22 -19
- package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
- package/dist/core/runner/prepare-turn-wiring.js +14 -49
- package/dist/core/runner/prepare-wiring-manifest.d.ts +10 -5
- package/dist/core/runner/prepare-wiring-manifest.js +9 -6
- package/dist/core/runner/prepare-workspace-restore.js +2 -2
- package/dist/core/runner/resume-admission.d.ts +4 -1
- package/dist/core/runner/resume-admission.js +16 -14
- package/dist/core/runner/resume-apply.js +4 -4
- package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
- package/dist/core/runner/resume-internals-and-config.js +3 -8
- package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
- package/dist/core/runner/resume-policy-outcome.js +18 -15
- package/dist/core/runner/resume-preflight.js +2 -2
- package/dist/core/runner/resume-review-outcome.js +3 -3
- package/dist/core/runner/retired-runner-deps.d.ts +5 -6
- package/dist/core/runner/retired-runner-deps.js +1 -4
- package/dist/core/runner/run-leg.js +97 -43
- package/dist/core/runner/run-recovery-lanes.js +5 -3
- package/dist/core/runner/run-settle-and-teardown.js +2 -0
- package/dist/core/runner/run-terminal-adoption.js +21 -9
- package/dist/core/runner/run-turn-boundary.js +9 -3
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/session-file-state-replay.d.ts +5 -2
- package/dist/core/runner/session-file-state-replay.js +3 -2
- package/dist/core/runner/skills-seat.d.ts +15 -0
- package/dist/core/runner/skills-seat.js +57 -0
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
- package/dist/core/runner/sub-agent-deny-lists.js +7 -5
- package/dist/core/runner/synthetic-tools.d.ts +5 -2
- package/dist/core/runner/synthetic-tools.js +2 -12
- package/dist/core/runner/tool-face-overlay.d.ts +24 -6
- package/dist/core/runner/tool-face-overlay.js +24 -15
- package/dist/core/runner-deps.d.ts +37 -22
- package/dist/core/session-policy-store.d.ts +19 -0
- package/dist/core/session-policy-store.js +22 -2
- package/dist/core/session-store.d.ts +35 -16
- package/dist/core/session-store.js +20 -12
- package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
- package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
- package/dist/core/shell-wrapper-table.d.ts +5 -3
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
- package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
- package/dist/core/store-contracts/session-store-contract.js +639 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
- package/dist/core/task-event.d.ts +44 -6
- package/dist/core/task-notification.js +2 -2
- package/dist/core/task-registry-agent.js +1 -0
- package/dist/core/task-registry-shared.d.ts +5 -0
- package/dist/core/task-registry.d.ts +7 -0
- package/dist/core/task-registry.js +17 -0
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +7 -7
- package/dist/core/tighten-task-spec.d.ts +6 -4
- package/dist/core/tighten-task-spec.js +2 -2
- package/dist/core/tool-catalog-entries.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +52 -52
- package/dist/core/tool-face-reader.d.ts +49 -0
- package/dist/core/tool-face-reader.js +94 -0
- package/dist/core/tool-face.d.ts +17 -8
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +67 -23
- package/dist/core/tool-policy.js +72 -60
- package/dist/core/tool-roster.d.ts +46 -28
- package/dist/core/tool-roster.js +91 -14
- package/dist/core/tool-spec-members.js +2 -2
- package/dist/core/tool-spec.d.ts +20 -4
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +24 -2
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +23 -0
- package/dist/core/untrusted-text.js +10 -10
- package/dist/core/user-attachment.d.ts +56 -2
- package/dist/core/user-attachment.js +139 -56
- package/dist/core/wiring-manifest.d.ts +4 -2
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/harness/types.d.ts +10 -4
- package/dist/engine/llm/types.d.ts +7 -2
- package/dist/engine/llm/types.js +2 -1
- package/dist/engine/loop/agent-loop.d.ts +12 -1
- package/dist/engine/loop/agent-loop.js +17 -5
- package/dist/engine/loop/types.d.ts +7 -1
- package/dist/engine/session/repo-utils.d.ts +5 -0
- package/dist/engine/session/repo-utils.js +9 -0
- package/dist/engine/session/storage-base.js +2 -2
- package/dist/index.d.ts +37 -17
- package/dist/index.js +31 -14
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.d.ts +24 -1
- package/dist/orchestration/goal.js +3 -2
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +1 -0
- package/dist/orchestration/workflow-governance.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +2 -1
- package/dist/prompt-assembly/artifact-store.d.ts +44 -9
- package/dist/prompt-assembly/artifact-store.js +38 -12
- package/dist/prompt-assembly/artifact.d.ts +12 -11
- package/dist/prompt-assembly/artifact.js +52 -21
- package/dist/prompt-assembly/assemble.d.ts +2 -0
- package/dist/prompt-assembly/assemble.js +2 -1
- package/dist/prompt-assembly/catalog/index.js +2 -1
- package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
- package/dist/prompt-assembly/catalog/memory.js +6 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +19 -2
- package/dist/prompt-assembly/catalog/schema.js +3 -0
- package/dist/prompt-assembly/composer.d.ts +2 -0
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/overlay.d.ts +21 -11
- package/dist/prompt-assembly/overlay.js +57 -19
- package/dist/prompt-assembly/select.d.ts +21 -6
- package/dist/prompt-assembly/select.js +41 -4
- package/dist/prompts/default.d.ts +1 -12
- package/dist/prompts/default.js +0 -3
- package/dist/shell/lex.d.ts +87 -8
- package/dist/shell/lex.js +283 -49
- package/dist/stores/file/index.d.ts +8 -6
- package/dist/stores/file/permission-rule-store.d.ts +1 -1
- package/dist/stores/file/permission-rule-store.js +2 -1
- package/dist/tools/artifact/artifact-tool.js +14 -3
- package/dist/tools/fs/bash-program-position.d.ts +3 -15
- package/dist/tools/fs/bash-program-position.js +3 -10
- package/dist/tools/fs/bash-readonly-classifier.js +2 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-bash.js +72 -101
- package/dist/tools/fs/fs-read.d.ts +12 -0
- package/dist/tools/fs/fs-read.js +10 -9
- package/dist/tools/fs/fs-shared.d.ts +27 -31
- package/dist/tools/fs/fs-shared.js +12 -15
- package/dist/tools/fs/fs-write.js +1 -1
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/read-deny-home.d.ts +1 -1
- package/dist/tools/fs/read-deny-home.js +5 -4
- package/dist/tools/fs/read-deny.d.ts +16 -3
- package/dist/tools/fs/read-deny.js +12 -9
- package/dist/tools/fs/safety.d.ts +7 -6
- package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
- package/dist/tools/fs/shell-read-bindings.js +15 -16
- package/dist/tools/fs/shell-read-device.js +1 -1
- package/dist/tools/fs/shell-read-plan.js +36 -47
- package/dist/tools/fs/shell-read-word.d.ts +1 -6
- package/dist/tools/fs/shell-read-word.js +2 -20
- package/dist/tools/fs/shell-reentry-text.js +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +5651 -5457
- package/wire-changes/core@7.53.0.json +1968 -0
- package/wire-changes/core@7.54.0.json +2870 -0
- package/dist/core/shell-scan.d.ts +0 -60
- package/dist/core/shell-scan.js +0 -183
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CATCH_BUDGET_MS, createSelfBudget, POST_ABORT_GRACE_MS, RUNAWAY_AFTER_MS, unrefTimer, watchRunaway } from "./budget.js";
|
|
2
2
|
import { expandModPattern, isModEventName, MOD_SEATS, nextToRefusal, stationOn } from "./events.js";
|
|
3
3
|
import { ENGINE_ORIGIN, modsInvalid, screenModSeats, } from "./registration.js";
|
|
4
|
-
import { answerUpward, answerViolation, detachedCopy, matcherMatches, matcherViolation, methodAnswerViolation, NEXT_IN_FLIGHT,
|
|
4
|
+
import { answerUpward, answerViolation, detachedCopy, engineObjectsOnce, handedOn, matcherMatches, matcherViolation, methodAnswerViolation, NEXT_IN_FLIGHT, receiveAnswer, receiveEvent, receivePayload, } from "./site-rules.js";
|
|
5
5
|
const TIER_RANK = { prepend: 0, user: 1, append: 2, builtin: 3, core: 4 };
|
|
6
6
|
const bypassed = (floors, tier) => floors.some((f) => TIER_RANK[f.from] < TIER_RANK[tier] && TIER_RANK[tier] < TIER_RANK[f.to]);
|
|
7
7
|
export async function admitMods(input) {
|
|
@@ -202,7 +202,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
202
202
|
hasHandlers: (event, participant) => mounted.some((h) => h.events.has(event) && admits(participant, h)),
|
|
203
203
|
dispatch: (event, e, options) => {
|
|
204
204
|
const st = stationOn(event, side);
|
|
205
|
-
const received = st === undefined ? { refusal: `${event} is not raised on the ${side} bus` } :
|
|
205
|
+
const received = st === undefined ? { refusal: `${event} is not raised on the ${side} bus` } : receiveEvent(e);
|
|
206
206
|
if (st === undefined || "refusal" in received) {
|
|
207
207
|
const reason = `${event}: ${"refusal" in received ? received.refusal : "not raised"}`;
|
|
208
208
|
report(new Error(`engine: ${reason} — the dispatch was not run`));
|
|
@@ -237,7 +237,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
237
237
|
throw new Error(`${caller.origin.plugin}: $.${event}: not raised on the ${side} bus`);
|
|
238
238
|
let e0 = args;
|
|
239
239
|
if (seat.enter !== undefined) {
|
|
240
|
-
const shaped = receivePayload(seat.enter(args),
|
|
240
|
+
const shaped = receivePayload(seat.enter(args), isProxy, engineObjectsOnce(args)());
|
|
241
241
|
if ("refusal" in shaped)
|
|
242
242
|
throw new TypeError(`${caller.origin.plugin}: $.${event}: ${shaped.refusal}`);
|
|
243
243
|
e0 = shaped.payload;
|
|
@@ -263,7 +263,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
263
263
|
throw new Error(`${caller.origin.plugin}: $.${event}: ${deny}`);
|
|
264
264
|
return typeof answer === "object" && answer !== null ? Reflect.get(answer, "value") : undefined;
|
|
265
265
|
}
|
|
266
|
-
function dollarFor(reg, frames, budget, signal) {
|
|
266
|
+
function dollarFor(reg, frames, budget, signal, engines) {
|
|
267
267
|
const origin = Object.freeze({ plugin: reg.name, tier: reg.tier });
|
|
268
268
|
const callerFrames = Object.freeze([...frames, Object.freeze({ kind: "dollar", plugin: reg.name })]);
|
|
269
269
|
const namespaces = new Map();
|
|
@@ -273,7 +273,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
273
273
|
ns[m.method] = async (args) => {
|
|
274
274
|
if (!reg.callsBound.has(m.event))
|
|
275
275
|
throw new Error(`${reg.name}: $.${m.event}: not declared in uses.calls`);
|
|
276
|
-
const received = receivePayload(args === undefined ? {} : args,
|
|
276
|
+
const received = receivePayload(args === undefined ? {} : args, isProxy, engines());
|
|
277
277
|
if ("refusal" in received)
|
|
278
278
|
throw new TypeError(`${reg.name}: $.${m.event}: takes one object — ${received.refusal}`);
|
|
279
279
|
if (m.pauses)
|
|
@@ -347,19 +347,17 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
347
347
|
const drop = () => void pendingRuns.delete(run);
|
|
348
348
|
run.then(drop, drop);
|
|
349
349
|
};
|
|
350
|
+
const engines = engineObjectsOnce(e0);
|
|
350
351
|
const handOn = (passed) => {
|
|
351
352
|
if (passed === e0)
|
|
352
353
|
return { snap: e0 };
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
return { violation: `next() takes the event object: ${received.refusal}` };
|
|
356
|
-
const k = pinnedKeyChanged(st.pinned, e0, received.payload);
|
|
357
|
-
return k === undefined ? { snap: received.payload } : { violation: `next() changed the pinned key "${k}"` };
|
|
354
|
+
const handed = handedOn(st.pinned, e0, passed, engines(), isProxy);
|
|
355
|
+
return "violation" in handed ? handed : { snap: handed.payload };
|
|
358
356
|
};
|
|
359
357
|
const takeAnswer = (answer, s, e, h) => {
|
|
360
358
|
let taken = answer;
|
|
361
359
|
if (!s.answers.some((a) => Object.is(a, answer))) {
|
|
362
|
-
const received = receiveAnswer(answer, isProxy);
|
|
360
|
+
const received = receiveAnswer(answer, engines(), isProxy);
|
|
363
361
|
if ("refusal" in received)
|
|
364
362
|
return { violation: received.refusal };
|
|
365
363
|
taken = received.answer;
|
|
@@ -472,7 +470,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
472
470
|
}
|
|
473
471
|
else {
|
|
474
472
|
const next = makeNext({ budget, signal: ac.signal, trace: () => Object.freeze([...state.below]) }, (x) => descend(x, floors), to);
|
|
475
|
-
const $ = dollarFor(h.reg, myFrames, budget, ac.signal);
|
|
473
|
+
const $ = dollarFor(h.reg, myFrames, budget, ac.signal, engines);
|
|
476
474
|
handlerP = invokeNow(() => h.fn($, e, next));
|
|
477
475
|
try {
|
|
478
476
|
const raced = await Promise.race([handlerP, budget.expired]);
|
|
@@ -578,7 +576,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
578
576
|
return why !== undefined ? Promise.reject(new Error(`${h.reg.name}: ${why}`)) : replay(x, [...floors, { from: h.reg.tier, to: tier }]);
|
|
579
577
|
}, { error, called: state.called });
|
|
580
578
|
try {
|
|
581
|
-
const raced = await Promise.race([invokeNow(() => onCatch(dollarFor(h.reg, myFrames, budget, ac.signal), e, next)), budget.expired]);
|
|
579
|
+
const raced = await Promise.race([invokeNow(() => onCatch(dollarFor(h.reg, myFrames, budget, ac.signal, engines), e, next)), budget.expired]);
|
|
582
580
|
if (raced === "expired" && budget.isExpired())
|
|
583
581
|
return { problem: `its .catch ran past its ${CATCH_BUDGET_MS}ms budget` };
|
|
584
582
|
if (violated !== undefined)
|
|
@@ -610,7 +608,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
610
608
|
report(new Error(`${name}: ${event}: an observe handler returned a verdict — not adopted; an observe handler answers undefined`), "observational-hook-verdict-ignored");
|
|
611
609
|
};
|
|
612
610
|
try {
|
|
613
|
-
const raced = await Promise.race([invokeNow(() => h.fn(dollarFor(h.reg, myFrames, budget, ac.signal), detachedCopy(e0), next)), budget.expired]);
|
|
611
|
+
const raced = await Promise.race([invokeNow(() => h.fn(dollarFor(h.reg, myFrames, budget, ac.signal, engines), detachedCopy(e0), next)), budget.expired]);
|
|
614
612
|
if (raced === "expired" && budget.isExpired())
|
|
615
613
|
throw new Error(`ran past its ${h.reg.budgetMs}ms budget`);
|
|
616
614
|
verdict(raced);
|
|
@@ -631,7 +629,7 @@ function createBus(side, mounted, bottoms, report, records, describe, isProxy) {
|
|
|
631
629
|
called: false,
|
|
632
630
|
});
|
|
633
631
|
try {
|
|
634
|
-
const caught = await Promise.race([invokeNow(() => onCatch(dollarFor(h.reg, myFrames, catchBudget, cac.signal), detachedCopy(e0), cnext)), catchBudget.expired]);
|
|
632
|
+
const caught = await Promise.race([invokeNow(() => onCatch(dollarFor(h.reg, myFrames, catchBudget, cac.signal, engines), detachedCopy(e0), cnext)), catchBudget.expired]);
|
|
635
633
|
if (!(caught === "expired" && catchBudget.isExpired()))
|
|
636
634
|
verdict(caught);
|
|
637
635
|
}
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* The kernel CONTRACT number — a monotonic integer, independent of the package version (the package is
|
|
11
|
-
* cut with core every release; this number is not).
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* the
|
|
11
|
+
* cut with core every release; this number is not). It is exported for a host that loads a kernel copy
|
|
12
|
+
* beside another one to compare for EQUALITY; nothing in this folder or in the engine reads it, so two
|
|
13
|
+
* copies that differ are not detected here. It is raised when, and only when, one of four things changes:
|
|
14
|
+
* the chain semantics (`next`, `next.to`, origin, trace, re-entry frames), the registration form (`ModRegistration`, `on`, `uses`),
|
|
15
|
+
* the event closed set (names and their `side`), or the failure columns (failure, abort, pinned keys — which keys,
|
|
16
|
+
* and how a pinned key is judged: by value since 2).
|
|
15
17
|
*/
|
|
16
|
-
export declare const KERNEL_CONTRACT_VERSION =
|
|
18
|
+
export declare const KERNEL_CONTRACT_VERSION = 2;
|
|
17
19
|
/** The five tiers in run order (CC names). `builtin` and `core` are the engine's own. */
|
|
18
20
|
export declare const MOD_TIERS: readonly ["prepend", "user", "append", "builtin", "core"];
|
|
19
21
|
export type ModTier = (typeof MOD_TIERS)[number];
|
|
@@ -58,7 +60,8 @@ export declare const SEAT_TIER_TABLE: Readonly<{
|
|
|
58
60
|
export interface ModStation {
|
|
59
61
|
readonly failure: ModFailureAnswer;
|
|
60
62
|
readonly abort: ModAbortPosture;
|
|
61
|
-
/** Keys a handler may not change when it passes `e` on through `next
|
|
63
|
+
/** Keys a handler may not change when it passes `e` on through `next` — compared by value: the engine's fact handed on,
|
|
64
|
+
* or a copy of it (a spread, a structured clone, a JSON round trip), is not a change; a different value is. */
|
|
62
65
|
readonly pinned: readonly string[];
|
|
63
66
|
readonly method?: {
|
|
64
67
|
readonly pausesCallerBudget: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const KERNEL_CONTRACT_VERSION =
|
|
1
|
+
export const KERNEL_CONTRACT_VERSION = 2;
|
|
2
2
|
export const MOD_TIERS = Object.freeze(["prepend", "user", "append", "builtin", "core"]);
|
|
3
3
|
export const MOD_SEATS = Object.freeze(["deployment", "task"]);
|
|
4
4
|
export const MOD_EVENT_SIDES = Object.freeze(["engine", "surface", "both"]);
|
|
@@ -87,7 +87,7 @@ export const MOD_EVENT_TABLE = Object.freeze({
|
|
|
87
87
|
"prompt.context": engine(),
|
|
88
88
|
"prompt.attachment": engine(),
|
|
89
89
|
"prompt.mention": surface,
|
|
90
|
-
"prompt.compose": engine(station("skip", "grace", ["model"])),
|
|
90
|
+
"prompt.compose": engine(station("skip", "grace", ["model", "catalog", "selectors"])),
|
|
91
91
|
"tool.describe": engine(),
|
|
92
92
|
"command.run": surface,
|
|
93
93
|
"command.describe": surface,
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
* ordinary array — within `depth` levels is copied member by member off its own property descriptors, captured in
|
|
9
9
|
* one call before any of the caller's code can run; each member lands as an enumerable data property of the copy (a
|
|
10
10
|
* defined property, never an assignment, so an own `__proto__` key stays a plain key). Anything else — a function, an
|
|
11
|
-
* object of another prototype, a container past `depth` — is handed as it is
|
|
12
|
-
*
|
|
11
|
+
* object of another prototype, a container past `depth` — is handed as it is, refused, or (an object of another
|
|
12
|
+
* prototype under `copy`) copied off its own members like a record, by `others`, which also says whether cycles and
|
|
13
|
+
* shared references keep their shape or are refused / walked again. A refusal refuses the whole receipt, or — under
|
|
14
|
+
* `contain` — only the member it was met in. The walk keeps its own stack (one frame per container being copied), so
|
|
15
|
+
* neither how deep a value nests nor how deep its caller already stands decides a verdict: only `depth` does.
|
|
13
16
|
*
|
|
14
17
|
* Zero-dependency on purpose (this folder compiles on its own): a Proxy cannot be recognised from here, so the
|
|
15
18
|
* host passes its probe (`isProxy`); with a probe, a Proxy is refused before anything is asked of it.
|
|
@@ -18,9 +21,11 @@
|
|
|
18
21
|
export interface ReceiptMode {
|
|
19
22
|
/**
|
|
20
23
|
* `call-once`: every own string-keyed member is read — a data property's value, or an accessor's getter called exactly
|
|
21
|
-
* once on the object (a getter that throws refuses the receipt; one that moves the object's prototype refuses it
|
|
24
|
+
* once on the object (a getter that throws refuses the receipt; one that moves the object's prototype refuses it, but
|
|
25
|
+
* under `others: "copy"`).
|
|
22
26
|
* `refuse`: only own enumerable string-keyed DATA properties are members; an accessor, a non-enumerable property or
|
|
23
|
-
* a symbol-keyed one refuses the receipt (no getter ever runs)
|
|
27
|
+
* a symbol-keyed one refuses the receipt (no getter ever runs) — under `contain`, each is a member left out and reported
|
|
28
|
+
* (a symbol-keyed one at its container's path and its `String(symbol)`), its container received.
|
|
24
29
|
*/
|
|
25
30
|
readonly accessors: "call-once" | "refuse";
|
|
26
31
|
/** How many levels of containers are copied (`Infinity` = every level). */
|
|
@@ -28,14 +33,34 @@ export interface ReceiptMode {
|
|
|
28
33
|
/** What a value that is not copied is (a function, another prototype, a container past `depth`, a symbol or a
|
|
29
34
|
* bigint): handed as it is, or a refusal of the receipt. Shared references keep their shape in the copy (one copy
|
|
30
35
|
* each); under `as-is` a cycle does too, under `refuse` a cycle is refused and a shared reference must fit `depth`
|
|
31
|
-
* where it sits each time it is met.
|
|
32
|
-
|
|
36
|
+
* where it sits each time it is met. `copy` is `refuse`, except that an object of another prototype within `depth`
|
|
37
|
+
* — a class instance, another realm's object or array, an array of a subclass — is copied as an ordinary record (an
|
|
38
|
+
* array as an ordinary array) off its OWN members: its prototype is not kept and no code of the prototype runs, so a
|
|
39
|
+
* prototype's getters and a built-in's internal state (a `Date`'s time, a `Map`'s entries) are not members and are
|
|
40
|
+
* not copied, while every own data member is (and an own accessor is read as `accessors` says; one that moves the
|
|
41
|
+
* object's prototype changes nothing the copy holds). A Proxy and a cycle are still refused. */
|
|
42
|
+
readonly others: "as-is" | "refuse" | "copy";
|
|
43
|
+
/** `refuse`: a container (an ordinary record or array) past `depth` refuses the receipt (`too-deep`) even where
|
|
44
|
+
* `others` hands other values as they are — a value of another kind there is still what `others` says — and a shared
|
|
45
|
+
* reference must fit `depth` where it sits each time it is met, by the height its first walk found (a walk that ran
|
|
46
|
+
* into a container still being walked — a cycle — counts that container as one level, and so does an object the
|
|
47
|
+
* reader holds, met directly or in what holds it): `depth` is a bound, never a copy depth. Absent ⇒ a container past
|
|
48
|
+
* `depth` is what `others` says. */
|
|
49
|
+
readonly past?: "refuse";
|
|
50
|
+
/** A fault met in a member — its getter threw, it is a value the receipt refuses, it holds a cycle, it runs too deep,
|
|
51
|
+
* or it could not be copied at all (`uncopyable`) — leaves THAT member out of its container's copy and is reported in the
|
|
52
|
+
* receipt's `faults` (where it was met); the walk goes on with the next member. A container refused where it was met
|
|
53
|
+
* is refused again wherever else it is met (never read twice). Only a fault of the received value itself refuses the
|
|
54
|
+
* receipt. Absent ⇒ the first fault refuses the receipt. */
|
|
55
|
+
readonly contain?: true;
|
|
33
56
|
/** Every container the copy makes is frozen (a received value cannot be changed after it was received). */
|
|
34
57
|
readonly freeze?: boolean;
|
|
35
58
|
/** The host's Proxy probe. */
|
|
36
59
|
readonly isProxy?: (value: object) => boolean;
|
|
37
60
|
}
|
|
38
|
-
/** Why a receipt was refused.
|
|
61
|
+
/** Why a receipt was refused. `uncopyable` has two causes, and depth is neither (the walk keeps its own stack): reading
|
|
62
|
+
* the value threw where none of its getters runs — a Proxy's trap, on a receipt given no Proxy probe; what it threw is
|
|
63
|
+
* never read — or the value holds more objects than one receipt can index. */
|
|
39
64
|
export declare const RECEIPT_FAULTS: readonly ["proxy", "accessor", "hidden", "getter-threw", "prototype-moved", "not-data", "cycle", "too-deep", "uncopyable"];
|
|
40
65
|
export type ReceiptFaultKind = (typeof RECEIPT_FAULTS)[number];
|
|
41
66
|
/** A refusal and where in the value it was met (member names from the top). */
|
|
@@ -43,9 +68,11 @@ export interface ReceiptFault {
|
|
|
43
68
|
readonly kind: ReceiptFaultKind;
|
|
44
69
|
readonly path: readonly string[];
|
|
45
70
|
}
|
|
71
|
+
/** A receipt: the copy (with, under `contain`, every fault a member was left out for), or the refusal. */
|
|
46
72
|
export type Receipt = {
|
|
47
73
|
readonly ok: true;
|
|
48
74
|
readonly value: unknown;
|
|
75
|
+
readonly faults?: readonly ReceiptFault[];
|
|
49
76
|
} | {
|
|
50
77
|
readonly ok: false;
|
|
51
78
|
readonly fault: ReceiptFault;
|
|
@@ -53,13 +80,16 @@ export type Receipt = {
|
|
|
53
80
|
/** Whether `v` is an ordinary record: an object whose prototype is `Object.prototype` or none (an array is not one). */
|
|
54
81
|
export declare function isPlainRecord(v: unknown): v is Record<string, unknown>;
|
|
55
82
|
/**
|
|
56
|
-
* Receive `value` by `mode`. `held` names objects the reader already owns: met in the walk, each is kept as itself
|
|
57
|
-
*
|
|
83
|
+
* Receive `value` by `mode`. `held` names objects the reader already owns: met in the walk, each is kept as itself — not
|
|
84
|
+
* received again, never walked — so a member handed back unchanged keeps its identity. The set is consulted as it is,
|
|
85
|
+
* never copied, so one set serves every receipt of the same owner.
|
|
58
86
|
*/
|
|
59
|
-
export declare function receive(value: unknown, mode: ReceiptMode, held?:
|
|
87
|
+
export declare function receive(value: unknown, mode: ReceiptMode, held?: ReadonlySet<object>): Receipt;
|
|
60
88
|
/** The mods bus's mode: a payload and an answer received whole — no accessor runs, no depth limit, cycles and shared
|
|
61
89
|
* references kept, a function or a class instance handed as it is, every copied container frozen (so a member the
|
|
62
|
-
* bus holds cannot be changed under it by a handler that holds it too).
|
|
90
|
+
* bus holds cannot be changed under it by a handler that holds it too). The engine's own event is received in it as it
|
|
91
|
+
* is; what a handler gives the bus — a payload, an answer, a `$` call's arguments — in it held to the bus's one depth
|
|
92
|
+
* (the site rules set `depth` and `past: "refuse"`). */
|
|
63
93
|
export declare const MODS_PAYLOAD_MODE: ReceiptMode;
|
|
64
94
|
/** One clause naming a fault for a sentence ("an accessor at input.deep.x"). */
|
|
65
95
|
export declare function describeFault(fault: ReceiptFault): string;
|
|
@@ -10,91 +10,161 @@ function isOrdinaryArray(v) {
|
|
|
10
10
|
}
|
|
11
11
|
export function receive(value, mode, held) {
|
|
12
12
|
const seen = new Map();
|
|
13
|
-
if (held !== undefined)
|
|
14
|
-
for (const h of held)
|
|
15
|
-
if (typeof h === "object" && h !== null)
|
|
16
|
-
seen.set(h, h);
|
|
17
13
|
const path = [];
|
|
18
14
|
const open = new Set();
|
|
19
15
|
const heights = new Map();
|
|
16
|
+
const faults = [];
|
|
17
|
+
const refusedAt = new Map();
|
|
18
|
+
const stack = [];
|
|
19
|
+
const refusals = new Set();
|
|
20
20
|
const refuse = (kind) => {
|
|
21
|
-
|
|
21
|
+
const fault = Object.freeze({ kind, path: Object.freeze([...path]) });
|
|
22
|
+
refusals.add(fault);
|
|
23
|
+
throw fault;
|
|
22
24
|
};
|
|
25
|
+
const faultOf = (err) => typeof err === "object" && err !== null && refusals.has(err) ? err : Object.freeze({ kind: "uncopyable", path: Object.freeze([...path]) });
|
|
23
26
|
const other = (v, kind) => (mode.others === "as-is" ? v : refuse(kind));
|
|
24
|
-
const
|
|
27
|
+
const refuseContainer = (v, kind) => {
|
|
28
|
+
if (mode.contain === true) {
|
|
29
|
+
refusedAt.set(v, kind);
|
|
30
|
+
open.delete(v);
|
|
31
|
+
}
|
|
32
|
+
return refuse(kind);
|
|
33
|
+
};
|
|
34
|
+
const memberOf = (v, d) => {
|
|
35
|
+
if (Object.hasOwn(d, "value")) {
|
|
36
|
+
if (mode.accessors === "refuse" && d.enumerable !== true)
|
|
37
|
+
refuse("hidden");
|
|
38
|
+
return d.value;
|
|
39
|
+
}
|
|
40
|
+
if (mode.accessors === "refuse")
|
|
41
|
+
refuse("accessor");
|
|
42
|
+
const get = Object.hasOwn(d, "get") ? d.get : undefined;
|
|
43
|
+
try {
|
|
44
|
+
return get === undefined ? undefined : Reflect.apply(get, v, []);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return refuse("getter-threw");
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const measured = mode.past === "refuse" || mode.others !== "as-is";
|
|
51
|
+
const heightOf = (v) => heights.get(v) ?? (open.has(v) || (held?.has(v) === true && mode.isProxy?.(v) !== true && (isOrdinaryArray(v) || isPlainRecord(v))) ? 1 : 0);
|
|
52
|
+
const pastDepth = (v, level) => measured && level + heightOf(v) > mode.depth;
|
|
53
|
+
const meet = (v, level) => {
|
|
25
54
|
if (v === null || v === undefined || typeof v === "string" || typeof v === "number" || typeof v === "boolean")
|
|
26
55
|
return v;
|
|
27
56
|
if (typeof v !== "object")
|
|
28
57
|
return other(v, "not-data");
|
|
58
|
+
if (held?.has(v) === true)
|
|
59
|
+
return pastDepth(v, level) ? refuse("too-deep") : v;
|
|
29
60
|
if (seen.has(v)) {
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
32
|
-
if (
|
|
61
|
+
if (refusedAt.has(v))
|
|
62
|
+
return refuse(refusedAt.get(v));
|
|
63
|
+
if (open.has(v) && mode.others !== "as-is")
|
|
64
|
+
return refuse("cycle");
|
|
65
|
+
return pastDepth(v, level) ? refuse("too-deep") : seen.get(v);
|
|
66
|
+
}
|
|
67
|
+
if (level >= mode.depth && mode.past === "refuse") {
|
|
68
|
+
if (mode.isProxy?.(v) === true)
|
|
69
|
+
return refuse("proxy");
|
|
70
|
+
if (isOrdinaryArray(v) || isPlainRecord(v))
|
|
33
71
|
return refuse("too-deep");
|
|
34
|
-
return seen.get(v);
|
|
35
72
|
}
|
|
36
73
|
if (level >= mode.depth)
|
|
37
74
|
return other(v, "too-deep");
|
|
38
75
|
if (mode.isProxy?.(v) === true)
|
|
39
76
|
return refuse("proxy");
|
|
40
|
-
const list = isOrdinaryArray(v);
|
|
41
|
-
if (!list && !isPlainRecord(v))
|
|
77
|
+
const list = isOrdinaryArray(v) || (mode.others === "copy" && Array.isArray(v));
|
|
78
|
+
if (!list && !isPlainRecord(v) && mode.others !== "copy")
|
|
42
79
|
return other(v, "not-data");
|
|
43
80
|
const proto = Object.getPrototypeOf(v);
|
|
44
81
|
const captured = Object.getOwnPropertyDescriptors(v);
|
|
45
82
|
const out = list ? [] : {};
|
|
46
83
|
seen.set(v, out);
|
|
47
84
|
open.add(v);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const d = captured[key];
|
|
55
|
-
path.push(key);
|
|
56
|
-
let member;
|
|
57
|
-
if (Object.hasOwn(d, "value")) {
|
|
58
|
-
if (mode.accessors === "refuse" && d.enumerable !== true)
|
|
59
|
-
refuse("hidden");
|
|
60
|
-
member = d.value;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
if (mode.accessors === "refuse")
|
|
64
|
-
refuse("accessor");
|
|
65
|
-
const get = Object.hasOwn(d, "get") ? d.get : undefined;
|
|
66
|
-
try {
|
|
67
|
-
member = get === undefined ? undefined : get.call(v);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return refuse("getter-threw");
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
Object.defineProperty(out, key, { value: walk(member, level + 1), enumerable: true, writable: true, configurable: true });
|
|
74
|
-
if (typeof member === "object" && member !== null)
|
|
75
|
-
height = Math.max(height, (heights.get(member) ?? 0) + 1);
|
|
76
|
-
path.pop();
|
|
85
|
+
if (mode.accessors === "refuse") {
|
|
86
|
+
const symbols = Object.getOwnPropertySymbols(captured);
|
|
87
|
+
if (symbols.length > 0 && mode.contain !== true)
|
|
88
|
+
refuseContainer(v, "hidden");
|
|
89
|
+
for (const s of symbols)
|
|
90
|
+
faults.push(Object.freeze({ kind: "hidden", path: Object.freeze([...path, String(s)]) }));
|
|
77
91
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
stack.push({ v, out, list, proto, captured, keys: Object.getOwnPropertyNames(captured), level, next: 0, height: 1, key: "", member: undefined });
|
|
93
|
+
return out;
|
|
94
|
+
};
|
|
95
|
+
const land = (f, key, copy, member) => {
|
|
96
|
+
if (measured && typeof member === "object" && member !== null)
|
|
97
|
+
f.height = Math.max(f.height, heightOf(member) + 1);
|
|
98
|
+
Object.defineProperty(f.out, key, { value: copy, enumerable: true, writable: true, configurable: true });
|
|
99
|
+
path.length = f.level;
|
|
100
|
+
};
|
|
101
|
+
const finish = (f) => {
|
|
102
|
+
heights.set(f.v, f.height);
|
|
103
|
+
if (mode.accessors === "call-once" && mode.others !== "copy" && Object.getPrototypeOf(f.v) !== f.proto)
|
|
104
|
+
refuseContainer(f.v, "prototype-moved");
|
|
105
|
+
if (Array.isArray(f.out)) {
|
|
106
|
+
const length = f.captured["length"]?.value;
|
|
83
107
|
if (typeof length === "number")
|
|
84
|
-
out.length = length;
|
|
108
|
+
f.out.length = length;
|
|
85
109
|
}
|
|
86
110
|
if (mode.freeze === true)
|
|
87
|
-
Object.freeze(out);
|
|
88
|
-
open.delete(v);
|
|
89
|
-
return out;
|
|
111
|
+
Object.freeze(f.out);
|
|
112
|
+
open.delete(f.v);
|
|
113
|
+
return f.out;
|
|
90
114
|
};
|
|
115
|
+
const received = (copy) => (mode.contain === true ? { ok: true, value: copy, faults: Object.freeze(faults) } : { ok: true, value: copy });
|
|
91
116
|
try {
|
|
92
|
-
|
|
117
|
+
const copy = meet(value, 0);
|
|
118
|
+
if (stack.length === 0)
|
|
119
|
+
return received(copy);
|
|
93
120
|
}
|
|
94
121
|
catch (err) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
return { ok: false, fault: faultOf(err) };
|
|
123
|
+
}
|
|
124
|
+
for (;;) {
|
|
125
|
+
const f = stack[stack.length - 1];
|
|
126
|
+
if (f.next < f.keys.length) {
|
|
127
|
+
const key = f.keys[f.next++];
|
|
128
|
+
if (f.list && key === "length")
|
|
129
|
+
continue;
|
|
130
|
+
path.push(key);
|
|
131
|
+
try {
|
|
132
|
+
const member = memberOf(f.v, f.captured[key]);
|
|
133
|
+
const frames = stack.length;
|
|
134
|
+
const copy = meet(member, f.level + 1);
|
|
135
|
+
if (stack.length > frames) {
|
|
136
|
+
f.key = key;
|
|
137
|
+
f.member = member;
|
|
138
|
+
}
|
|
139
|
+
else
|
|
140
|
+
land(f, key, copy, member);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
if (mode.contain !== true)
|
|
144
|
+
return { ok: false, fault: faultOf(err) };
|
|
145
|
+
faults.push(faultOf(err));
|
|
146
|
+
path.length = f.level;
|
|
147
|
+
}
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
let copy;
|
|
151
|
+
try {
|
|
152
|
+
copy = finish(f);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
stack.pop();
|
|
156
|
+
const holder = stack[stack.length - 1];
|
|
157
|
+
if (mode.contain !== true || holder === undefined)
|
|
158
|
+
return { ok: false, fault: faultOf(err) };
|
|
159
|
+
faults.push(faultOf(err));
|
|
160
|
+
path.length = holder.level;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
stack.pop();
|
|
164
|
+
const holder = stack[stack.length - 1];
|
|
165
|
+
if (holder === undefined)
|
|
166
|
+
return received(copy);
|
|
167
|
+
land(holder, holder.key, copy, holder.member);
|
|
98
168
|
}
|
|
99
169
|
}
|
|
100
170
|
export const MODS_PAYLOAD_MODE = Object.freeze({ accessors: "refuse", depth: Infinity, others: "as-is", freeze: true });
|
|
@@ -7,6 +7,19 @@ import { type ModSeat, type ModTier } from "./events.js";
|
|
|
7
7
|
/** The host's Proxy probe (this folder cannot recognise a Proxy on its own): with one, a handler's Proxy is refused
|
|
8
8
|
* before any of its traps runs; without one, it is read like any object. */
|
|
9
9
|
export type ProxyProbe = (value: object) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* The one depth the bus holds a handler's values to: how many container levels a value may have below a payload member
|
|
12
|
+
* or an answer's top (1 = the member itself). Every value a handler gives the bus — what it hands to `next`, a `$`
|
|
13
|
+
* call's arguments, its answer — is received in a mode bounded by it (a shared reference measured again where it sits
|
|
14
|
+
* each time it is met), so a value nested deeper is refused by the first walk that meets it before that
|
|
15
|
+
* walk goes any deeper. Every walk keeps its own stack, so neither the platform nor the caller's stack depth decides.
|
|
16
|
+
* The pinned-key comparison is held to the same depth. A container is one level wherever it is met, so the verdict
|
|
17
|
+
* does not depend on member order for a value without a cycle; through a cycle, depth is measured on the walk's way (a
|
|
18
|
+
* container still being walked counts as one level where it is met again). The engine's own event is received at any
|
|
19
|
+
* depth, and its objects — handed back anywhere in what a handler hands on, answers or passes to a `$` call — are taken
|
|
20
|
+
* as themselves, never walked: one of its containers is one level where it sits, whatever it holds.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MODS_VALUE_DEPTH = 1000;
|
|
10
23
|
/** Why a handler did not answer for itself: it threw, it ran past its budget, it broke the site's contract, or it was
|
|
11
24
|
* not run because the dispatch re-entered a frame it is part of (its `.catch` answers for it — CC 296 form, (cli296.js:242947) "hasCatch"). */
|
|
12
25
|
export declare const MOD_FAILURE_CAUSES: readonly ["threw", "timeout", "violation", "reentry"];
|
|
@@ -35,8 +48,50 @@ export declare const NEXT_IN_FLIGHT: Readonly<{
|
|
|
35
48
|
export type ModAnswerCheck = (answer: unknown, e: ModEventPayload, by: ModAnswerer, below: readonly unknown[]) => string | undefined;
|
|
36
49
|
/** A matcher: top-level fields of `e` that must equal these values exactly. */
|
|
37
50
|
export type ModMatcher = Readonly<Record<string, string | number | boolean>>;
|
|
38
|
-
/**
|
|
39
|
-
|
|
51
|
+
/** Why a pinned key of what a handler handed on is not taken: it holds another value, or it is a copy the comparison
|
|
52
|
+
* could not walk to the end (`unproven` says why) — refused all the same, since only a copy proven the same is taken. */
|
|
53
|
+
export interface PinnedKeyBreak {
|
|
54
|
+
readonly key: string;
|
|
55
|
+
readonly unproven?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The first pinned key `next` did not hand on as the engine's fact, or undefined. A pinned value is compared by value
|
|
59
|
+
* ({@link sameModValue}): the engine's own fact handed on as is, or a copy of it, is not a change.
|
|
60
|
+
*/
|
|
61
|
+
export declare function pinnedKeyChanged(pinned: readonly string[], received: ModEventPayload, passed: ModEventPayload): PinnedKeyBreak | undefined;
|
|
62
|
+
/** {@link engineObjects} of a dispatch's own event, found the first time it is asked and the same set every time after:
|
|
63
|
+
* the event is frozen, so one finding serves every receipt of the dispatch. */
|
|
64
|
+
export declare function engineObjectsOnce(held: ModEventPayload): () => ReadonlySet<object>;
|
|
65
|
+
/**
|
|
66
|
+
* What the next handler reads when a handler hands `passed` to `next` (not the dispatch's own e): `passed` received
|
|
67
|
+
* whole in the mode held to {@link MODS_VALUE_DEPTH} (every object of the dispatch's own e in it — `engines`, found once
|
|
68
|
+
* per dispatch by {@link engineObjectsOnce} — kept as itself), then {@link pinnedHandOn}. A value nested past the depth
|
|
69
|
+
* is refused by the receipt, before any deeper walk — under a pinned key in the comparison's own words (too deep to
|
|
70
|
+
* compare), under any other member as the payload holding it.
|
|
71
|
+
*/
|
|
72
|
+
export declare function handedOn(pinned: readonly string[], held: ModEventPayload, passed: unknown, engines: ReadonlySet<object>, isProxy?: ProxyProbe): {
|
|
73
|
+
readonly payload: ModEventPayload;
|
|
74
|
+
} | {
|
|
75
|
+
readonly violation: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* What the next handler reads when a handler hands on `passed` (already received whole): the payload with every
|
|
79
|
+
* pinned key the engine's own member — the same object `held` carries, or no member where `held` has none — so a
|
|
80
|
+
* handler below a copy-forwarder reads the engine's fact, not the copy's shape (a member that is `undefined`, a
|
|
81
|
+
* member order, a −0 the comparison does not count). A pinned key the copy did not hand on as the engine's fact
|
|
82
|
+
* ({@link pinnedKeyChanged}) breaks the site instead. The comparison decides only whether to refuse; what travels down
|
|
83
|
+
* for a pinned key is the engine's member, always. The payload keeps the shape it was received in: a reference inside
|
|
84
|
+
* it to the payload itself is a reference to what is handed on (a cycle stays a cycle), and one to any object inside
|
|
85
|
+
* what the handler handed on under a pinned key — the copy itself, a member of it, an element of one of its lists, at
|
|
86
|
+
* any depth — is a reference to the engine's object it was proven the same as (a shared reference stays shared; an
|
|
87
|
+
* object of the copy standing for two of the engine's goes to the one the comparison met first). `engines`: every
|
|
88
|
+
* object of `held` (found here when not given).
|
|
89
|
+
*/
|
|
90
|
+
export declare function pinnedHandOn(pinned: readonly string[], held: ModEventPayload, passed: ModEventPayload, engines?: ReadonlySet<object>): {
|
|
91
|
+
readonly payload: ModEventPayload;
|
|
92
|
+
} | {
|
|
93
|
+
readonly violation: string;
|
|
94
|
+
};
|
|
40
95
|
/** Why a handler's answer breaks the site, or undefined. No answer at all is never an answer. */
|
|
41
96
|
export declare function answerViolation(answer: unknown, check: ModAnswerCheck | undefined, e: ModEventPayload, by: ModAnswerer, below: readonly unknown[]): string | undefined;
|
|
42
97
|
/**
|
|
@@ -52,14 +107,18 @@ export declare function methodAnswerViolation(answer: unknown, _e?: ModEventPayl
|
|
|
52
107
|
export declare function matcherViolation(m: unknown): string | undefined;
|
|
53
108
|
/** Whether every matcher field equals `e`'s own top-level field exactly. */
|
|
54
109
|
export declare function matcherMatches(m: ModMatcher | undefined, e: ModEventPayload): boolean;
|
|
55
|
-
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
110
|
+
/** A record a handler gives the bus other than through `next` — a `$` call's arguments, and a method's `enter` shaping
|
|
111
|
+
* of them — received held to {@link MODS_VALUE_DEPTH}; an object of `held` ({@link engineObjectsOnce} of what the bus
|
|
112
|
+
* already holds: the dispatch the handler runs in, or the call's received arguments) is kept as itself, never walked. */
|
|
113
|
+
export declare function receivePayload(v: unknown, isProxy?: ProxyProbe, held?: ReadonlySet<object>): {
|
|
114
|
+
readonly payload: ModEventPayload;
|
|
115
|
+
} | {
|
|
116
|
+
readonly refusal: string;
|
|
117
|
+
};
|
|
118
|
+
/** The engine's own event at a dispatch's entry, received whole at any depth (one the receipt cannot copy whole —
|
|
119
|
+
* reading it threw where none of its getters runs, or it holds more objects than one receipt can index — is refused,
|
|
120
|
+
* never handed on shorter). */
|
|
121
|
+
export declare function receiveEvent(e: unknown): {
|
|
63
122
|
readonly payload: ModEventPayload;
|
|
64
123
|
} | {
|
|
65
124
|
readonly refusal: string;
|
|
@@ -70,15 +129,21 @@ export declare function receivePayload(v: unknown, held?: ModEventPayload, isPro
|
|
|
70
129
|
* copied once and frozen; an answer already frozen (an engine sentinel) or not a plain container is itself.
|
|
71
130
|
*/
|
|
72
131
|
export declare function answerUpward(v: unknown): unknown;
|
|
73
|
-
/** A handler's answer, received by the same receipt
|
|
74
|
-
|
|
132
|
+
/** A handler's answer, received by the same receipt held to {@link MODS_VALUE_DEPTH} (an answer need not be a record; a
|
|
133
|
+
* primitive is itself); an object of the dispatch's own event in it (`engines`, {@link engineObjectsOnce}) is kept as
|
|
134
|
+
* itself, never walked. */
|
|
135
|
+
export declare function receiveAnswer(answer: unknown, engines: ReadonlySet<object>, isProxy?: ProxyProbe): {
|
|
75
136
|
readonly answer: unknown;
|
|
76
137
|
} | {
|
|
77
138
|
readonly refusal: string;
|
|
78
139
|
};
|
|
79
140
|
/**
|
|
80
|
-
* A copy for an observe handler
|
|
81
|
-
*
|
|
82
|
-
*
|
|
141
|
+
* A copy for an observe handler, made by the one receipt (its own stack, so no depth of the event decides whether an
|
|
142
|
+
* observer runs — the event it observes was received at any depth too): every data container (a plain object, an
|
|
143
|
+
* ordinary array) detached at any depth; then every other object the copy holds — a tool result's `Map`, `Date` or
|
|
144
|
+
* typed array — detached by a structured clone of that object alone (one clone per object, so a shared one stays shared),
|
|
145
|
+
* and one the clone refuses (a function, a handle, a class instance holding one) handed as is. The engine's own event
|
|
146
|
+
* holds data properties only, so the copy is whole; a receipt that could not make it (a Proxy whose trap throws, on a bus
|
|
147
|
+
* given no probe) is the observer's failure, reported like any other.
|
|
83
148
|
*/
|
|
84
149
|
export declare function detachedCopy(e: ModEventPayload): Record<string, unknown>;
|