@smthrs/harness 0.0.0-stage → 1.0.0-rc.4
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 +387 -0
- package/LICENSE +21 -0
- package/README.md +138 -2
- package/dist/cjs/AgentEvent.d.ts +3092 -0
- package/dist/cjs/AgentEvent.d.ts.map +1 -0
- package/dist/cjs/AgentEvent.js +1116 -0
- package/dist/cjs/AgentEvent.js.map +7 -0
- package/dist/cjs/CallLedger.d.ts +378 -0
- package/dist/cjs/CallLedger.d.ts.map +1 -0
- package/dist/cjs/CallLedger.js +240 -0
- package/dist/cjs/CallLedger.js.map +7 -0
- package/dist/cjs/Cell.d.ts +774 -0
- package/dist/cjs/Cell.d.ts.map +1 -0
- package/dist/cjs/Cell.js +431 -0
- package/dist/cjs/Cell.js.map +7 -0
- package/dist/cjs/CellCalls.d.ts +115 -0
- package/dist/cjs/CellCalls.d.ts.map +1 -0
- package/dist/cjs/CellCalls.js +98 -0
- package/dist/cjs/CellCalls.js.map +7 -0
- package/dist/cjs/CellHistory.d.ts +102 -0
- package/dist/cjs/CellHistory.d.ts.map +1 -0
- package/dist/cjs/CellHistory.js +54 -0
- package/dist/cjs/CellHistory.js.map +7 -0
- package/dist/cjs/CellTurn.d.ts +1071 -0
- package/dist/cjs/CellTurn.d.ts.map +1 -0
- package/dist/cjs/CellTurn.js +2618 -0
- package/dist/cjs/CellTurn.js.map +7 -0
- package/dist/cjs/CellValidation.d.ts +94 -0
- package/dist/cjs/CellValidation.d.ts.map +1 -0
- package/dist/cjs/CellValidation.js +218 -0
- package/dist/cjs/CellValidation.js.map +7 -0
- package/dist/cjs/Compaction.d.ts +158 -0
- package/dist/cjs/Compaction.d.ts.map +1 -0
- package/dist/cjs/Compaction.js +189 -0
- package/dist/cjs/Compaction.js.map +7 -0
- package/dist/cjs/CompletionClaim.d.ts +801 -0
- package/dist/cjs/CompletionClaim.d.ts.map +1 -0
- package/dist/cjs/CompletionClaim.js +303 -0
- package/dist/cjs/CompletionClaim.js.map +7 -0
- package/dist/cjs/ContextWindow.d.ts +435 -0
- package/dist/cjs/ContextWindow.d.ts.map +1 -0
- package/dist/cjs/ContextWindow.js +319 -0
- package/dist/cjs/ContextWindow.js.map +7 -0
- package/dist/cjs/EngineLike.d.ts +546 -0
- package/dist/cjs/EngineLike.d.ts.map +1 -0
- package/dist/cjs/EngineLike.js +114 -0
- package/dist/cjs/EngineLike.js.map +7 -0
- package/dist/cjs/ExternalTranscript.d.ts +349 -0
- package/dist/cjs/ExternalTranscript.d.ts.map +1 -0
- package/dist/cjs/ExternalTranscript.js +826 -0
- package/dist/cjs/ExternalTranscript.js.map +7 -0
- package/dist/cjs/FailedCall.d.ts +132 -0
- package/dist/cjs/FailedCall.d.ts.map +1 -0
- package/dist/cjs/FailedCall.js +53 -0
- package/dist/cjs/FailedCall.js.map +7 -0
- package/dist/cjs/FlowBinding.d.ts +289 -0
- package/dist/cjs/FlowBinding.d.ts.map +1 -0
- package/dist/cjs/FlowBinding.js +251 -0
- package/dist/cjs/FlowBinding.js.map +7 -0
- package/dist/cjs/HarnessError.d.ts +57 -0
- package/dist/cjs/HarnessError.d.ts.map +1 -0
- package/dist/cjs/HarnessError.js +75 -0
- package/dist/cjs/HarnessError.js.map +7 -0
- package/dist/cjs/Judgement.d.ts +289 -0
- package/dist/cjs/Judgement.d.ts.map +1 -0
- package/dist/cjs/Judgement.js +240 -0
- package/dist/cjs/Judgement.js.map +7 -0
- package/dist/cjs/Monitor.d.ts +374 -0
- package/dist/cjs/Monitor.d.ts.map +1 -0
- package/dist/cjs/Monitor.js +233 -0
- package/dist/cjs/Monitor.js.map +7 -0
- package/dist/cjs/NarrowedCheck.d.ts +523 -0
- package/dist/cjs/NarrowedCheck.d.ts.map +1 -0
- package/dist/cjs/NarrowedCheck.js +263 -0
- package/dist/cjs/NarrowedCheck.js.map +7 -0
- package/dist/cjs/Notifications.d.ts +42 -0
- package/dist/cjs/Notifications.d.ts.map +1 -0
- package/dist/cjs/Notifications.js +177 -0
- package/dist/cjs/Notifications.js.map +7 -0
- package/dist/cjs/Plan.d.ts +127 -0
- package/dist/cjs/Plan.d.ts.map +1 -0
- package/dist/cjs/Plan.js +77 -0
- package/dist/cjs/Plan.js.map +7 -0
- package/dist/cjs/QuickJSSandbox.d.ts +151 -0
- package/dist/cjs/QuickJSSandbox.d.ts.map +1 -0
- package/dist/cjs/QuickJSSandbox.js +987 -0
- package/dist/cjs/QuickJSSandbox.js.map +7 -0
- package/dist/cjs/Relevance.d.ts +213 -0
- package/dist/cjs/Relevance.d.ts.map +1 -0
- package/dist/cjs/Relevance.js +183 -0
- package/dist/cjs/Relevance.js.map +7 -0
- package/dist/cjs/Sandbox.d.ts +637 -0
- package/dist/cjs/Sandbox.d.ts.map +1 -0
- package/dist/cjs/Sandbox.js +260 -0
- package/dist/cjs/Sandbox.js.map +7 -0
- package/dist/cjs/Steering.d.ts +464 -0
- package/dist/cjs/Steering.d.ts.map +1 -0
- package/dist/cjs/Steering.js +153 -0
- package/dist/cjs/Steering.js.map +7 -0
- package/dist/cjs/StructuredOutput.d.ts +252 -0
- package/dist/cjs/StructuredOutput.d.ts.map +1 -0
- package/dist/cjs/StructuredOutput.js +266 -0
- package/dist/cjs/StructuredOutput.js.map +7 -0
- package/dist/cjs/Sufficiency.d.ts +195 -0
- package/dist/cjs/Sufficiency.d.ts.map +1 -0
- package/dist/cjs/Sufficiency.js +110 -0
- package/dist/cjs/Sufficiency.js.map +7 -0
- package/dist/cjs/Supervisor.d.ts +719 -0
- package/dist/cjs/Supervisor.d.ts.map +1 -0
- package/dist/cjs/Supervisor.js +313 -0
- package/dist/cjs/Supervisor.js.map +7 -0
- package/dist/cjs/Tokens.d.ts +86 -0
- package/dist/cjs/Tokens.d.ts.map +1 -0
- package/dist/cjs/Tokens.js +72 -0
- package/dist/cjs/Tokens.js.map +7 -0
- package/dist/cjs/Transcript.d.ts +171 -0
- package/dist/cjs/Transcript.d.ts.map +1 -0
- package/dist/cjs/Transcript.js +342 -0
- package/dist/cjs/Transcript.js.map +7 -0
- package/dist/cjs/TruncatedOutput.d.ts +186 -0
- package/dist/cjs/TruncatedOutput.d.ts.map +1 -0
- package/dist/cjs/TruncatedOutput.js +143 -0
- package/dist/cjs/TruncatedOutput.js.map +7 -0
- package/dist/cjs/UnmovedTree.d.ts +113 -0
- package/dist/cjs/UnmovedTree.d.ts.map +1 -0
- package/dist/cjs/UnmovedTree.js +38 -0
- package/dist/cjs/UnmovedTree.js.map +7 -0
- package/dist/cjs/UnresolvedFailure.d.ts +196 -0
- package/dist/cjs/UnresolvedFailure.d.ts.map +1 -0
- package/dist/cjs/UnresolvedFailure.js +77 -0
- package/dist/cjs/UnresolvedFailure.js.map +7 -0
- package/dist/cjs/VacuousVerification.d.ts +237 -0
- package/dist/cjs/VacuousVerification.d.ts.map +1 -0
- package/dist/cjs/VacuousVerification.js +91 -0
- package/dist/cjs/VacuousVerification.js.map +7 -0
- package/dist/cjs/VariablesPanel.d.ts +117 -0
- package/dist/cjs/VariablesPanel.d.ts.map +1 -0
- package/dist/cjs/VariablesPanel.js +108 -0
- package/dist/cjs/VariablesPanel.js.map +7 -0
- package/dist/cjs/index.d.ts +172 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/bytes.d.ts +36 -0
- package/dist/cjs/internal/bytes.d.ts.map +1 -0
- package/dist/cjs/internal/bytes.js +57 -0
- package/dist/cjs/internal/bytes.js.map +7 -0
- package/dist/cjs/internal/cellPrompt.d.ts +122 -0
- package/dist/cjs/internal/cellPrompt.d.ts.map +1 -0
- package/dist/cjs/internal/cellPrompt.js +146 -0
- package/dist/cjs/internal/cellPrompt.js.map +7 -0
- package/dist/cjs/internal/compactable.d.ts +44 -0
- package/dist/cjs/internal/compactable.d.ts.map +1 -0
- package/dist/cjs/internal/compactable.js +56 -0
- package/dist/cjs/internal/compactable.js.map +7 -0
- package/dist/cjs/internal/compactionMarks.d.ts +278 -0
- package/dist/cjs/internal/compactionMarks.d.ts.map +1 -0
- package/dist/cjs/internal/compactionMarks.js +212 -0
- package/dist/cjs/internal/compactionMarks.js.map +7 -0
- package/dist/cjs/internal/demandText.d.ts +95 -0
- package/dist/cjs/internal/demandText.d.ts.map +1 -0
- package/dist/cjs/internal/demandText.js +70 -0
- package/dist/cjs/internal/demandText.js.map +7 -0
- package/dist/cjs/internal/elide.d.ts +109 -0
- package/dist/cjs/internal/elide.d.ts.map +1 -0
- package/dist/cjs/internal/elide.js +59 -0
- package/dist/cjs/internal/elide.js.map +7 -0
- package/dist/cjs/internal/frame.d.ts +463 -0
- package/dist/cjs/internal/frame.d.ts.map +1 -0
- package/dist/cjs/internal/frame.js +514 -0
- package/dist/cjs/internal/frame.js.map +7 -0
- package/dist/cjs/internal/nonNegativeSafeInt.d.ts +20 -0
- package/dist/cjs/internal/nonNegativeSafeInt.d.ts.map +1 -0
- package/dist/cjs/internal/nonNegativeSafeInt.js +29 -0
- package/dist/cjs/internal/nonNegativeSafeInt.js.map +7 -0
- package/dist/cjs/internal/paidUsage.d.ts +52 -0
- package/dist/cjs/internal/paidUsage.d.ts.map +1 -0
- package/dist/cjs/internal/paidUsage.js +70 -0
- package/dist/cjs/internal/paidUsage.js.map +7 -0
- package/dist/cjs/internal/printChannel.d.ts +233 -0
- package/dist/cjs/internal/printChannel.d.ts.map +1 -0
- package/dist/cjs/internal/printChannel.js +165 -0
- package/dist/cjs/internal/printChannel.js.map +7 -0
- package/dist/cjs/internal/printsObservation.d.ts +26 -0
- package/dist/cjs/internal/printsObservation.d.ts.map +1 -0
- package/dist/cjs/internal/printsObservation.js +27 -0
- package/dist/cjs/internal/printsObservation.js.map +7 -0
- package/dist/cjs/internal/refusal.d.ts +40 -0
- package/dist/cjs/internal/refusal.d.ts.map +1 -0
- package/dist/cjs/internal/refusal.js +45 -0
- package/dist/cjs/internal/refusal.js.map +7 -0
- package/dist/cjs/internal/supervision.d.ts +174 -0
- package/dist/cjs/internal/supervision.d.ts.map +1 -0
- package/dist/cjs/internal/supervision.js +402 -0
- package/dist/cjs/internal/supervision.js.map +7 -0
- package/dist/cjs/internal/unfinishedWork.d.ts +99 -0
- package/dist/cjs/internal/unfinishedWork.d.ts.map +1 -0
- package/dist/cjs/internal/unfinishedWork.js +80 -0
- package/dist/cjs/internal/unfinishedWork.js.map +7 -0
- package/dist/cjs/internal/unobservedCall.d.ts +112 -0
- package/dist/cjs/internal/unobservedCall.d.ts.map +1 -0
- package/dist/cjs/internal/unobservedCall.js +345 -0
- package/dist/cjs/internal/unobservedCall.js.map +7 -0
- package/dist/cjs/internal/untrustedData.d.ts +14 -0
- package/dist/cjs/internal/untrustedData.d.ts.map +1 -0
- package/dist/cjs/internal/untrustedData.js +30 -0
- package/dist/cjs/internal/untrustedData.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/AgentEvent.d.ts +3092 -0
- package/dist/esm/AgentEvent.d.ts.map +1 -0
- package/dist/esm/AgentEvent.js +1610 -0
- package/dist/esm/AgentEvent.js.map +1 -0
- package/dist/esm/CallLedger.d.ts +378 -0
- package/dist/esm/CallLedger.d.ts.map +1 -0
- package/dist/esm/CallLedger.js +506 -0
- package/dist/esm/CallLedger.js.map +1 -0
- package/dist/esm/Cell.d.ts +774 -0
- package/dist/esm/Cell.d.ts.map +1 -0
- package/dist/esm/Cell.js +772 -0
- package/dist/esm/Cell.js.map +1 -0
- package/dist/esm/CellCalls.d.ts +115 -0
- package/dist/esm/CellCalls.d.ts.map +1 -0
- package/dist/esm/CellCalls.js +97 -0
- package/dist/esm/CellCalls.js.map +1 -0
- package/dist/esm/CellHistory.d.ts +102 -0
- package/dist/esm/CellHistory.d.ts.map +1 -0
- package/dist/esm/CellHistory.js +91 -0
- package/dist/esm/CellHistory.js.map +1 -0
- package/dist/esm/CellTurn.d.ts +1071 -0
- package/dist/esm/CellTurn.d.ts.map +1 -0
- package/dist/esm/CellTurn.js +3410 -0
- package/dist/esm/CellTurn.js.map +1 -0
- package/dist/esm/CellValidation.d.ts +94 -0
- package/dist/esm/CellValidation.d.ts.map +1 -0
- package/dist/esm/CellValidation.js +335 -0
- package/dist/esm/CellValidation.js.map +1 -0
- package/dist/esm/Compaction.d.ts +158 -0
- package/dist/esm/Compaction.d.ts.map +1 -0
- package/dist/esm/Compaction.js +216 -0
- package/dist/esm/Compaction.js.map +1 -0
- package/dist/esm/CompletionClaim.d.ts +801 -0
- package/dist/esm/CompletionClaim.d.ts.map +1 -0
- package/dist/esm/CompletionClaim.js +833 -0
- package/dist/esm/CompletionClaim.js.map +1 -0
- package/dist/esm/ContextWindow.d.ts +435 -0
- package/dist/esm/ContextWindow.d.ts.map +1 -0
- package/dist/esm/ContextWindow.js +427 -0
- package/dist/esm/ContextWindow.js.map +1 -0
- package/dist/esm/EngineLike.d.ts +546 -0
- package/dist/esm/EngineLike.d.ts.map +1 -0
- package/dist/esm/EngineLike.js +218 -0
- package/dist/esm/EngineLike.js.map +1 -0
- package/dist/esm/ExternalTranscript.d.ts +349 -0
- package/dist/esm/ExternalTranscript.d.ts.map +1 -0
- package/dist/esm/ExternalTranscript.js +985 -0
- package/dist/esm/ExternalTranscript.js.map +1 -0
- package/dist/esm/FailedCall.d.ts +132 -0
- package/dist/esm/FailedCall.d.ts.map +1 -0
- package/dist/esm/FailedCall.js +131 -0
- package/dist/esm/FailedCall.js.map +1 -0
- package/dist/esm/FlowBinding.d.ts +289 -0
- package/dist/esm/FlowBinding.d.ts.map +1 -0
- package/dist/esm/FlowBinding.js +376 -0
- package/dist/esm/FlowBinding.js.map +1 -0
- package/dist/esm/HarnessError.d.ts +57 -0
- package/dist/esm/HarnessError.d.ts.map +1 -0
- package/dist/esm/HarnessError.js +85 -0
- package/dist/esm/HarnessError.js.map +1 -0
- package/dist/esm/Judgement.d.ts +289 -0
- package/dist/esm/Judgement.d.ts.map +1 -0
- package/dist/esm/Judgement.js +305 -0
- package/dist/esm/Judgement.js.map +1 -0
- package/dist/esm/Monitor.d.ts +374 -0
- package/dist/esm/Monitor.d.ts.map +1 -0
- package/dist/esm/Monitor.js +370 -0
- package/dist/esm/Monitor.js.map +1 -0
- package/dist/esm/NarrowedCheck.d.ts +523 -0
- package/dist/esm/NarrowedCheck.d.ts.map +1 -0
- package/dist/esm/NarrowedCheck.js +612 -0
- package/dist/esm/NarrowedCheck.js.map +1 -0
- package/dist/esm/Notifications.d.ts +42 -0
- package/dist/esm/Notifications.d.ts.map +1 -0
- package/dist/esm/Notifications.js +215 -0
- package/dist/esm/Notifications.js.map +1 -0
- package/dist/esm/Plan.d.ts +127 -0
- package/dist/esm/Plan.d.ts.map +1 -0
- package/dist/esm/Plan.js +97 -0
- package/dist/esm/Plan.js.map +1 -0
- package/dist/esm/QuickJSSandbox.d.ts +151 -0
- package/dist/esm/QuickJSSandbox.d.ts.map +1 -0
- package/dist/esm/QuickJSSandbox.js +1364 -0
- package/dist/esm/QuickJSSandbox.js.map +1 -0
- package/dist/esm/Relevance.d.ts +213 -0
- package/dist/esm/Relevance.d.ts.map +1 -0
- package/dist/esm/Relevance.js +254 -0
- package/dist/esm/Relevance.js.map +1 -0
- package/dist/esm/Sandbox.d.ts +637 -0
- package/dist/esm/Sandbox.d.ts.map +1 -0
- package/dist/esm/Sandbox.js +464 -0
- package/dist/esm/Sandbox.js.map +1 -0
- package/dist/esm/Steering.d.ts +464 -0
- package/dist/esm/Steering.d.ts.map +1 -0
- package/dist/esm/Steering.js +193 -0
- package/dist/esm/Steering.js.map +1 -0
- package/dist/esm/StructuredOutput.d.ts +252 -0
- package/dist/esm/StructuredOutput.d.ts.map +1 -0
- package/dist/esm/StructuredOutput.js +430 -0
- package/dist/esm/StructuredOutput.js.map +1 -0
- package/dist/esm/Sufficiency.d.ts +195 -0
- package/dist/esm/Sufficiency.d.ts.map +1 -0
- package/dist/esm/Sufficiency.js +207 -0
- package/dist/esm/Sufficiency.js.map +1 -0
- package/dist/esm/Supervisor.d.ts +719 -0
- package/dist/esm/Supervisor.d.ts.map +1 -0
- package/dist/esm/Supervisor.js +575 -0
- package/dist/esm/Supervisor.js.map +1 -0
- package/dist/esm/Tokens.d.ts +86 -0
- package/dist/esm/Tokens.d.ts.map +1 -0
- package/dist/esm/Tokens.js +92 -0
- package/dist/esm/Tokens.js.map +1 -0
- package/dist/esm/Transcript.d.ts +171 -0
- package/dist/esm/Transcript.d.ts.map +1 -0
- package/dist/esm/Transcript.js +424 -0
- package/dist/esm/Transcript.js.map +1 -0
- package/dist/esm/TruncatedOutput.d.ts +186 -0
- package/dist/esm/TruncatedOutput.d.ts.map +1 -0
- package/dist/esm/TruncatedOutput.js +257 -0
- package/dist/esm/TruncatedOutput.js.map +1 -0
- package/dist/esm/UnmovedTree.d.ts +113 -0
- package/dist/esm/UnmovedTree.d.ts.map +1 -0
- package/dist/esm/UnmovedTree.js +90 -0
- package/dist/esm/UnmovedTree.js.map +1 -0
- package/dist/esm/UnresolvedFailure.d.ts +196 -0
- package/dist/esm/UnresolvedFailure.d.ts.map +1 -0
- package/dist/esm/UnresolvedFailure.js +218 -0
- package/dist/esm/UnresolvedFailure.js.map +1 -0
- package/dist/esm/VacuousVerification.d.ts +237 -0
- package/dist/esm/VacuousVerification.d.ts.map +1 -0
- package/dist/esm/VacuousVerification.js +245 -0
- package/dist/esm/VacuousVerification.js.map +1 -0
- package/dist/esm/VariablesPanel.d.ts +117 -0
- package/dist/esm/VariablesPanel.d.ts.map +1 -0
- package/dist/esm/VariablesPanel.js +142 -0
- package/dist/esm/VariablesPanel.js.map +1 -0
- package/dist/esm/index.d.ts +172 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +172 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/bytes.d.ts +36 -0
- package/dist/esm/internal/bytes.d.ts.map +1 -0
- package/dist/esm/internal/bytes.js +70 -0
- package/dist/esm/internal/bytes.js.map +1 -0
- package/dist/esm/internal/cellPrompt.d.ts +122 -0
- package/dist/esm/internal/cellPrompt.d.ts.map +1 -0
- package/dist/esm/internal/cellPrompt.js +276 -0
- package/dist/esm/internal/cellPrompt.js.map +1 -0
- package/dist/esm/internal/compactable.d.ts +44 -0
- package/dist/esm/internal/compactable.d.ts.map +1 -0
- package/dist/esm/internal/compactable.js +71 -0
- package/dist/esm/internal/compactable.js.map +1 -0
- package/dist/esm/internal/compactionMarks.d.ts +278 -0
- package/dist/esm/internal/compactionMarks.d.ts.map +1 -0
- package/dist/esm/internal/compactionMarks.js +317 -0
- package/dist/esm/internal/compactionMarks.js.map +1 -0
- package/dist/esm/internal/demandText.d.ts +95 -0
- package/dist/esm/internal/demandText.d.ts.map +1 -0
- package/dist/esm/internal/demandText.js +128 -0
- package/dist/esm/internal/demandText.js.map +1 -0
- package/dist/esm/internal/elide.d.ts +109 -0
- package/dist/esm/internal/elide.d.ts.map +1 -0
- package/dist/esm/internal/elide.js +123 -0
- package/dist/esm/internal/elide.js.map +1 -0
- package/dist/esm/internal/frame.d.ts +463 -0
- package/dist/esm/internal/frame.d.ts.map +1 -0
- package/dist/esm/internal/frame.js +861 -0
- package/dist/esm/internal/frame.js.map +1 -0
- package/dist/esm/internal/nonNegativeSafeInt.d.ts +20 -0
- package/dist/esm/internal/nonNegativeSafeInt.d.ts.map +1 -0
- package/dist/esm/internal/nonNegativeSafeInt.js +20 -0
- package/dist/esm/internal/nonNegativeSafeInt.js.map +1 -0
- package/dist/esm/internal/paidUsage.d.ts +52 -0
- package/dist/esm/internal/paidUsage.d.ts.map +1 -0
- package/dist/esm/internal/paidUsage.js +72 -0
- package/dist/esm/internal/paidUsage.js.map +1 -0
- package/dist/esm/internal/printChannel.d.ts +233 -0
- package/dist/esm/internal/printChannel.d.ts.map +1 -0
- package/dist/esm/internal/printChannel.js +376 -0
- package/dist/esm/internal/printChannel.js.map +1 -0
- package/dist/esm/internal/printsObservation.d.ts +26 -0
- package/dist/esm/internal/printsObservation.d.ts.map +1 -0
- package/dist/esm/internal/printsObservation.js +29 -0
- package/dist/esm/internal/printsObservation.js.map +1 -0
- package/dist/esm/internal/refusal.d.ts +40 -0
- package/dist/esm/internal/refusal.d.ts.map +1 -0
- package/dist/esm/internal/refusal.js +47 -0
- package/dist/esm/internal/refusal.js.map +1 -0
- package/dist/esm/internal/supervision.d.ts +174 -0
- package/dist/esm/internal/supervision.d.ts.map +1 -0
- package/dist/esm/internal/supervision.js +485 -0
- package/dist/esm/internal/supervision.js.map +1 -0
- package/dist/esm/internal/unfinishedWork.d.ts +99 -0
- package/dist/esm/internal/unfinishedWork.d.ts.map +1 -0
- package/dist/esm/internal/unfinishedWork.js +85 -0
- package/dist/esm/internal/unfinishedWork.js.map +1 -0
- package/dist/esm/internal/unobservedCall.d.ts +112 -0
- package/dist/esm/internal/unobservedCall.d.ts.map +1 -0
- package/dist/esm/internal/unobservedCall.js +501 -0
- package/dist/esm/internal/unobservedCall.js.map +1 -0
- package/dist/esm/internal/untrustedData.d.ts +14 -0
- package/dist/esm/internal/untrustedData.d.ts.map +1 -0
- package/dist/esm/internal/untrustedData.js +15 -0
- package/dist/esm/internal/untrustedData.js.map +1 -0
- package/docs/README.md +129 -0
- package/docs/api.md +1869 -0
- package/docs/concepts.md +238 -0
- package/docs/external-transcripts.md +245 -0
- package/docs/guides/bind-flows.md +167 -0
- package/docs/guides/drive-the-loop.md +265 -0
- package/docs/guides/run-cells.md +262 -0
- package/docs/guides/workerd.md +144 -0
- package/docs/installation.md +69 -0
- package/docs/quickstart.md +121 -0
- package/docs/reference.md +954 -0
- package/docs/troubleshooting.md +177 -0
- package/package.json +463 -3
- package/src/AgentEvent.ts +1772 -0
- package/src/CallLedger.ts +560 -0
- package/src/Cell.ts +926 -0
- package/src/CellCalls.ts +198 -0
- package/src/CellHistory.ts +128 -0
- package/src/CellTurn.ts +4450 -0
- package/src/CellValidation.ts +382 -0
- package/src/Compaction.ts +330 -0
- package/src/CompletionClaim.ts +1013 -0
- package/src/ContextWindow.ts +669 -0
- package/src/EngineLike.ts +614 -0
- package/src/ExternalTranscript.ts +1142 -0
- package/src/FailedCall.ts +163 -0
- package/src/FlowBinding.ts +603 -0
- package/src/HarnessError.ts +98 -0
- package/src/Judgement.ts +526 -0
- package/src/Monitor.ts +579 -0
- package/src/NarrowedCheck.ts +694 -0
- package/src/Notifications.ts +262 -0
- package/src/Plan.ts +113 -0
- package/src/QuickJSSandbox.ts +1557 -0
- package/src/Relevance.ts +352 -0
- package/src/Sandbox.ts +908 -0
- package/src/Steering.ts +405 -0
- package/src/StructuredOutput.ts +484 -0
- package/src/Sufficiency.ts +247 -0
- package/src/Supervisor.ts +798 -0
- package/src/Tokens.ts +108 -0
- package/src/Transcript.ts +513 -0
- package/src/TruncatedOutput.ts +297 -0
- package/src/UnmovedTree.ts +121 -0
- package/src/UnresolvedFailure.ts +240 -0
- package/src/VacuousVerification.ts +280 -0
- package/src/VariablesPanel.ts +165 -0
- package/src/index.ts +204 -0
- package/src/internal/bytes.ts +70 -0
- package/src/internal/cellPrompt.ts +337 -0
- package/src/internal/compactable.ts +76 -0
- package/src/internal/compactionMarks.ts +454 -0
- package/src/internal/demandText.ts +145 -0
- package/src/internal/elide.ts +130 -0
- package/src/internal/frame.ts +1178 -0
- package/src/internal/nonNegativeSafeInt.ts +24 -0
- package/src/internal/paidUsage.ts +90 -0
- package/src/internal/printChannel.ts +434 -0
- package/src/internal/printsObservation.ts +31 -0
- package/src/internal/refusal.ts +53 -0
- package/src/internal/supervision.ts +652 -0
- package/src/internal/unfinishedWork.ts +123 -0
- package/src/internal/unobservedCall.ts +536 -0
- package/src/internal/untrustedData.ts +19 -0
package/docs/concepts.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Concepts"
|
|
3
|
+
description: "The mental models behind @smthrs/harness: cells, the persistent realm, durable flow calls as the only I/O, and the design decisions each module enforces."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This page states the designs `@smthrs/harness` is built on: what each one
|
|
7
|
+
decides, and which module holds you to the decision. Three mental models
|
|
8
|
+
organize all of them: the cell, the persistent realm, and the durable flow
|
|
9
|
+
call.
|
|
10
|
+
|
|
11
|
+
## The cell loop
|
|
12
|
+
|
|
13
|
+
A run of the built-in agent is a sequence of frames. One frame is:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
model -> generated cell -> realm evaluation -> individually durable flow calls -> next transition
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The model's whole answer is text, and the harness recovers a program from it:
|
|
20
|
+
every fenced `cell` block of the reply, joined in order into one JavaScript
|
|
21
|
+
program. That program is the cell. It runs inside a realm the run keeps, and
|
|
22
|
+
it states how the run should proceed by calling: `ctx.done(output)` completes
|
|
23
|
+
the run, `ctx.park(reason, message)` waits durably, and a cell that calls
|
|
24
|
+
neither continues to the next frame. `Sandbox.replTransition` builds the
|
|
25
|
+
`Cell.Transition` the journal records from that call.
|
|
26
|
+
|
|
27
|
+
The loop is cell-first rather than tool-call-first. The controller seals every
|
|
28
|
+
model request with `tools: []` and `toolChoice: "none"`, so continuation never
|
|
29
|
+
comes from provider plumbing: it comes from the transition the cell settled
|
|
30
|
+
and the budgets the run declared. A model that wants to read a file, run a
|
|
31
|
+
command, or ask a human writes JavaScript that awaits `ctx.call`, the same two
|
|
32
|
+
lines for every capability, and the harness turns each call into its own
|
|
33
|
+
durable boundary.
|
|
34
|
+
|
|
35
|
+
Four actors share the frame, and the package draws a hard line between them.
|
|
36
|
+
The model authors cells. The realm evaluates them. The controller (`CellTurn`)
|
|
37
|
+
decides what the transition means and what the next frame shows. The engine
|
|
38
|
+
(`EngineLike`) owns everything durable: sealed model steps, flow-call
|
|
39
|
+
settlements, journaled records, workspace measurement, checkpoints, and
|
|
40
|
+
suspension. The package is the translation between the four; scheduling,
|
|
41
|
+
persistence, transport, and model execution stay behind the ports.
|
|
42
|
+
|
|
43
|
+
A frame lookup writes an empty attempt marker when no terminal record exists.
|
|
44
|
+
Evaluation then runs outside the record activity, and its result is written
|
|
45
|
+
to the next slot. Replay skips existing empty markers before reconstructing
|
|
46
|
+
the terminal frame. An attempt that parks or is interrupted leaves a marker
|
|
47
|
+
and can resume its calls without an enclosing frame activity.
|
|
48
|
+
|
|
49
|
+
A whole-frame timeout records the last dispatched and last delivered bridge
|
|
50
|
+
ordinals with the frame outcome. Replay reads that record before evaluating
|
|
51
|
+
the cell, reconstructs the settled prefix, and interrupts the bridge at the
|
|
52
|
+
recorded cutoff. Calls and checkpoints beyond that cutoff cannot run, and
|
|
53
|
+
JavaScript awaiting the interrupted bridge receives the same teardown as the
|
|
54
|
+
original attempt. Settled calls in this prefix use their recorded results,
|
|
55
|
+
including per-call timeouts. A limit rejection without a recorded frontier
|
|
56
|
+
still decodes for inspection, but replay fails with `incompatible_journal`
|
|
57
|
+
before evaluating it. A binding must return the frontier to resume such a
|
|
58
|
+
frame safely.
|
|
59
|
+
|
|
60
|
+
## Repl realm
|
|
61
|
+
|
|
62
|
+
A run holds **one** realm for its whole life. The realm is the run's memory:
|
|
63
|
+
names bound by frame 3 are still bound in frame 9, so a cell reads what earlier
|
|
64
|
+
cells built instead of re-deriving it, and nothing is filed on the way out. What
|
|
65
|
+
the next model turn reads is what the frame printed.
|
|
66
|
+
|
|
67
|
+
Consequences the code enforces:
|
|
68
|
+
|
|
69
|
+
- `Sandbox.Realm` is acquired once and scoped to the run, not to a frame.
|
|
70
|
+
`QuickJSSandbox.openRealm` is the only implementation that offers one.
|
|
71
|
+
- The per-frame budgets (`steps`, `timeMs`, `totalMs`) reset at each frame; the
|
|
72
|
+
memory budget cannot, so `memoryBytes` is a **run** budget enforced by the
|
|
73
|
+
panel probe at each frame's close.
|
|
74
|
+
- The realm is sealed per frame, not per run: `ctx.done` / `ctx.park` latch for
|
|
75
|
+
the frame they were called in and the host clears the latch as the next frame
|
|
76
|
+
opens.
|
|
77
|
+
- `VariablesPanel` exists because the value is still there under the name the
|
|
78
|
+
panel prints. The panel measures each name cheaply rather than serializing it.
|
|
79
|
+
|
|
80
|
+
Enforced by `Sandbox`, `QuickJSSandbox`, and `VariablesPanel`.
|
|
81
|
+
|
|
82
|
+
## Durable cell loop
|
|
83
|
+
|
|
84
|
+
A frame is `model -> cell -> realm evaluation -> durable flow calls ->
|
|
85
|
+
transition`. Every `ctx.call` is its own keyed, journaled, permission-gated
|
|
86
|
+
boundary. On a compatible journal, a crash or a permission park mid-cell
|
|
87
|
+
re-executes source from the top and replays settled calls. This requires the
|
|
88
|
+
same controller format, declarations, and deterministic cell computation;
|
|
89
|
+
changing key material can turn a replay into a fresh call.
|
|
90
|
+
|
|
91
|
+
Harness journal format 2 changes summaries to user context. The agent session
|
|
92
|
+
checks persisted trace versions before opening model or cell boundaries, and
|
|
93
|
+
`CellTurn.run` rejects controller state decoded from an older format with typed
|
|
94
|
+
`HarnessError` code `incompatible_journal`. Start a new run for old journals;
|
|
95
|
+
rc.0 has no compatibility promise. Transcript projection is for display and
|
|
96
|
+
normalizes historical summary text to user messages; it does not authorize
|
|
97
|
+
resuming a historical run. The session trace is best-effort telemetry, while
|
|
98
|
+
the engine's sealed steps and recorded boundaries provide durable replay.
|
|
99
|
+
|
|
100
|
+
The controller's own reads of the world go through `EngineLike.record` for the
|
|
101
|
+
same reason. `(name, identity)` together key a record, and the controller folds
|
|
102
|
+
each boundary's purpose into its identity so it is correct even under an engine
|
|
103
|
+
that keys on identity alone.
|
|
104
|
+
|
|
105
|
+
Enforced by `CellTurn`, `Cell`, and `EngineLike`.
|
|
106
|
+
|
|
107
|
+
## Agent cell context
|
|
108
|
+
|
|
109
|
+
What a cell can see and reach, and nothing else:
|
|
110
|
+
|
|
111
|
+
- `ctx.call(flowName, input)` is the only authority. There is no `ctx.fs`, no
|
|
112
|
+
`ctx.shell`, no `ctx.mcp`, no `ctx.spawn`.
|
|
113
|
+
- `ctx.flows` is the catalog, projected from the registry through
|
|
114
|
+
`Cell.FlowProjection`, so the shape a cell reads is the shape the schema
|
|
115
|
+
declares.
|
|
116
|
+
- `ctx.done`, `ctx.park` and `ctx.justify` are how a cell states its intent.
|
|
117
|
+
- `ctx.checkpoint()` mints a read-only view of the tree; a mint settles on the
|
|
118
|
+
call channel and spends the call budget.
|
|
119
|
+
|
|
120
|
+
Enforced by the `QuickJSSandbox` realm prelude and the `Cell` contract.
|
|
121
|
+
|
|
122
|
+
## Flow registry
|
|
123
|
+
|
|
124
|
+
A cell may call only what the registry disclosed to it, and it must call the
|
|
125
|
+
declaration it was shown. `Cell.declarationDigest` is `@smthrs/registry`'s
|
|
126
|
+
`Descriptor.declarationDigest`, the one declaration identity for
|
|
127
|
+
`FlowDescriptor`; it hashes the complete material declaration, `Cell.CallIdentity` folds that digest into every call's identity,
|
|
128
|
+
and `CellCalls.make` re-derives it at the boundary: an entry that moved between
|
|
129
|
+
the frame that showed the catalog and the boundary that runs the call is refused
|
|
130
|
+
with `declaration_changed` rather than dispatched to a body the model never saw.
|
|
131
|
+
|
|
132
|
+
An executable binding answers before a discovered implementation, because a
|
|
133
|
+
binding is the implementation of the declaration it projected.
|
|
134
|
+
|
|
135
|
+
Enforced by `CellCalls`, `FlowBinding`, and `Cell`.
|
|
136
|
+
|
|
137
|
+
## Context window
|
|
138
|
+
|
|
139
|
+
The context assembled for one model request is immutable, provider-neutral, and
|
|
140
|
+
zoned, so a provider's prefix cache covers the stable span. Segments carry their
|
|
141
|
+
own digest and estimated token count, computed once at construction; the arrays
|
|
142
|
+
are frozen so a mutation cannot invalidate a cached digest silently.
|
|
143
|
+
|
|
144
|
+
The volatile block, the frame's state section, is a user message after the
|
|
145
|
+
transcript rather than inside the system context, so the whole stable span is
|
|
146
|
+
byte-identical for the life of a run. Each frame's section stays in the window
|
|
147
|
+
once written, and a later section lists only the calls settled since the last
|
|
148
|
+
one, so every request is the previous request, its reply, and new messages.
|
|
149
|
+
The newest section is read just before the frame's asks, or last when there
|
|
150
|
+
are none.
|
|
151
|
+
|
|
152
|
+
Compaction summaries are rendered as user messages, including summaries read
|
|
153
|
+
from older journal records. This keeps every compacted request anchored by a
|
|
154
|
+
leading user turn on providers that reject assistant-first conversations.
|
|
155
|
+
The settlement records the retained suffix's message count so transcript
|
|
156
|
+
projection replaces only the summarized prefix. Repeated compactions apply in
|
|
157
|
+
journal order. Legacy settlements without a count replace all earlier messages.
|
|
158
|
+
|
|
159
|
+
Enforced by `ContextWindow`, `Tokens`, and `Compaction`.
|
|
160
|
+
|
|
161
|
+
## Structured output
|
|
162
|
+
|
|
163
|
+
A boundary that must produce a typed value decodes the original `ctx.done`
|
|
164
|
+
value against the declared schema. String answers can use JSON text extraction
|
|
165
|
+
when the schema requires another type. Older text-only completions retain text
|
|
166
|
+
decoding. The boundary spends a bounded number of correction re-prompts,
|
|
167
|
+
and then fails with a typed, coded failure rather than prose. The failure names
|
|
168
|
+
the schema digest, the candidate digest, the corrections spent, the budget, and
|
|
169
|
+
a bounded list of `{ path, message }` issues, so two identical-looking refusals
|
|
170
|
+
are distinguishable and a consumer branches on `code`.
|
|
171
|
+
|
|
172
|
+
Enforced by `StructuredOutput`.
|
|
173
|
+
|
|
174
|
+
## Notification queue
|
|
175
|
+
|
|
176
|
+
Human steering reaches a run only at safe turn boundaries. The durable queue
|
|
177
|
+
decides which notifications a boundary may deliver; the harness folds what it
|
|
178
|
+
promoted into inserts and seat changes, journals the drain as a record so a
|
|
179
|
+
resumed run does not drain an already-drained queue, and never lets an
|
|
180
|
+
un-actionable steer look delivered.
|
|
181
|
+
|
|
182
|
+
Steering is considered after raised and rejected cells as well as successful
|
|
183
|
+
transitions. A completion is an idle boundary: queued follow-ups can keep the
|
|
184
|
+
run going. When the frame budget is exhausted, undeliverable notifications stay
|
|
185
|
+
pending in the durable queue for the host to carry forward.
|
|
186
|
+
|
|
187
|
+
Pending steering detected after the model returns holds the proposed cell until
|
|
188
|
+
another model frame consumes the instruction. If no frame remains, the run fails
|
|
189
|
+
with `engine_failed` and leaves the instruction pending, including when the
|
|
190
|
+
proposed cell would have parked. If the drain finds nothing left to deliver,
|
|
191
|
+
the proposed cell can execute.
|
|
192
|
+
|
|
193
|
+
Enforced by `Notifications` and `Steering`.
|
|
194
|
+
|
|
195
|
+
An outside-change note names changed files as untrusted data. Re-read those files
|
|
196
|
+
before editing or writing; after a `stale_read` refusal, read again before retrying.
|
|
197
|
+
Outside-change delivery stays disabled until authenticated watcher ingestion,
|
|
198
|
+
durable delivery to the pinned coding run, and machine stale-write enforcement
|
|
199
|
+
are available.
|
|
200
|
+
|
|
201
|
+
Reserved `outside_change` payloads fail queue admission with
|
|
202
|
+
`NotificationError.code = "notification_refused"`. They never enter the journal;
|
|
203
|
+
other steers at the same boundary still deliver and replay.
|
|
204
|
+
|
|
205
|
+
## Step keys and the model layer
|
|
206
|
+
|
|
207
|
+
A sealed model step is keyed on the exact wire request plus the declared key
|
|
208
|
+
material. Anything that says _how long the caller will wait_ rather than _what
|
|
209
|
+
the model was asked_ is deliberately not key material: a step keyed on a budget
|
|
210
|
+
would miss its cache the moment a host retuned it. `SealedModelStep.modelCallMs`
|
|
211
|
+
is the example, and it travels on the step so the number the controller journals
|
|
212
|
+
as armed is the number the engine enforces.
|
|
213
|
+
|
|
214
|
+
Enforced by `EngineLike`, with the request shape owned by [`@smthrs/model`](/api/model).
|
|
215
|
+
|
|
216
|
+
## Child plans and the splice boundary
|
|
217
|
+
|
|
218
|
+
`Plan.Batch` describes children in source order; `EngineLike.splice` is the one
|
|
219
|
+
boundary that turns a batch into running children and streams their progress
|
|
220
|
+
back. The harness translates and never schedules.
|
|
221
|
+
|
|
222
|
+
Enforced by `Plan` and `EngineLike`.
|
|
223
|
+
|
|
224
|
+
## Model authoring surface
|
|
225
|
+
|
|
226
|
+
The cell contract is the text the model is taught with, and its size is a cost
|
|
227
|
+
the run pays every frame. The package pins a token ceiling on the rendered
|
|
228
|
+
contract, so growing it is a deliberate act with a number attached.
|
|
229
|
+
|
|
230
|
+
The `jev` teaching is a section of its own, rendered between the environment
|
|
231
|
+
facts and the catalog only when the catalog binds `jev`. It carries the
|
|
232
|
+
thresholds a cell acts on (a boolean at probability 0.8, a choice or score at
|
|
233
|
+
the provider's confidence 0.7) and one worked example that the package runs
|
|
234
|
+
verbatim. It is constant for a run, so the cached prefix holds.
|
|
235
|
+
|
|
236
|
+
Enforced by `CellTurn.teach`, which renders the contract and the callable-flow
|
|
237
|
+
catalog into the prefix zone of a `ContextWindow`, where every transition
|
|
238
|
+
preserves them.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# External transcripts
|
|
2
|
+
|
|
3
|
+
A person runs Codex or Claude Code in a branch terminal with their own login.
|
|
4
|
+
`ExternalTranscript` from `@smthrs/harness` decodes the transcript file that
|
|
5
|
+
agent writes into ordered, read-only entries, so the branch conversation can
|
|
6
|
+
show the session (mvp.md M-38). The module has two decoders and nothing else:
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { ExternalTranscript } from "@smthrs/harness"
|
|
10
|
+
|
|
11
|
+
ExternalTranscript.decodeCodex(state, chunk) // rollout-*.jsonl under $CODEX_HOME/sessions
|
|
12
|
+
ExternalTranscript.decodeClaude(state, chunk) // <session>.jsonl under ~/.claude/projects/<project>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Each returns `Result<Decoded<State>, ExternalTranscriptError>`: the entries the
|
|
16
|
+
chunk completed and the state to pass with the next chunk. Both are pure. They
|
|
17
|
+
read no file, clock, network or process, register no importer and publish
|
|
18
|
+
nothing. The reference for every type is [api.md](api.md#externaltranscript).
|
|
19
|
+
|
|
20
|
+
## Machine side
|
|
21
|
+
|
|
22
|
+
The bytes a decoder gets are one line of one file, framed in the member's
|
|
23
|
+
machine by `smithers-machined` (spec §9.6.6). No decoder runs there.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
member's terminal session root broker daemon (uid 19998)
|
|
27
|
+
┌────────────────────┐ kernel ┌─────────────────────┐ list ┌────────────────────┐
|
|
28
|
+
│ codex / claude │─facts──▶│ discovery │◀────────│ pump, 4 passes/s │
|
|
29
|
+
│ (member's uid) │ │ resolver (owner uid)│ socket │ one reader/source │──▶ outbox ──▶ variant 5
|
|
30
|
+
└────────────────────┘ │ reader (owner uid) ─┼────────▶│ checkpoint/source │
|
|
31
|
+
└─────────────────────┘ └────────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **Which process is an agent.** A process in a roster member's own terminal
|
|
35
|
+
session, with every uid the member's, whose executable is `codex`, `claude`
|
|
36
|
+
or `claude/versions/<release>`, whose agent home is beneath the member's home
|
|
37
|
+
(`CODEX_HOME` or `CLAUDE_CONFIG_DIR` is honored only there), and which is
|
|
38
|
+
linked to exactly one transcript: the rollout a Codex process holds open, or
|
|
39
|
+
the session a Claude Code process names in `sessions/<pid>.json`. A coding
|
|
40
|
+
run's session is the factory's and is never read.
|
|
41
|
+
- **Who reads.** Root reads kernel facts about processes and opens no home. A
|
|
42
|
+
child running as the member answers which file is the transcript and which
|
|
43
|
+
release wrote it; another tails that one file beneath the member's agent
|
|
44
|
+
root without following a link. The profile is `<family>/<major.minor>` of
|
|
45
|
+
that release.
|
|
46
|
+
- **Participants and sources.** A participant is one agent process. A source
|
|
47
|
+
is one file of that process. `/clear` in Claude Code starts a new source of
|
|
48
|
+
the same participant. A record's identity is its source, generation and byte
|
|
49
|
+
range, so a replay after a reconnect or a restart is the same record.
|
|
50
|
+
- **Stopping.** A record the host refuses stops its source for the life of the
|
|
51
|
+
process. A removed member's readers are killed with their sessions.
|
|
52
|
+
|
|
53
|
+
## Host caller
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
machine (member's uid) host PostgreSQL
|
|
57
|
+
┌──────────────────────┐ record ┌──────────────────────┐
|
|
58
|
+
│ owner-uid reader │──variant 5─▶│ backend ingest │
|
|
59
|
+
│ frames whole lines │ (bytes) │ registry binding ───┼──▶ who owns it
|
|
60
|
+
└──────────────────────┘ │ POST /v1/transcript/│
|
|
61
|
+
│ normalize ─────┼─▶ model-host: decodeCodex / decodeClaude
|
|
62
|
+
│ entries + checkpoint│
|
|
63
|
+
│ + receipt, one tx ──┼──▶ chat_turns, machine_event_receipts
|
|
64
|
+
└──────────────────────┘
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The install-shipped caller is `apps/model-host/src/transcript.ts`, served at
|
|
68
|
+
`POST /v1/transcript/normalize` behind the host bearer. The backend sends one
|
|
69
|
+
framed record, the profile the registry pinned, the registry's owner,
|
|
70
|
+
participant and session, and the decoder state from the previous committed
|
|
71
|
+
receipt. The host decodes that one record and returns drafts and the next
|
|
72
|
+
state. It keeps no state between requests.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = profile.startsWith("codex-rollout/")
|
|
76
|
+
? ExternalTranscript.decodeCodex(state ?? ExternalTranscript.codexStart, record + "\n")
|
|
77
|
+
: ExternalTranscript.decodeClaude(state ?? ExternalTranscript.claudeStart, record + "\n")
|
|
78
|
+
if (Result.isFailure(result)) {
|
|
79
|
+
// Refuse the request with result.failure.code. The backend commits no entry and does not advance the receipt.
|
|
80
|
+
} else {
|
|
81
|
+
// Stamp each entry with the registry's owner and participant, then return result.success.state as the checkpoint.
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Rules the caller keeps:
|
|
86
|
+
|
|
87
|
+
- **Identity comes from the registry.** An entry's `role` says whether the
|
|
88
|
+
owner or the agent side authored it. The caller maps `user` to the
|
|
89
|
+
registered owner and `assistant` to the registered agent participant. A
|
|
90
|
+
name, session or role written in a transcript confers nothing; the decoded
|
|
91
|
+
`session_id` is the agent's own id and never selects a member or a branch.
|
|
92
|
+
- **One record per call, in order, per source.** A failed decode returns no
|
|
93
|
+
entries from its chunk, so a caller that sends one record keeps every entry
|
|
94
|
+
before the refused one.
|
|
95
|
+
- **The state is the checkpoint.** It is plain JSON, held tool requests
|
|
96
|
+
included. Decoding the same record from the same state yields the same
|
|
97
|
+
entries and `source_id`s, so a replay after a crash is idempotent.
|
|
98
|
+
- **A refusal stops that source.** The caller shows the import as stopped and
|
|
99
|
+
never retries under a newer profile.
|
|
100
|
+
- **Nothing decoded runs.** A command, a patch or a script in an entry is
|
|
101
|
+
text. No prompt is queued, no model is called and no run is created.
|
|
102
|
+
|
|
103
|
+
T-AGT-02 owns discovery, the owner-uid reader, framing, the receipt
|
|
104
|
+
transaction and publication. T-AGT-03 owns the conversation view.
|
|
105
|
+
|
|
106
|
+
## Why two decoders and no framework
|
|
107
|
+
|
|
108
|
+
`Transcript.projectResult` projects harness journal entries into model
|
|
109
|
+
messages; it does not parse another agent's JSONL.
|
|
110
|
+
`GatewayProjection.transcript` needs an executable `runId`, so feeding it an
|
|
111
|
+
external record would invent a run. `EntryRowCard` and `CardPrimitives.Actor`
|
|
112
|
+
describe presentation and participants; neither decodes a source record. The
|
|
113
|
+
smallest missing piece is one decoder per format. There is no adapter
|
|
114
|
+
interface: two callers of two functions do not need one.
|
|
115
|
+
|
|
116
|
+
## Profiles
|
|
117
|
+
|
|
118
|
+
Neither format carries a schema version, so the profile is the CLI release
|
|
119
|
+
line that wrote the record.
|
|
120
|
+
|
|
121
|
+
| Agent | Profile | Named by | Releases read |
|
|
122
|
+
| ----------- | ----------------------------- | -------------------------------------- | ----------------------------- |
|
|
123
|
+
| Codex | `codex-rollout/<major.minor>` | `session_meta.payload.cli_version` | `codexReleases`: 0.159, 0.160 |
|
|
124
|
+
| Claude Code | `claude-code/<major.minor>` | `version` on every conversation record | `claudeReleases`: 2.1 |
|
|
125
|
+
|
|
126
|
+
| Error code | When |
|
|
127
|
+
| --------------------- | ------------------------------------------------------------------------------------------ |
|
|
128
|
+
| `missing_version` | A Codex row before `session_meta`; a Claude Code conversation record with no `version` |
|
|
129
|
+
| `unsupported_version` | A release outside the lists above, or none |
|
|
130
|
+
| `unsupported_record` | A complete record, event, item, status line, attachment or block of a kind not named below |
|
|
131
|
+
| `malformed_record` | A complete line that is not a JSON record, or a named kind in another shape |
|
|
132
|
+
|
|
133
|
+
An incomplete last line is not an error: it waits in `state.pending` for its
|
|
134
|
+
newline.
|
|
135
|
+
|
|
136
|
+
## Mapping: Codex
|
|
137
|
+
|
|
138
|
+
| Source | Entry |
|
|
139
|
+
| ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `event_msg` `item_completed` `UserMessage` | The owner's `prompt` |
|
|
141
|
+
| `item_completed` `AgentMessage` | `text`, `final` for the turn's answer; `encrypted` when the body is ciphertext |
|
|
142
|
+
| `item_completed` `Reasoning` | `reasoning` when Codex wrote a summary; otherwise nothing |
|
|
143
|
+
| `item_completed` `CommandExecution` | `tool`: command, `reads` labels, status, exit code, output, duration |
|
|
144
|
+
| `item_completed` `FileChange` | `edit`: each file's unified diff, `applied` or `failed` |
|
|
145
|
+
| `item_completed` `Extension` (web search) | `search` |
|
|
146
|
+
| `item_completed` `SubAgentActivity`, `CollabAgentToolCall` | `helper` |
|
|
147
|
+
| `item_completed` `McpToolCall`, `FunctionCallOutput`, `ImageView` | `tool` |
|
|
148
|
+
| `item_completed` `ContextCompaction` | `compaction` |
|
|
149
|
+
| `event_msg` `thread_goal_updated` | The owner's `goal`, once per objective and status |
|
|
150
|
+
| `event_msg` `task_complete` with `error` | `error` with Codex's message (usage limit, capacity, a refused request) |
|
|
151
|
+
| `event_msg` `turn_aborted`, `error` | `error` with the reason or message |
|
|
152
|
+
| `response_item` `agent_message` with `encrypted_content` | One `encrypted` placeholder for the whole body, header included |
|
|
153
|
+
| `response_item` `agent_message`, readable | The agent side's `text` |
|
|
154
|
+
| `response_item` `custom_tool_call` | Held in `state.calls` until its output; no entry |
|
|
155
|
+
| `response_item` `custom_tool_call_output` reporting a failed script | Failed `tool` with the requested script as its command; plus a failed `edit` for a patch that did not apply |
|
|
156
|
+
| `response_item` `custom_tool_call_output`, script completed or still running | Nothing: its completed items already say it |
|
|
157
|
+
| `response_item` `message`, `reasoning`, `function_call`, `function_call_output` | Skipped by name: the model-facing copy |
|
|
158
|
+
| `event_msg` `task_started`, `token_count`, `thread_settings_applied`, `task_complete` without `error` | Skipped by name |
|
|
159
|
+
| `session_meta` | Selects the profile and session |
|
|
160
|
+
| `turn_context`, `world_state`, `token_usage_record`, `compacted`, `inter_agent_communication_metadata` | Skipped by name |
|
|
161
|
+
| Anything else | `unsupported_record` |
|
|
162
|
+
|
|
163
|
+
Codex encrypts every `response_item` `reasoning` body. Reasoning is not a
|
|
164
|
+
message: without a summary it has nothing to show, like Claude Code's
|
|
165
|
+
signature-only thinking, and it is skipped. A failed edit's diff is empty
|
|
166
|
+
because the report names a file and no change; the patch the agent asked for
|
|
167
|
+
stays in the failed `tool`'s command. An edit is what the agent reported, never
|
|
168
|
+
an observed write.
|
|
169
|
+
|
|
170
|
+
## Mapping: Claude Code
|
|
171
|
+
|
|
172
|
+
| Source | Entry |
|
|
173
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
174
|
+
| `user` text the owner wrote (`origin` `human` or none) | `prompt`; a slash command reads `/<name> <args>`, a shell command `!<command>` |
|
|
175
|
+
| `user` `[Request interrupted by user…]` | `error` with that text |
|
|
176
|
+
| `user` `isMeta`, `isCompactSummary`, another origin, local command output | Nothing: skill bodies, summaries, task notifications, peer messages |
|
|
177
|
+
| `assistant` `text` | `text`, `final` when `stop_reason` is `end_turn` |
|
|
178
|
+
| `assistant` `thinking` with a body | `reasoning` |
|
|
179
|
+
| `assistant` empty `thinking`, `redacted_thinking`, `fallback` | Nothing |
|
|
180
|
+
| `assistant` with `isApiErrorMessage` | `error` with Claude Code's message |
|
|
181
|
+
| `assistant` `tool_use` | Held in `state.calls` until its result; no entry |
|
|
182
|
+
| `user` `tool_result` for `Bash` and any other tool | `tool`: command, `ok` or `error`, exit code, output, duration |
|
|
183
|
+
| `tool_result` for `Read`, `Grep`, `Glob`, `LS` | `tool` with a `reads` label |
|
|
184
|
+
| `tool_result` for `Edit`, `Write`, `MultiEdit`, `NotebookEdit` | `edit`: reported hunks, or the requested change; `failed` when the result is an error |
|
|
185
|
+
| `tool_result` for `WebSearch`, `WebFetch` | `search` |
|
|
186
|
+
| `tool_result` for `Agent`, `Task` | `helper` |
|
|
187
|
+
| `system` `compact_boundary` | `compaction` |
|
|
188
|
+
| `system` `turn_duration`, `informational`, `stop_hook_summary`, `away_summary`, `api_error`, `local_command`, `scheduled_task_fire`, `agents_killed`, `model_refusal_fallback` | Skipped by name: status lines |
|
|
189
|
+
| `attachment` `queued_command` the owner typed | `prompt` |
|
|
190
|
+
| `attachment` of the 44 named context types | Skipped by name: context for the model |
|
|
191
|
+
| `mode`, `permission-mode`, `atis-latch`, `last-prompt`, `ai-title`, `custom-title`, `agent-name`, `queue-operation`, `file-history-snapshot`, `file-history-delta`, `cost-state`, `pr-link`, `bridge-session` | Skipped by name: bookkeeping |
|
|
192
|
+
| `isSidechain` records | Nothing: a subagent's own transcript |
|
|
193
|
+
| Anything else | `unsupported_record` |
|
|
194
|
+
|
|
195
|
+
A tool call becomes one entry at its result's record, so two calls issued
|
|
196
|
+
together appear in the order their results arrive. A call whose result has
|
|
197
|
+
not arrived stays in `state.calls` and has no entry yet.
|
|
198
|
+
|
|
199
|
+
## Evidence
|
|
200
|
+
|
|
201
|
+
`test/fixtures/external/manifest.json` lists five captures. Each directory has
|
|
202
|
+
the transcript the CLI wrote, the committed `expected.json` and a `MANIFEST.md`
|
|
203
|
+
with the capture procedure, record shapes and redactions.
|
|
204
|
+
|
|
205
|
+
| Capture | Release | Where | Covers |
|
|
206
|
+
| ---------------------------- | ------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
|
|
207
|
+
| `codex-0.160` | 0.160.0 | Maintainer's interactive session, macOS | Two turns, commands, searches, edits, helpers, an encrypted message body, a goal |
|
|
208
|
+
| `codex-machine-0.160` | 0.160.0 | Unprivileged member in a microVM, Mac mini | Applied edits, a failed edit, a command that exited 7 |
|
|
209
|
+
| `codex-signed-out-0.160` | 0.160.1 | `codex exec` in an empty temporary home | A turn that ended in a failure Codex reported |
|
|
210
|
+
| `claude-code-2.1` | 2.1.277 | Maintainer's interactive session, macOS | Turns, commands, searches, applied and failed edits, an interruption, a usage-limit error, compaction |
|
|
211
|
+
| `claude-code-signed-out-2.1` | 2.1.291 | `claude -p` in an empty temporary home | An authentication error Claude Code reported |
|
|
212
|
+
|
|
213
|
+
Tests compare decoder output with the committed files and never regenerate
|
|
214
|
+
them. Every capture is replayed whole, from every split at a record boundary
|
|
215
|
+
and one record at a time from a state restored from JSON. Rows a test builds
|
|
216
|
+
by hand are labeled constructed and are not golden evidence.
|
|
217
|
+
|
|
218
|
+
The named kinds come from every transcript on the capture machine: 4,309
|
|
219
|
+
Claude Code files from 2.1.261 to 2.1.291 and 1,029 Codex rollouts from
|
|
220
|
+
0.159.0 to 0.160.1 decode with no tagged error (2026-10-08).
|
|
221
|
+
|
|
222
|
+
`test/ExternalTranscript.live.test.ts` runs the installed `claude` and `codex`
|
|
223
|
+
in empty temporary homes, lets each write its own transcript and decodes it as
|
|
224
|
+
a tail would. It reaches the network, so it runs only with
|
|
225
|
+
`SMITHERS_REAL_AGENT_CLI=1`.
|
|
226
|
+
|
|
227
|
+
## Limits
|
|
228
|
+
|
|
229
|
+
- A member's Claude Code session captured inside a machine, with tool calls
|
|
230
|
+
and edits, is pending on the reference Mac mini. The Claude Code captures
|
|
231
|
+
here ran on a maintainer's Mac.
|
|
232
|
+
- A release line outside the lists is refused. Reading a new line means
|
|
233
|
+
capturing a session, adding its `major.minor` and naming any new kinds.
|
|
234
|
+
- The machine side has run on an arm64 Linux kernel with stand-in agent
|
|
235
|
+
processes, not yet in a microVM with the real CLIs.
|
|
236
|
+
- Claude Code started through a Node launcher is not found: its executable is
|
|
237
|
+
`node`. The native install is.
|
|
238
|
+
- A byte that is not UTF-8, or a NUL, reaches a decoder as `?`, one byte for
|
|
239
|
+
one, and an empty line as leading whitespace of the next record. Neither
|
|
240
|
+
stops a source.
|
|
241
|
+
- A line over 1 MiB stops its source in the machine. No entry says so yet.
|
|
242
|
+
- An agent process is a participant of its entries but is not yet in
|
|
243
|
+
presence; that needs a wire addition too.
|
|
244
|
+
- smithers-38 has not signed off the exports or the §21.1 evidence.
|
|
245
|
+
- No §21.1 benchmark hot path changes: decoding is linear in the bytes given.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Expose flows to cells"
|
|
3
|
+
description: "How to pair a flow declaration with its handler using FlowBinding, compose bindings into a catalog, disclose them through a registry, and resolve ctx.call with CellCalls."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
A cell's only authority is `ctx.call(flowName, input)`, so every capability an
|
|
9
|
+
agent can reach has to arrive as an ordinary flow declaration plus the code
|
|
10
|
+
that runs it. Standard host capabilities, incoming MCP tools, and subagents
|
|
11
|
+
all take this one shape. `FlowBinding` pairs the two halves; `CellCalls`
|
|
12
|
+
resolves a call name against the registry and dispatches to the body the
|
|
13
|
+
declaration names.
|
|
14
|
+
|
|
15
|
+
## Bind one flow
|
|
16
|
+
|
|
17
|
+
`FlowBinding.make` takes a flow declaration and a handler:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import * as FlowBinding from "@smthrs/harness/FlowBinding"
|
|
21
|
+
import { Effect, Schema } from "effect"
|
|
22
|
+
|
|
23
|
+
const echo = FlowBinding.make({
|
|
24
|
+
flow: {
|
|
25
|
+
name: "echo",
|
|
26
|
+
description: "Echo one string back.",
|
|
27
|
+
input: Schema.Struct({ text: Schema.String }),
|
|
28
|
+
output: Schema.Struct({ text: Schema.String, length: Schema.Number }),
|
|
29
|
+
capabilities: [],
|
|
30
|
+
effects: { reads: [], writes: [], mode: "hermetic", onConflict: "serialize", tier: "sealed" }
|
|
31
|
+
},
|
|
32
|
+
handler: (input) => Effect.succeed({ text: input.text, length: input.text.length })
|
|
33
|
+
})
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The declaration is the `FlowBinding.Declared` shape plus `input` and `output`
|
|
37
|
+
schemas; the `Flow.make` declarations of [`@smthrs/core`](/api/core) satisfy
|
|
38
|
+
it as-is. The handler receives the decoded input and the `Cell.Call` itself,
|
|
39
|
+
because a handler that opens a durable boundary of its own needs
|
|
40
|
+
`call.identity` as a replay-stable name for it.
|
|
41
|
+
|
|
42
|
+
A binding is `{ descriptor, run }`:
|
|
43
|
+
|
|
44
|
+
- `descriptor` is an ordinary `FlowDescriptor` from
|
|
45
|
+
[`@smthrs/registry`](/api/registry), projected by
|
|
46
|
+
`FlowBinding.descriptorOf`. `make` derives the body's content digest from
|
|
47
|
+
the handler source and renders both schemas as inline JSON Schema documents,
|
|
48
|
+
which is what puts a parameter schema beside the flow in `ctx.flows`.
|
|
49
|
+
- `run` decodes the call's input through the input schema, executes the
|
|
50
|
+
handler, and validates the handler's output back into serializable JSON.
|
|
51
|
+
|
|
52
|
+
A handler with remaining service requirements produces a `Binding<R>`; close
|
|
53
|
+
them with `FlowBinding.provide(binding, context)` before composing.
|
|
54
|
+
|
|
55
|
+
## How a call settles
|
|
56
|
+
|
|
57
|
+
Inside `run`, every failure lands where the cell contract says it must:
|
|
58
|
+
|
|
59
|
+
- Input the schema rejects settles as a resolved `invalid_input` failure
|
|
60
|
+
without running the handler. For struct inputs, a failed decode retries once
|
|
61
|
+
with `null` omitted only from declared optional fields that reject it on the
|
|
62
|
+
encoded side. Schema-valid nulls remain present; the full schema validates
|
|
63
|
+
the retry. If it still fails, the original rejection is reported.
|
|
64
|
+
The encoded input must be a struct-like object; unions of structs and
|
|
65
|
+
records get no null-omission retry.
|
|
66
|
+
- An ordinary handler failure settles as a resolved `flow_failed` with the
|
|
67
|
+
opaque message `Flow <name> failed.` No raw error message, object, or cause
|
|
68
|
+
enters the call result or its journal record.
|
|
69
|
+
- Output the output schema rejects, or that is not serializable, settles as
|
|
70
|
+
`flow_failed` naming which.
|
|
71
|
+
- Existing `HarnessError` values pass through the error channel unchanged,
|
|
72
|
+
preserving their code and identity.
|
|
73
|
+
- `PermissionRequired` and `PermissionDenied` become `HarnessError` values
|
|
74
|
+
with code `suspended`, so a cell cannot ignore its own permission park.
|
|
75
|
+
Interruptions are never caught.
|
|
76
|
+
|
|
77
|
+
A binding can opt safe details into the public failure using
|
|
78
|
+
`publicError: (error: E) => string | undefined`. Select only fields approved
|
|
79
|
+
for cells and journals, for example a public status code. The returned text
|
|
80
|
+
is bounded before it enters the call result. Returning `undefined`, throwing,
|
|
81
|
+
or returning a non-string at runtime uses the opaque default. Harness and
|
|
82
|
+
permission errors bypass this renderer.
|
|
83
|
+
|
|
84
|
+
Raw diagnostics remain in the host handler. Inspect them there, for example
|
|
85
|
+
with `Effect.tapError`, and redact credentials before logging or persisting
|
|
86
|
+
anything. `publicError` is an explicit disclosure decision, not a sanitizer;
|
|
87
|
+
forward `message` only for error classes the host authored with model-facing
|
|
88
|
+
text; never forward messages of transport, SDK, OS, or unknown errors,
|
|
89
|
+
headers, URLs, or serialized causes.
|
|
90
|
+
|
|
91
|
+
## Compose a catalog
|
|
92
|
+
|
|
93
|
+
`FlowBinding.Source` produces bindings, possibly effectfully, so a lazily
|
|
94
|
+
connected server or a plugin contributes without being resolved at import
|
|
95
|
+
time. `FlowBinding.source(name, bindings)` lifts a fixed list into one.
|
|
96
|
+
`FlowBinding.catalog` resolves ordered sources into one
|
|
97
|
+
`FlowBinding.Catalog`:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
const catalog = await Effect.runPromise(
|
|
101
|
+
FlowBinding.catalog([FlowBinding.source("standard", [echo])])
|
|
102
|
+
)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A catalog refuses two implementations under one name: `catalogResult` fails
|
|
106
|
+
with a `HarnessError` of code `assembly_failed`, because one descriptor
|
|
107
|
+
dispatched to another implementation is how a call runs the wrong body. An
|
|
108
|
+
unnamed binding fails the same way with its own message.
|
|
109
|
+
`FlowBinding.empty()` is the empty catalog.
|
|
110
|
+
|
|
111
|
+
## Disclose through a registry
|
|
112
|
+
|
|
113
|
+
`FlowBinding.registry(base, catalog)` discloses a catalog's descriptors
|
|
114
|
+
through an existing `Registry.Registry`:
|
|
115
|
+
|
|
116
|
+
- File-discovered entries keep their names: a binding whose name a discovery
|
|
117
|
+
source already found is not disclosed, and the shadowed binding is reported
|
|
118
|
+
as an ordinary `duplicate_name` warning. Discovery precedence stays exactly
|
|
119
|
+
where discovery put it.
|
|
120
|
+
- `list`, `visible`, `getOption`, and `get` answer from both sources; body
|
|
121
|
+
loading, prompt rendering, and refresh pass through to the base registry.
|
|
122
|
+
|
|
123
|
+
## Resolve calls with CellCalls
|
|
124
|
+
|
|
125
|
+
`CellCalls.make` turns a call name into the body that answers it:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import * as CellCalls from "@smthrs/harness/CellCalls"
|
|
129
|
+
|
|
130
|
+
const resolver = CellCalls.make({
|
|
131
|
+
registry,
|
|
132
|
+
catalog,
|
|
133
|
+
implementations: new Map(),
|
|
134
|
+
prompt: runMarkdownFlow
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The resolver's `run` has exactly the shape a durable host's call runner
|
|
139
|
+
consumes, so the host wires it in behind `EngineLike.call`. Resolution works
|
|
140
|
+
in this order:
|
|
141
|
+
|
|
142
|
+
1. The registry must know the name, or the call settles `unknown_flow`.
|
|
143
|
+
2. The descriptor must be model-invocable, or the call settles
|
|
144
|
+
`capability_refused`.
|
|
145
|
+
3. The descriptor's declaration digest must equal the digest folded into the
|
|
146
|
+
call's identity, or the call settles `declaration_changed`. The registry is
|
|
147
|
+
refreshable, and this check is what keeps a call bound to the declaration
|
|
148
|
+
the agent was shown.
|
|
149
|
+
4. An executable binding answers first, after an identity check that the
|
|
150
|
+
binding's declaration is the disclosed one. A markdown flow renders against
|
|
151
|
+
the call's arguments and runs through the `CellCalls.PromptRunner` the host
|
|
152
|
+
supplied, or settles `unimplemented` when the host runs none. Anything else
|
|
153
|
+
dispatches to the host's `Implementation` for the name, or settles
|
|
154
|
+
`unimplemented`.
|
|
155
|
+
|
|
156
|
+
Every refusal is a `failure` `Cell.CallResult` that resolves in the cell as
|
|
157
|
+
`{ ok: false, error }`. Inspect `.ok === false` and `.error.code` to recover;
|
|
158
|
+
ordinary refusals do not throw.
|
|
159
|
+
|
|
160
|
+
## Next steps
|
|
161
|
+
|
|
162
|
+
- To run cells against the bound catalog, see
|
|
163
|
+
[Run cells in a persistent realm](./run-cells.md).
|
|
164
|
+
- To wire the resolver into the controller's durable call boundary, see
|
|
165
|
+
[Drive the cell loop](./drive-the-loop.md).
|
|
166
|
+
- For the contract details, see [`FlowBinding`](../api.md#flowbinding) and
|
|
167
|
+
[`CellCalls`](../api.md#cellcalls) in the API reference.
|