looply-cli 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +137 -3
- package/dist/.src-hash +1 -0
- package/dist/acceptance-observe.d.ts +108 -0
- package/dist/acceptance-observe.d.ts.map +1 -0
- package/dist/acceptance-observe.js +152 -0
- package/dist/acceptance-observe.js.map +1 -0
- package/dist/agent-cmd.d.ts +131 -0
- package/dist/agent-cmd.d.ts.map +1 -0
- package/dist/agent-cmd.js +154 -0
- package/dist/agent-cmd.js.map +1 -0
- package/dist/agent-contained.d.ts +114 -0
- package/dist/agent-contained.d.ts.map +1 -0
- package/dist/agent-contained.js +292 -0
- package/dist/agent-contained.js.map +1 -0
- package/dist/agent-driver.d.ts +130 -0
- package/dist/agent-driver.d.ts.map +1 -0
- package/dist/agent-driver.js +170 -0
- package/dist/agent-driver.js.map +1 -0
- package/dist/agent-envelope.d.ts +94 -0
- package/dist/agent-envelope.d.ts.map +1 -0
- package/dist/agent-envelope.js +214 -0
- package/dist/agent-envelope.js.map +1 -0
- package/dist/agent-exec.d.ts +182 -0
- package/dist/agent-exec.d.ts.map +1 -0
- package/dist/agent-exec.js +125 -0
- package/dist/agent-exec.js.map +1 -0
- package/dist/agent-runtime.d.ts +23 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +143 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/approval-gate-read.d.ts +66 -0
- package/dist/approval-gate-read.d.ts.map +1 -0
- package/dist/approval-gate-read.js +138 -0
- package/dist/approval-gate-read.js.map +1 -0
- package/dist/approval-resolution.d.ts +87 -0
- package/dist/approval-resolution.d.ts.map +1 -0
- package/dist/approval-resolution.js +100 -0
- package/dist/approval-resolution.js.map +1 -0
- package/dist/approval-resumes.d.ts +102 -0
- package/dist/approval-resumes.d.ts.map +1 -0
- package/dist/approval-resumes.js +167 -0
- package/dist/approval-resumes.js.map +1 -0
- package/dist/ask-brain.d.ts +167 -0
- package/dist/ask-brain.d.ts.map +1 -0
- package/dist/ask-brain.js +355 -0
- package/dist/ask-brain.js.map +1 -0
- package/dist/autonomy-authority.d.ts +80 -0
- package/dist/autonomy-authority.d.ts.map +1 -0
- package/dist/autonomy-authority.js +82 -0
- package/dist/autonomy-authority.js.map +1 -0
- package/dist/autonomy-controller.d.ts +321 -0
- package/dist/autonomy-controller.d.ts.map +1 -0
- package/dist/autonomy-controller.js +517 -0
- package/dist/autonomy-controller.js.map +1 -0
- package/dist/autonomy-store.d.ts +327 -0
- package/dist/autonomy-store.d.ts.map +1 -0
- package/dist/autonomy-store.js +581 -0
- package/dist/autonomy-store.js.map +1 -0
- package/dist/autonomy-tick.d.ts +257 -0
- package/dist/autonomy-tick.d.ts.map +1 -0
- package/dist/autonomy-tick.js +616 -0
- package/dist/autonomy-tick.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +2727 -0
- package/dist/bin.js.map +1 -0
- package/dist/brain-advice.d.ts +21 -0
- package/dist/brain-advice.d.ts.map +1 -0
- package/dist/brain-advice.js +51 -0
- package/dist/brain-advice.js.map +1 -0
- package/dist/candidate-replay-runtime.d.ts +125 -0
- package/dist/candidate-replay-runtime.d.ts.map +1 -0
- package/dist/candidate-replay-runtime.js +188 -0
- package/dist/candidate-replay-runtime.js.map +1 -0
- package/dist/checkout-carry.d.ts +76 -0
- package/dist/checkout-carry.d.ts.map +1 -0
- package/dist/checkout-carry.js +125 -0
- package/dist/checkout-carry.js.map +1 -0
- package/dist/citation-readers.d.ts +26 -0
- package/dist/citation-readers.d.ts.map +1 -0
- package/dist/citation-readers.js +102 -0
- package/dist/citation-readers.js.map +1 -0
- package/dist/command-receipts.d.ts +79 -0
- package/dist/command-receipts.d.ts.map +1 -0
- package/dist/command-receipts.js +143 -0
- package/dist/command-receipts.js.map +1 -0
- package/dist/command-runner.d.ts +32 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +108 -0
- package/dist/command-runner.js.map +1 -0
- package/dist/compatible-sets.d.ts +67 -0
- package/dist/compatible-sets.d.ts.map +1 -0
- package/dist/compatible-sets.js +81 -0
- package/dist/compatible-sets.js.map +1 -0
- package/dist/compile-check.d.ts +31 -0
- package/dist/compile-check.d.ts.map +1 -0
- package/dist/compile-check.js +34 -0
- package/dist/compile-check.js.map +1 -0
- package/dist/compile-store.d.ts +16 -0
- package/dist/compile-store.d.ts.map +1 -0
- package/dist/compile-store.js +21 -0
- package/dist/compile-store.js.map +1 -0
- package/dist/completion.d.ts +106 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +131 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +549 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +763 -0
- package/dist/config.js.map +1 -0
- package/dist/control-file.d.ts +142 -0
- package/dist/control-file.d.ts.map +1 -0
- package/dist/control-file.js +144 -0
- package/dist/control-file.js.map +1 -0
- package/dist/coordinator-state.d.ts +131 -0
- package/dist/coordinator-state.d.ts.map +1 -0
- package/dist/coordinator-state.js +380 -0
- package/dist/coordinator-state.js.map +1 -0
- package/dist/coordinator.d.ts +95 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +97 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/cursor-store.d.ts +53 -0
- package/dist/cursor-store.d.ts.map +1 -0
- package/dist/cursor-store.js +98 -0
- package/dist/cursor-store.js.map +1 -0
- package/dist/daemon-cmd.d.ts +239 -0
- package/dist/daemon-cmd.d.ts.map +1 -0
- package/dist/daemon-cmd.js +1751 -0
- package/dist/daemon-cmd.js.map +1 -0
- package/dist/daemon-lock.d.ts +140 -0
- package/dist/daemon-lock.d.ts.map +1 -0
- package/dist/daemon-lock.js +352 -0
- package/dist/daemon-lock.js.map +1 -0
- package/dist/daemon-recovery.d.ts +78 -0
- package/dist/daemon-recovery.d.ts.map +1 -0
- package/dist/daemon-recovery.js +161 -0
- package/dist/daemon-recovery.js.map +1 -0
- package/dist/daemon.d.ts +368 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +601 -0
- package/dist/daemon.js.map +1 -0
- package/dist/declared-response-shape.d.ts +93 -0
- package/dist/declared-response-shape.d.ts.map +1 -0
- package/dist/declared-response-shape.js +200 -0
- package/dist/declared-response-shape.js.map +1 -0
- package/dist/declared-surfaces.d.ts +16 -0
- package/dist/declared-surfaces.d.ts.map +1 -0
- package/dist/declared-surfaces.js +19 -0
- package/dist/declared-surfaces.js.map +1 -0
- package/dist/depends-review.d.ts +113 -0
- package/dist/depends-review.d.ts.map +1 -0
- package/dist/depends-review.js +110 -0
- package/dist/depends-review.js.map +1 -0
- package/dist/doctor.d.ts +91 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +71 -0
- package/dist/doctor.js.map +1 -0
- package/dist/edge-approval.d.ts +105 -0
- package/dist/edge-approval.d.ts.map +1 -0
- package/dist/edge-approval.js +100 -0
- package/dist/edge-approval.js.map +1 -0
- package/dist/evidence-cache.d.ts +45 -0
- package/dist/evidence-cache.d.ts.map +1 -0
- package/dist/evidence-cache.js +90 -0
- package/dist/evidence-cache.js.map +1 -0
- package/dist/evidence-cmd.d.ts +133 -0
- package/dist/evidence-cmd.d.ts.map +1 -0
- package/dist/evidence-cmd.js +347 -0
- package/dist/evidence-cmd.js.map +1 -0
- package/dist/evidence-facts.d.ts +40 -0
- package/dist/evidence-facts.d.ts.map +1 -0
- package/dist/evidence-facts.js +114 -0
- package/dist/evidence-facts.js.map +1 -0
- package/dist/exclusive-lock.d.ts +52 -0
- package/dist/exclusive-lock.d.ts.map +1 -0
- package/dist/exclusive-lock.js +150 -0
- package/dist/exclusive-lock.js.map +1 -0
- package/dist/exec-domains.d.ts +140 -0
- package/dist/exec-domains.d.ts.map +1 -0
- package/dist/exec-domains.js +287 -0
- package/dist/exec-domains.js.map +1 -0
- package/dist/exemption-store.d.ts +197 -0
- package/dist/exemption-store.d.ts.map +1 -0
- package/dist/exemption-store.js +266 -0
- package/dist/exemption-store.js.map +1 -0
- package/dist/explicit-start-gate.d.ts +96 -0
- package/dist/explicit-start-gate.d.ts.map +1 -0
- package/dist/explicit-start-gate.js +103 -0
- package/dist/explicit-start-gate.js.map +1 -0
- package/dist/fs-trouble.d.ts +70 -0
- package/dist/fs-trouble.d.ts.map +1 -0
- package/dist/fs-trouble.js +98 -0
- package/dist/fs-trouble.js.map +1 -0
- package/dist/gate.d.ts +278 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +278 -0
- package/dist/gate.js.map +1 -0
- package/dist/git-driver.d.ts +519 -0
- package/dist/git-driver.d.ts.map +1 -0
- package/dist/git-driver.js +900 -0
- package/dist/git-driver.js.map +1 -0
- package/dist/git-push-executor.d.ts +41 -0
- package/dist/git-push-executor.d.ts.map +1 -0
- package/dist/git-push-executor.js +142 -0
- package/dist/git-push-executor.js.map +1 -0
- package/dist/glob.d.ts +26 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +93 -0
- package/dist/glob.js.map +1 -0
- package/dist/goal-adaptive.d.ts +295 -0
- package/dist/goal-adaptive.d.ts.map +1 -0
- package/dist/goal-adaptive.js +393 -0
- package/dist/goal-adaptive.js.map +1 -0
- package/dist/goal-compile.d.ts +342 -0
- package/dist/goal-compile.d.ts.map +1 -0
- package/dist/goal-compile.js +444 -0
- package/dist/goal-compile.js.map +1 -0
- package/dist/goal-depends-executor.d.ts +55 -0
- package/dist/goal-depends-executor.d.ts.map +1 -0
- package/dist/goal-depends-executor.js +202 -0
- package/dist/goal-depends-executor.js.map +1 -0
- package/dist/goal-execution-evidence.d.ts +135 -0
- package/dist/goal-execution-evidence.d.ts.map +1 -0
- package/dist/goal-execution-evidence.js +159 -0
- package/dist/goal-execution-evidence.js.map +1 -0
- package/dist/goal-gap.d.ts +140 -0
- package/dist/goal-gap.d.ts.map +1 -0
- package/dist/goal-gap.js +197 -0
- package/dist/goal-gap.js.map +1 -0
- package/dist/goal-met-target.d.ts +98 -0
- package/dist/goal-met-target.d.ts.map +1 -0
- package/dist/goal-met-target.js +92 -0
- package/dist/goal-met-target.js.map +1 -0
- package/dist/goal-ownership.d.ts +416 -0
- package/dist/goal-ownership.d.ts.map +1 -0
- package/dist/goal-ownership.js +576 -0
- package/dist/goal-ownership.js.map +1 -0
- package/dist/goal-runs.d.ts +82 -0
- package/dist/goal-runs.d.ts.map +1 -0
- package/dist/goal-runs.js +120 -0
- package/dist/goal-runs.js.map +1 -0
- package/dist/goal-store.d.ts +146 -0
- package/dist/goal-store.d.ts.map +1 -0
- package/dist/goal-store.js +294 -0
- package/dist/goal-store.js.map +1 -0
- package/dist/goal-view.d.ts +156 -0
- package/dist/goal-view.d.ts.map +1 -0
- package/dist/goal-view.js +499 -0
- package/dist/goal-view.js.map +1 -0
- package/dist/governed-approvals.d.ts +152 -0
- package/dist/governed-approvals.d.ts.map +1 -0
- package/dist/governed-approvals.js +246 -0
- package/dist/governed-approvals.js.map +1 -0
- package/dist/governed-broker.d.ts +169 -0
- package/dist/governed-broker.d.ts.map +1 -0
- package/dist/governed-broker.js +196 -0
- package/dist/governed-broker.js.map +1 -0
- package/dist/governed-run.d.ts +220 -0
- package/dist/governed-run.d.ts.map +1 -0
- package/dist/governed-run.js +406 -0
- package/dist/governed-run.js.map +1 -0
- package/dist/grant-reconcile.d.ts +63 -0
- package/dist/grant-reconcile.d.ts.map +1 -0
- package/dist/grant-reconcile.js +121 -0
- package/dist/grant-reconcile.js.map +1 -0
- package/dist/index-for-head.d.ts +56 -0
- package/dist/index-for-head.d.ts.map +1 -0
- package/dist/index-for-head.js +103 -0
- package/dist/index-for-head.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/init-detect.d.ts +39 -0
- package/dist/init-detect.d.ts.map +1 -0
- package/dist/init-detect.js +188 -0
- package/dist/init-detect.js.map +1 -0
- package/dist/integration-deps.d.ts +62 -0
- package/dist/integration-deps.d.ts.map +1 -0
- package/dist/integration-deps.js +251 -0
- package/dist/integration-deps.js.map +1 -0
- package/dist/integration-runtime.d.ts +458 -0
- package/dist/integration-runtime.d.ts.map +1 -0
- package/dist/integration-runtime.js +681 -0
- package/dist/integration-runtime.js.map +1 -0
- package/dist/integration.d.ts +45 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +87 -0
- package/dist/integration.js.map +1 -0
- package/dist/integrator.d.ts +84 -0
- package/dist/integrator.d.ts.map +1 -0
- package/dist/integrator.js +193 -0
- package/dist/integrator.js.map +1 -0
- package/dist/lane-claims.d.ts +174 -0
- package/dist/lane-claims.d.ts.map +1 -0
- package/dist/lane-claims.js +218 -0
- package/dist/lane-claims.js.map +1 -0
- package/dist/lane-coverage.d.ts +87 -0
- package/dist/lane-coverage.d.ts.map +1 -0
- package/dist/lane-coverage.js +129 -0
- package/dist/lane-coverage.js.map +1 -0
- package/dist/ledger-replay.d.ts +115 -0
- package/dist/ledger-replay.d.ts.map +1 -0
- package/dist/ledger-replay.js +155 -0
- package/dist/ledger-replay.js.map +1 -0
- package/dist/ledger-store.d.ts +68 -0
- package/dist/ledger-store.d.ts.map +1 -0
- package/dist/ledger-store.js +111 -0
- package/dist/ledger-store.js.map +1 -0
- package/dist/loop-safety-observer.d.ts +132 -0
- package/dist/loop-safety-observer.d.ts.map +1 -0
- package/dist/loop-safety-observer.js +76 -0
- package/dist/loop-safety-observer.js.map +1 -0
- package/dist/loop-safety-store.d.ts +339 -0
- package/dist/loop-safety-store.d.ts.map +1 -0
- package/dist/loop-safety-store.js +800 -0
- package/dist/loop-safety-store.js.map +1 -0
- package/dist/machine-store.d.ts +54 -0
- package/dist/machine-store.d.ts.map +1 -0
- package/dist/machine-store.js +149 -0
- package/dist/machine-store.js.map +1 -0
- package/dist/mcp-main.d.ts +2 -0
- package/dist/mcp-main.d.ts.map +1 -0
- package/dist/mcp-main.js +116 -0
- package/dist/mcp-main.js.map +1 -0
- package/dist/mcp-server.d.ts +72 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +259 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/model-routing.d.ts +75 -0
- package/dist/model-routing.d.ts.map +1 -0
- package/dist/model-routing.js +108 -0
- package/dist/model-routing.js.map +1 -0
- package/dist/model-transport.d.ts +188 -0
- package/dist/model-transport.d.ts.map +1 -0
- package/dist/model-transport.js +625 -0
- package/dist/model-transport.js.map +1 -0
- package/dist/notify-cadence.d.ts +55 -0
- package/dist/notify-cadence.d.ts.map +1 -0
- package/dist/notify-cadence.js +68 -0
- package/dist/notify-cadence.js.map +1 -0
- package/dist/notify-channel.d.ts +69 -0
- package/dist/notify-channel.d.ts.map +1 -0
- package/dist/notify-channel.js +151 -0
- package/dist/notify-channel.js.map +1 -0
- package/dist/notify.d.ts +71 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +125 -0
- package/dist/notify.js.map +1 -0
- package/dist/observation-inventory.d.ts +65 -0
- package/dist/observation-inventory.d.ts.map +1 -0
- package/dist/observation-inventory.js +139 -0
- package/dist/observation-inventory.js.map +1 -0
- package/dist/owned-children.d.ts +45 -0
- package/dist/owned-children.d.ts.map +1 -0
- package/dist/owned-children.js +64 -0
- package/dist/owned-children.js.map +1 -0
- package/dist/packet-for-goal.d.ts +19 -0
- package/dist/packet-for-goal.d.ts.map +1 -0
- package/dist/packet-for-goal.js +32 -0
- package/dist/packet-for-goal.js.map +1 -0
- package/dist/pair-cmd.d.ts +85 -0
- package/dist/pair-cmd.d.ts.map +1 -0
- package/dist/pair-cmd.js +205 -0
- package/dist/pair-cmd.js.map +1 -0
- package/dist/partial-asker.d.ts +96 -0
- package/dist/partial-asker.d.ts.map +1 -0
- package/dist/partial-asker.js +117 -0
- package/dist/partial-asker.js.map +1 -0
- package/dist/pdf-text-lines.d.ts +17 -0
- package/dist/pdf-text-lines.d.ts.map +1 -0
- package/dist/pdf-text-lines.js +70 -0
- package/dist/pdf-text-lines.js.map +1 -0
- package/dist/pdf-text-worker.d.ts +2 -0
- package/dist/pdf-text-worker.d.ts.map +1 -0
- package/dist/pdf-text-worker.js +81 -0
- package/dist/pdf-text-worker.js.map +1 -0
- package/dist/pdf-text.d.ts +56 -0
- package/dist/pdf-text.d.ts.map +1 -0
- package/dist/pdf-text.js +64 -0
- package/dist/pdf-text.js.map +1 -0
- package/dist/pending-action.d.ts +154 -0
- package/dist/pending-action.d.ts.map +1 -0
- package/dist/pending-action.js +148 -0
- package/dist/pending-action.js.map +1 -0
- package/dist/preemptor.d.ts +40 -0
- package/dist/preemptor.d.ts.map +1 -0
- package/dist/preemptor.js +49 -0
- package/dist/preemptor.js.map +1 -0
- package/dist/programme-mode.d.ts +29 -0
- package/dist/programme-mode.d.ts.map +1 -0
- package/dist/programme-mode.js +50 -0
- package/dist/programme-mode.js.map +1 -0
- package/dist/progress-view.d.ts +14 -0
- package/dist/progress-view.d.ts.map +1 -0
- package/dist/progress-view.js +114 -0
- package/dist/progress-view.js.map +1 -0
- package/dist/project-graph-builder.d.ts +81 -0
- package/dist/project-graph-builder.d.ts.map +1 -0
- package/dist/project-graph-builder.js +246 -0
- package/dist/project-graph-builder.js.map +1 -0
- package/dist/project-graph-runtime.d.ts +86 -0
- package/dist/project-graph-runtime.d.ts.map +1 -0
- package/dist/project-graph-runtime.js +112 -0
- package/dist/project-graph-runtime.js.map +1 -0
- package/dist/project-index-builder.d.ts +96 -0
- package/dist/project-index-builder.d.ts.map +1 -0
- package/dist/project-index-builder.js +298 -0
- package/dist/project-index-builder.js.map +1 -0
- package/dist/project-index-facts.d.ts +51 -0
- package/dist/project-index-facts.d.ts.map +1 -0
- package/dist/project-index-facts.js +117 -0
- package/dist/project-index-facts.js.map +1 -0
- package/dist/project-index-store.d.ts +97 -0
- package/dist/project-index-store.d.ts.map +1 -0
- package/dist/project-index-store.js +140 -0
- package/dist/project-index-store.js.map +1 -0
- package/dist/project-memory-store.d.ts +127 -0
- package/dist/project-memory-store.d.ts.map +1 -0
- package/dist/project-memory-store.js +302 -0
- package/dist/project-memory-store.js.map +1 -0
- package/dist/proposal-store.d.ts +14 -0
- package/dist/proposal-store.d.ts.map +1 -0
- package/dist/proposal-store.js +19 -0
- package/dist/proposal-store.js.map +1 -0
- package/dist/prover.d.ts +80 -0
- package/dist/prover.d.ts.map +1 -0
- package/dist/prover.js +137 -0
- package/dist/prover.js.map +1 -0
- package/dist/provider-identity-store.d.ts +34 -0
- package/dist/provider-identity-store.d.ts.map +1 -0
- package/dist/provider-identity-store.js +72 -0
- package/dist/provider-identity-store.js.map +1 -0
- package/dist/provider-identity.d.ts +104 -0
- package/dist/provider-identity.d.ts.map +1 -0
- package/dist/provider-identity.js +167 -0
- package/dist/provider-identity.js.map +1 -0
- package/dist/provider-limit.d.ts +79 -0
- package/dist/provider-limit.d.ts.map +1 -0
- package/dist/provider-limit.js +148 -0
- package/dist/provider-limit.js.map +1 -0
- package/dist/provider-preflight.d.ts +171 -0
- package/dist/provider-preflight.d.ts.map +1 -0
- package/dist/provider-preflight.js +395 -0
- package/dist/provider-preflight.js.map +1 -0
- package/dist/provider-state.d.ts +120 -0
- package/dist/provider-state.d.ts.map +1 -0
- package/dist/provider-state.js +182 -0
- package/dist/provider-state.js.map +1 -0
- package/dist/providers.d.ts +132 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +161 -0
- package/dist/providers.js.map +1 -0
- package/dist/publication-recorder.d.ts +117 -0
- package/dist/publication-recorder.d.ts.map +1 -0
- package/dist/publication-recorder.js +124 -0
- package/dist/publication-recorder.js.map +1 -0
- package/dist/pursuit-delivery.d.ts +24 -0
- package/dist/pursuit-delivery.d.ts.map +1 -0
- package/dist/pursuit-delivery.js +38 -0
- package/dist/pursuit-delivery.js.map +1 -0
- package/dist/queue-store.d.ts +132 -0
- package/dist/queue-store.d.ts.map +1 -0
- package/dist/queue-store.js +185 -0
- package/dist/queue-store.js.map +1 -0
- package/dist/queue-summary.d.ts +14 -0
- package/dist/queue-summary.d.ts.map +1 -0
- package/dist/queue-summary.js +82 -0
- package/dist/queue-summary.js.map +1 -0
- package/dist/queue-view.d.ts +20 -0
- package/dist/queue-view.d.ts.map +1 -0
- package/dist/queue-view.js +163 -0
- package/dist/queue-view.js.map +1 -0
- package/dist/queue-write-lease.d.ts +106 -0
- package/dist/queue-write-lease.d.ts.map +1 -0
- package/dist/queue-write-lease.js +282 -0
- package/dist/queue-write-lease.js.map +1 -0
- package/dist/rails-home.d.ts +162 -0
- package/dist/rails-home.d.ts.map +1 -0
- package/dist/rails-home.js +452 -0
- package/dist/rails-home.js.map +1 -0
- package/dist/rails-migrations.d.ts +75 -0
- package/dist/rails-migrations.d.ts.map +1 -0
- package/dist/rails-migrations.js +199 -0
- package/dist/rails-migrations.js.map +1 -0
- package/dist/rails-stores.d.ts +49 -0
- package/dist/rails-stores.d.ts.map +1 -0
- package/dist/rails-stores.js +100 -0
- package/dist/rails-stores.js.map +1 -0
- package/dist/reaper.d.ts +69 -0
- package/dist/reaper.d.ts.map +1 -0
- package/dist/reaper.js +152 -0
- package/dist/reaper.js.map +1 -0
- package/dist/record-store.d.ts +36 -0
- package/dist/record-store.d.ts.map +1 -0
- package/dist/record-store.js +78 -0
- package/dist/record-store.js.map +1 -0
- package/dist/recovery-io.d.ts +50 -0
- package/dist/recovery-io.d.ts.map +1 -0
- package/dist/recovery-io.js +122 -0
- package/dist/recovery-io.js.map +1 -0
- package/dist/recovery.d.ts +146 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +110 -0
- package/dist/recovery.js.map +1 -0
- package/dist/redraw.d.ts +34 -0
- package/dist/redraw.d.ts.map +1 -0
- package/dist/redraw.js +62 -0
- package/dist/redraw.js.map +1 -0
- package/dist/rejected-evidence.d.ts +255 -0
- package/dist/rejected-evidence.d.ts.map +1 -0
- package/dist/rejected-evidence.js +324 -0
- package/dist/rejected-evidence.js.map +1 -0
- package/dist/report-cmd.d.ts +32 -0
- package/dist/report-cmd.d.ts.map +1 -0
- package/dist/report-cmd.js +201 -0
- package/dist/report-cmd.js.map +1 -0
- package/dist/repos-cmd.d.ts +80 -0
- package/dist/repos-cmd.d.ts.map +1 -0
- package/dist/repos-cmd.js +240 -0
- package/dist/repos-cmd.js.map +1 -0
- package/dist/request-body-shape.d.ts +93 -0
- package/dist/request-body-shape.d.ts.map +1 -0
- package/dist/request-body-shape.js +407 -0
- package/dist/request-body-shape.js.map +1 -0
- package/dist/requirement-claims.d.ts +89 -0
- package/dist/requirement-claims.d.ts.map +1 -0
- package/dist/requirement-claims.js +92 -0
- package/dist/requirement-claims.js.map +1 -0
- package/dist/retention-apply-runtime.d.ts +105 -0
- package/dist/retention-apply-runtime.d.ts.map +1 -0
- package/dist/retention-apply-runtime.js +269 -0
- package/dist/retention-apply-runtime.js.map +1 -0
- package/dist/reverify.d.ts +41 -0
- package/dist/reverify.d.ts.map +1 -0
- package/dist/reverify.js +69 -0
- package/dist/reverify.js.map +1 -0
- package/dist/round-records.d.ts +65 -0
- package/dist/round-records.d.ts.map +1 -0
- package/dist/round-records.js +61 -0
- package/dist/round-records.js.map +1 -0
- package/dist/round-runner.d.ts +924 -0
- package/dist/round-runner.d.ts.map +1 -0
- package/dist/round-runner.js +1693 -0
- package/dist/round-runner.js.map +1 -0
- package/dist/run-approval.d.ts +180 -0
- package/dist/run-approval.d.ts.map +1 -0
- package/dist/run-approval.js +199 -0
- package/dist/run-approval.js.map +1 -0
- package/dist/run-cmd.d.ts +359 -0
- package/dist/run-cmd.d.ts.map +1 -0
- package/dist/run-cmd.js +4418 -0
- package/dist/run-cmd.js.map +1 -0
- package/dist/run-delivery.d.ts +71 -0
- package/dist/run-delivery.d.ts.map +1 -0
- package/dist/run-delivery.js +104 -0
- package/dist/run-delivery.js.map +1 -0
- package/dist/run-ended.d.ts +75 -0
- package/dist/run-ended.d.ts.map +1 -0
- package/dist/run-ended.js +27 -0
- package/dist/run-ended.js.map +1 -0
- package/dist/run-ending-locator.d.ts +125 -0
- package/dist/run-ending-locator.d.ts.map +1 -0
- package/dist/run-ending-locator.js +133 -0
- package/dist/run-ending-locator.js.map +1 -0
- package/dist/run-launcher.d.ts +459 -0
- package/dist/run-launcher.d.ts.map +1 -0
- package/dist/run-launcher.js +652 -0
- package/dist/run-launcher.js.map +1 -0
- package/dist/run-lease.d.ts +208 -0
- package/dist/run-lease.d.ts.map +1 -0
- package/dist/run-lease.js +301 -0
- package/dist/run-lease.js.map +1 -0
- package/dist/run-refusal-marks.d.ts +189 -0
- package/dist/run-refusal-marks.d.ts.map +1 -0
- package/dist/run-refusal-marks.js +249 -0
- package/dist/run-refusal-marks.js.map +1 -0
- package/dist/run-start-marks.d.ts +153 -0
- package/dist/run-start-marks.d.ts.map +1 -0
- package/dist/run-start-marks.js +269 -0
- package/dist/run-start-marks.js.map +1 -0
- package/dist/scan-cmd.d.ts +14 -0
- package/dist/scan-cmd.d.ts.map +1 -0
- package/dist/scan-cmd.js +270 -0
- package/dist/scan-cmd.js.map +1 -0
- package/dist/scan-events.d.ts +50 -0
- package/dist/scan-events.d.ts.map +1 -0
- package/dist/scan-events.js +91 -0
- package/dist/scan-events.js.map +1 -0
- package/dist/scan.d.ts +191 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +417 -0
- package/dist/scan.js.map +1 -0
- package/dist/scope-rule.d.ts +148 -0
- package/dist/scope-rule.d.ts.map +1 -0
- package/dist/scope-rule.js +121 -0
- package/dist/scope-rule.js.map +1 -0
- package/dist/self-repo-id.d.ts +18 -0
- package/dist/self-repo-id.d.ts.map +1 -0
- package/dist/self-repo-id.js +70 -0
- package/dist/self-repo-id.js.map +1 -0
- package/dist/serve-cmd.d.ts +115 -0
- package/dist/serve-cmd.d.ts.map +1 -0
- package/dist/serve-cmd.js +505 -0
- package/dist/serve-cmd.js.map +1 -0
- package/dist/serve.d.ts +167 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +336 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-client.d.ts +766 -0
- package/dist/server-client.d.ts.map +1 -0
- package/dist/server-client.js +475 -0
- package/dist/server-client.js.map +1 -0
- package/dist/session-adapter-runtime.d.ts +195 -0
- package/dist/session-adapter-runtime.d.ts.map +1 -0
- package/dist/session-adapter-runtime.js +373 -0
- package/dist/session-adapter-runtime.js.map +1 -0
- package/dist/session-checkpoint-runtime.d.ts +62 -0
- package/dist/session-checkpoint-runtime.d.ts.map +1 -0
- package/dist/session-checkpoint-runtime.js +268 -0
- package/dist/session-checkpoint-runtime.js.map +1 -0
- package/dist/session-control-transport.d.ts +106 -0
- package/dist/session-control-transport.d.ts.map +1 -0
- package/dist/session-control-transport.js +232 -0
- package/dist/session-control-transport.js.map +1 -0
- package/dist/session-observation-store.d.ts +98 -0
- package/dist/session-observation-store.d.ts.map +1 -0
- package/dist/session-observation-store.js +155 -0
- package/dist/session-observation-store.js.map +1 -0
- package/dist/session-observe-runtime.d.ts +123 -0
- package/dist/session-observe-runtime.d.ts.map +1 -0
- package/dist/session-observe-runtime.js +317 -0
- package/dist/session-observe-runtime.js.map +1 -0
- package/dist/session-store.d.ts +98 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +116 -0
- package/dist/session-store.js.map +1 -0
- package/dist/sessions-cmd.d.ts +202 -0
- package/dist/sessions-cmd.d.ts.map +1 -0
- package/dist/sessions-cmd.js +609 -0
- package/dist/sessions-cmd.js.map +1 -0
- package/dist/settings-overlay.d.ts +53 -0
- package/dist/settings-overlay.d.ts.map +1 -0
- package/dist/settings-overlay.js +175 -0
- package/dist/settings-overlay.js.map +1 -0
- package/dist/setup-prompt.d.ts +34 -0
- package/dist/setup-prompt.d.ts.map +1 -0
- package/dist/setup-prompt.js +92 -0
- package/dist/setup-prompt.js.map +1 -0
- package/dist/setup.d.ts +103 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +283 -0
- package/dist/setup.js.map +1 -0
- package/dist/shared-grants.d.ts +164 -0
- package/dist/shared-grants.d.ts.map +1 -0
- package/dist/shared-grants.js +242 -0
- package/dist/shared-grants.js.map +1 -0
- package/dist/signals.d.ts +55 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +85 -0
- package/dist/signals.js.map +1 -0
- package/dist/source-cmd.d.ts +201 -0
- package/dist/source-cmd.d.ts.map +1 -0
- package/dist/source-cmd.js +684 -0
- package/dist/source-cmd.js.map +1 -0
- package/dist/source-verdict.d.ts +99 -0
- package/dist/source-verdict.d.ts.map +1 -0
- package/dist/source-verdict.js +182 -0
- package/dist/source-verdict.js.map +1 -0
- package/dist/spend-ledger.d.ts +350 -0
- package/dist/spend-ledger.d.ts.map +1 -0
- package/dist/spend-ledger.js +546 -0
- package/dist/spend-ledger.js.map +1 -0
- package/dist/stale-run-sweep.d.ts +79 -0
- package/dist/stale-run-sweep.d.ts.map +1 -0
- package/dist/stale-run-sweep.js +116 -0
- package/dist/stale-run-sweep.js.map +1 -0
- package/dist/start-attempts.d.ts +385 -0
- package/dist/start-attempts.d.ts.map +1 -0
- package/dist/start-attempts.js +613 -0
- package/dist/start-attempts.js.map +1 -0
- package/dist/status-cmd.d.ts +28 -0
- package/dist/status-cmd.d.ts.map +1 -0
- package/dist/status-cmd.js +116 -0
- package/dist/status-cmd.js.map +1 -0
- package/dist/stop-follow-up.d.ts +107 -0
- package/dist/stop-follow-up.d.ts.map +1 -0
- package/dist/stop-follow-up.js +172 -0
- package/dist/stop-follow-up.js.map +1 -0
- package/dist/surface-lease.d.ts +118 -0
- package/dist/surface-lease.d.ts.map +1 -0
- package/dist/surface-lease.js +485 -0
- package/dist/surface-lease.js.map +1 -0
- package/dist/sync.d.ts +54 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +93 -0
- package/dist/sync.js.map +1 -0
- package/dist/syncing-ledger.d.ts +45 -0
- package/dist/syncing-ledger.d.ts.map +1 -0
- package/dist/syncing-ledger.js +53 -0
- package/dist/syncing-ledger.js.map +1 -0
- package/dist/temp-fixtures.d.ts +68 -0
- package/dist/temp-fixtures.d.ts.map +1 -0
- package/dist/temp-fixtures.js +38 -0
- package/dist/temp-fixtures.js.map +1 -0
- package/dist/token-window.d.ts +84 -0
- package/dist/token-window.d.ts.map +1 -0
- package/dist/token-window.js +143 -0
- package/dist/token-window.js.map +1 -0
- package/dist/tool-bridge.d.ts +177 -0
- package/dist/tool-bridge.d.ts.map +1 -0
- package/dist/tool-bridge.js +329 -0
- package/dist/tool-bridge.js.map +1 -0
- package/dist/tool-call-record.d.ts +197 -0
- package/dist/tool-call-record.d.ts.map +1 -0
- package/dist/tool-call-record.js +276 -0
- package/dist/tool-call-record.js.map +1 -0
- package/dist/tool-protocol.d.ts +135 -0
- package/dist/tool-protocol.d.ts.map +1 -0
- package/dist/tool-protocol.js +104 -0
- package/dist/tool-protocol.js.map +1 -0
- package/dist/tool-worker.d.ts +3 -0
- package/dist/tool-worker.d.ts.map +1 -0
- package/dist/tool-worker.js +478 -0
- package/dist/tool-worker.js.map +1 -0
- package/dist/toolchain-mirror.d.ts +86 -0
- package/dist/toolchain-mirror.d.ts.map +1 -0
- package/dist/toolchain-mirror.js +307 -0
- package/dist/toolchain-mirror.js.map +1 -0
- package/dist/trusted-git.d.ts +243 -0
- package/dist/trusted-git.d.ts.map +1 -0
- package/dist/trusted-git.js +920 -0
- package/dist/trusted-git.js.map +1 -0
- package/dist/ui.d.ts +76 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +118 -0
- package/dist/ui.js.map +1 -0
- package/dist/untrusted-exec.d.ts +275 -0
- package/dist/untrusted-exec.d.ts.map +1 -0
- package/dist/untrusted-exec.js +479 -0
- package/dist/untrusted-exec.js.map +1 -0
- package/dist/untrusted-gate.d.ts +73 -0
- package/dist/untrusted-gate.d.ts.map +1 -0
- package/dist/untrusted-gate.js +226 -0
- package/dist/untrusted-gate.js.map +1 -0
- package/dist/uploader.d.ts +153 -0
- package/dist/uploader.d.ts.map +1 -0
- package/dist/uploader.js +204 -0
- package/dist/uploader.js.map +1 -0
- package/dist/verifier.d.ts +66 -0
- package/dist/verifier.d.ts.map +1 -0
- package/dist/verifier.js +170 -0
- package/dist/verifier.js.map +1 -0
- package/dist/verify-apply.d.ts +26 -0
- package/dist/verify-apply.d.ts.map +1 -0
- package/dist/verify-apply.js +36 -0
- package/dist/verify-apply.js.map +1 -0
- package/dist/verify-cmd.d.ts +44 -0
- package/dist/verify-cmd.d.ts.map +1 -0
- package/dist/verify-cmd.js +125 -0
- package/dist/verify-cmd.js.map +1 -0
- package/dist/verify-pass.d.ts +73 -0
- package/dist/verify-pass.d.ts.map +1 -0
- package/dist/verify-pass.js +103 -0
- package/dist/verify-pass.js.map +1 -0
- package/dist/welcome.d.ts +43 -0
- package/dist/welcome.d.ts.map +1 -0
- package/dist/welcome.js +116 -0
- package/dist/welcome.js.map +1 -0
- package/dist/workspace-provisioner.d.ts +65 -0
- package/dist/workspace-provisioner.d.ts.map +1 -0
- package/dist/workspace-provisioner.js +66 -0
- package/dist/workspace-provisioner.js.map +1 -0
- package/dist/workspace-quarantine.d.ts +64 -0
- package/dist/workspace-quarantine.d.ts.map +1 -0
- package/dist/workspace-quarantine.js +156 -0
- package/dist/workspace-quarantine.js.map +1 -0
- package/dist/workspace-residue-sweep.d.ts +113 -0
- package/dist/workspace-residue-sweep.d.ts.map +1 -0
- package/dist/workspace-residue-sweep.js +158 -0
- package/dist/workspace-residue-sweep.js.map +1 -0
- package/dist/workspace.d.ts +639 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +2026 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +52 -4
- package/win/CredProbe.cs +64 -0
- package/win/FakeClaude.cs +56 -0
- package/win/HandleProbe.cs +116 -0
- package/win/TokenProbe.cs +53 -0
- package/win/appcontainer.ps1 +500 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { type AnyEvent } from '@looply/core';
|
|
2
|
+
import type { LedgerFs } from './ledger-store';
|
|
3
|
+
/**
|
|
4
|
+
* Sending the server what a previous process never managed to.
|
|
5
|
+
*
|
|
6
|
+
* The ledger on disk is the record; the server is a mirror that may lag. Until
|
|
7
|
+
* now the lag could be permanent: acknowledged heads lived in memory, so a run
|
|
8
|
+
* that exited with events still buffered — or one that was killed — left them
|
|
9
|
+
* on disk with nothing that would ever look at them again. `looply report` had
|
|
10
|
+
* the whole run and the phone had a hole in it.
|
|
11
|
+
*
|
|
12
|
+
* Replay closes that by doing the obvious thing: read the ledger, skip what a
|
|
13
|
+
* durable cursor proves the server holds, and hand the rest to the uploader in
|
|
14
|
+
* its normal order. Nothing here mints ids, renumbers, or rewrites an event —
|
|
15
|
+
* a replayed event is byte-for-byte the original, which is what lets ingest
|
|
16
|
+
* recognise it by `(runId, seq)` and answer "duplicate" instead of storing it
|
|
17
|
+
* twice. That idempotency is why replaying too much is safe and replaying too
|
|
18
|
+
* little is not.
|
|
19
|
+
*/
|
|
20
|
+
export interface ReplaySink {
|
|
21
|
+
enqueue(event: AnyEvent): void;
|
|
22
|
+
durableHead(runId: string): number;
|
|
23
|
+
}
|
|
24
|
+
export interface ReplayResult {
|
|
25
|
+
/** Events handed to the uploader. */
|
|
26
|
+
replayed: number;
|
|
27
|
+
/** Events the cursor showed were already held. */
|
|
28
|
+
skipped: number;
|
|
29
|
+
/** Ledger lines too damaged to parse. Reported, never fatal. */
|
|
30
|
+
damaged: number;
|
|
31
|
+
/**
|
|
32
|
+
* Ledger lines that ARE events, naming a kind this build has no name for.
|
|
33
|
+
*
|
|
34
|
+
* Not damaged, and counted apart from M8-12: the uploader cannot send what it
|
|
35
|
+
* cannot type, but there is nothing torn and nothing to repair — the line was
|
|
36
|
+
* written by a newer looply.
|
|
37
|
+
*/
|
|
38
|
+
fromNewerBuild: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* How many events to hand over in one pass.
|
|
42
|
+
*
|
|
43
|
+
* A machine that was offline all night can have a very long ledger, and the
|
|
44
|
+
* uploader's buffer sheds the oldest when it overflows — so pouring the whole
|
|
45
|
+
* backlog in at once would drop the beginning of the very history we are trying
|
|
46
|
+
* to restore. Bounded per pass, the daemon simply replays again on its next
|
|
47
|
+
* tick until there is nothing left.
|
|
48
|
+
*/
|
|
49
|
+
export declare const DEFAULT_REPLAY_LIMIT = 1000;
|
|
50
|
+
export declare function replayLedger(stateDir: string, fs: LedgerFs, sink: ReplaySink, limit?: number): Promise<ReplayResult>;
|
|
51
|
+
/**
|
|
52
|
+
* A replay the daemon can afford to ask for on every tick.
|
|
53
|
+
*
|
|
54
|
+
* `replayLedger` reads and parses the whole ledger. That is the right thing to
|
|
55
|
+
* do when there is something to send and pure waste when there is not — and on
|
|
56
|
+
* an idle machine there never is. Measured on this machine: roughly 11 ms and
|
|
57
|
+
* 2.3 MiB per pass at ten thousand events, 204 ms and 46 MiB at two hundred
|
|
58
|
+
* thousand. Every five seconds, for ever, because `events.jsonl` is append-only
|
|
59
|
+
* and nothing rotates it.
|
|
60
|
+
*
|
|
61
|
+
* So the pass is skipped when the ledger cannot possibly hold anything new.
|
|
62
|
+
* `LedgerStore.append` is its only writer and it only ever appends, which makes
|
|
63
|
+
* the byte count a signal that changes exactly when the contents do — and a
|
|
64
|
+
* stat costs about 25 microseconds against the read's tens of milliseconds.
|
|
65
|
+
*
|
|
66
|
+
* Two conditions do the load-bearing work, and both are easy to get wrong:
|
|
67
|
+
*
|
|
68
|
+
* The size is taken **before** the read, not after. A size read afterwards
|
|
69
|
+
* could include an event appended while we were parsing, and remembering it
|
|
70
|
+
* would skip that event for ever. Taken first, the read is guaranteed to have
|
|
71
|
+
* covered at least those bytes, so the worst this can cause is one redundant
|
|
72
|
+
* pass.
|
|
73
|
+
*
|
|
74
|
+
* The guard is armed only by a pass that replayed **nothing**. A pass that
|
|
75
|
+
* stopped at the limit, or one whose events the uploader later shed, has work
|
|
76
|
+
* outstanding that the file's size says nothing about — and skipping the next
|
|
77
|
+
* pass would strand exactly the tail this mechanism exists to recover.
|
|
78
|
+
*
|
|
79
|
+
* This is what the daemon's old `replayDone` should have been: a re-armable
|
|
80
|
+
* memo of the size at which the file was last proved covered, rather than a
|
|
81
|
+
* terminal state. That flag memoised "covered" against nothing, so nothing
|
|
82
|
+
* could ever invalidate it.
|
|
83
|
+
*/
|
|
84
|
+
export declare function makeLedgerReplay(stateDir: string, fs: LedgerFs, limit?: number): (sink: ReplaySink) => Promise<ReplayResult>;
|
|
85
|
+
/**
|
|
86
|
+
* EVERY LEDGER THE MACHINE HOLDS (M5-6).
|
|
87
|
+
*
|
|
88
|
+
* The replay above reads ONE file — the project's ledger. A placed run writes
|
|
89
|
+
* its ledger in its own checkout (M4), and the reaper keeps a died run's
|
|
90
|
+
* records under `retired/` (M4-4); until now those reached the server by
|
|
91
|
+
* nobody, and the measurement said so on every such ledger. This replays each
|
|
92
|
+
* place the caller lists — the same list `looply goal` reads — through the
|
|
93
|
+
* same sink and the same per-run cursor: a run lives on one ledger, so a
|
|
94
|
+
* cursor per run is a cursor per ledger, and nothing is sent twice.
|
|
95
|
+
*
|
|
96
|
+
* Re-listed on every pass, so a checkout provisioned or retired an hour into
|
|
97
|
+
* the night is picked up. One `makeLedgerReplay` per directory, memoised, so
|
|
98
|
+
* each file keeps its own byte-size latch; a place that vanishes drops its
|
|
99
|
+
* memo. The pass limit is SHARED: what one ledger sends is what the next may
|
|
100
|
+
* still send, so one busy ledger cannot pour the uploader's buffer full and
|
|
101
|
+
* shed the others' history. A ledger whose read throws is skipped for the pass
|
|
102
|
+
* and named once — the others still ship — and asked again next pass; it can
|
|
103
|
+
* never be the reason another ledger's events are missed.
|
|
104
|
+
*/
|
|
105
|
+
export interface LedgerPlaceToReplay {
|
|
106
|
+
/** The state directory the ledger sits in. */
|
|
107
|
+
readonly dir: string;
|
|
108
|
+
/** How to name it in a log line. */
|
|
109
|
+
readonly label: string;
|
|
110
|
+
}
|
|
111
|
+
export declare function makeLedgersReplay(places: () => readonly LedgerPlaceToReplay[], fs: LedgerFs, opts?: {
|
|
112
|
+
limit?: number;
|
|
113
|
+
log?: (line: string) => void;
|
|
114
|
+
}): (sink: ReplaySink) => Promise<ReplayResult>;
|
|
115
|
+
//# sourceMappingURL=ledger-replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger-replay.d.ts","sourceRoot":"","sources":["../src/ledger-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAE1C,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,SAAuB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAoCvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ,EACZ,KAAK,SAAuB,GAC3B,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CA4B7C;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,SAAS,mBAAmB,EAAE,EAC5C,EAAE,EAAE,QAAQ,EACZ,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAC1D,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CAmC7C"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_REPLAY_LIMIT = void 0;
|
|
4
|
+
exports.replayLedger = replayLedger;
|
|
5
|
+
exports.makeLedgerReplay = makeLedgerReplay;
|
|
6
|
+
exports.makeLedgersReplay = makeLedgersReplay;
|
|
7
|
+
const core_1 = require("@looply/core");
|
|
8
|
+
/**
|
|
9
|
+
* How many events to hand over in one pass.
|
|
10
|
+
*
|
|
11
|
+
* A machine that was offline all night can have a very long ledger, and the
|
|
12
|
+
* uploader's buffer sheds the oldest when it overflows — so pouring the whole
|
|
13
|
+
* backlog in at once would drop the beginning of the very history we are trying
|
|
14
|
+
* to restore. Bounded per pass, the daemon simply replays again on its next
|
|
15
|
+
* tick until there is nothing left.
|
|
16
|
+
*/
|
|
17
|
+
exports.DEFAULT_REPLAY_LIMIT = 1_000;
|
|
18
|
+
async function replayLedger(stateDir, fs, sink, limit = exports.DEFAULT_REPLAY_LIMIT) {
|
|
19
|
+
// A ledger that cannot be read is not an empty ledger, and this used to
|
|
20
|
+
// return "nothing to replay" for both. That was survivable while the caller
|
|
21
|
+
// treated every quiet pass alike; it is not now, because `makeLedgerReplay`
|
|
22
|
+
// remembers the size at which a pass found nothing left to send. A read that
|
|
23
|
+
// failed — a lock, an exhausted fd table, a scanner holding the file open on
|
|
24
|
+
// Windows — would arm that memo against a file it never looked at, and the
|
|
25
|
+
// tail would then be skipped until something appended to it. So the failure
|
|
26
|
+
// is raised: the daemon catches it, says so once, and asks again next tick.
|
|
27
|
+
//
|
|
28
|
+
// `readFile` resolving to null is a different thing entirely — there is no
|
|
29
|
+
// ledger yet — and stays a quiet, armable zero.
|
|
30
|
+
const text = await fs.readFile(`${stateDir}/events.jsonl`);
|
|
31
|
+
if (text === null || text.length === 0)
|
|
32
|
+
return { replayed: 0, skipped: 0, damaged: 0, fromNewerBuild: 0 };
|
|
33
|
+
// Damage-tolerant, exactly as the ledger's own reader is: a process killed
|
|
34
|
+
// mid-append leaves a partial final line, and losing every durable event
|
|
35
|
+
// before it because the last one is short would be absurd.
|
|
36
|
+
const { events, badLines, fromNewerBuild } = (0, core_1.parseLines)(text);
|
|
37
|
+
let replayed = 0;
|
|
38
|
+
let skipped = 0;
|
|
39
|
+
// Ordered so the uploader receives a run's events in seq order and the
|
|
40
|
+
// durable head can advance one at a time rather than stalling on a gap it
|
|
41
|
+
// only appears to have.
|
|
42
|
+
for (const e of (0, core_1.sortEvents)(events)) {
|
|
43
|
+
if (e.seq <= sink.durableHead(e.runId)) {
|
|
44
|
+
skipped += 1;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (replayed >= limit)
|
|
48
|
+
break;
|
|
49
|
+
sink.enqueue(e);
|
|
50
|
+
replayed += 1;
|
|
51
|
+
}
|
|
52
|
+
return { replayed, skipped, damaged: badLines.length, fromNewerBuild: fromNewerBuild.length };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A replay the daemon can afford to ask for on every tick.
|
|
56
|
+
*
|
|
57
|
+
* `replayLedger` reads and parses the whole ledger. That is the right thing to
|
|
58
|
+
* do when there is something to send and pure waste when there is not — and on
|
|
59
|
+
* an idle machine there never is. Measured on this machine: roughly 11 ms and
|
|
60
|
+
* 2.3 MiB per pass at ten thousand events, 204 ms and 46 MiB at two hundred
|
|
61
|
+
* thousand. Every five seconds, for ever, because `events.jsonl` is append-only
|
|
62
|
+
* and nothing rotates it.
|
|
63
|
+
*
|
|
64
|
+
* So the pass is skipped when the ledger cannot possibly hold anything new.
|
|
65
|
+
* `LedgerStore.append` is its only writer and it only ever appends, which makes
|
|
66
|
+
* the byte count a signal that changes exactly when the contents do — and a
|
|
67
|
+
* stat costs about 25 microseconds against the read's tens of milliseconds.
|
|
68
|
+
*
|
|
69
|
+
* Two conditions do the load-bearing work, and both are easy to get wrong:
|
|
70
|
+
*
|
|
71
|
+
* The size is taken **before** the read, not after. A size read afterwards
|
|
72
|
+
* could include an event appended while we were parsing, and remembering it
|
|
73
|
+
* would skip that event for ever. Taken first, the read is guaranteed to have
|
|
74
|
+
* covered at least those bytes, so the worst this can cause is one redundant
|
|
75
|
+
* pass.
|
|
76
|
+
*
|
|
77
|
+
* The guard is armed only by a pass that replayed **nothing**. A pass that
|
|
78
|
+
* stopped at the limit, or one whose events the uploader later shed, has work
|
|
79
|
+
* outstanding that the file's size says nothing about — and skipping the next
|
|
80
|
+
* pass would strand exactly the tail this mechanism exists to recover.
|
|
81
|
+
*
|
|
82
|
+
* This is what the daemon's old `replayDone` should have been: a re-armable
|
|
83
|
+
* memo of the size at which the file was last proved covered, rather than a
|
|
84
|
+
* terminal state. That flag memoised "covered" against nothing, so nothing
|
|
85
|
+
* could ever invalidate it.
|
|
86
|
+
*/
|
|
87
|
+
function makeLedgerReplay(stateDir, fs, limit = exports.DEFAULT_REPLAY_LIMIT) {
|
|
88
|
+
const path = `${stateDir}/events.jsonl`;
|
|
89
|
+
/** Bytes as of the last pass that proved the file fully covered; null re-reads. */
|
|
90
|
+
let coveredAtBytes = null;
|
|
91
|
+
// The limit may be handed in per pass (M5-6): when many ledgers share one
|
|
92
|
+
// pass, what one has already sent is what the next may still send.
|
|
93
|
+
return async (sink, passLimit = limit) => {
|
|
94
|
+
// A filesystem that cannot answer gets the full read every time: the guard
|
|
95
|
+
// is an optimisation and must never be the reason an event is missed.
|
|
96
|
+
const before = fs.size ? await fs.size(path).catch(() => null) : null;
|
|
97
|
+
if (before !== null && before === coveredAtBytes) {
|
|
98
|
+
return { replayed: 0, skipped: 0, damaged: 0, fromNewerBuild: 0 };
|
|
99
|
+
}
|
|
100
|
+
let r;
|
|
101
|
+
try {
|
|
102
|
+
r = await replayLedger(stateDir, fs, sink, passLimit);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
// Disarm before rethrowing. A pass that failed proved nothing about the
|
|
106
|
+
// file, and leaving a stale `coveredAtBytes` armed would let the *next*
|
|
107
|
+
// pass skip on a size this one never verified.
|
|
108
|
+
coveredAtBytes = null;
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
coveredAtBytes = r.replayed === 0 ? before : null;
|
|
112
|
+
return r;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function makeLedgersReplay(places, fs, opts = {}) {
|
|
116
|
+
const limit = opts.limit ?? exports.DEFAULT_REPLAY_LIMIT;
|
|
117
|
+
const log = opts.log ?? (() => { });
|
|
118
|
+
const replays = new Map();
|
|
119
|
+
const named = new Set();
|
|
120
|
+
return async (sink) => {
|
|
121
|
+
const total = { replayed: 0, skipped: 0, damaged: 0, fromNewerBuild: 0 };
|
|
122
|
+
const listed = places();
|
|
123
|
+
const current = new Set(listed.map((p) => p.dir));
|
|
124
|
+
for (const dir of [...replays.keys()])
|
|
125
|
+
if (!current.has(dir))
|
|
126
|
+
replays.delete(dir);
|
|
127
|
+
let remaining = limit;
|
|
128
|
+
for (const place of listed) {
|
|
129
|
+
if (remaining <= 0)
|
|
130
|
+
break;
|
|
131
|
+
let replay = replays.get(place.dir);
|
|
132
|
+
if (replay === undefined) {
|
|
133
|
+
replay = makeLedgerReplay(place.dir, fs, limit);
|
|
134
|
+
replays.set(place.dir, replay);
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const r = await replay(sink, remaining);
|
|
138
|
+
total.replayed += r.replayed;
|
|
139
|
+
total.skipped += r.skipped;
|
|
140
|
+
total.damaged += r.damaged;
|
|
141
|
+
total.fromNewerBuild += r.fromNewerBuild;
|
|
142
|
+
remaining -= r.replayed;
|
|
143
|
+
named.delete(place.dir);
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
if (!named.has(place.dir)) {
|
|
147
|
+
named.add(place.dir);
|
|
148
|
+
log(`daemon : could not read the ledger at ${place.label} — ${e.message}; the others still ship, and it is asked again next pass`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return total;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=ledger-replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger-replay.js","sourceRoot":"","sources":["../src/ledger-replay.ts"],"names":[],"mappings":";;;AAsDA,oCAyCC;AAmCD,4CAgCC;AA6BD,8CAuCC;AAtOD,uCAAqE;AA2CrE;;;;;;;;GAQG;AACU,QAAA,oBAAoB,GAAG,KAAK,CAAC;AAEnC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,EAAY,EACZ,IAAgB,EAChB,KAAK,GAAG,4BAAoB;IAE5B,wEAAwE;IACxE,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,EAAE;IACF,2EAA2E;IAC3E,gDAAgD;IAChD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,eAAe,CAAC,CAAC;IAC3D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;IAE1G,2EAA2E;IAC3E,yEAAyE;IACzE,2DAA2D;IAC3D,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAA,iBAAU,EAAC,IAAI,CAAC,CAAC;IAE9D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,uEAAuE;IACvE,0EAA0E;IAC1E,wBAAwB;IACxB,KAAK,MAAM,CAAC,IAAI,IAAA,iBAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,CAAC;YACb,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,IAAI,KAAK;YAAE,MAAM;QAC7B,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChB,QAAQ,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;AAChG,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,SAAgB,gBAAgB,CAC9B,QAAgB,EAChB,EAAY,EACZ,KAAK,GAAG,4BAAoB;IAE5B,MAAM,IAAI,GAAG,GAAG,QAAQ,eAAe,CAAC;IACxC,mFAAmF;IACnF,IAAI,cAAc,GAAkB,IAAI,CAAC;IAEzC,0EAA0E;IAC1E,mEAAmE;IACnE,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,EAAE;QACvC,2EAA2E;QAC3E,sEAAsE;QACtE,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtE,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;YACjD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACpE,CAAC;QAED,IAAI,CAAe,CAAC;QACpB,IAAI,CAAC;YACH,CAAC,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,wEAAwE;YACxE,wEAAwE;YACxE,+CAA+C;YAC/C,cAAc,GAAG,IAAI,CAAC;YACtB,MAAM,CAAC,CAAC;QACV,CAAC;QACD,cAAc,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;AACJ,CAAC;AA6BD,SAAgB,iBAAiB,CAC/B,MAA4C,EAC5C,EAAY,EACZ,OAAyD,EAAE;IAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,4BAAoB,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2E,CAAC;IACnG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;QACpB,MAAM,KAAK,GAAiB,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACvF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClF,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,SAAS,IAAI,CAAC;gBAAE,MAAM;YAC1B,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;gBAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACjC,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBACxC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC;gBAC7B,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC3B,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC3B,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC,cAAc,CAAC;gBACzC,SAAS,IAAI,CAAC,CAAC,QAAQ,CAAC;gBACxB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACrB,GAAG,CAAC,0CAA0C,KAAK,CAAC,KAAK,MAAO,CAAW,CAAC,OAAO,0DAA0D,CAAC,CAAC;gBACjJ,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type AnyEvent, type EventKind, type LooplyEvent, type Status } from '@looply/core';
|
|
2
|
+
/**
|
|
3
|
+
* The ledger writer — the only code that puts events on disk.
|
|
4
|
+
*
|
|
5
|
+
* Two files, two contracts. `events.jsonl` is append-only and is the truth;
|
|
6
|
+
* `status.json` is a projection rebuilt from it, rewritten via temp-then-rename
|
|
7
|
+
* so a concurrent reader (the `status` command, the daemon's poller) never sees
|
|
8
|
+
* half a file. All filesystem calls come through {@link LedgerFs}, so every
|
|
9
|
+
* behaviour here is testable without touching disk.
|
|
10
|
+
*/
|
|
11
|
+
export interface LedgerFs {
|
|
12
|
+
/** Resolves to null when the file does not exist. */
|
|
13
|
+
readFile(path: string): Promise<string | null>;
|
|
14
|
+
appendFile(path: string, data: string): Promise<void>;
|
|
15
|
+
writeFile(path: string, data: string): Promise<void>;
|
|
16
|
+
rename(from: string, to: string): Promise<void>;
|
|
17
|
+
/** Recursive; succeeds when the directory already exists. */
|
|
18
|
+
mkdir(path: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* The file's size in bytes, or null when it does not exist.
|
|
21
|
+
*
|
|
22
|
+
* Optional, because it buys speed and not correctness: a store that cannot
|
|
23
|
+
* answer simply pays for the whole read every time. `makeLedgerReplay` uses
|
|
24
|
+
* it to skip a pass over a ledger that cannot have grown — see the note on
|
|
25
|
+
* `append` below, which is what makes a byte count a sound signal here.
|
|
26
|
+
*/
|
|
27
|
+
size?(path: string): Promise<number | null>;
|
|
28
|
+
}
|
|
29
|
+
/** An event as the caller hands it over: everything but `seq`, which the store owns. */
|
|
30
|
+
export type AnyEventInput = {
|
|
31
|
+
[K in EventKind]: Omit<LooplyEvent<K>, 'seq'>;
|
|
32
|
+
}[EventKind];
|
|
33
|
+
export declare class LedgerStore {
|
|
34
|
+
private readonly stateDir;
|
|
35
|
+
private readonly fs;
|
|
36
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
37
|
+
private static writes;
|
|
38
|
+
private readonly nextSeq;
|
|
39
|
+
private status;
|
|
40
|
+
private opened;
|
|
41
|
+
constructor(stateDir: string, fs: LedgerFs);
|
|
42
|
+
private get eventsPath();
|
|
43
|
+
private get statusPath();
|
|
44
|
+
/**
|
|
45
|
+
* Replay whatever is on disk. Damaged lines are skipped, not fatal: a truncated
|
|
46
|
+
* final line is the normal consequence of a process dying mid-append, and the
|
|
47
|
+
* next seq must continue from the last line that survived.
|
|
48
|
+
*/
|
|
49
|
+
open(): Promise<Status>;
|
|
50
|
+
/**
|
|
51
|
+
* Assign the next per-run seq, append the line, then rewrite the projection.
|
|
52
|
+
* Ledger first, projection second: if the process dies between the two, reopen
|
|
53
|
+
* rebuilds `status.json` from events — the other order cannot recover.
|
|
54
|
+
*
|
|
55
|
+
* ⚠️ This is the only writer of `events.jsonl` in the repository, and it only
|
|
56
|
+
* ever appends. `makeLedgerReplay` depends on that: it skips a pass when the
|
|
57
|
+
* file's byte count has not changed. Rotation, compaction or any in-place
|
|
58
|
+
* rewrite would make that guard unsound in the dangerous direction — a
|
|
59
|
+
* rewrite preserving the byte count would be invisible to it.
|
|
60
|
+
*/
|
|
61
|
+
append(input: AnyEventInput): Promise<AnyEvent>;
|
|
62
|
+
/** The in-memory projection; identical to what `status.json` holds after each append. */
|
|
63
|
+
currentStatus(): Status;
|
|
64
|
+
private writeStatus;
|
|
65
|
+
}
|
|
66
|
+
/** The real filesystem, shaped to the injected interface. */
|
|
67
|
+
export declare const nodeLedgerFs: LedgerFs;
|
|
68
|
+
//# sourceMappingURL=ledger-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger-store.d.ts","sourceRoot":"","sources":["../src/ledger-store.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAEtB;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,6DAA6D;IAC7D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7C;AAED,wFAAwF;AACxF,MAAM,MAAM,aAAa,GAAG;KAAG,CAAC,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CAAE,CAAC,SAAS,CAAC,CAAC;AAEzF,qBAAa,WAAW;IASpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE;IATrB,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAS;gBAGJ,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ;IAG/B,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,UAAU,GAErB;IAED;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAY7B;;;;;;;;;;OAUG;IACG,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAerD,yFAAyF;IACzF,aAAa,IAAI,MAAM;YAIT,WAAW;CAU1B;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY,EAAE,QAuB1B,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nodeLedgerFs = exports.LedgerStore = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const core_1 = require("@looply/core");
|
|
6
|
+
class LedgerStore {
|
|
7
|
+
stateDir;
|
|
8
|
+
fs;
|
|
9
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
10
|
+
static writes = 0;
|
|
11
|
+
nextSeq = new Map();
|
|
12
|
+
status = (0, core_1.emptyStatus)();
|
|
13
|
+
opened = false;
|
|
14
|
+
constructor(stateDir, fs) {
|
|
15
|
+
this.stateDir = stateDir;
|
|
16
|
+
this.fs = fs;
|
|
17
|
+
}
|
|
18
|
+
get eventsPath() {
|
|
19
|
+
return `${this.stateDir}/events.jsonl`;
|
|
20
|
+
}
|
|
21
|
+
get statusPath() {
|
|
22
|
+
return `${this.stateDir}/status.json`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Replay whatever is on disk. Damaged lines are skipped, not fatal: a truncated
|
|
26
|
+
* final line is the normal consequence of a process dying mid-append, and the
|
|
27
|
+
* next seq must continue from the last line that survived.
|
|
28
|
+
*/
|
|
29
|
+
async open() {
|
|
30
|
+
await this.fs.mkdir(this.stateDir);
|
|
31
|
+
const text = await this.fs.readFile(this.eventsPath);
|
|
32
|
+
const events = text === null ? [] : (0, core_1.parseLines)(text).events;
|
|
33
|
+
for (const e of events) {
|
|
34
|
+
if (e.seq >= (this.nextSeq.get(e.runId) ?? 0))
|
|
35
|
+
this.nextSeq.set(e.runId, e.seq + 1);
|
|
36
|
+
this.status = (0, core_1.applyEvent)(this.status, e);
|
|
37
|
+
}
|
|
38
|
+
this.opened = true;
|
|
39
|
+
return this.status;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Assign the next per-run seq, append the line, then rewrite the projection.
|
|
43
|
+
* Ledger first, projection second: if the process dies between the two, reopen
|
|
44
|
+
* rebuilds `status.json` from events — the other order cannot recover.
|
|
45
|
+
*
|
|
46
|
+
* ⚠️ This is the only writer of `events.jsonl` in the repository, and it only
|
|
47
|
+
* ever appends. `makeLedgerReplay` depends on that: it skips a pass when the
|
|
48
|
+
* file's byte count has not changed. Rotation, compaction or any in-place
|
|
49
|
+
* rewrite would make that guard unsound in the dangerous direction — a
|
|
50
|
+
* rewrite preserving the byte count would be invisible to it.
|
|
51
|
+
*/
|
|
52
|
+
async append(input) {
|
|
53
|
+
if (!this.opened) {
|
|
54
|
+
// Appending before replay would restart seq at 0 and corrupt the run's
|
|
55
|
+
// `(runId, seq)` uniqueness on disk. Fail loudly instead.
|
|
56
|
+
throw new Error('ledger: append() before open() — seq would restart and collide');
|
|
57
|
+
}
|
|
58
|
+
const seq = this.nextSeq.get(input.runId) ?? 0;
|
|
59
|
+
const event = { ...input, seq };
|
|
60
|
+
await this.fs.appendFile(this.eventsPath, (0, core_1.encodeLine)(event) + '\n');
|
|
61
|
+
this.nextSeq.set(input.runId, seq + 1);
|
|
62
|
+
this.status = (0, core_1.applyEvent)(this.status, event);
|
|
63
|
+
await this.writeStatus();
|
|
64
|
+
return event;
|
|
65
|
+
}
|
|
66
|
+
/** The in-memory projection; identical to what `status.json` holds after each append. */
|
|
67
|
+
currentStatus() {
|
|
68
|
+
return this.status;
|
|
69
|
+
}
|
|
70
|
+
async writeStatus() {
|
|
71
|
+
// The temp name is PRIVATE TO THIS WRITER. A shared `status.json.tmp` is
|
|
72
|
+
// two processes writing one path: the second truncates and rewrites what
|
|
73
|
+
// the first is midway through, and then both rename it into place. The
|
|
74
|
+
// rename is atomic and the file it renames is a splice of two writes, and
|
|
75
|
+
// nothing downstream can tell.
|
|
76
|
+
const tmp = `${this.statusPath}.${process.pid}.${(LedgerStore.writes += 1)}.tmp`;
|
|
77
|
+
await this.fs.writeFile(tmp, JSON.stringify(this.status, null, 2) + '\n');
|
|
78
|
+
await this.fs.rename(tmp, this.statusPath);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.LedgerStore = LedgerStore;
|
|
82
|
+
/** The real filesystem, shaped to the injected interface. */
|
|
83
|
+
exports.nodeLedgerFs = {
|
|
84
|
+
async readFile(path) {
|
|
85
|
+
try {
|
|
86
|
+
return await node_fs_1.promises.readFile(path, 'utf8');
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
if (e.code === 'ENOENT')
|
|
90
|
+
return null;
|
|
91
|
+
throw e;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
appendFile: (path, data) => node_fs_1.promises.appendFile(path, data, 'utf8'),
|
|
95
|
+
writeFile: (path, data) => node_fs_1.promises.writeFile(path, data, 'utf8'),
|
|
96
|
+
rename: (from, to) => node_fs_1.promises.rename(from, to),
|
|
97
|
+
async mkdir(path) {
|
|
98
|
+
await node_fs_1.promises.mkdir(path, { recursive: true });
|
|
99
|
+
},
|
|
100
|
+
async size(path) {
|
|
101
|
+
try {
|
|
102
|
+
return (await node_fs_1.promises.stat(path)).size;
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
if (e.code === 'ENOENT')
|
|
106
|
+
return null;
|
|
107
|
+
throw e;
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=ledger-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger-store.js","sourceRoot":"","sources":["../src/ledger-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { type AttemptOutcome, type ExcludedReason, type ProgressVector, type SafetyObservation } from '@looply/core';
|
|
2
|
+
import { type Item } from '@looply/core';
|
|
3
|
+
/**
|
|
4
|
+
* TURNING WHAT A RUN LEFT BEHIND INTO WHAT IT ACHIEVED.
|
|
5
|
+
*
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
* WHICH FACTS ARE REAL, AND WHICH ARE DELIBERATELY NOT INVENTED
|
|
8
|
+
*
|
|
9
|
+
* The pure `ProgressVector` has room for five kinds of achievement. This
|
|
10
|
+
* producer populates the three this architecture actually establishes, and
|
|
11
|
+
* leaves two empty ON PURPOSE — an empty array here means "this codebase does
|
|
12
|
+
* not record that", not "none of it happened", and the difference matters
|
|
13
|
+
* because a reader who assumed the second would think a passing gate had been
|
|
14
|
+
* ignored.
|
|
15
|
+
*
|
|
16
|
+
* verifiedItemIds REAL. An item reaches `done` on the COMMIT path only, and
|
|
17
|
+
* the commit path is reached only after the deterministic
|
|
18
|
+
* gate passes (`round-runner.ts`, `state: 'done'` is written
|
|
19
|
+
* immediately after `git.commit`). So item state already
|
|
20
|
+
* carries gate success.
|
|
21
|
+
* workRemaining REAL. Counted from item states through the same predicate
|
|
22
|
+
* the run itself uses to decide whether anything is pickable.
|
|
23
|
+
* planRevision REAL, and CARRIED RATHER THAN COUNTED — see the pure file.
|
|
24
|
+
*
|
|
25
|
+
* passingGates REAL SINCE PHASE 6, and the argument for leaving it empty
|
|
26
|
+
* had a hole. It said: "a gate only ever passes on the way
|
|
27
|
+
* to `done`, so a gate that went red→green has already moved
|
|
28
|
+
* `verifiedItemIds`." That is true of every round the gate
|
|
29
|
+
* ENDS — and false of the one that matters. A round whose
|
|
30
|
+
* gate goes GREEN and whose PROVER then refuses is
|
|
31
|
+
* discarded: the deterministic checks genuinely started
|
|
32
|
+
* passing, nothing moved to `done`, and the observation was
|
|
33
|
+
* identical to the round before it. So `no_progress` counted
|
|
34
|
+
* real progress as none, three times in a row, and held the
|
|
35
|
+
* pursuit.
|
|
36
|
+
*
|
|
37
|
+
* ⚠️ IT IS THE STEP NAMES, NOT A COUNT. A count cannot tell
|
|
38
|
+
* "the same two gates passed again" from "a different two
|
|
39
|
+
* passed", and the second is progress while the first is not.
|
|
40
|
+
* provenCriteria EMPTY. No deterministic per-criterion proof exists in this
|
|
41
|
+
* repository yet. Inventing a number here — a percentage, a
|
|
42
|
+
* model's own estimate — is precisely the thing the phase
|
|
43
|
+
* forbids, because it would make progress claimable.
|
|
44
|
+
*
|
|
45
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
+
* THE BOUNDARY IS HALF THE VALUE
|
|
47
|
+
*
|
|
48
|
+
* `observationFor` returns null for anything that could not have advanced the
|
|
49
|
+
* work. A person taking ten minutes over an approval is not ten failed
|
|
50
|
+
* attempts, and a governed execution being reconciled is one authority being
|
|
51
|
+
* carried out rather than a fresh try. Counting either would hold a pursuit for
|
|
52
|
+
* somebody else's lunch break.
|
|
53
|
+
*/
|
|
54
|
+
/** Items belonging to one pursuit. The caller has already narrowed by goal. */
|
|
55
|
+
export interface PursuitItems {
|
|
56
|
+
readonly items: readonly Item[];
|
|
57
|
+
readonly planRevision: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The achievement facts, read off the queue.
|
|
61
|
+
*
|
|
62
|
+
* `done` is the only state that means an item was actually finished — the
|
|
63
|
+
* others are all "not yet" of one kind or another, and `workLeft` is the
|
|
64
|
+
* repository's own reading of what a set of them amounts to.
|
|
65
|
+
*/
|
|
66
|
+
export declare function vectorFor(goalId: string, goalVersion: number, pursuit: PursuitItems, passingGates?: readonly string[]): ProgressVector;
|
|
67
|
+
export interface AttemptFacts {
|
|
68
|
+
readonly goalId: string;
|
|
69
|
+
readonly goalVersion: number;
|
|
70
|
+
readonly ordinal: number;
|
|
71
|
+
readonly runId: string;
|
|
72
|
+
readonly outcome: AttemptOutcome;
|
|
73
|
+
readonly pursuit: PursuitItems;
|
|
74
|
+
/**
|
|
75
|
+
* Gate steps that passed in this attempt, by name.
|
|
76
|
+
*
|
|
77
|
+
* ⚠️ ABSENT IS "NOT RECORDED", NOT "NONE PASSED". The run-level producer
|
|
78
|
+
* cannot say — a run summarises many rounds — so it omits this and the vector
|
|
79
|
+
* is exactly what it always was.
|
|
80
|
+
*/
|
|
81
|
+
readonly passingGates?: readonly string[];
|
|
82
|
+
/**
|
|
83
|
+
* Every gate step that has EVER passed in this pursuit before now.
|
|
84
|
+
*
|
|
85
|
+
* 🔴 WITHOUT THIS, ONE FLAKY GATE STEP TURNS EVERY DETECTOR OFF.
|
|
86
|
+
*
|
|
87
|
+
* `passingGates` was folded into the progress fingerprint raw, and the
|
|
88
|
+
* argument for it is right as far as it goes: a round whose gate goes green
|
|
89
|
+
* and whose prover then refuses IS progress, and recording it as none held
|
|
90
|
+
* pursuits that were moving.
|
|
91
|
+
*
|
|
92
|
+
* But `noProgress` fires only on three IDENTICAL fingerprints in a row. A
|
|
93
|
+
* gate step that flickers — a timeout, a port already in use, a slow
|
|
94
|
+
* container — changes the set every round, so the fingerprint changes every
|
|
95
|
+
* round, so three identical ones never happen. MEASURED: two round facts
|
|
96
|
+
* differing ONLY in `passingGates` produce different fingerprints, and with
|
|
97
|
+
* one flapping step a genuinely stuck pursuit is never held by ANY of the
|
|
98
|
+
* four detectors, for ever.
|
|
99
|
+
*
|
|
100
|
+
* The fix is to make the contribution MONOTONE. Progress is the set GROWING —
|
|
101
|
+
* a step passing for the first time. A step that oscillates green-red-green
|
|
102
|
+
* adds nothing the second time, so the fingerprint settles and the detectors
|
|
103
|
+
* work again.
|
|
104
|
+
*
|
|
105
|
+
* ⚠️ ABSENT IS "THIS CALLER KEEPS NO HISTORY", which reproduces the old
|
|
106
|
+
* behaviour exactly. The run-level producer omits both fields.
|
|
107
|
+
*/
|
|
108
|
+
readonly gatesEverPassed?: readonly string[];
|
|
109
|
+
readonly treeFingerprint: string | null;
|
|
110
|
+
readonly failureSignature: string | null;
|
|
111
|
+
readonly actionFingerprint: string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Why this attempt does not count, or null when it does.
|
|
114
|
+
*
|
|
115
|
+
* 🔴 THE CALLER NAMES THE REASON; THIS FILE DOES NOT GUESS ONE. A producer
|
|
116
|
+
* that inferred "waiting" from the absence of work would eventually infer it
|
|
117
|
+
* wrongly, and the direction it fails in decides whether a person's lunch
|
|
118
|
+
* break becomes a safety incident.
|
|
119
|
+
*/
|
|
120
|
+
readonly excluded: ExcludedReason | null;
|
|
121
|
+
readonly at: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* One observation, or null when this attempt is not the model's to answer for.
|
|
125
|
+
*
|
|
126
|
+
* Null is the common case in a quiet daemon and is not a failure: a tick that
|
|
127
|
+
* held, an approval nobody has answered, a recovery carrying one authority
|
|
128
|
+
* forward. None of those is an attempt that achieved nothing — they are attempts
|
|
129
|
+
* that never happened.
|
|
130
|
+
*/
|
|
131
|
+
export declare function observationFor(facts: AttemptFacts): SafetyObservation | null;
|
|
132
|
+
//# sourceMappingURL=loop-safety-observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-safety-observer.d.ts","sourceRoot":"","sources":["../src/loop-safety-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,YAAY,EACrB,YAAY,GAAE,SAAS,MAAM,EAAO,GACnC,cAAc,CAsBhB;AAOD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,GAAG,IAAI,CA+B5E"}
|