looply-cli 0.0.0-stage → 0.2.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 +2719 -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/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 +54 -6
- 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,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STALE_AFTER_MS = void 0;
|
|
4
|
+
exports.parseStatusFile = parseStatusFile;
|
|
5
|
+
exports.renderStatus = renderStatus;
|
|
6
|
+
const core_1 = require("@looply/core");
|
|
7
|
+
const gate_1 = require("./gate");
|
|
8
|
+
/**
|
|
9
|
+
* `looply status` — a one-screen snapshot read from `status.json` and nothing
|
|
10
|
+
* else (DESIGN §5.2). Not the ledger, not the queue: the projection is the
|
|
11
|
+
* contract, and it is the same file a phone polls. If it cannot answer a
|
|
12
|
+
* question the screen needs, the fix belongs in the projection, never in a
|
|
13
|
+
* side-channel read here that only the CLI would benefit from.
|
|
14
|
+
*
|
|
15
|
+
* Pure text-in, text-out; the filesystem and the clock stay in `bin.ts`.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The longest legal silence in a healthy run is one gate step running to its
|
|
19
|
+
* default timeout, so the stale window is that plus slack. DESIGN §12 case 25:
|
|
20
|
+
* a quiet run must read as STALE, not resting — a silent loop and a healthy
|
|
21
|
+
* one look identical otherwise.
|
|
22
|
+
*/
|
|
23
|
+
exports.STALE_AFTER_MS = (gate_1.DEFAULT_TIMEOUT_S + 300) * 1000;
|
|
24
|
+
function isRecord(v) {
|
|
25
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Shallow shape check only: the writer is our own `LedgerStore`, so this guard
|
|
29
|
+
* exists to catch a foreign or hand-edited file, not to re-validate our schema.
|
|
30
|
+
*/
|
|
31
|
+
function parseStatusFile(text) {
|
|
32
|
+
let v;
|
|
33
|
+
try {
|
|
34
|
+
v = JSON.parse(text);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
if (!isRecord(v))
|
|
40
|
+
return null;
|
|
41
|
+
if (!isRecord(v.totals) || typeof v.totals.rounds !== 'number')
|
|
42
|
+
return null;
|
|
43
|
+
if (!Array.isArray(v.openQuestions))
|
|
44
|
+
return null;
|
|
45
|
+
return v;
|
|
46
|
+
}
|
|
47
|
+
function liveness(s, now) {
|
|
48
|
+
if (!s.live)
|
|
49
|
+
return `ended (${s.stopReason ?? 'unknown'})`;
|
|
50
|
+
if (s.lastEventAt !== null && (0, core_1.isStale)(s, now, exports.STALE_AFTER_MS)) {
|
|
51
|
+
const min = Math.floor((now - Date.parse(s.lastEventAt)) / 60_000);
|
|
52
|
+
return `STALE — no event for ${min}min`;
|
|
53
|
+
}
|
|
54
|
+
return 'live';
|
|
55
|
+
}
|
|
56
|
+
function roundLine(s) {
|
|
57
|
+
if (s.round === null)
|
|
58
|
+
return s.live ? 'round : between rounds' : 'round : none';
|
|
59
|
+
const r = s.round;
|
|
60
|
+
const what = r.title ?? r.itemId ?? '(unknown item)';
|
|
61
|
+
return `round : #${r.n} attempt ${r.attempt} — ${r.state ?? 'picked'} — ${what}`;
|
|
62
|
+
}
|
|
63
|
+
function renderStatus(text, now) {
|
|
64
|
+
if (text === null) {
|
|
65
|
+
return {
|
|
66
|
+
out: 'status : no status.json yet — nothing has run here (try `looply doctor`, then `looply run`)\n',
|
|
67
|
+
code: 1,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const s = parseStatusFile(text);
|
|
71
|
+
if (s === null) {
|
|
72
|
+
// status.json is rewritten via temp-then-rename, so a half-written file
|
|
73
|
+
// cannot exist; unparseable means something other than looply wrote it.
|
|
74
|
+
// Refuse loudly rather than rendering a guess as if it were the run.
|
|
75
|
+
return { out: 'status : status.json is not a looply projection — refusing to guess\n', code: 1 };
|
|
76
|
+
}
|
|
77
|
+
const lines = [];
|
|
78
|
+
/**
|
|
79
|
+
* 🔴 THE SAME WORD THE PHONE SHOWS, FROM THE SAME FUNCTION.
|
|
80
|
+
*
|
|
81
|
+
* This said "none recorded yet" off its own `runId === null` check while the
|
|
82
|
+
* route said nothing at all — so the two surfaces described an unstarted
|
|
83
|
+
* project differently, and the phone's version was wrong (it read as a
|
|
84
|
+
* finished run). `projectStanding` is in core precisely so a CLI-only
|
|
85
|
+
* side-channel cannot grow here: the owner's ruling is one vocabulary for
|
|
86
|
+
* both, and this is the CLI's half of it.
|
|
87
|
+
*/
|
|
88
|
+
const standing = (0, core_1.projectStanding)(s);
|
|
89
|
+
if (standing === 'no-runs-yet') {
|
|
90
|
+
lines.push(`run : ${(0, core_1.describeProjectStanding)(standing).toLowerCase()}`);
|
|
91
|
+
}
|
|
92
|
+
else if (s.runId === null) {
|
|
93
|
+
lines.push('run : none recorded yet');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
lines.push(`run : ${s.runId} on ${s.branch ?? '(no branch)'} — ${liveness(s, now)}`);
|
|
97
|
+
if (s.startedAt !== null)
|
|
98
|
+
lines.push(`started : ${s.startedAt}`);
|
|
99
|
+
}
|
|
100
|
+
lines.push(roundLine(s));
|
|
101
|
+
const t = s.totals;
|
|
102
|
+
lines.push(`tallies : ${t.rounds} rounds — ${t.committed} committed · ${t.discarded} discarded · ${t.abandoned} abandoned`);
|
|
103
|
+
if (s.lastOutcomes.length > 0)
|
|
104
|
+
lines.push(`recent : ${s.lastOutcomes.join(', ')}`);
|
|
105
|
+
if (s.openQuestions.length === 0) {
|
|
106
|
+
lines.push('questions: none open');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
lines.push('questions:');
|
|
110
|
+
for (const q of s.openQuestions) {
|
|
111
|
+
lines.push(` - [${q.qId}] ${q.text} (default ${q.default}, by ${q.deadline})`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return { out: lines.join('\n') + '\n', code: 0 };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=status-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-cmd.js","sourceRoot":"","sources":["../src/status-cmd.ts"],"names":[],"mappings":";;;AAkCA,0CAWC;AAkBD,oCAkDC;AAjHD,uCAA8F;AAC9F,iCAA2C;AAE3C;;;;;;;;GAQG;AAEH;;;;;GAKG;AACU,QAAA,cAAc,GAAG,CAAC,wBAAiB,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;AAO/D,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAU,CAAC;IACf,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,CAAsB,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,GAAW;IACtC,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,UAAU,CAAC,CAAC,UAAU,IAAI,SAAS,GAAG,CAAC;IAC3D,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,IAAI,IAAA,cAAO,EAAC,CAAC,EAAE,GAAG,EAAE,sBAAc,CAAC,EAAE,CAAC;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QACnE,OAAO,wBAAwB,GAAG,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACpF,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAClB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,gBAAgB,CAAC;IACrD,OAAO,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,QAAQ,MAAM,IAAI,EAAE,CAAC;AACrF,CAAC;AAED,SAAgB,YAAY,CAAC,IAAmB,EAAE,GAAW;IAC3D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;YACL,GAAG,EAAE,gGAAgG;YACrG,IAAI,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACf,wEAAwE;QACxE,wEAAwE;QACxE,qEAAqE;QACrE,OAAO,EAAE,GAAG,EAAE,wEAAwE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpG,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B;;;;;;;;;OASG;IACH,MAAM,QAAQ,GAAG,IAAA,sBAAe,EAAC,CAAC,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,aAAa,IAAA,8BAAuB,EAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,MAAM,IAAI,aAAa,MAAM,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,CACR,aAAa,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC,SAAS,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,CAAC,CAAC,SAAS,YAAY,CAChH,CAAC;IACF,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE FOLLOW-UP ON A RUN THAT IGNORES ITS STOP (M6-5, STATE §5 item 16).
|
|
3
|
+
*
|
|
4
|
+
* A stop is a request. A person's tap on the phone and the coordinator's
|
|
5
|
+
* preemption both write `stop` to a control file the run reads between rounds
|
|
6
|
+
* (round-runner.ts), and the run honours it at its next round boundary: "the
|
|
7
|
+
* run ends after the current round". Nothing followed that up. A run that never
|
|
8
|
+
* reads the file — a runner without a control source, a stuck round, a bug —
|
|
9
|
+
* or that reads it and begins another round anyway kept spending, and the
|
|
10
|
+
* daemon's log said "stop written" and then nothing.
|
|
11
|
+
*
|
|
12
|
+
* This module NOTICES and SAYS SO. Once per sweep cadence the daemon looks at
|
|
13
|
+
* every live run whose control file says `stop`; if the run has begun a round
|
|
14
|
+
* since the request (plus a grace for the read-then-pick race at the boundary),
|
|
15
|
+
* the daemon names the run once in its log and appends ONE `alert` to the run's
|
|
16
|
+
* own ledger — the kind the phone already shows — so it ships on the next flush
|
|
17
|
+
* with no server or app change. Idempotent per (run, requestedAt): the alert on
|
|
18
|
+
* the ledger is the memory, so a restarted daemon does not repeat it.
|
|
19
|
+
*
|
|
20
|
+
* IT DOES NOT KILL. Ending a run by force is a person's act, or a later slice's;
|
|
21
|
+
* this one turns silence into a sentence the person can act on.
|
|
22
|
+
*
|
|
23
|
+
* The decision is pure (`decideStopFollowUp`); the reading and the writing are
|
|
24
|
+
* behind `followUpOnStops`'s deps, with the node ones in `nodeStopFollowUp`.
|
|
25
|
+
*/
|
|
26
|
+
import type { AnyEvent } from '@looply/core';
|
|
27
|
+
import { type ControlRequest } from './control-file';
|
|
28
|
+
import { type AnyEventInput, type LedgerFs } from './ledger-store';
|
|
29
|
+
import { type RunRecord } from './workspace';
|
|
30
|
+
/**
|
|
31
|
+
* A round picked this soon after the request is the boundary race — the runner
|
|
32
|
+
* read the control file, found nothing, and picked before the stop landed —
|
|
33
|
+
* not a run refusing to stop. Fifteen seconds is far longer than that read
|
|
34
|
+
* takes and far shorter than any round.
|
|
35
|
+
*/
|
|
36
|
+
export declare const STOP_GRACE_MS = 15000;
|
|
37
|
+
/** The alert's `code`; the text carries the request's stamp, which is what makes it once-per-request. */
|
|
38
|
+
export declare const STOP_IGNORED_CODE = "stop-ignored";
|
|
39
|
+
export interface StopFollowUpFacts {
|
|
40
|
+
readonly runId: string;
|
|
41
|
+
/** The standing stop, or null when the control file says nothing, `pause` or `resume`. */
|
|
42
|
+
readonly stop: {
|
|
43
|
+
readonly requestedAt: string;
|
|
44
|
+
readonly actor?: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/** The registry still lists the run as live. */
|
|
47
|
+
readonly alive: boolean;
|
|
48
|
+
/** The ledger carries the run's `run.ended`. */
|
|
49
|
+
readonly ended: boolean;
|
|
50
|
+
/** `round.picked` events written after the request plus the grace. */
|
|
51
|
+
readonly roundsBegunAfter: number;
|
|
52
|
+
/** The ledger already carries this request's alert. */
|
|
53
|
+
readonly alreadySaid: boolean;
|
|
54
|
+
}
|
|
55
|
+
export type StopFollowUp = {
|
|
56
|
+
readonly kind: 'nothing';
|
|
57
|
+
readonly because: string;
|
|
58
|
+
} | {
|
|
59
|
+
readonly kind: 'alert';
|
|
60
|
+
readonly code: typeof STOP_IGNORED_CODE;
|
|
61
|
+
readonly text: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function stopIgnoredSentence(runId: string, stop: {
|
|
64
|
+
readonly requestedAt: string;
|
|
65
|
+
readonly actor?: string;
|
|
66
|
+
}, roundsBegunAfter: number): string;
|
|
67
|
+
/** Pure: what the daemon should do about one live run and its control file. */
|
|
68
|
+
export declare function decideStopFollowUp(f: StopFollowUpFacts): StopFollowUp;
|
|
69
|
+
/** The `round.picked` events of `runId` written after `requestedAt` plus the grace. */
|
|
70
|
+
export declare function roundsBegunAfter(events: readonly AnyEvent[], runId: string, requestedAt: string, graceMs?: number): number;
|
|
71
|
+
export declare function hasEnded(events: readonly AnyEvent[], runId: string): boolean;
|
|
72
|
+
export declare function alreadySaid(events: readonly AnyEvent[], runId: string, requestedAt: string): boolean;
|
|
73
|
+
export interface StopFollowUpDeps {
|
|
74
|
+
/** The runs the registry lists as live, the same list `requestControlEverywhere` writes to. */
|
|
75
|
+
readonly live: () => readonly RunRecord[];
|
|
76
|
+
/** The run's standing control request: its addressed file first, then the project's. */
|
|
77
|
+
readonly controlOf: (record: RunRecord) => Promise<ControlRequest | null>;
|
|
78
|
+
/** The run's ledger, or null when it cannot be read this pass. */
|
|
79
|
+
readonly eventsOf: (record: RunRecord) => Promise<readonly AnyEvent[] | null>;
|
|
80
|
+
readonly appendTo: (record: RunRecord, input: AnyEventInput) => Promise<void>;
|
|
81
|
+
readonly projectId: string;
|
|
82
|
+
readonly now: () => number;
|
|
83
|
+
readonly log: (line: string) => void;
|
|
84
|
+
}
|
|
85
|
+
export interface StopFollowUpOutcome {
|
|
86
|
+
readonly runId: string;
|
|
87
|
+
readonly outcome: StopFollowUp | {
|
|
88
|
+
readonly kind: 'unreadable';
|
|
89
|
+
readonly because: string;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** One pass over the live runs. Never throws for one run's sake; each is named on its own. */
|
|
93
|
+
export declare function followUpOnStops(deps: StopFollowUpDeps): Promise<StopFollowUpOutcome[]>;
|
|
94
|
+
/** The ledger's lines, as `LedgerStore.open()` reads them; a malformed line is skipped, not fatal. */
|
|
95
|
+
export declare function parseLedgerText(text: string): AnyEvent[];
|
|
96
|
+
export interface NodeStopFollowUpOptions {
|
|
97
|
+
readonly projectState: string;
|
|
98
|
+
readonly projectId: string;
|
|
99
|
+
readonly fs?: LedgerFs;
|
|
100
|
+
readonly log: (line: string) => void;
|
|
101
|
+
readonly now?: () => number;
|
|
102
|
+
/** The registry's live list by default; a test hands in its own records. */
|
|
103
|
+
readonly live?: () => readonly RunRecord[];
|
|
104
|
+
}
|
|
105
|
+
/** The daemon's follow-up: real registry, real control files, real ledgers. */
|
|
106
|
+
export declare function nodeStopFollowUp(o: NodeStopFollowUpOptions): () => Promise<StopFollowUpOutcome[]>;
|
|
107
|
+
//# sourceMappingURL=stop-follow-up.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-follow-up.d.ts","sourceRoot":"","sources":["../src/stop-follow-up.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STOP_IGNORED_CODE = exports.STOP_GRACE_MS = void 0;
|
|
4
|
+
exports.stopIgnoredSentence = stopIgnoredSentence;
|
|
5
|
+
exports.decideStopFollowUp = decideStopFollowUp;
|
|
6
|
+
exports.roundsBegunAfter = roundsBegunAfter;
|
|
7
|
+
exports.hasEnded = hasEnded;
|
|
8
|
+
exports.alreadySaid = alreadySaid;
|
|
9
|
+
exports.followUpOnStops = followUpOnStops;
|
|
10
|
+
exports.parseLedgerText = parseLedgerText;
|
|
11
|
+
exports.nodeStopFollowUp = nodeStopFollowUp;
|
|
12
|
+
const control_file_1 = require("./control-file");
|
|
13
|
+
const ledger_store_1 = require("./ledger-store");
|
|
14
|
+
const workspace_1 = require("./workspace");
|
|
15
|
+
/**
|
|
16
|
+
* A round picked this soon after the request is the boundary race — the runner
|
|
17
|
+
* read the control file, found nothing, and picked before the stop landed —
|
|
18
|
+
* not a run refusing to stop. Fifteen seconds is far longer than that read
|
|
19
|
+
* takes and far shorter than any round.
|
|
20
|
+
*/
|
|
21
|
+
exports.STOP_GRACE_MS = 15_000;
|
|
22
|
+
/** The alert's `code`; the text carries the request's stamp, which is what makes it once-per-request. */
|
|
23
|
+
exports.STOP_IGNORED_CODE = 'stop-ignored';
|
|
24
|
+
function stopIgnoredSentence(runId, stop, roundsBegunAfter) {
|
|
25
|
+
const who = stop.actor === undefined ? '' : ` by ${stop.actor}`;
|
|
26
|
+
const rounds = `${roundsBegunAfter} round${roundsBegunAfter === 1 ? '' : 's'}`;
|
|
27
|
+
return (`run ${runId} was asked to stop at ${stop.requestedAt}${who} and has begun ${rounds} since — ` +
|
|
28
|
+
'it is not honouring the stop; nothing here ends it');
|
|
29
|
+
}
|
|
30
|
+
/** Pure: what the daemon should do about one live run and its control file. */
|
|
31
|
+
function decideStopFollowUp(f) {
|
|
32
|
+
if (f.stop === null)
|
|
33
|
+
return { kind: 'nothing', because: 'no stop is standing' };
|
|
34
|
+
if (f.ended)
|
|
35
|
+
return { kind: 'nothing', because: 'the run has ended' };
|
|
36
|
+
if (!f.alive)
|
|
37
|
+
return { kind: 'nothing', because: 'the run is not alive — the sweep closes it' };
|
|
38
|
+
if (f.roundsBegunAfter === 0)
|
|
39
|
+
return { kind: 'nothing', because: 'no round has begun since the stop' };
|
|
40
|
+
if (f.alreadySaid)
|
|
41
|
+
return { kind: 'nothing', because: 'already said' };
|
|
42
|
+
return { kind: 'alert', code: exports.STOP_IGNORED_CODE, text: stopIgnoredSentence(f.runId, f.stop, f.roundsBegunAfter) };
|
|
43
|
+
}
|
|
44
|
+
/** The `round.picked` events of `runId` written after `requestedAt` plus the grace. */
|
|
45
|
+
function roundsBegunAfter(events, runId, requestedAt, graceMs = exports.STOP_GRACE_MS) {
|
|
46
|
+
const after = Date.parse(requestedAt) + graceMs;
|
|
47
|
+
if (Number.isNaN(after))
|
|
48
|
+
return 0;
|
|
49
|
+
return events.filter((e) => e.runId === runId && e.kind === 'round.picked' && Date.parse(e.ts) > after).length;
|
|
50
|
+
}
|
|
51
|
+
function hasEnded(events, runId) {
|
|
52
|
+
return events.some((e) => e.runId === runId && e.kind === 'run.ended');
|
|
53
|
+
}
|
|
54
|
+
function alreadySaid(events, runId, requestedAt) {
|
|
55
|
+
return events.some((e) => e.runId === runId &&
|
|
56
|
+
e.kind === 'alert' &&
|
|
57
|
+
e.data.code === exports.STOP_IGNORED_CODE &&
|
|
58
|
+
e.data.text.includes(requestedAt));
|
|
59
|
+
}
|
|
60
|
+
/** One pass over the live runs. Never throws for one run's sake; each is named on its own. */
|
|
61
|
+
async function followUpOnStops(deps) {
|
|
62
|
+
const out = [];
|
|
63
|
+
for (const record of deps.live()) {
|
|
64
|
+
const runId = record.runId;
|
|
65
|
+
let control;
|
|
66
|
+
try {
|
|
67
|
+
control = await deps.controlOf(record);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
deps.log(`daemon : could not read the control file of run ${runId} — ${e.message}`);
|
|
71
|
+
out.push({ runId, outcome: { kind: 'unreadable', because: e.message } });
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const stop = control !== null && control.kind === 'stop'
|
|
75
|
+
? { requestedAt: control.requestedAt, ...(control.actor === undefined ? {} : { actor: control.actor }) }
|
|
76
|
+
: null;
|
|
77
|
+
if (stop === null) {
|
|
78
|
+
out.push({ runId, outcome: { kind: 'nothing', because: 'no stop is standing' } });
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
let events = null;
|
|
82
|
+
let why = 'the ledger could not be read this pass';
|
|
83
|
+
try {
|
|
84
|
+
events = await deps.eventsOf(record);
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
why = e.message;
|
|
88
|
+
}
|
|
89
|
+
if (events === null) {
|
|
90
|
+
// Named every pass it stays unreadable: a ledger nobody can read while a
|
|
91
|
+
// stop stands is itself something a person should hear about.
|
|
92
|
+
deps.log(`daemon : could not read the ledger of run ${runId} to follow up its stop — ${why}`);
|
|
93
|
+
out.push({ runId, outcome: { kind: 'unreadable', because: why } });
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const decided = decideStopFollowUp({
|
|
97
|
+
runId,
|
|
98
|
+
stop,
|
|
99
|
+
alive: true,
|
|
100
|
+
ended: hasEnded(events, runId),
|
|
101
|
+
roundsBegunAfter: roundsBegunAfter(events, runId, stop.requestedAt),
|
|
102
|
+
alreadySaid: alreadySaid(events, runId, stop.requestedAt),
|
|
103
|
+
});
|
|
104
|
+
if (decided.kind === 'alert') {
|
|
105
|
+
const started = events.find((e) => e.runId === runId && e.kind === 'run.started');
|
|
106
|
+
try {
|
|
107
|
+
await deps.appendTo(record, {
|
|
108
|
+
ts: new Date(deps.now()).toISOString(),
|
|
109
|
+
runId,
|
|
110
|
+
projectId: deps.projectId,
|
|
111
|
+
lane: started?.lane ?? 'feature',
|
|
112
|
+
kind: 'alert',
|
|
113
|
+
actor: 'system',
|
|
114
|
+
data: { code: decided.code, severity: 'warn', text: decided.text },
|
|
115
|
+
});
|
|
116
|
+
deps.log(`daemon : ${decided.text}`);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
deps.log(`daemon : could not record that run ${runId} ignores its stop — ${e.message}`);
|
|
120
|
+
out.push({ runId, outcome: { kind: 'unreadable', because: e.message } });
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
out.push({ runId, outcome: decided });
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/** The ledger's lines, as `LedgerStore.open()` reads them; a malformed line is skipped, not fatal. */
|
|
129
|
+
function parseLedgerText(text) {
|
|
130
|
+
const out = [];
|
|
131
|
+
for (const line of text.split('\n')) {
|
|
132
|
+
if (line.trim() === '')
|
|
133
|
+
continue;
|
|
134
|
+
try {
|
|
135
|
+
const parsed = JSON.parse(line);
|
|
136
|
+
if (typeof parsed.runId === 'string' && typeof parsed.kind === 'string' && typeof parsed.ts === 'string') {
|
|
137
|
+
out.push(parsed);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
/* a half-written line; the next pass sees it whole */
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
/** The daemon's follow-up: real registry, real control files, real ledgers. */
|
|
147
|
+
function nodeStopFollowUp(o) {
|
|
148
|
+
const fs = o.fs ?? ledger_store_1.nodeLedgerFs;
|
|
149
|
+
const now = o.now ?? (() => Date.now());
|
|
150
|
+
const project = new control_file_1.ControlStore(o.projectState, fs);
|
|
151
|
+
const deps = {
|
|
152
|
+
live: o.live ?? (() => new workspace_1.RunRegistry(o.projectState).active()),
|
|
153
|
+
controlOf: async (record) => {
|
|
154
|
+
const mine = await control_file_1.ControlStore.addressed(record.stateDir, record.runId, fs).read();
|
|
155
|
+
return mine ?? project.read();
|
|
156
|
+
},
|
|
157
|
+
eventsOf: async (record) => {
|
|
158
|
+
const text = await fs.readFile(`${record.stateDir}/events.jsonl`);
|
|
159
|
+
return text === null ? [] : parseLedgerText(text);
|
|
160
|
+
},
|
|
161
|
+
appendTo: async (record, input) => {
|
|
162
|
+
const ledger = new ledger_store_1.LedgerStore(record.stateDir, fs);
|
|
163
|
+
await ledger.open();
|
|
164
|
+
await ledger.append(input);
|
|
165
|
+
},
|
|
166
|
+
projectId: o.projectId,
|
|
167
|
+
now,
|
|
168
|
+
log: o.log,
|
|
169
|
+
};
|
|
170
|
+
return () => followUpOnStops(deps);
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=stop-follow-up.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-follow-up.js","sourceRoot":"","sources":["../src/stop-follow-up.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type Fence, type SurfaceKey } from '@looply/core';
|
|
2
|
+
/**
|
|
3
|
+
* A LEASE OVER A RESOURCE SURFACE, WITH A FENCE.
|
|
4
|
+
*
|
|
5
|
+
* ⚠️ THE SAME PRIMITIVE `RunLeaseStore` USES, PARAMETERISED — the recon's own
|
|
6
|
+
* words: "`RunLeaseStore` parameterised from `run.lease.json` to
|
|
7
|
+
* `leases/<surfaceKey>.json` is a resource lease with no new correctness
|
|
8
|
+
* argument." What IS new is the fence, and it is new because this lease may
|
|
9
|
+
* expire and the run lease may not.
|
|
10
|
+
*
|
|
11
|
+
* 🔴 EXPIRY EXISTS ONLY HERE, AND ONLY BECAUSE OF THE FENCE.
|
|
12
|
+
*
|
|
13
|
+
* The run lease has no expiry on purpose: a run inside a forty-five-minute
|
|
14
|
+
* model call is legitimately silent, and a lease that timed out would be
|
|
15
|
+
* reclaimed from a run that was working perfectly. A SURFACE lease can expire
|
|
16
|
+
* because a stale holder is caught at the publishing site by comparing two
|
|
17
|
+
* integers — which still works when the thing being checked has been asleep.
|
|
18
|
+
* Take the fence away and the expiry becomes exactly the hazard the run lease
|
|
19
|
+
* refuses to have.
|
|
20
|
+
*/
|
|
21
|
+
/** Where one surface's claims live: `<projectState>/leases/<hash>/`. */
|
|
22
|
+
export declare function surfaceDir(cwd: string, surface: SurfaceKey): string;
|
|
23
|
+
export interface SurfaceClaim {
|
|
24
|
+
readonly surface: SurfaceKey;
|
|
25
|
+
readonly ordinal: number;
|
|
26
|
+
readonly runId: string;
|
|
27
|
+
readonly pid: number;
|
|
28
|
+
readonly host: string;
|
|
29
|
+
readonly acquiredAt: string;
|
|
30
|
+
/** Milliseconds. See the note on expiry above. */
|
|
31
|
+
readonly ttlMs: number;
|
|
32
|
+
}
|
|
33
|
+
export type AcquireOutcome = {
|
|
34
|
+
readonly ok: true;
|
|
35
|
+
readonly held: readonly Fence[];
|
|
36
|
+
} | {
|
|
37
|
+
readonly ok: false;
|
|
38
|
+
readonly because: string;
|
|
39
|
+
readonly blockedBy?: SurfaceKey;
|
|
40
|
+
};
|
|
41
|
+
/** The highest ordinal ever issued for a surface, or null when it cannot be read. */
|
|
42
|
+
export declare function highestIssued(cwd: string, surface: SurfaceKey): number | null;
|
|
43
|
+
/**
|
|
44
|
+
* Who holds this surface right now, if anybody.
|
|
45
|
+
*
|
|
46
|
+
* 🔴 THE LOWEST LIVE ORDINAL HOLDS IT — READING ONLY THE HIGHEST WAS A SECOND
|
|
47
|
+
* WRITER.
|
|
48
|
+
*
|
|
49
|
+
* MEASURED: run_LOW claims ordinal 1 and run_HIGH claims ordinal 2; run_HIGH
|
|
50
|
+
* releases; `holderOf` reads the top, sees it released, and answers NOBODY
|
|
51
|
+
* while run_LOW is alive and unaware. A third run then acquires ordinal 3 and
|
|
52
|
+
* two live holders write the same files.
|
|
53
|
+
*
|
|
54
|
+
* A lease is first-come-first-served, so the holder is the OLDEST claim that is
|
|
55
|
+
* still live. That composes with the fence rather than contradicting it: the
|
|
56
|
+
* fence asks "is my ordinal still the highest ever issued" at the moment of
|
|
57
|
+
* PUBLISHING, which is what catches a holder whose lease lapsed while a newer
|
|
58
|
+
* one took over.
|
|
59
|
+
*
|
|
60
|
+
* ⚠️ AND AN UNREADABLE CLAIM IS A HOLDER. `readClaim` returning null used to
|
|
61
|
+
* mean "free", which is the exact inversion of `mayPublish`'s own rule that
|
|
62
|
+
* unknown is a refusal — and it is reachable by a torn write, a full disk, or a
|
|
63
|
+
* permissions change. A surface this process cannot judge is one it must not
|
|
64
|
+
* take.
|
|
65
|
+
*/
|
|
66
|
+
export declare function holderOf(cwd: string, surface: SurfaceKey, now?: number): SurfaceClaim | null;
|
|
67
|
+
/**
|
|
68
|
+
* TAKE EVERY DECLARED SURFACE, IN ORDER, ALL OR NOTHING.
|
|
69
|
+
*
|
|
70
|
+
* 🔴 THE ORDER IS WHAT MAKES DEADLOCK UNREPRESENTABLE. Lexicographic and
|
|
71
|
+
* total, so two Runs wanting the same pair always contend on the same one
|
|
72
|
+
* first. A Run never acquires a second surface while holding a first — which is
|
|
73
|
+
* the same statement, and is why there is no detector here to write.
|
|
74
|
+
*
|
|
75
|
+
* ⚠️ AND A PARTIAL ACQUISITION IS ROLLED BACK. Holding two of three surfaces
|
|
76
|
+
* while waiting for the third is precisely the state a total order exists to
|
|
77
|
+
* make impossible; leaving one behind on a failure would reintroduce it by the
|
|
78
|
+
* back door.
|
|
79
|
+
*/
|
|
80
|
+
export declare function acquireSurfaces(cwd: string, surfaces: readonly SurfaceKey[], who: {
|
|
81
|
+
runId: string;
|
|
82
|
+
ttlMs: number;
|
|
83
|
+
}, now?: number): AcquireOutcome;
|
|
84
|
+
/**
|
|
85
|
+
* MAY THIS HOLDER PUBLISH?
|
|
86
|
+
*
|
|
87
|
+
* The whole point of the fence, asked at the moment of the write rather than
|
|
88
|
+
* assumed at the moment of the claim.
|
|
89
|
+
*/
|
|
90
|
+
export declare function checkFence(cwd: string, fence: Fence): {
|
|
91
|
+
ok: true;
|
|
92
|
+
} | {
|
|
93
|
+
ok: false;
|
|
94
|
+
because: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Give a surface back.
|
|
98
|
+
*
|
|
99
|
+
* 🔴 IT MARKS, IT DOES NOT DELETE — AND THE FIRST VERSION DELETED, WHICH BROKE
|
|
100
|
+
* THE FENCE OUTRIGHT. Caught by this file's own test.
|
|
101
|
+
*
|
|
102
|
+
* `highestIssued` reads the directory. Remove the claim and the count drops
|
|
103
|
+
* back, so the next acquirer is handed the SAME ordinal — and a revived holder
|
|
104
|
+
* from the previous generation then compares EQUAL to the current one and is
|
|
105
|
+
* allowed to publish. Two writers on one surface, arrived at by giving a
|
|
106
|
+
* surface back politely.
|
|
107
|
+
*
|
|
108
|
+
* "Highest ever issued" has to mean EVER. So the directory is append-only, like
|
|
109
|
+
* every other ledger in this codebase: a release adds `<NNNN>.released` beside
|
|
110
|
+
* the claim rather than taking the claim away. `highestIssued` counts claims;
|
|
111
|
+
* `holderOf` reads the marker.
|
|
112
|
+
*
|
|
113
|
+
* ⚠️ BY IDENTITY, AND BY EXCLUSIVE CREATE. Phase 1 measured what removing a
|
|
114
|
+
* claim by PATH costs: a process that had already lost its hold deleted the
|
|
115
|
+
* winner's, and four processes then held one lock.
|
|
116
|
+
*/
|
|
117
|
+
export declare function releaseSurface(cwd: string, fence: Fence, runId: string): boolean;
|
|
118
|
+
//# sourceMappingURL=surface-lease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface-lease.d.ts","sourceRoot":"","sources":["../src/surface-lease.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,KAAK,EACV,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAKtB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,MAAM,CAanE;AAwED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,KAAK,EAAE,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAEtF,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAgB7E;AAuDD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,GAAE,MAAmB,GAAG,YAAY,GAAG,IAAI,CAwBxG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACrC,GAAG,GAAE,MAAmB,GACvB,cAAc,CAchB;AAwKD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAEnG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAkBhF"}
|