@sema-agent/core 5.20.0 → 5.21.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 +9 -0
- package/dist/agents/agent-definition.d.ts +7 -0
- package/dist/agents/agent-transcript-tool.d.ts +30 -0
- package/dist/agents/builtin-agents.d.ts +60 -0
- package/dist/agents/cascade.d.ts +107 -0
- package/dist/agents/cumulative-stats.d.ts +56 -0
- package/dist/agents/observer.d.ts +162 -0
- package/dist/agents/peer-admission.d.ts +95 -0
- package/dist/agents/repair-loop.d.ts +226 -0
- package/dist/agents/retain-ledger.d.ts +141 -0
- package/dist/agents/roster-store.d.ts +105 -0
- package/dist/agents/send-message-tool.d.ts +92 -0
- package/dist/agents/session-util.d.ts +5 -0
- package/dist/agents/subagent-steps.d.ts +66 -0
- package/dist/agents/subagent.d.ts +600 -0
- package/dist/agents/suspend-guard.d.ts +29 -0
- package/dist/agents/teacher.d.ts +75 -0
- package/dist/agents/team.d.ts +120 -1
- package/dist/agents/tool-filter.d.ts +34 -0
- package/dist/agents/verify.d.ts +198 -0
- package/dist/bench/metrics.d.ts +455 -0
- package/dist/brain/anthropic.d.ts +30 -0
- package/dist/brain/circuit-breaker.d.ts +33 -0
- package/dist/brain/context-overflow.d.ts +60 -3
- package/dist/brain/degrading.d.ts +67 -0
- package/dist/brain/errors.d.ts +42 -0
- package/dist/brain/failover.d.ts +15 -0
- package/dist/brain/media-degrade.d.ts +39 -0
- package/dist/brain/model-presets.d.ts +31 -0
- package/dist/brain/open-responses.d.ts +19 -0
- package/dist/brain/openai.d.ts +46 -0
- package/dist/brain/reasoning.d.ts +106 -1
- package/dist/brain/repetition.d.ts +83 -0
- package/dist/brain/request-params.d.ts +56 -0
- package/dist/brain/retry.d.ts +46 -0
- package/dist/brain/routing.d.ts +12 -0
- package/dist/brain/status-sink.d.ts +30 -1
- package/dist/brain/stream-engine.d.ts +147 -0
- package/dist/brain/stream-shared.d.ts +34 -0
- package/dist/brain/terminal-cause.d.ts +31 -0
- package/dist/brain/timeout.d.ts +107 -0
- package/dist/brain/tool-call-id.d.ts +20 -0
- package/dist/brain/tool-call-repair.d.ts +13 -0
- package/dist/config/catalog.d.ts +47 -0
- package/dist/config/defaults.d.ts +33 -0
- package/dist/core/a2a-task-state.d.ts +53 -0
- package/dist/core/a2a.d.ts +51 -0
- package/dist/core/arg-summary.d.ts +62 -0
- package/dist/core/ask-question.d.ts +272 -2
- package/dist/core/auto-compaction.d.ts +467 -0
- package/dist/core/auto-compaction.js +20 -6
- package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
- package/dist/core/auto-mode-prompt.d.ts +27 -0
- package/dist/core/auto-mode.d.ts +54 -3
- package/dist/core/auto-promote.d.ts +100 -0
- package/dist/core/background-agent-store.d.ts +292 -0
- package/dist/core/background-shell.d.ts +110 -0
- package/dist/core/cache-break-detector.d.ts +34 -0
- package/dist/core/canonical-json.d.ts +57 -0
- package/dist/core/checkpoint-store.d.ts +1574 -16
- package/dist/core/compliance.d.ts +30 -0
- package/dist/core/consolidate-scope.d.ts +75 -0
- package/dist/core/context-edit.d.ts +99 -0
- package/dist/core/context-guard.d.ts +46 -0
- package/dist/core/exec-gate.d.ts +44 -0
- package/dist/core/exec-output-tail.d.ts +61 -0
- package/dist/core/file-snapshot-store.d.ts +104 -0
- package/dist/core/fs-write-gate-policy.d.ts +36 -0
- package/dist/core/git-worktree-env.d.ts +31 -0
- package/dist/core/governance-codes.d.ts +19 -0
- package/dist/core/hooks.d.ts +608 -1
- package/dist/core/human-input-projection.d.ts +37 -0
- package/dist/core/human-input-projection.js +13 -0
- package/dist/core/image-downsample.d.ts +74 -0
- package/dist/core/locked-config.d.ts +37 -0
- package/dist/core/lsp-diagnostics.d.ts +77 -0
- package/dist/core/lsp-protocol.d.ts +29 -0
- package/dist/core/lsp-session.d.ts +60 -1
- package/dist/core/lsp.d.ts +150 -1
- package/dist/core/mailbox-store.d.ts +57 -0
- package/dist/core/mcp.d.ts +381 -0
- package/dist/core/media-byte-cap.d.ts +21 -0
- package/dist/core/memory-admission.d.ts +71 -0
- package/dist/core/memory-engine/content-origin.d.ts +64 -0
- package/dist/core/memory-engine/data-plane.d.ts +43 -0
- package/dist/core/memory-engine/dual-root.d.ts +24 -0
- package/dist/core/memory-engine/engine.d.ts +230 -0
- package/dist/core/memory-engine/engine.js +103 -35
- package/dist/core/memory-engine/file-backend.d.ts +155 -0
- package/dist/core/memory-engine/frontmatter.d.ts +16 -0
- package/dist/core/memory-engine/layout.d.ts +217 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
- package/dist/core/memory-engine/migrate.d.ts +9 -0
- package/dist/core/memory-engine/scan.d.ts +12 -0
- package/dist/core/memory-engine/scope-contract.d.ts +61 -1
- package/dist/core/memory-engine/sync-client.d.ts +87 -0
- package/dist/core/memory-engine/sync.d.ts +60 -0
- package/dist/core/memory-engine/tools.d.ts +41 -0
- package/dist/core/memory-engine/types.d.ts +188 -0
- package/dist/core/memory-recall.d.ts +141 -0
- package/dist/core/memory-vector.d.ts +20 -0
- package/dist/core/memory.d.ts +458 -0
- package/dist/core/message-utils.d.ts +6 -0
- package/dist/core/oracle-isolation.d.ts +69 -0
- package/dist/core/permission-rule-consent.d.ts +138 -0
- package/dist/core/permission-rule-model.d.ts +122 -0
- package/dist/core/permission-rule-store.d.ts +119 -3
- package/dist/core/permission-rules.d.ts +87 -1
- package/dist/core/present-plan-tool.d.ts +20 -0
- package/dist/core/pricing.d.ts +26 -0
- package/dist/core/property-harness.d.ts +86 -0
- package/dist/core/protocol-naming.d.ts +38 -0
- package/dist/core/protocol-table.d.ts +61 -0
- package/dist/core/push-queue.d.ts +1 -0
- package/dist/core/remote-env.d.ts +383 -1
- package/dist/core/retention-policy.d.ts +33 -0
- package/dist/core/retention.d.ts +51 -0
- package/dist/core/roles.d.ts +59 -0
- package/dist/core/runner/active-skill-scope.d.ts +34 -0
- package/dist/core/runner/assemble-result.d.ts +134 -0
- package/dist/core/runner/compaction-call-options.d.ts +97 -1
- package/dist/core/runner/grounding-signal.d.ts +10 -0
- package/dist/core/runner/image.d.ts +17 -0
- package/dist/core/runner/image.js +29 -15
- package/dist/core/runner/memory-consolidation.d.ts +60 -0
- package/dist/core/runner/prepare-memory.d.ts +59 -0
- package/dist/core/runner/prepare-task.d.ts +1011 -2
- package/dist/core/runner/prepare-task.js +12 -11
- package/dist/core/runner/prompt-suggestions.d.ts +7 -0
- package/dist/core/runner/runtask.d.ts +304 -3
- package/dist/core/runner/session-file-state-replay.d.ts +49 -0
- package/dist/core/runner/session-rule-policy.d.ts +58 -0
- package/dist/core/runner/strict-output-schema.d.ts +18 -3
- package/dist/core/runner/synthetic-tools.d.ts +113 -0
- package/dist/core/runner/teardown-bounded.d.ts +34 -0
- package/dist/core/runner/tool-disclosure.d.ts +227 -0
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/turn-attachments.d.ts +634 -0
- package/dist/core/runner/usage-accounting.d.ts +32 -0
- package/dist/core/runtime.d.ts +9 -0
- package/dist/core/safe-notify.d.ts +64 -0
- package/dist/core/safety-axis-vocab.d.ts +23 -0
- package/dist/core/safety-merge-corpus.d.ts +37 -0
- package/dist/core/scheduler.d.ts +121 -0
- package/dist/core/secret-env.d.ts +32 -0
- package/dist/core/select-model.d.ts +15 -0
- package/dist/core/sensitive-path-policy.d.ts +42 -0
- package/dist/core/session-policy-store.d.ts +94 -0
- package/dist/core/session-reconcile.d.ts +80 -0
- package/dist/core/session-store.d.ts +85 -0
- package/dist/core/session.d.ts +153 -0
- package/dist/core/shared-memory/contract.d.ts +22 -0
- package/dist/core/shared-memory/normalize.d.ts +123 -2
- package/dist/core/shared-memory/tools.d.ts +14 -0
- package/dist/core/shared-memory/types.d.ts +105 -0
- package/dist/core/shutdown-debug.d.ts +6 -0
- package/dist/core/side-query.d.ts +38 -0
- package/dist/core/side-query.js +6 -1
- package/dist/core/skill-tool-specifier.d.ts +72 -0
- package/dist/core/skills-directory.d.ts +100 -1
- package/dist/core/spec-contract.d.ts +89 -0
- package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
- package/dist/core/store-contracts/contract-harness.d.ts +20 -0
- package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
- package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
- package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
- package/dist/core/strategy-store.d.ts +37 -0
- package/dist/core/stub-env.d.ts +7 -0
- package/dist/core/surrogate-safe-slice.d.ts +35 -0
- package/dist/core/task-notification.d.ts +202 -0
- package/dist/core/task-outcome.d.ts +53 -0
- package/dist/core/task-registry-agent.d.ts +337 -1
- package/dist/core/task-registry-monitor.d.ts +12 -0
- package/dist/core/task-registry-shared.d.ts +540 -0
- package/dist/core/task-registry.d.ts +343 -0
- package/dist/core/task-registry.js +13 -2
- package/dist/core/task-tool-shape.d.ts +44 -0
- package/dist/core/tighten-task-spec.d.ts +21 -0
- package/dist/core/tool-detach.d.ts +21 -0
- package/dist/core/tool-errors.d.ts +131 -0
- package/dist/core/tool-errors.js +4 -0
- package/dist/core/tool-name-aliases.d.ts +27 -0
- package/dist/core/tool-policy.d.ts +555 -0
- package/dist/core/tool-result-budget.d.ts +32 -0
- package/dist/core/tool-result-store.d.ts +174 -1
- package/dist/core/tools.d.ts +45 -0
- package/dist/core/trace.d.ts +323 -0
- package/dist/core/types.d.ts +3859 -2
- package/dist/core/untrusted-egress.d.ts +8 -0
- package/dist/core/untrusted-text.d.ts +156 -0
- package/dist/core/usage-window-store.d.ts +95 -0
- package/dist/core/version.d.ts +1 -0
- package/dist/core/warm-resume.d.ts +17 -0
- package/dist/core/wiring-manifest.d.ts +169 -0
- package/dist/core/with-retry.d.ts +24 -0
- package/dist/core/workflow-journal-store.d.ts +160 -0
- package/dist/core/workflow-run-store-contract.d.ts +25 -0
- package/dist/core/workflow-run-store.d.ts +119 -0
- package/dist/engine/compaction/compaction.d.ts +256 -1
- package/dist/engine/compaction/utils.d.ts +94 -0
- package/dist/engine/execution-env/kill-tree.d.ts +29 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
- package/dist/engine/harness/agent-harness.d.ts +116 -0
- package/dist/engine/harness/agent-harness.js +3 -14
- package/dist/engine/harness/messages.d.ts +15 -0
- package/dist/engine/harness/types.d.ts +464 -2
- package/dist/engine/llm/diagnostics.d.ts +4 -0
- package/dist/engine/llm/event-stream.d.ts +3 -0
- package/dist/engine/llm/index.d.ts +7 -0
- package/dist/engine/llm/types.d.ts +500 -3
- package/dist/engine/llm/validation.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +87 -2
- package/dist/engine/loop/runtime-deps.d.ts +7 -0
- package/dist/engine/loop/types.d.ts +424 -0
- package/dist/engine/lsp/frame-decoder.d.ts +13 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
- package/dist/engine/session/import-validate.d.ts +27 -0
- package/dist/engine/session/log-digest.d.ts +93 -0
- package/dist/engine/session/memory-repo.d.ts +6 -0
- package/dist/engine/session/memory-storage.d.ts +2 -0
- package/dist/engine/session/session.d.ts +75 -0
- package/dist/engine/session/storage-base.d.ts +8 -0
- package/dist/fixtures/index.d.ts +36 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +0 -1
- package/dist/internal/harness-types.d.ts +6 -0
- package/dist/internal/harness.d.ts +11 -0
- package/dist/internal/llm.d.ts +6 -0
- package/dist/orchestration/builtin-workflows.d.ts +53 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
- package/dist/orchestration/goal.d.ts +57 -0
- package/dist/orchestration/goal.js +3 -0
- package/dist/orchestration/run-spec.d.ts +42 -0
- package/dist/orchestration/run-workflow-tool.d.ts +169 -0
- package/dist/orchestration/workflow-governance.d.ts +61 -0
- package/dist/orchestration/workflow-meta.d.ts +28 -0
- package/dist/orchestration/workflow-observe.d.ts +60 -0
- package/dist/orchestration/workflow-primitives.d.ts +23 -1
- package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
- package/dist/orchestration/workflow-script-runner.d.ts +88 -0
- package/dist/orchestration/workflow-script-store.d.ts +98 -0
- package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
- package/dist/orchestration/workflow-types.d.ts +169 -2
- package/dist/orchestration/workflow.d.ts +358 -0
- package/dist/prompt-assembly/artifact-store.d.ts +33 -0
- package/dist/prompt-assembly/artifact.d.ts +25 -0
- package/dist/prompt-assembly/assemble.d.ts +20 -0
- package/dist/prompt-assembly/composer.d.ts +29 -0
- package/dist/prompt-assembly/epoch.d.ts +55 -1
- package/dist/prompt-assembly/event-registry.d.ts +35 -0
- package/dist/prompt-assembly/explain.d.ts +12 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
- package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
- package/dist/prompt-assembly/types.d.ts +115 -0
- package/dist/prompts/coordinator.d.ts +27 -0
- package/dist/prompts/default.d.ts +539 -0
- package/dist/prompts/simple-sections.d.ts +45 -0
- package/dist/prompts/supervisor.d.ts +66 -0
- package/dist/scenarios/env.d.ts +28 -0
- package/dist/scenarios/full-body.d.ts +50 -0
- package/dist/scenarios/scenario-registry.d.ts +60 -0
- package/dist/scenarios/teacher-quickstart.d.ts +27 -0
- package/dist/server/http.d.ts +17 -0
- package/dist/stores/cc/lockfile.d.ts +6 -0
- package/dist/stores/cc/mailbox-store.d.ts +8 -0
- package/dist/stores/cc/roster-adapter.d.ts +4 -0
- package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
- package/dist/stores/file/background-agent-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.d.ts +38 -0
- package/dist/stores/file/file-snapshot-store.d.ts +25 -0
- package/dist/stores/file/fs-atomic.d.ts +155 -0
- package/dist/stores/file/index.d.ts +89 -0
- package/dist/stores/file/mailbox-store.d.ts +36 -0
- package/dist/stores/file/memory-store.d.ts +82 -0
- package/dist/stores/file/permission-rule-store.d.ts +79 -0
- package/dist/stores/file/session-policy-store.d.ts +28 -0
- package/dist/stores/file/session-store.d.ts +40 -0
- package/dist/stores/file/shared-ledger.d.ts +83 -0
- package/dist/stores/file/tool-result-store.d.ts +11 -0
- package/dist/stores/file/usage-window-store.d.ts +18 -0
- package/dist/stores/file/workflow-journal-store.d.ts +100 -0
- package/dist/stores/file/workflow-run-store.d.ts +11 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
- package/dist/tools/fs/encoding.d.ts +60 -0
- package/dist/tools/fs/fs-bash.d.ts +133 -0
- package/dist/tools/fs/fs-pdf.d.ts +28 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-shared.d.ts +360 -0
- package/dist/tools/fs/fs-write.d.ts +16 -0
- package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
- package/dist/tools/fs/index.d.ts +79 -0
- package/dist/tools/fs/notebook.d.ts +56 -0
- package/dist/tools/fs/pdf.d.ts +70 -0
- package/dist/tools/fs/pdf.js +8 -2
- package/dist/tools/fs/repo-map.d.ts +10 -0
- package/dist/tools/fs/safety.d.ts +376 -0
- package/dist/tools/fs/search.d.ts +131 -0
- package/dist/tools/loop-tick.d.ts +24 -0
- package/dist/tools/monitor.d.ts +55 -0
- package/dist/tools/scheduler-tools.d.ts +51 -0
- package/dist/tools/sql-adapters.d.ts +18 -0
- package/dist/tools/sql.d.ts +25 -0
- package/dist/tools/task-list.d.ts +77 -0
- package/dist/tools/todo.d.ts +8 -0
- package/dist/tools/web.d.ts +184 -0
- package/dist/tools/worktree.d.ts +81 -0
- package/package.json +2 -2
- package/dist/tools/gitea-issue.d.ts +0 -13
- package/dist/tools/gitea-issue.js +0 -75
|
@@ -4,49 +4,275 @@ import type { ExecutionEnv } from "../internal/harness-types.js";
|
|
|
4
4
|
import type { VerificationResult } from "./verify.js";
|
|
5
5
|
import type { Checkpoint } from "../core/checkpoint-store.js";
|
|
6
6
|
import { type OracleIsolationVerdict } from "../core/oracle-isolation.js";
|
|
7
|
+
/**
|
|
8
|
+
* SAFE-tier oracle self-repair loop (design/76 D1 命门, design/78 Slice-1). Given an implementation spec
|
|
9
|
+
* and an **injected, trusted oracle**, this runs the worker, grades it with the oracle, and — on failure —
|
|
10
|
+
* loops a fix turn (and a bounded clean-restart) until the oracle passes or the loop gives up. The terminal
|
|
11
|
+
* is then projected through the {@link terminalForTier} table, which **caps every PASS at `candidate_only`**:
|
|
12
|
+
* this layer NEVER auto-accepts. Auto-accept (`fixed`) requires the OFF Gate-1 out-of-process
|
|
13
|
+
* `oracleIsolation` boundary that this slice deliberately does not build — SAFE-tier escalates to a human
|
|
14
|
+
* (`needs_human_oracle`) or surfaces a candidate, but never clears its own work.
|
|
15
|
+
*
|
|
16
|
+
* Like {@link verifyCompleted}, this is a **thin composition** over `runner.runTask` (verify.ts:18-21 posture)
|
|
17
|
+
* — it adds no Runner-core surface, touches no vendored code, and is called by a leader/profile (the sibling
|
|
18
|
+
* of {@link runWithVerification}). The oracle internals (which gate/judge/property-harness to compose) live
|
|
19
|
+
* in the PROFILE-injected {@link RepairOracle} closure; core only fixes the {@link OracleResult} shape and the
|
|
20
|
+
* read-only / identity contract (§1 裁决①). N-parallel candidate fan-out + a robustness-first selection ranker
|
|
21
|
+
* are PROFILE concerns (§3 裁决②) — core stays single-candidate.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The provenance/strength tier of the oracle that produced a verdict. The control plane assigns this — it is
|
|
25
|
+
* NEVER derived from agent-visible state (not a {@link TaskSpec} field), mirroring design/44 §7 Q4. Drives the
|
|
26
|
+
* {@link terminalForTier} projection.
|
|
27
|
+
* - `trusted_hidden` — a hidden, spec-derived held-out oracle (strongest; still candidate_only here).
|
|
28
|
+
* - `trusted_visible` — a visible trusted oracle (must be paired with an anchor + no property-harness regression + L3).
|
|
29
|
+
* - `property_harness_weak` — derived property invariants only (a weak signal).
|
|
30
|
+
* - `l3_judge_advisory` — an L3 read-only judge that advises but does not clear.
|
|
31
|
+
* - `none` — no oracle available → only a human can adjudicate.
|
|
32
|
+
*/
|
|
7
33
|
export type OracleTier = "trusted_hidden" | "trusted_visible" | "property_harness_weak" | "l3_judge_advisory" | "none";
|
|
34
|
+
/**
|
|
35
|
+
* The terminal state the repair loop resolves to. SAFE-tier (this slice) can reach every value EXCEPT `fixed`:
|
|
36
|
+
* `fixed` is reserved for auto-accept, which needs the OFF Gate-1 out-of-process oracleIsolation boundary and
|
|
37
|
+
* is therefore unreachable here (terminal-by-tier §2 caps PASS at `candidate_only`).
|
|
38
|
+
* - `fixed` — auto-accepted (NOT reachable SAFE-tier; reserved for a future Gate-1 slice).
|
|
39
|
+
* - `candidate_only` — the oracle passed; surface the candidate for human acceptance, do not auto-accept.
|
|
40
|
+
* - `needs_human_oracle` — no usable oracle (`tier: "none"`) → only a human can adjudicate.
|
|
41
|
+
* - `gave_up` — attempts exhausted without a passing oracle (a first-class abstain, never "satisfy the test").
|
|
42
|
+
* - `conflict` — the spec and the oracle disagree (escalate; never rewrite the work to satisfy the test).
|
|
43
|
+
* Slice-1 core does NOT synthesize this (the test-tampering diff-monitor is §6-deferred to the profile —
|
|
44
|
+
* core honestly `gave_up`s rather than under-detect a conflict); it is in the vocabulary for the profile.
|
|
45
|
+
* - `oracle.unprotected` — fail-closed: the grader env was not isolated from the worker env (identity check).
|
|
46
|
+
*
|
|
47
|
+
* `needs_human_oracle` is disjoint from `needs_review` (a future dry-run gate) and `irreversible_ask` (shipped).
|
|
48
|
+
*/
|
|
8
49
|
export type RepairTerminal = "fixed" | "candidate_only" | "needs_human_oracle" | "gave_up" | "conflict" | "oracle.unprotected";
|
|
50
|
+
/**
|
|
51
|
+
* One oracle verdict. Produced by the injected {@link RepairOracle} closure. `flaky` records that the oracle
|
|
52
|
+
* was non-deterministic across `retries` (a flaky verdict is NEVER projected to `fixed` — §5 / §6 flakyK).
|
|
53
|
+
* `trace` is the raw failure output fed back into the next fix turn; it is treated as untrusted worker-adjacent
|
|
54
|
+
* data (delimited into context, sanitized into the objective) but its INNER text is NEVER rewritten (§5.5 #8a)
|
|
55
|
+
* — rewriting it would destroy the real-trace feedback lever.
|
|
56
|
+
*/
|
|
9
57
|
export interface OracleResult {
|
|
10
58
|
tier: OracleTier;
|
|
11
59
|
passed: boolean;
|
|
60
|
+
/** Raw failure trace (on a failed verdict). Untrusted; fed back verbatim into the fix turn (never inner-rewritten). */
|
|
12
61
|
trace?: string;
|
|
62
|
+
/** The oracle's verdict was non-deterministic across `retries` re-isolations. A flaky verdict never → `fixed`. */
|
|
13
63
|
flaky: boolean;
|
|
64
|
+
/** How many re-isolation retries the oracle ran to settle the verdict. */
|
|
14
65
|
retries: number;
|
|
66
|
+
/**
|
|
67
|
+
* HRD-AGO-6 — what producing this verdict COST (micro-USD, the oracle's own spend: judge/gate model calls,
|
|
68
|
+
* re-isolation retries, …). Optional: a mechanical oracle (an exec gate, a property harness) spends nothing
|
|
69
|
+
* and omits it. When supplied it counts against {@link RepairLoopConfig.costCeilingMicroUsd} exactly like the
|
|
70
|
+
* worker's spend — an LLM-judge oracle re-run per attempt is real money the ceiling used to be blind to —
|
|
71
|
+
* and is surfaced cumulatively as {@link RepairResult.oracleCostMicroUsd}. It is NOT folded into
|
|
72
|
+
* `TaskResult.stats` (those are the WORKER's, and the oracle runs outside `runner.runTask`).
|
|
73
|
+
*/
|
|
15
74
|
costMicroUsd?: number;
|
|
16
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* The PROFILE-injected oracle (§1 裁决①). The profile composes the actual grading inside this closure —
|
|
78
|
+
* `runExecGate(graderEnv, steps)` (exec-gate.ts:185, env is the FIRST param = L2 provenance bound to the
|
|
79
|
+
* grader) → `verifyCompleted` (verify.ts:212, the read-only L3 judge) → `checkInvariants`
|
|
80
|
+
* (property-harness.ts:217, explore-only) — and maps the composite to an {@link OracleResult}. Core never
|
|
81
|
+
* composes these internals (so the oracle type can't grow a long discriminated union); it only fixes the
|
|
82
|
+
* `OracleResult` shape and the read-only/identity contract. `graderEnv` is the isolated grader env; `evidence`
|
|
83
|
+
* is the diff/results to judge (recompute it from the post-resume working tree on a resume — verify.ts:328 BUG5).
|
|
84
|
+
*/
|
|
17
85
|
export type RepairOracle = (graderEnv: ExecutionEnv, evidence: string | undefined) => Promise<OracleResult>;
|
|
86
|
+
/**
|
|
87
|
+
* The durable, JSON-safe repair state carried across an orthogonal durable suspend (§4). Serialized ONLY when
|
|
88
|
+
* an unrelated resource/HITL suspend interleaves the loop (happy-path is in-memory) and re-seeded on resume so
|
|
89
|
+
* `attemptCount` advances MONOTONICALLY (never reset). Contains NO functions/Dates (epoch ms if a timestamp is
|
|
90
|
+
* ever needed) so `structuredClone`/`JSON.stringify` round-trip it on the checkpoint. `baselinePassTests` is
|
|
91
|
+
* DELIBERATELY ABSENT (§4 MAJOR-C): the anchor is grader-computed out-of-process so a worker can't shrink it.
|
|
92
|
+
*/
|
|
18
93
|
export interface RepairBundle {
|
|
94
|
+
/** The latest failure trace (untrusted; fed back into the fix turn). */
|
|
19
95
|
failureTrace: string;
|
|
96
|
+
/** Reflexion-style diagnoses accumulated across attempts (≤3, Reflexion cap — §1). */
|
|
20
97
|
diagnostics: string[];
|
|
98
|
+
/** Hypotheses tried and rejected (so a re-seed doesn't re-explore them). */
|
|
21
99
|
rejectedHypotheses: string[];
|
|
100
|
+
/** The in-loop attempt counter — re-seeded MONOTONICALLY on resume, never reset/max/downscaled (§4 / §5). */
|
|
22
101
|
attemptCount: number;
|
|
102
|
+
/** The tier of the last oracle verdict (for the resumed loop's projection). */
|
|
23
103
|
oracleTier: OracleTier;
|
|
104
|
+
/** F1 (ruling 2026-08-02) — cumulative loop spend (micro-USD: worker + nested + oracle) at the last
|
|
105
|
+
* attempt boundary. Re-seeded on resume so a resumed loop CONTINUES the money account instead of
|
|
106
|
+
* restarting it at 0 (a resume must not wash `costCeilingMicroUsd`). Optional: bundles serialized
|
|
107
|
+
* before this field existed read as 0 — the pre-F1 behavior, monotonic direction only. Updated at
|
|
108
|
+
* attempt boundaries HERE; a mid-attempt park is topped up by the RUNNER (RB-481): the checkpoint mint
|
|
109
|
+
* folds the in-flight leg's spend into the serialized copy on a HUMAN-DECISION park (whose resume reports
|
|
110
|
+
* its own leg only), and deliberately does not on a resource-slice park (whose resume returns that money
|
|
111
|
+
* through its cumulative stats). Either way the parked account is complete, never washed. */
|
|
24
112
|
spentMicroUsd?: number;
|
|
113
|
+
/** F1 — cumulative ACTIVE loop wall-time (ms) at the last attempt boundary. ACTIVE means time the loop
|
|
114
|
+
* was actually running: the suspended interval (a human deciding a HITL gate for days) is excluded by
|
|
115
|
+
* construction, so `totalTimeoutMs` bounds loop work, not human latency. Same optionality/monotonic
|
|
116
|
+
* contract as {@link RepairBundle.spentMicroUsd}. */
|
|
25
117
|
activeElapsedMs?: number;
|
|
26
118
|
}
|
|
27
119
|
export interface RepairLoopConfig {
|
|
120
|
+
/** The PROFILE-injected, trusted oracle (§1 裁决①). Core calls it; it never composes the oracle internals. */
|
|
28
121
|
oracle: RepairOracle;
|
|
122
|
+
/**
|
|
123
|
+
* The ISOLATED grader env the oracle grades in. MUST be a distinct object from {@link workerEnv}: if they
|
|
124
|
+
* are the SAME reference the loop fails closed to `oracle.unprotected` BEFORE running anything (§5.1 —
|
|
125
|
+
* necessary-not-sufficient; the real out-of-process boundary is the OFF Gate-1).
|
|
126
|
+
*/
|
|
29
127
|
graderEnv: ExecutionEnv;
|
|
128
|
+
/**
|
|
129
|
+
* The worker's execution env (the env `runner.runTask` runs the impl in), passed by the trusted caller so
|
|
130
|
+
* the §5.1 identity check can run: `graderEnv === workerEnv` → fail-closed `oracle.unprotected`. `TaskSpec`
|
|
131
|
+
* deliberately has NO `executionEnv` (the worker env is wired on the Runner deps / `executionEnvFactory`, not
|
|
132
|
+
* reachable from `implSpec`), so the caller must supply the reference here for the check to be meaningful.
|
|
133
|
+
* Omit it only when the worker env genuinely can't collide with the grader (e.g. distinct factories) — the
|
|
134
|
+
* check is then skipped (no reference to compare) and isolation is the caller's deployment contract.
|
|
135
|
+
*/
|
|
30
136
|
workerEnv?: ExecutionEnv;
|
|
137
|
+
/**
|
|
138
|
+
* design/77 §1 Gate-1 (oracleIsolation): the paths the oracle/spec lives behind that the worker must NOT be
|
|
139
|
+
* able to corrupt (e.g. a hidden held-out test dir). When supplied **together with** {@link workerEnv}, the
|
|
140
|
+
* loop runs the FULL structural {@link assertOracleIsolation} (identity + structural-class + bash write-probe)
|
|
141
|
+
* instead of the bare reference-identity check, and surfaces {@link RepairResult.isolationClass}. Omit it (the
|
|
142
|
+
* default) to keep the existing necessary-not-sufficient reference-identity check (the merged Slice-1 posture).
|
|
143
|
+
*
|
|
144
|
+
* The real isolated grader env is SERVICE-provided ({@link import("../core/types.js").RunnerDeps.graderEnvFactory});
|
|
145
|
+
* `graderEnv` here is its `.env`, and the control-plane `provenance` brand is reattached internally for the
|
|
146
|
+
* assertion. The assertion only matters for the (mandate-OFF) auto-accept path: `isolationClass` caps a
|
|
147
|
+
* non-`out_of_process` grader at `candidate_only`. SAFE-tier never auto-accepts regardless.
|
|
148
|
+
*/
|
|
31
149
|
immutableOraclePaths?: string[];
|
|
150
|
+
/**
|
|
151
|
+
* In-loop attempt ceiling (the loop runs at most this many GENERATE/oracle attempts, PLUS the documented
|
|
152
|
+
* one-shot CLEAN_RESTART the state machine grants once at exhaustion). Profile validates this to 2-3; core
|
|
153
|
+
* only enforces it as a ceiling, it does not fence the value — except that a NON-FINITE one falls back
|
|
154
|
+
* to 1 and is reported on {@link RepairLoopConfig.onWarn} (CLS-A-3/A-7 class: a NaN ceiling makes every
|
|
155
|
+
* `>=` gate false, i.e. no ceiling at all). This counter is DISTINCT from
|
|
156
|
+
* `suspendCount`(maxSuspends) and `sliceCount`(maxSlices) — it never borrows those budgets (§5 / §7).
|
|
157
|
+
*
|
|
158
|
+
* HRD-AGO-4: enforced BEFORE each dispatch as well as after, so a loop entered with {@link resumeBundle}
|
|
159
|
+
* whose `attemptCount` already reached the ceiling dispatches NOTHING and returns `gave_up`
|
|
160
|
+
* (`errorCode: "repair.attempts_exhausted"`) instead of spending one more worker run (plus a restart).
|
|
161
|
+
*/
|
|
32
162
|
maxAttempts: number;
|
|
163
|
+
/**
|
|
164
|
+
* On a resume after an orthogonal durable suspend, the restored {@link RepairBundle} (from
|
|
165
|
+
* `PrepareResume.seed.repairBundle`). `attemptCount` is re-seeded from it MONOTONICALLY (§4) — never reset.
|
|
166
|
+
*/
|
|
33
167
|
resumeBundle?: RepairBundle;
|
|
168
|
+
/**
|
|
169
|
+
* Stop the loop once cumulative cost reaches this (verify.ts:278 backstop). HRD-AGO-6 — "cumulative" is
|
|
170
|
+
* every leg the loop pays for: each attempt's own + nested `runTask` cost PLUS each verdict's
|
|
171
|
+
* {@link OracleResult.costMicroUsd} (an LLM-judge oracle is charged per attempt too).
|
|
172
|
+
*/
|
|
34
173
|
costCeilingMicroUsd?: number;
|
|
174
|
+
/** Overall ACTIVE wall-clock ceiling for the whole loop (verify.ts:277 backstop). F1: both ceilings
|
|
175
|
+
* are CROSS-RESUME — the carried {@link RepairBundle.spentMicroUsd}/{@link RepairBundle.activeElapsedMs}
|
|
176
|
+
* re-seed the accounts, so a durable resume continues the budget rather than restarting it. */
|
|
35
177
|
totalTimeoutMs?: number;
|
|
178
|
+
/** Per-attempt callback (observability). */
|
|
36
179
|
onAttempt?: (info: {
|
|
37
180
|
attempt: number;
|
|
38
181
|
terminal?: RepairTerminal;
|
|
39
182
|
oracle: OracleResult;
|
|
40
183
|
}) => void;
|
|
184
|
+
/**
|
|
185
|
+
* Operational-warning sink (observability). MINOR-2: the §5.1 isolation identity check is SKIPPED when
|
|
186
|
+
* `workerEnv` is undefined (no reference to compare). An ACCIDENTAL omission — `graderEnv` supplied but
|
|
187
|
+
* `workerEnv` forgotten — would then disable the check silently. When wired, that case is surfaced here
|
|
188
|
+
* once at loop start so the gap is observable; the posture stays necessary-not-sufficient (no hard-fail).
|
|
189
|
+
*/
|
|
41
190
|
onWarn?: (warning: Error) => void;
|
|
42
191
|
}
|
|
43
192
|
export interface RepairResult extends VerificationResult {
|
|
193
|
+
/** The projected terminal (§2). SAFE-tier never returns `fixed`. */
|
|
44
194
|
terminal: RepairTerminal;
|
|
195
|
+
/** The final repair state (in-memory unless an orthogonal suspend serialized it — §4). */
|
|
45
196
|
bundle: RepairBundle;
|
|
197
|
+
/**
|
|
198
|
+
* design/77 §1 Gate-1: the structural isolation class of the grader env, when the full
|
|
199
|
+
* {@link assertOracleIsolation} ran (i.e. {@link RepairLoopConfig.immutableOraclePaths} + `workerEnv` were
|
|
200
|
+
* supplied). `"out_of_process"` is the ONLY class the (mandate-OFF) auto-accept path may consider;
|
|
201
|
+
* `"in_process_probe_only"` CAPS the run at `candidate_only`. Undefined when only the bare reference-identity
|
|
202
|
+
* check ran. SAFE-tier never auto-accepts regardless of this value.
|
|
203
|
+
*/
|
|
46
204
|
isolationClass?: OracleIsolationVerdict["isolationClass"];
|
|
205
|
+
/**
|
|
206
|
+
* HRD-AGO-6 — cumulative ORACLE spend (micro-USD) across every verdict this loop took, summed from
|
|
207
|
+
* {@link OracleResult.costMicroUsd}. Reported SEPARATELY from `stats` (the worker legs) because the oracle
|
|
208
|
+
* runs outside `runner.runTask`: `stats.costMicroUsd + stats.nested.costMicroUsd + oracleCostMicroUsd` is the
|
|
209
|
+
* loop's true total. `0` when no verdict reported a cost (a mechanical oracle).
|
|
210
|
+
*/
|
|
47
211
|
oracleCostMicroUsd: number;
|
|
48
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* design/77 §1 Gate-1 invariant — auto-accept (`fixed`) is UNREACHABLE here. The terminal-by-tier projection
|
|
215
|
+
* (§2) already caps every PASS at `candidate_only`, so `isolationClass` only ever matters for the (OFF)
|
|
216
|
+
* auto-accept path. This guard makes the invariant load-bearing rather than caller discipline: a non-isolated
|
|
217
|
+
* (`in_process_probe_only`) or unprotected verdict can NEVER carry a `fixed` terminal — at most
|
|
218
|
+
* `candidate_only` / `oracle.unprotected`. It is a pure assertion over the projected terminal; it never
|
|
219
|
+
* upgrades anything (auto-accept stays OFF — only a future Gate-1 slice running on an `out_of_process` grader
|
|
220
|
+
* may even consider it).
|
|
221
|
+
*/
|
|
49
222
|
export declare function isolationPermitsAutoAccept(verdict: OracleIsolationVerdict): boolean;
|
|
223
|
+
/**
|
|
224
|
+
* CONSUMER seam (design/78 Slice-1, MAJOR-3 wiring — the re-entry side of the round-trip). Read the durable
|
|
225
|
+
* {@link RepairBundle} a resumed checkpoint carries, so a leader/profile resuming a repair-interleaved
|
|
226
|
+
* suspend can re-seed a FRESH {@link runRepairLoop} call with it.
|
|
227
|
+
*
|
|
228
|
+
* ## The contract (core vs profile)
|
|
229
|
+
* - **CORE owns the persistence + restore.** When an orthogonal durable suspend (resource/HITL) interleaves a
|
|
230
|
+
* `runRepairLoop` attempt, the Runner serializes the live bundle onto the minted checkpoint
|
|
231
|
+
* (`prepareTask.serializeCheckpointState` sources `internals.repairBundle`), and on resume re-seeds it back
|
|
232
|
+
* into `prepareTask` from `cp.state.repairBundle`. So `cp.state.repairBundle` is round-trip-true after a
|
|
233
|
+
* `runner.resume(token, …)`: it survives the suspend with `attemptCount` intact (never reset — §4 / MAJOR-A).
|
|
234
|
+
* - **PROFILE owns the re-entry loop.** The leader that resumes the worker (`runner.resume`) is a PROFILE
|
|
235
|
+
* concern — core does NOT build the "resume → grade → re-seed `runRepairLoop`" loop. The profile reads the
|
|
236
|
+
* restored bundle (via this accessor) off the SAME checkpoint it resumed, and on its NEXT repair attempt
|
|
237
|
+
* passes it as {@link RepairLoopConfig.resumeBundle}. `runRepairLoop` then re-seeds `attemptCount`
|
|
238
|
+
* MONOTONICALLY from it (`config.resumeBundle` → the loop's `bundle`), so the repair ratchet is preserved
|
|
239
|
+
* across the durable suspend rather than starting the attempt budget over.
|
|
240
|
+
*
|
|
241
|
+
* Returns `undefined` when the checkpoint carries no repair state (a non-repair task, or a repair attempt that
|
|
242
|
+
* suspended on its very first GENERATE before any oracle verdict — the re-seed treats `undefined` as a clean
|
|
243
|
+
* start). The returned object is the checkpoint's own (already an independent `structuredClone` from the
|
|
244
|
+
* store); pass it straight into `resumeBundle` — `runRepairLoop` copies its arrays defensively on re-seed.
|
|
245
|
+
*/
|
|
50
246
|
export declare function repairBundleFromCheckpoint(cp: Checkpoint): RepairBundle | undefined;
|
|
247
|
+
/**
|
|
248
|
+
* The terminal-by-tier projection (§2) — a PURE function, the core invariant. **SAFE-tier caps every PASS at
|
|
249
|
+
* `candidate_only`**; `fixed` (auto-accept) is unreachable here because it needs the OFF Gate-1 out-of-process
|
|
250
|
+
* boundary. Enforced HERE (in the projection table), not as caller discipline, so no consumer can promote a
|
|
251
|
+
* PASS to `fixed`.
|
|
252
|
+
*
|
|
253
|
+
* - any tier, `passed: true` → `candidate_only` (trusted_hidden/trusted_visible/property_harness_weak alike).
|
|
254
|
+
* - `l3_judge_advisory` → advisory only; even a "pass" can't clear → `candidate_only` (it never self-clears).
|
|
255
|
+
* - `none` → `needs_human_oracle` (no usable oracle → only a human adjudicates).
|
|
256
|
+
* - not-passed with a usable tier → not a terminal yet (the loop continues / gives up); represented as
|
|
257
|
+
* `undefined` so the caller's state machine drives the `gave_up`/`conflict` path explicitly.
|
|
258
|
+
*/
|
|
51
259
|
export declare function terminalForTier(oracle: OracleResult): RepairTerminal | undefined;
|
|
260
|
+
/**
|
|
261
|
+
* Run the SAFE-tier oracle self-repair loop over `implSpec` (design/78 §1 state machine — a DETERMINISTIC
|
|
262
|
+
* switch, no LLM in the control flow):
|
|
263
|
+
*
|
|
264
|
+
* `ASSERT_ISOLATION` (identity check → fail-closed `oracle.unprotected`) → `GENERATE` (`runner.runTask`) →
|
|
265
|
+
* `ORACLE` (the injected closure) → { passed → terminal-by-tier projection } | { failed & attempt<max → REPAIR
|
|
266
|
+
* (a fix turn) → loop } | { failed & attempt==max → CLEAN_RESTART once, else `gave_up` } | { conflict → terminal }.
|
|
267
|
+
*
|
|
268
|
+
* `ASSERT_ISOLATION` is the design/77 §1 Gate-1 seam: when {@link RepairLoopConfig.immutableOraclePaths} +
|
|
269
|
+
* `workerEnv` are supplied it runs the FULL {@link assertOracleIsolation} (identity + structural-class + bash
|
|
270
|
+
* write-probe) and surfaces {@link RepairResult.isolationClass}; otherwise it runs the bare reference-identity
|
|
271
|
+
* check (the merged Slice-1 posture). Either way a failed assertion fails closed to `oracle.unprotected` before
|
|
272
|
+
* any work runs, and the result NEVER reaches `fixed` — `isolationClass` only gates the (mandate-OFF) auto-accept
|
|
273
|
+
* path that this SAFE-tier loop does not take.
|
|
274
|
+
*
|
|
275
|
+
* SAFE-tier: the projection caps every PASS at `candidate_only` — this NEVER auto-accepts. `runRepairLoop` is a
|
|
276
|
+
* SIBLING of {@link verifyCompleted}: it composes over `runner.runTask` and never touches the Runner core.
|
|
277
|
+
*/
|
|
52
278
|
export declare function runRepairLoop(runner: Runner, implSpec: TaskSpec, config: RepairLoopConfig): Promise<RepairResult>;
|
|
@@ -1,78 +1,219 @@
|
|
|
1
1
|
import type { Runner } from "../core/runner/runtask.js";
|
|
2
2
|
import type { TaskSpec } from "../core/types.js";
|
|
3
3
|
import type { RunInternals } from "../core/runner/prepare-task.js";
|
|
4
|
+
/** design/122 D2 — per-child resume cap (default 8): a child can be revived at most this many times. */
|
|
4
5
|
export declare const SUBAGENT_RESUME_CAP = 8;
|
|
6
|
+
/**
|
|
7
|
+
* design/122 D1 — one RETAINED child ledger row. `specSnapshot` is a FROZEN plain value-copy of the spawn
|
|
8
|
+
* childSpec (r1-m5: retaining the live `ctx`/spec-builder closures would pin the parent run's whole prepare
|
|
9
|
+
* graph — harness ref, tool wrappers — in memory for up to ttl×max); `internalsSnapshot` is the spawn-time
|
|
10
|
+
* trusted internals copy (parentToolCallId / onForwardEvent / onSubagentSpawn — the grandchild chain stays
|
|
11
|
+
* unbroken on resume, D2). `release` captures the DELEGATION runner (deployment-scoped, allowed) and
|
|
12
|
+
* performs the unpin + explicit release that restores throwaway semantics.
|
|
13
|
+
*/
|
|
5
14
|
export interface SubagentRetainEntry {
|
|
6
15
|
childSessionId: string;
|
|
16
|
+
/**
|
|
17
|
+
* Dual-runner wake fix — the DELEGATION runner that OWNS the child session (its `sessions` store minted
|
|
18
|
+
* and holds `childSessionId`, and its run face executes resumes). The Agent tool can be CALLER-mounted
|
|
19
|
+
* with its own runner (e.g. a server's throwaway in-memory subRunner) while SendMessage/AgentTranscript
|
|
20
|
+
* are core-mounted with the HOST runner — two DIFFERENT session stores. A resume/transcript acquire on
|
|
21
|
+
* the host runner's (durable) store then fails `not_found` for a child that only ever lived in the spawn
|
|
22
|
+
* runner's store ("resumable:true 停机帧 → resume.session_not_found"). Resume MUST go through this runner
|
|
23
|
+
* when present; the mount runner is only the fallback for pre-existing rows. In-process pointer only —
|
|
24
|
+
* retain is NOT durable, so cross-process semantics are unchanged (the ledger dies with the process →
|
|
25
|
+
* resume.evicted, the 1.283 ruling). Lifetime: the entry's `release` closure already captures the same
|
|
26
|
+
* runner, so this adds no new retention class.
|
|
27
|
+
*/
|
|
7
28
|
runner?: Runner;
|
|
8
29
|
agentName?: string;
|
|
30
|
+
/** fix-C5: PER-ENTRY retain TTL override (ms). A SESSION-scoped ledger is shared by two purposes with
|
|
31
|
+
* different windows (failure-evidence retain = FAILED_SESSION_RETAIN_TTL_MS vs a session-scoped bg
|
|
32
|
+
* child's opt-in retain = the run's configured ttl); the ledger-level `ttlMs` is fixed by whichever
|
|
33
|
+
* purpose CREATED the ledger first, which silently truncated (or stretched) the other's window.
|
|
34
|
+
* Expiry (lazy sweep + active timer) uses this when present, the ledger default otherwise. */
|
|
9
35
|
ttlMs?: number;
|
|
10
36
|
specSnapshot: Readonly<TaskSpec>;
|
|
11
37
|
internalsSnapshot: RunInternals;
|
|
38
|
+
/** True while the initial run OR a resume run is in flight (resume re-entry rejects `steering.still_running`). */
|
|
12
39
|
running: boolean;
|
|
40
|
+
/** True once the initial run settled at least once. */
|
|
13
41
|
settled: boolean;
|
|
42
|
+
/** Last settle timestamp (epoch ms) — the retain-TTL base. */
|
|
14
43
|
settledAt: number;
|
|
15
44
|
resumeCount: number;
|
|
45
|
+
/** design/144 §1.1 — the child's STOP-CYCLE number (207-equivalent per-stop notification identity).
|
|
46
|
+
* Minted 1 at registration (the spawn run's settle notifies cycle 1); every resume that actually
|
|
47
|
+
* LAUNCHES bumps it, so the resumed run's settle notifies 2, 3, … The background_agent notification
|
|
48
|
+
* producers ride it as `TaskNotificationPayload.seq`, which uniquifies the `task_id:status[:seq]`
|
|
49
|
+
* dedup key per stop cycle — without it a stop→wake→stop chain's second `completed` frame collided
|
|
50
|
+
* with the first and was silently swallowed by the SystemInjectionQueue/inbox/shell dedup layers. */
|
|
16
51
|
cycleSeq: number;
|
|
52
|
+
/** design/144 §1.2 (child gate) — the PARKED completion notification of this child's spawn settle:
|
|
53
|
+
* present while a `completed` frame sits deferred behind the child's still-running background tasks
|
|
54
|
+
* (owner key = childSessionId). `seq` is the parked frame's stop-cycle number (park does not change
|
|
55
|
+
* cycle semantics); `cancel` unsubscribes the registry quiescence watcher and voids the frame.
|
|
56
|
+
* RULING (recorded in design/144 §1.2): a resume/wake VOIDS the parked frame — the wake opens the
|
|
57
|
+
* next stop cycle, whose own settle produces this child's next frame; delivering the stale parked
|
|
58
|
+
* "completed (idle)" after the child is running again would break "one cycle, exactly one frame".
|
|
59
|
+
* 1.284 C2 RULING (宁发勿丢): entry EVICTION (TTL / LRU / abandon / disposeAll / session reap) voids
|
|
60
|
+
* the park PROMISE, not the frame — `flush` delivers the park-time snapshot IMMEDIATELY (summary
|
|
61
|
+
* undecorated, honest ungated degradation) and unsubscribes the quiescence watcher; the pre-fix
|
|
62
|
+
* leak left the watcher alive (a late quiescence poke delivered a ZOMBIE notification for an entry
|
|
63
|
+
* long gone, and a never-settling grandchild pinned watcher + captured frame forever). */
|
|
17
64
|
deferredNotify?: {
|
|
18
65
|
seq?: number;
|
|
19
66
|
cancel: () => void;
|
|
20
67
|
flush: () => void;
|
|
21
68
|
};
|
|
69
|
+
/** The in-flight resume run's abort controller (parent-terminal cleanup aborts it — r1-M2). */
|
|
22
70
|
activeAbort?: AbortController;
|
|
71
|
+
/** Unpin + explicitly release the retained session (best-effort; the TTL reaper is the backstop). */
|
|
23
72
|
release: () => Promise<void>;
|
|
24
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* HRD-AGO-5 — which DETACHED (fire-and-forget) cleanup failed. The ledger frees slots synchronously and
|
|
76
|
+
* releases the session in the background; every one of those background calls can reject, because
|
|
77
|
+
* {@link SubagentRetainEntry.release} is caller-supplied and reaches a session store / pin.
|
|
78
|
+
*/
|
|
25
79
|
export type RetainEvictionTrigger = "ttl_sweep" | "ttl_timer" | "lru_overflow" | "session_ledger_lru" | "session_reap";
|
|
80
|
+
/** HRD-AGO-5 — deployment-side sinks for the retain ledger's background failures. */
|
|
26
81
|
export interface RetainLedgerHooks {
|
|
82
|
+
/**
|
|
83
|
+
* A detached eviction's `release` (unpin + session release) FAILED. The row is already gone from the ledger
|
|
84
|
+
* (containment is synchronous), so this is not recoverable state — it is the honest signal that a retained
|
|
85
|
+
* session may still be pinned in the session store, which was previously either an `unhandledRejection` on
|
|
86
|
+
* the host process or nothing at all. A throwing sink is swallowed (it cannot strand the reaper).
|
|
87
|
+
*/
|
|
27
88
|
onEvictionError?: (info: {
|
|
28
89
|
parentToolCallId?: string;
|
|
29
90
|
trigger: RetainEvictionTrigger;
|
|
30
91
|
error: Error;
|
|
31
92
|
}) => void;
|
|
32
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* design/122 D1 — the parent-run-scoped RETAIN ledger (`TaskSpec.retainSubagentSessions`). Created by
|
|
96
|
+
* `prepareTask` when the spec opts in, threaded to delegation tools as the TRUSTED `ctx.subagentRetain`,
|
|
97
|
+
* and disposed by the Runner in the task's terminal `finally` (D4: abort in-flight resumes + unpin +
|
|
98
|
+
* release every retained session — retain is NOT durable; resume is reachable only while the parent run
|
|
99
|
+
* lives, codex-B3). Leaks are double-bounded by `max` + `ttlMs` (codex-B2).
|
|
100
|
+
*/
|
|
33
101
|
export declare class SubagentRetainLedger {
|
|
34
102
|
readonly ttlMs: number;
|
|
35
103
|
readonly max: number;
|
|
36
104
|
private entries;
|
|
105
|
+
/** Tombstones: ids that WERE (or would have been) retained but got evicted — their resume rejects `resume.evicted`.
|
|
106
|
+
* fix-C2: capped FIFO (see `tombstone`) — a long-lived SESSION ledger kept producing unique failed
|
|
107
|
+
* toolCallIds, so an uncapped set grew without bound for the session's whole life. */
|
|
37
108
|
private evictedIds;
|
|
109
|
+
/** fidelity R4-1: per-entry unref'd TTL timers, armed at `markSettled` — ACTIVE expiry enforcement.
|
|
110
|
+
* The lazy `sweepExpired` used to be the only reaper, so a ledger nobody touched again (no later
|
|
111
|
+
* spawn/resume on it) kept its pinned sessions until process end. Cleared on evict/abandon/dispose;
|
|
112
|
+
* the lazy sweep stays as the backstop (and the only reaper for absurd over-clamp TTLs). */
|
|
38
113
|
private ttlTimers;
|
|
39
114
|
private isDisposed;
|
|
40
115
|
private readonly hooks;
|
|
41
116
|
private failedEvictions;
|
|
42
117
|
private lastFailure;
|
|
118
|
+
/** RB-463: the shared host-callback isolation scope (this ledger's own `onEvictionError` sink lives on it).
|
|
119
|
+
* The EVICTION counters above are a different quantity and stay: they count evictions that failed, not
|
|
120
|
+
* invocations of the sink that threw. */
|
|
43
121
|
private readonly notifier;
|
|
44
122
|
constructor(config: true | {
|
|
45
123
|
ttlMs?: number;
|
|
46
124
|
max?: number;
|
|
47
125
|
}, hooks?: RetainLedgerHooks);
|
|
126
|
+
/** HRD-AGO-5 — how many DETACHED evictions failed to release their session on this ledger. Non-zero means
|
|
127
|
+
* some retained session may still be pinned in the session store. Observable even with no sink wired. */
|
|
48
128
|
get evictionFailureCount(): number;
|
|
129
|
+
/** HRD-AGO-5 — the most recent detached-eviction failure (see {@link evictionFailureCount}). */
|
|
49
130
|
get lastEvictionError(): Error | undefined;
|
|
131
|
+
/** RB-463 diagnostics — how many times the deployment's `onEvictionError` SINK itself threw (distinct from
|
|
132
|
+
* {@link evictionFailureCount}, which counts the evictions being reported). */
|
|
50
133
|
get evictionSinkFailureCount(): number;
|
|
134
|
+
/**
|
|
135
|
+
* HRD-AGO-5 — record a failure from a DETACHED call this ledger made (or that a module-level helper made on
|
|
136
|
+
* its behalf, e.g. the session-ledger LRU disposal). Counts it, keeps the last error, and offers it to the
|
|
137
|
+
* sink; a throwing sink is swallowed so a broken observer cannot strand the reaper.
|
|
138
|
+
*/
|
|
51
139
|
noteDetachedFailure(trigger: RetainEvictionTrigger, error: unknown, parentToolCallId?: string): void;
|
|
140
|
+
/**
|
|
141
|
+
* HRD-AGO-5 — the ONLY way this class issues a background eviction. `evict` removes the row + tombstones it
|
|
142
|
+
* synchronously and only the `release` is async, so the caller never waits; but a bare `void evict(...)` made
|
|
143
|
+
* a rejecting `release` an `unhandledRejection` on the host process (a library killing its embedder over a
|
|
144
|
+
* best-effort cleanup) and left no trace that a session went unreleased. Every detached site routes here.
|
|
145
|
+
*/
|
|
52
146
|
private evictDetached;
|
|
147
|
+
/** HRD-AGO-5 — `disposeAll` for a caller that cannot await it (the module-level session-ledger LRU). Same
|
|
148
|
+
* contract as {@link evictDetached}: containment is synchronous, the failure is reported, never thrown. */
|
|
53
149
|
disposeAllDetached(trigger: RetainEvictionTrigger): void;
|
|
150
|
+
/** fix-C2: hard cap on tombstones. A tombstone is only an anti-resurrection sentinel (an evicted id's
|
|
151
|
+
* resume reads the honest `resume.evicted` instead of the generic not-retained text) — dropping the
|
|
152
|
+
* OLDEST one merely degrades that id's error text, so FIFO eviction is a safe bound. */
|
|
54
153
|
private static readonly TOMBSTONES_MAX;
|
|
154
|
+
/** fix-C2: record an eviction sentinel, FIFO-bounded (re-tombstoning an id refreshes its position). */
|
|
55
155
|
private tombstone;
|
|
156
|
+
/** fix-C5: an entry's own retain window when it carries one, the ledger default otherwise. */
|
|
56
157
|
private effectiveTtlMs;
|
|
57
158
|
get disposed(): boolean;
|
|
58
159
|
get size(): number;
|
|
59
160
|
get(parentToolCallId: string): SubagentRetainEntry | undefined;
|
|
60
161
|
wasEvicted(parentToolCallId: string): boolean;
|
|
162
|
+
/** codex impl-review MAJOR-1 — LAZY TTL sweep: evict every settled idle entry whose retain TTL
|
|
163
|
+
* elapsed (unpin + release + tombstone), so an expired session is freed at the NEXT ledger touch
|
|
164
|
+
* (every spawn-registration and resume entry call this) rather than only when its own resume is tried.
|
|
165
|
+
* fidelity R4-1: no longer the only reaper — `markSettled` also arms a per-entry ACTIVE timer, so
|
|
166
|
+
* expiry fires by time even on a ledger nobody touches again. This sweep stays as the backstop.
|
|
167
|
+
* The parent-terminal `disposeAll` stays the final backstop. `evict` removes the row + tombstones
|
|
168
|
+
* synchronously; the release itself is fire-and-forget best-effort. */
|
|
61
169
|
sweepExpired(now?: number): void;
|
|
170
|
+
/** Register a child at SPAWN (running until `markSettled`). Over `max`: the oldest settled idle entry is
|
|
171
|
+
* evicted (unpin+release); when every slot is still running, the NEW child is NOT retained (tombstoned →
|
|
172
|
+
* its resume rejects `resume.evicted`) and `undefined` is returned — the caller falls back to throwaway. */
|
|
62
173
|
register(parentToolCallId: string, entry: Omit<SubagentRetainEntry, "running" | "settled" | "settledAt" | "resumeCount" | "cycleSeq" | "activeAbort" | "deferredNotify">): SubagentRetainEntry | undefined;
|
|
174
|
+
/** Flip a child to settled (idle, resumable) — called when the initial run's stream drains.
|
|
175
|
+
* fidelity R4-1: also (re-)arms the entry's own TTL timer, so the retain window expires by TIME,
|
|
176
|
+
* not only at the next ledger touch. */
|
|
63
177
|
markSettled(parentToolCallId: string): void;
|
|
178
|
+
/** fidelity R4-1 — arm/re-arm the ACTIVE per-entry TTL reaper (unref'd: never keeps the process
|
|
179
|
+
* alive). Idempotent with the lazy sweep: the callback re-checks the same settled/idle/elapsed
|
|
180
|
+
* predicate, so a resume in flight (or an entry already evicted/re-settled) is left alone. */
|
|
64
181
|
private armTtlTimer;
|
|
65
182
|
private clearTtlTimer;
|
|
183
|
+
/** 1.284 C2 — an entry leaving the ledger takes its park promise with it: deliver the parked frame
|
|
184
|
+
* NOW (undecorated; 宁发勿丢 ruling — see the deferredNotify field doc) and unsubscribe the registry
|
|
185
|
+
* quiescence watcher. Without this, EVERY release path (TTL timer / lazy sweep / LRU register
|
|
186
|
+
* overflow / abandon / disposeAll / session reap) leaked the watcher: a late quiescence poke then
|
|
187
|
+
* delivered a zombie notification for a long-gone entry, and a never-settling grandchild pinned the
|
|
188
|
+
* watcher + captured frame forever. */
|
|
66
189
|
private flushDeferredNotify;
|
|
190
|
+
/** Drop a row WITHOUT releasing (durable-pause posture: a committed checkpoint owns the session/pin —
|
|
191
|
+
* releasing here would orphan it, mirroring the delegation tool's own no-release guard). */
|
|
67
192
|
abandon(parentToolCallId: string): void;
|
|
193
|
+
/** Evict one row: flush its parked notification (C2), abort its in-flight resume (if any), unpin +
|
|
194
|
+
* release the session, tombstone the id. */
|
|
68
195
|
evict(parentToolCallId: string): Promise<void>;
|
|
196
|
+
/** design/122 D4 — parent-run terminal cleanup: abort EVERY in-flight resume + unpin + release EVERY
|
|
197
|
+
* retained session (throwaway semantics restored; no orphan run burns tokens — same posture as
|
|
198
|
+
* `abortBackgroundAgentsForOwner`). Idempotent; further register/resume attempts are refused. */
|
|
69
199
|
disposeAll(): Promise<void>;
|
|
70
200
|
}
|
|
201
|
+
/** Look up (never create) the session-scoped retain ledger for `sessionId` — SendMessage's read side.
|
|
202
|
+
* fix-C1: a read hit refreshes `touchedAt` (TRUE LRU) — a session kept alive ONLY by SendMessage resumes
|
|
203
|
+
* otherwise looked stale to the cap eviction below and got its ledger disposed (aborting in-flight
|
|
204
|
+
* resumes) while 63+ other sessions churned. */
|
|
71
205
|
export declare function getSessionRetainLedger(sessionId: string): SubagentRetainLedger | undefined;
|
|
72
206
|
export declare function getOrCreateSessionRetainLedger(sessionId: string, config: {
|
|
73
207
|
ttlMs: number;
|
|
74
208
|
max: number;
|
|
75
209
|
}, hooks?: RetainLedgerHooks): SubagentRetainLedger;
|
|
210
|
+
/** Anchor ② — dispose the session's retain ledger (abort in-flight resumes, unpin + release every retained
|
|
211
|
+
* child session) and drop it. Idempotent; wired to `TaskRegistry.onSessionReap` at retain time. */
|
|
76
212
|
export declare function releaseSessionRetainLedger(sessionId: string): Promise<void>;
|
|
77
213
|
export declare function ensureSessionReapHook(registry: import("../core/task-registry.js").TaskRegistry): void;
|
|
214
|
+
/**
|
|
215
|
+
* design/122 D2 — the SINGLE resume-prompt builder: a constant TRUSTED frame core owns (operator authority +
|
|
216
|
+
* an unpredictable correlation marker) around the operator content, which stays fenced DATA (same posture as
|
|
217
|
+
* steer — content is never authority, and `delimitUntrusted` neutralizes fence/tag break-out sentinels).
|
|
218
|
+
*/
|
|
78
219
|
export declare function createResumePrompt(marker: string, content: string, origin?: "operator" | "peer"): string;
|