@telora/daemon 0.23.0 → 0.23.5
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/build-info.json +6 -3
- package/dist/completion/review-exit/review-census-record.d.ts.map +1 -1
- package/dist/completion/review-exit/review-census-record.js +1 -0
- package/dist/completion/review-exit/review-census-record.js.map +1 -1
- package/dist/completion/review-exit/review-exit-deps.d.ts +2 -1
- package/dist/completion/review-exit/review-exit-deps.d.ts.map +1 -1
- package/dist/completion/review-exit/review-exit-phase.d.ts +9 -0
- package/dist/completion/review-exit/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit/review-exit-phase.js +5 -4
- package/dist/completion/review-exit/review-exit-phase.js.map +1 -1
- package/dist/completion/review-exit-holds/commit-verdict-release.d.ts.map +1 -1
- package/dist/completion/review-exit-holds/commit-verdict-release.js +34 -12
- package/dist/completion/review-exit-holds/commit-verdict-release.js.map +1 -1
- package/dist/completion/review-exit-holds/review-exit-verdict-gate.d.ts +35 -2
- package/dist/completion/review-exit-holds/review-exit-verdict-gate.d.ts.map +1 -1
- package/dist/completion/review-exit-holds/review-exit-verdict-gate.js +38 -6
- package/dist/completion/review-exit-holds/review-exit-verdict-gate.js.map +1 -1
- package/dist/completion/state-cascade/review-approved-head-gate.d.ts +6 -0
- package/dist/completion/state-cascade/review-approved-head-gate.d.ts.map +1 -1
- package/dist/completion/state-cascade/review-approved-head-gate.js +2 -1
- package/dist/completion/state-cascade/review-approved-head-gate.js.map +1 -1
- package/dist/completion/state-cascade/review-next-step.d.ts.map +1 -1
- package/dist/completion/state-cascade/review-next-step.js +15 -8
- package/dist/completion/state-cascade/review-next-step.js.map +1 -1
- package/dist/completion/state-cascade/standing-approval-convergence.d.ts.map +1 -1
- package/dist/completion/state-cascade/standing-approval-convergence.js +24 -12
- package/dist/completion/state-cascade/standing-approval-convergence.js.map +1 -1
- package/dist/completion/team-exit/status-advance-phase.d.ts.map +1 -1
- package/dist/completion/team-exit/status-advance-phase.js +6 -6
- package/dist/completion/team-exit/status-advance-phase.js.map +1 -1
- package/dist/completion/team-liveness/supervision-firing-record.d.ts +6 -0
- package/dist/completion/team-liveness/supervision-firing-record.d.ts.map +1 -1
- package/dist/completion/team-liveness/supervision-firing-record.js +10 -1
- package/dist/completion/team-liveness/supervision-firing-record.js.map +1 -1
- package/dist/completion/team-outcome/apply-advance.d.ts.map +1 -1
- package/dist/completion/team-outcome/apply-advance.js +3 -2
- package/dist/completion/team-outcome/apply-advance.js.map +1 -1
- package/dist/completion/team-outcome/decide-close-rows.d.ts +9 -0
- package/dist/completion/team-outcome/decide-close-rows.d.ts.map +1 -1
- package/dist/completion/team-outcome/decide-close-rows.js +18 -4
- package/dist/completion/team-outcome/decide-close-rows.js.map +1 -1
- package/dist/completion/team-outcome/delivery-advance-types.d.ts +19 -2
- package/dist/completion/team-outcome/delivery-advance-types.d.ts.map +1 -1
- package/dist/composition/completion-event-context.js +2 -2
- package/dist/composition/completion-event-context.js.map +1 -1
- package/dist/composition/daemon-contexts.d.ts.map +1 -1
- package/dist/composition/daemon-contexts.js +5 -1
- package/dist/composition/daemon-contexts.js.map +1 -1
- package/dist/composition/engine-start-context.d.ts +3 -0
- package/dist/composition/engine-start-context.d.ts.map +1 -0
- package/dist/composition/engine-start-context.js +24 -0
- package/dist/composition/engine-start-context.js.map +1 -0
- package/dist/composition/execution-spawn-context.d.ts.map +1 -1
- package/dist/composition/execution-spawn-context.js +13 -1
- package/dist/composition/execution-spawn-context.js.map +1 -1
- package/dist/composition/runtime-delivery-advance-context.js +3 -3
- package/dist/composition/runtime-delivery-advance-context.js.map +1 -1
- package/dist/composition/runtime-heartbeat-context.d.ts.map +1 -1
- package/dist/composition/runtime-heartbeat-context.js +3 -0
- package/dist/composition/runtime-heartbeat-context.js.map +1 -1
- package/dist/composition/runtime-poll-context.d.ts +29 -2
- package/dist/composition/runtime-poll-context.d.ts.map +1 -1
- package/dist/composition/runtime-poll-context.js +51 -4
- package/dist/composition/runtime-poll-context.js.map +1 -1
- package/dist/composition/runtime-prd-context.d.ts.map +1 -1
- package/dist/composition/runtime-prd-context.js +25 -1
- package/dist/composition/runtime-prd-context.js.map +1 -1
- package/dist/composition/runtime-spawn-pass-context.js +1 -1
- package/dist/composition/runtime-spawn-pass-context.js.map +1 -1
- package/dist/composition/spawn-pass-deps.d.ts +1 -1
- package/dist/composition/spawn-pass-deps.d.ts.map +1 -1
- package/dist/composition/spawn-pass-deps.js +3 -0
- package/dist/composition/spawn-pass-deps.js.map +1 -1
- package/dist/composition/standing-approval-context.d.ts.map +1 -1
- package/dist/composition/standing-approval-context.js +2 -1
- package/dist/composition/standing-approval-context.js.map +1 -1
- package/dist/composition/state-cascade-context.js +1 -1
- package/dist/composition/state-cascade-context.js.map +1 -1
- package/dist/composition/tower-pass-context.d.ts +9 -0
- package/dist/composition/tower-pass-context.d.ts.map +1 -0
- package/dist/composition/tower-pass-context.js +53 -0
- package/dist/composition/tower-pass-context.js.map +1 -0
- package/dist/composition/verify-rework-context.d.ts +26 -2
- package/dist/composition/verify-rework-context.d.ts.map +1 -1
- package/dist/composition/verify-rework-context.js +34 -10
- package/dist/composition/verify-rework-context.js.map +1 -1
- package/dist/config/live-daemon-config.d.ts.map +1 -1
- package/dist/config/live-daemon-config.js +1 -19
- package/dist/config/live-daemon-config.js.map +1 -1
- package/dist/daemon-state/awaiting-slot.d.ts.map +1 -1
- package/dist/daemon-state/awaiting-slot.js +2 -1
- package/dist/daemon-state/awaiting-slot.js.map +1 -1
- package/dist/daemon-state/focus-team-state.js +1 -1
- package/dist/daemon-state/intake-control.d.ts.map +1 -1
- package/dist/daemon-state/intake-control.js +2 -1
- package/dist/daemon-state/intake-control.js.map +1 -1
- package/dist/delivery/recorded-concerns.d.ts +19 -2
- package/dist/delivery/recorded-concerns.d.ts.map +1 -1
- package/dist/delivery/recorded-concerns.js +32 -6
- package/dist/delivery/recorded-concerns.js.map +1 -1
- package/dist/directive/directive-queue.js +1 -1
- package/dist/focus/closed-review-window.d.ts +12 -0
- package/dist/focus/closed-review-window.d.ts.map +1 -1
- package/dist/focus/closed-review-window.js +18 -0
- package/dist/focus/closed-review-window.js.map +1 -1
- package/dist/focus/control-state.d.ts +30 -26
- package/dist/focus/control-state.d.ts.map +1 -1
- package/dist/focus/control-state.js +60 -46
- package/dist/focus/control-state.js.map +1 -1
- package/dist/focus/daemon-contexts.d.ts +23 -0
- package/dist/focus/daemon-contexts.d.ts.map +1 -1
- package/dist/focus/daemon-contexts.js +1 -1
- package/dist/focus/daemon-contexts.js.map +1 -1
- package/dist/focus/engine-ready-pass.d.ts +11 -0
- package/dist/focus/engine-ready-pass.d.ts.map +1 -0
- package/dist/focus/engine-ready-pass.js +25 -0
- package/dist/focus/engine-ready-pass.js.map +1 -0
- package/dist/focus/failed-head-wedge.d.ts +95 -0
- package/dist/focus/failed-head-wedge.d.ts.map +1 -0
- package/dist/focus/failed-head-wedge.js +85 -0
- package/dist/focus/failed-head-wedge.js.map +1 -0
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +20 -20
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/focus-loop-registry.d.ts.map +1 -1
- package/dist/focus/focus-loop-registry.js +2 -1
- package/dist/focus/focus-loop-registry.js.map +1 -1
- package/dist/focus/focus-poller-auto-advance.d.ts.map +1 -1
- package/dist/focus/focus-poller-auto-advance.js +4 -4
- package/dist/focus/focus-poller-auto-advance.js.map +1 -1
- package/dist/focus/focus-poller-spawn.d.ts +42 -49
- package/dist/focus/focus-poller-spawn.d.ts.map +1 -1
- package/dist/focus/focus-poller-spawn.js +129 -83
- package/dist/focus/focus-poller-spawn.js.map +1 -1
- package/dist/focus/focus-poller-state.d.ts.map +1 -1
- package/dist/focus/focus-poller-state.js +1 -19
- package/dist/focus/focus-poller-state.js.map +1 -1
- package/dist/focus/focus-poller.d.ts.map +1 -1
- package/dist/focus/focus-poller.js +2 -1
- package/dist/focus/focus-poller.js.map +1 -1
- package/dist/focus/focus-respawn-guard.d.ts +7 -0
- package/dist/focus/focus-respawn-guard.d.ts.map +1 -1
- package/dist/focus/focus-respawn-guard.js +20 -1
- package/dist/focus/focus-respawn-guard.js.map +1 -1
- package/dist/focus/focus-spawn-decision.d.ts +11 -3
- package/dist/focus/focus-spawn-decision.d.ts.map +1 -1
- package/dist/focus/focus-spawn-decision.js +3 -1
- package/dist/focus/focus-spawn-decision.js.map +1 -1
- package/dist/focus/heartbeat-metadata.d.ts +3 -0
- package/dist/focus/heartbeat-metadata.d.ts.map +1 -1
- package/dist/focus/heartbeat-metadata.js +6 -1
- package/dist/focus/heartbeat-metadata.js.map +1 -1
- package/dist/focus/heartbeat.d.ts.map +1 -1
- package/dist/focus/heartbeat.js +2 -0
- package/dist/focus/heartbeat.js.map +1 -1
- package/dist/focus/pending-directive-gates.d.ts +47 -0
- package/dist/focus/pending-directive-gates.d.ts.map +1 -0
- package/dist/focus/pending-directive-gates.js +76 -0
- package/dist/focus/pending-directive-gates.js.map +1 -0
- package/dist/focus/pending-review-approved-head.d.ts +2 -1
- package/dist/focus/pending-review-approved-head.d.ts.map +1 -1
- package/dist/focus/pending-review-approved-head.js +3 -4
- package/dist/focus/pending-review-approved-head.js.map +1 -1
- package/dist/focus/pending-spawn-pass-deps.d.ts +5 -0
- package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -1
- package/dist/focus/pending-spawn-pass-deps.js +4 -1
- package/dist/focus/pending-spawn-pass-deps.js.map +1 -1
- package/dist/focus/pending-spawn-verify-hold.d.ts +13 -0
- package/dist/focus/pending-spawn-verify-hold.d.ts.map +1 -0
- package/dist/focus/pending-spawn-verify-hold.js +30 -0
- package/dist/focus/pending-spawn-verify-hold.js.map +1 -0
- package/dist/focus/ready-focus-spawn-action.d.ts +15 -2
- package/dist/focus/ready-focus-spawn-action.d.ts.map +1 -1
- package/dist/focus/ready-focus-spawn-action.js +25 -8
- package/dist/focus/ready-focus-spawn-action.js.map +1 -1
- package/dist/focus/spawn-demand-probe.d.ts +45 -0
- package/dist/focus/spawn-demand-probe.d.ts.map +1 -0
- package/dist/focus/spawn-demand-probe.js +74 -0
- package/dist/focus/spawn-demand-probe.js.map +1 -0
- package/dist/focus/stranded-review-reroute.d.ts.map +1 -1
- package/dist/focus/stranded-review-reroute.js +5 -3
- package/dist/focus/stranded-review-reroute.js.map +1 -1
- package/dist/focus/verify-routing-passes.d.ts +8 -3
- package/dist/focus/verify-routing-passes.d.ts.map +1 -1
- package/dist/focus/verify-routing-passes.js +1 -0
- package/dist/focus/verify-routing-passes.js.map +1 -1
- package/dist/git/focus-branch-containment.d.ts +39 -0
- package/dist/git/focus-branch-containment.d.ts.map +1 -0
- package/dist/git/focus-branch-containment.js +47 -0
- package/dist/git/focus-branch-containment.js.map +1 -0
- package/dist/git/types.d.ts.map +1 -1
- package/dist/git/types.js +1 -0
- package/dist/git/types.js.map +1 -1
- package/dist/poll-trigger.js +1 -1
- package/dist/poll-trigger.js.map +1 -1
- package/dist/prd/arm-readiness.d.ts.map +1 -1
- package/dist/prd/arm-readiness.js +2 -1
- package/dist/prd/arm-readiness.js.map +1 -1
- package/dist/prd/controller-shared.d.ts +32 -8
- package/dist/prd/controller-shared.d.ts.map +1 -1
- package/dist/prd/controller-shared.js +34 -18
- package/dist/prd/controller-shared.js.map +1 -1
- package/dist/prd/controller.d.ts.map +1 -1
- package/dist/prd/controller.js +3 -8
- package/dist/prd/controller.js.map +1 -1
- package/dist/prd/done-sweep.d.ts.map +1 -1
- package/dist/prd/done-sweep.js +2 -7
- package/dist/prd/done-sweep.js.map +1 -1
- package/dist/prd/frontier-arming.d.ts +13 -1
- package/dist/prd/frontier-arming.d.ts.map +1 -1
- package/dist/prd/frontier-arming.js +50 -2
- package/dist/prd/frontier-arming.js.map +1 -1
- package/dist/prd/index.d.ts.map +1 -1
- package/dist/prd/index.js +2 -1
- package/dist/prd/index.js.map +1 -1
- package/dist/queries/api-client/shared.d.ts +1 -0
- package/dist/queries/api-client/shared.d.ts.map +1 -1
- package/dist/queries/api-client/shared.js +16 -1
- package/dist/queries/api-client/shared.js.map +1 -1
- package/dist/queries/deliveries/issues.d.ts.map +1 -1
- package/dist/queries/deliveries/issues.js +3 -0
- package/dist/queries/deliveries/issues.js.map +1 -1
- package/dist/queries/focuses/focus-discovery.d.ts +15 -0
- package/dist/queries/focuses/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focuses/focus-discovery.js +10 -1
- package/dist/queries/focuses/focus-discovery.js.map +1 -1
- package/dist/queries/prd/prd.d.ts.map +1 -1
- package/dist/queries/prd/prd.js +2 -1
- package/dist/queries/prd/prd.js.map +1 -1
- package/dist/queries/tower/tower-state.d.ts +56 -0
- package/dist/queries/tower/tower-state.d.ts.map +1 -0
- package/dist/queries/tower/tower-state.js +76 -0
- package/dist/queries/tower/tower-state.js.map +1 -0
- package/dist/queries/wire-schemas/schemas.d.ts +12 -0
- package/dist/queries/wire-schemas/schemas.d.ts.map +1 -1
- package/dist/queries/wire-schemas/schemas.js +11 -0
- package/dist/queries/wire-schemas/schemas.js.map +1 -1
- package/dist/spawn/lead-continuation.d.ts +9 -1
- package/dist/spawn/lead-continuation.d.ts.map +1 -1
- package/dist/spawn/lead-continuation.js +37 -11
- package/dist/spawn/lead-continuation.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +4 -1
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/supervision/spawn-cooldown.js +1 -1
- package/dist/supervision/stop-rows-team-session.d.ts.map +1 -1
- package/dist/supervision/stop-rows-team-session.js +11 -10
- package/dist/supervision/stop-rows-team-session.js.map +1 -1
- package/dist/supervision/team-work.d.ts.map +1 -1
- package/dist/supervision/team-work.js +3 -1
- package/dist/supervision/team-work.js.map +1 -1
- package/dist/testing/fixtures/api-client.js +1 -1
- package/dist/testing/fixtures/approved-head-inert-deps.js +1 -1
- package/dist/testing/fixtures/approved-head-inert-deps.js.map +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/testing/fixtures/pending-spawn-world.d.ts.map +1 -1
- package/dist/testing/fixtures/pending-spawn-world.js +3 -1
- package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
- package/dist/testing/fixtures/review-exit-deps.js +1 -1
- package/dist/testing/fixtures/review-exit-deps.js.map +1 -1
- package/dist/testing/fixtures/verification-feedback-deps.d.ts.map +1 -1
- package/dist/testing/fixtures/verification-feedback-deps.js +2 -0
- package/dist/testing/fixtures/verification-feedback-deps.js.map +1 -1
- package/dist/tower/focus-landed.d.ts +4 -0
- package/dist/tower/focus-landed.d.ts.map +1 -0
- package/dist/tower/focus-landed.js +45 -0
- package/dist/tower/focus-landed.js.map +1 -0
- package/dist/tower/tower-admission.d.ts +91 -0
- package/dist/tower/tower-admission.d.ts.map +1 -0
- package/dist/tower/tower-admission.js +137 -0
- package/dist/tower/tower-admission.js.map +1 -0
- package/dist/tower/tower-graph.d.ts +23 -0
- package/dist/tower/tower-graph.d.ts.map +1 -0
- package/dist/tower/tower-graph.js +53 -0
- package/dist/tower/tower-graph.js.map +1 -0
- package/dist/tower/tower-heartbeat-status.d.ts +28 -0
- package/dist/tower/tower-heartbeat-status.d.ts.map +1 -0
- package/dist/tower/tower-heartbeat-status.js +11 -0
- package/dist/tower/tower-heartbeat-status.js.map +1 -0
- package/dist/tower/tower-mode.d.ts +9 -0
- package/dist/tower/tower-mode.d.ts.map +1 -0
- package/dist/tower/tower-mode.js +16 -0
- package/dist/tower/tower-mode.js.map +1 -0
- package/dist/tower/tower-pass-standing.d.ts +8 -0
- package/dist/tower/tower-pass-standing.d.ts.map +1 -0
- package/dist/tower/tower-pass-standing.js +50 -0
- package/dist/tower/tower-pass-standing.js.map +1 -0
- package/dist/tower/tower-pass.d.ts +55 -0
- package/dist/tower/tower-pass.d.ts.map +1 -0
- package/dist/tower/tower-pass.js +59 -0
- package/dist/tower/tower-pass.js.map +1 -0
- package/dist/tower/tower-production-pass.d.ts +3 -0
- package/dist/tower/tower-production-pass.d.ts.map +1 -0
- package/dist/tower/tower-production-pass.js +24 -0
- package/dist/tower/tower-production-pass.js.map +1 -0
- package/dist/tower/tower-spawn-intent.d.ts +72 -0
- package/dist/tower/tower-spawn-intent.d.ts.map +1 -0
- package/dist/tower/tower-spawn-intent.js +138 -0
- package/dist/tower/tower-spawn-intent.js.map +1 -0
- package/dist/tower/tower-verdicts.d.ts +81 -0
- package/dist/tower/tower-verdicts.d.ts.map +1 -0
- package/dist/tower/tower-verdicts.js +139 -0
- package/dist/tower/tower-verdicts.js.map +1 -0
- package/dist/types/index.js +1 -1
- package/dist/types/issue-status.d.ts +14 -0
- package/dist/types/issue-status.d.ts.map +1 -1
- package/dist/types/issue-status.js +14 -0
- package/dist/types/issue-status.js.map +1 -1
- package/dist/verify/gate-verdicts/commit-verdict-record.js +1 -1
- package/dist/verify/outcome-routing/verification-rework-issue.d.ts +44 -5
- package/dist/verify/outcome-routing/verification-rework-issue.d.ts.map +1 -1
- package/dist/verify/outcome-routing/verification-rework-issue.js +85 -27
- package/dist/verify/outcome-routing/verification-rework-issue.js.map +1 -1
- package/dist/worktree/focus-worktree-state.d.ts.map +1 -1
- package/dist/worktree/focus-worktree-state.js +1 -0
- package/dist/worktree/focus-worktree-state.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-exit-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/review-exit-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,uHAAuH;AACvH,gBAAgB;AAuBhB,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,YAAqC,EAAE;IACxE,OAAO;QACL,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAChC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAClC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAC9B,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACjC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;QAC7G,CAAC;QACD,oBAAoB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACpC,wBAAwB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACxC,wBAAwB,EAAE,GAAG,EAAE,CAAC,IAAI;QACpC,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC9B,sBAAsB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACtC,0BAA0B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"review-exit-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/review-exit-deps.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-feedback-deps.d.ts","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2DAA2D,CAAC;
|
|
1
|
+
{"version":3,"file":"verification-feedback-deps.d.ts","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2DAA2D,CAAC;AAGjG,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,2DAA2D;AAC3D,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAQzH;AAED,mGAAmG;AACnG,wBAAgB,yBAAyB,CAAC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,oBAAoB,CAS7G;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAO9F;AAED,0GAA0G;AAC1G,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,+BAA+B,CAAM,GACvD,+BAA+B,CAOjC;AAED,uFAAuF;AACvF,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,oBAAoB,GAAG,eAAe,CAAM,GAC9D,oBAAoB,GAAG,eAAe,CAExC;AAED,8FAA8F;AAC9F,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAMzH;AAED,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,kBAAkB,CAOvG"}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
*/
|
|
40
40
|
import { resolveReconciledWrite } from '../../delivery/delivery-reconciler-apply.js';
|
|
41
41
|
import { readVerificationLogText } from '../../verify/outcome-routing/failure-signature.js';
|
|
42
|
+
import { NO_RECORDED_CONCERNS } from '../../delivery/recorded-concerns.js';
|
|
42
43
|
/** The fixed instant the inert clock answers. */
|
|
43
44
|
export const INERT_FEEDBACK_NOW = '2026-01-01T00:00:00.000Z';
|
|
44
45
|
/** Inert gate_state write, no live team, a fixed clock. */
|
|
@@ -67,6 +68,7 @@ export function inertReworkIssueDeps(overrides = {}) {
|
|
|
67
68
|
return {
|
|
68
69
|
getDeliveryIssues: async () => [],
|
|
69
70
|
createIssue: async () => 'inert-rework-issue',
|
|
71
|
+
readRecordedConcernIds: async () => NO_RECORDED_CONCERNS,
|
|
70
72
|
...overrides,
|
|
71
73
|
};
|
|
72
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-feedback-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,gFAAgF;AAChF,4FAA4F;AAC5F,sEAAsE;AACtE,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,6DAA6D;AAC7D,uEAAuE;AACvE,2EAA2E;AAC3E,8EAA8E;AAC9E,oFAAoF;AACpF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,oEAAoE;AACpE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;
|
|
1
|
+
{"version":3,"file":"verification-feedback-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,gFAAgF;AAChF,4FAA4F;AAC5F,sEAAsE;AACtE,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,6DAA6D;AAC7D,uEAAuE;AACvE,2EAA2E;AAC3E,8EAA8E;AAC9E,oFAAoF;AACpF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,oEAAoE;AACpE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAS5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,iDAAiD;AACjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAE7D,2DAA2D;AAC3D,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC9B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE;QAC/B,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;QACvB,GAAG,EAAE,GAAG,EAAE,CAAC,kBAAkB;QAC7B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,yBAAyB,CAAC,YAA2C,EAAE;IACrF,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,kBAAkB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAClC,sBAAsB;QACtB,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QACpC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;QAC3B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,YAAsC,EAAE;IAC3E,OAAO;QACL,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACjC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,oBAAoB;QAC7C,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,oBAAoB;QACxD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,oCAAoC,CAClD,YAAsD,EAAE;IAExD,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,WAAW,EAAE,uBAAuB;QACpC,GAAG,oBAAoB,EAAE;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,oCAAoC,CAClD,YAA6D,EAAE;IAE/D,OAAO,EAAE,GAAG,yBAAyB,EAAE,EAAE,GAAG,oBAAoB,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;AACrF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACrF,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,uBAAuB,CAAC,YAAyC,EAAE;IACjF,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,GAAG,6BAA6B,EAAE;QAClC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC5B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
|
|
2
|
+
export type FocusLanded = 'landed' | 'not_landed' | 'unknown';
|
|
3
|
+
export declare function judgeFocusLanded(deliveryStatuses: readonly string[], branch: FocusBranchContainment): FocusLanded;
|
|
4
|
+
//# sourceMappingURL=focus-landed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-landed.d.ts","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,MAAM,EAAE,sBAAsB,GAC7B,WAAW,CAcb"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/focus-landed.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* LANDED: the ONE definition of "this focus's work has landed", judged by the
|
|
6
|
+
* daemon with no human close. Shared by the tower (a depends_on successor waits
|
|
7
|
+
* until its predecessor has landed) and the PRD frontier's completion signal
|
|
8
|
+
* (prd/controller-shared.ts computeCompletedFocusIds), so the two can never
|
|
9
|
+
* disagree about whether a focus is finished.
|
|
10
|
+
*
|
|
11
|
+
* A focus has LANDED when
|
|
12
|
+
* 1. it has at least one delivery, and
|
|
13
|
+
* 2. every non-cancelled delivery is done, at least one of them (a focus whose
|
|
14
|
+
* every delivery was cancelled landed nothing), and
|
|
15
|
+
* 3. its branch tip is contained in the integration branch -- or the branch is
|
|
16
|
+
* gone AND the focus's merge record names a merge commit integration
|
|
17
|
+
* contains (the daemon removes a branch only after merging it, and records
|
|
18
|
+
* the merge; git/focus-branch-containment.ts). A gone branch with no such
|
|
19
|
+
* record is unproven: unknown.
|
|
20
|
+
*
|
|
21
|
+
* NOT_LANDED when any of those is definitely false. UNKNOWN when 1-2 hold but
|
|
22
|
+
* git could not answer 3: never read as landed and never as not landed -- the
|
|
23
|
+
* tower leaves the dependent focus's verdict unavailable (fail open), and the
|
|
24
|
+
* PRD frontier does not clear the obstacle this tick.
|
|
25
|
+
*/
|
|
26
|
+
import { DELIVERY_STATUS } from '@telora/daemon-core';
|
|
27
|
+
export function judgeFocusLanded(deliveryStatuses, branch) {
|
|
28
|
+
if (deliveryStatuses.length === 0)
|
|
29
|
+
return 'not_landed';
|
|
30
|
+
const live = deliveryStatuses.filter((s) => s !== DELIVERY_STATUS.CANCELLED);
|
|
31
|
+
if (live.length === 0)
|
|
32
|
+
return 'not_landed';
|
|
33
|
+
if (!live.every((s) => s === DELIVERY_STATUS.DONE))
|
|
34
|
+
return 'not_landed';
|
|
35
|
+
switch (branch) {
|
|
36
|
+
case 'contained':
|
|
37
|
+
case 'merged_removed':
|
|
38
|
+
return 'landed';
|
|
39
|
+
case 'not_contained':
|
|
40
|
+
return 'not_landed';
|
|
41
|
+
case 'unknown':
|
|
42
|
+
return 'unknown';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=focus-landed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-landed.js","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4DAA4D;AAC5D,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAKtD,MAAM,UAAU,gBAAgB,CAC9B,gBAAmC,EACnC,MAA8B;IAE9B,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IACvD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IACxE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,gBAAgB;YACnB,OAAO,QAAQ,CAAC;QAClB,KAAK,eAAe;YAClB,OAAO,YAAY,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn admission through the tower: what the spawn passes ask before they
|
|
3
|
+
* start a coding or review team for an armed focus.
|
|
4
|
+
*
|
|
5
|
+
* THE RULE (docs/runbook-tower.md):
|
|
6
|
+
* off -- the tower is not consulted; spawning is exactly as before it.
|
|
7
|
+
* observe -- the verdict is read and never obeyed; a spawn decision enforce
|
|
8
|
+
* would have made differently is LOGGED (focus, verdict, the
|
|
9
|
+
* decision taken), so an operator judges the verdicts on real
|
|
10
|
+
* foci before enforcing.
|
|
11
|
+
* enforce -- a holding verdict that is FRESH holds the spawn.
|
|
12
|
+
*
|
|
13
|
+
* FAIL OPEN. Only an available, holding verdict ever holds, and only while
|
|
14
|
+
* this daemon's tower pass for the focus's product is standing
|
|
15
|
+
* (tower-pass-standing.ts): a pass that failed, or has not yet succeeded,
|
|
16
|
+
* leaves every verdict of that product unobeyed at once. A verdict that is
|
|
17
|
+
* missing, malformed, older than the bounded age or written under an earlier
|
|
18
|
+
* arm is no verdict (daemon-core readTowerVerdict). Either way the focus
|
|
19
|
+
* spawns as it would with the tower off, and the daemon says so. Admission fails open while
|
|
20
|
+
* the merge gates fail closed because the failures are not symmetric: a wrongly
|
|
21
|
+
* blocked merge is visible (a held delivery, a red gate), a wrongly held spawn
|
|
22
|
+
* is SILENT (a focus that simply never runs).
|
|
23
|
+
*
|
|
24
|
+
* The decision is pure (decideTowerAdmission); noteTowerAdmission logs it and
|
|
25
|
+
* records the focus's spawn intent once the spawn gate's final action is known.
|
|
26
|
+
*/
|
|
27
|
+
import { type TowerMode, type TowerVerdictReading } from '@telora/daemon-core';
|
|
28
|
+
import { type SpawnIntentSource } from './tower-spawn-intent.js';
|
|
29
|
+
import type { TowerPassStanding } from './tower-pass-standing.js';
|
|
30
|
+
/** The focus row fields admission reads (ready and active focus rows both carry them). */
|
|
31
|
+
export interface TowerAdmissionFocus {
|
|
32
|
+
focus_id: string;
|
|
33
|
+
focus_name: string;
|
|
34
|
+
product_id?: string | null;
|
|
35
|
+
agent_assigned_at?: string | null;
|
|
36
|
+
tower_verdict?: unknown;
|
|
37
|
+
}
|
|
38
|
+
export interface TowerAdmission {
|
|
39
|
+
mode: TowerMode;
|
|
40
|
+
/** The spawn is held (enforce + an available holding verdict). */
|
|
41
|
+
holds: boolean;
|
|
42
|
+
/** What enforce would do with this verdict: hold. */
|
|
43
|
+
enforceWouldHold: boolean;
|
|
44
|
+
/** The verdict as read; null in off mode (the tower is not consulted). */
|
|
45
|
+
reading: TowerVerdictReading | null;
|
|
46
|
+
/** The product's pass is not standing: every verdict is unobeyed (fail open). Null when it stands. */
|
|
47
|
+
passNotStanding: Exclude<TowerPassStanding, 'ok'> | null;
|
|
48
|
+
}
|
|
49
|
+
/** What admission reads of the tower each pass (the spawn passes' deps; composition/spawn-pass-deps.ts). */
|
|
50
|
+
export interface TowerAdmissionDeps {
|
|
51
|
+
/** TELORA_TOWER_MODE. */
|
|
52
|
+
mode: () => TowerMode;
|
|
53
|
+
/** This daemon's pass standing for a product (tower-pass-standing.ts). */
|
|
54
|
+
passStanding: (productId: string | null | undefined) => TowerPassStanding;
|
|
55
|
+
}
|
|
56
|
+
export declare function decideTowerAdmission(focus: TowerAdmissionFocus, tower: TowerAdmissionDeps, nowMs: number): TowerAdmission;
|
|
57
|
+
/** The outcome the spawn gate reached for a focus, after the tower was consulted. */
|
|
58
|
+
export type TowerGateOutcome = 'spawn' | 'tower_hold' | 'capacity' | 'not_wanting';
|
|
59
|
+
/** The line a decision produces, or null when it is not worth a line. Exported for tests. */
|
|
60
|
+
export declare function towerAdmissionMessage(focus: TowerAdmissionFocus, admission: TowerAdmission, outcome: TowerGateOutcome): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Log the admission (once per distinct line) and record the focus's spawn
|
|
63
|
+
* intent for the tower's next pass. Never throws: admission bookkeeping must
|
|
64
|
+
* not cost a spawn.
|
|
65
|
+
*/
|
|
66
|
+
export declare function noteTowerAdmission(focus: TowerAdmissionFocus, admission: TowerAdmission, outcome: TowerGateOutcome, nowMs?: number, source?: SpawnIntentSource): void;
|
|
67
|
+
/**
|
|
68
|
+
* The order the spawn pass offers ready foci to the host governor: in enforce,
|
|
69
|
+
* focus rank order (lowest priority_rank first, stable); otherwise the order the
|
|
70
|
+
* API returned them, exactly as before the tower.
|
|
71
|
+
*/
|
|
72
|
+
export declare function orderForTower<T extends {
|
|
73
|
+
priority_rank?: number | null;
|
|
74
|
+
}>(foci: readonly T[], mode: TowerMode): T[];
|
|
75
|
+
/**
|
|
76
|
+
* A spawn pass's offer: opens the pass's demand record over every focus it
|
|
77
|
+
* offers (tower-spawn-intent.ts beginSpawnIntentPass -- a focus some earlier
|
|
78
|
+
* gate stops is committed as not wanting) and returns them in orderForTower's
|
|
79
|
+
* order. The pass's runner commits it (focus/focus-poller-spawn.ts).
|
|
80
|
+
*/
|
|
81
|
+
export declare function offerForTower<T extends {
|
|
82
|
+
priority_rank?: number | null;
|
|
83
|
+
}>(source: SpawnIntentSource, foci: readonly T[], idOf: (f: T) => string, mode: TowerMode): T[];
|
|
84
|
+
/**
|
|
85
|
+
* The pending-spawn pass's tower check (a queued directive -- e.g. a review --
|
|
86
|
+
* on an armed focus): consulted after the cooldown and before the host cap,
|
|
87
|
+
* exactly where the ready pass consults it. True = held; the directive stays
|
|
88
|
+
* queued.
|
|
89
|
+
*/
|
|
90
|
+
export declare function pendingSpawnHeldByTower(focus: TowerAdmissionFocus, atHostCapacity: boolean, tower: TowerAdmissionDeps, nowMs: number): boolean;
|
|
91
|
+
//# sourceMappingURL=tower-admission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-admission.d.ts","sourceRoot":"","sources":["../../src/tower/tower-admission.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAA2C,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC1G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAC;IACf,qDAAqD;IACrD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACpC,sGAAsG;IACtG,eAAe,EAAE,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED,4GAA4G;AAC5G,MAAM,WAAW,kBAAkB;IACjC,yBAAyB;IACzB,IAAI,EAAE,MAAM,SAAS,CAAC;IACtB,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,iBAAiB,CAAC;CAC3E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAQzH;AAED,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,CAAC;AAYnF,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAsBrI;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,gBAAgB,EACzB,KAAK,GAAE,MAAmB,EAC1B,MAAM,GAAE,iBAA2B,GAClC,IAAI,CAWN;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,CAAC,EAAE,CAInH;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACvE,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACtB,IAAI,EAAE,SAAS,GACd,CAAC,EAAE,CAGL;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,mBAAmB,EAC1B,cAAc,EAAE,OAAO,EACvB,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAIT"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/tower-pass.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* Spawn admission through the tower: what the spawn passes ask before they
|
|
6
|
+
* start a coding or review team for an armed focus.
|
|
7
|
+
*
|
|
8
|
+
* THE RULE (docs/runbook-tower.md):
|
|
9
|
+
* off -- the tower is not consulted; spawning is exactly as before it.
|
|
10
|
+
* observe -- the verdict is read and never obeyed; a spawn decision enforce
|
|
11
|
+
* would have made differently is LOGGED (focus, verdict, the
|
|
12
|
+
* decision taken), so an operator judges the verdicts on real
|
|
13
|
+
* foci before enforcing.
|
|
14
|
+
* enforce -- a holding verdict that is FRESH holds the spawn.
|
|
15
|
+
*
|
|
16
|
+
* FAIL OPEN. Only an available, holding verdict ever holds, and only while
|
|
17
|
+
* this daemon's tower pass for the focus's product is standing
|
|
18
|
+
* (tower-pass-standing.ts): a pass that failed, or has not yet succeeded,
|
|
19
|
+
* leaves every verdict of that product unobeyed at once. A verdict that is
|
|
20
|
+
* missing, malformed, older than the bounded age or written under an earlier
|
|
21
|
+
* arm is no verdict (daemon-core readTowerVerdict). Either way the focus
|
|
22
|
+
* spawns as it would with the tower off, and the daemon says so. Admission fails open while
|
|
23
|
+
* the merge gates fail closed because the failures are not symmetric: a wrongly
|
|
24
|
+
* blocked merge is visible (a held delivery, a red gate), a wrongly held spawn
|
|
25
|
+
* is SILENT (a focus that simply never runs).
|
|
26
|
+
*
|
|
27
|
+
* The decision is pure (decideTowerAdmission); noteTowerAdmission logs it and
|
|
28
|
+
* records the focus's spawn intent once the spawn gate's final action is known.
|
|
29
|
+
*/
|
|
30
|
+
import { describeTowerHold, describeTowerUnavailable, readTowerVerdict, towerReadingHolds, } from '@telora/daemon-core';
|
|
31
|
+
import { createLogger } from '../log/daemon-log.js';
|
|
32
|
+
import { beginSpawnIntentPass, recordSpawnIntent } from './tower-spawn-intent.js';
|
|
33
|
+
const log = createLogger({ module: 'tower' });
|
|
34
|
+
export function decideTowerAdmission(focus, tower, nowMs) {
|
|
35
|
+
const mode = tower.mode();
|
|
36
|
+
if (mode === 'off')
|
|
37
|
+
return { mode, holds: false, enforceWouldHold: false, reading: null, passNotStanding: null };
|
|
38
|
+
const reading = readTowerVerdict(focus.tower_verdict ?? null, { armedAt: focus.agent_assigned_at ?? null }, nowMs);
|
|
39
|
+
const standing = tower.passStanding(focus.product_id);
|
|
40
|
+
if (standing !== 'ok')
|
|
41
|
+
return { mode, holds: false, enforceWouldHold: false, reading, passNotStanding: standing };
|
|
42
|
+
const enforceWouldHold = towerReadingHolds(reading);
|
|
43
|
+
return { mode, holds: mode === 'enforce' && enforceWouldHold, enforceWouldHold, reading, passNotStanding: null };
|
|
44
|
+
}
|
|
45
|
+
/** One log line per focus per distinct message (a held focus is not re-logged every poll). */
|
|
46
|
+
const lastLogged = new Map();
|
|
47
|
+
function logOnce(focusId, message, level) {
|
|
48
|
+
if (lastLogged.get(focusId) === message)
|
|
49
|
+
return;
|
|
50
|
+
lastLogged.set(focusId, message);
|
|
51
|
+
if (level === 'warn')
|
|
52
|
+
log.warn(message);
|
|
53
|
+
else
|
|
54
|
+
log.info(message);
|
|
55
|
+
}
|
|
56
|
+
/** The line a decision produces, or null when it is not worth a line. Exported for tests. */
|
|
57
|
+
export function towerAdmissionMessage(focus, admission, outcome) {
|
|
58
|
+
const { reading } = admission;
|
|
59
|
+
if (!reading || outcome === 'not_wanting')
|
|
60
|
+
return null;
|
|
61
|
+
const name = `"${focus.focus_name}" (${focus.focus_id.slice(0, 8)})`;
|
|
62
|
+
if (admission.passNotStanding) {
|
|
63
|
+
if (admission.mode !== 'enforce')
|
|
64
|
+
return null;
|
|
65
|
+
const why = admission.passNotStanding === 'failed' ? 'its product\'s tower pass failed' : 'its product\'s tower pass has not succeeded yet';
|
|
66
|
+
return `[tower] ${name}: ${why} -- failing open, spawning as with the tower off`;
|
|
67
|
+
}
|
|
68
|
+
if (reading.status === 'unavailable') {
|
|
69
|
+
if (admission.mode !== 'enforce')
|
|
70
|
+
return null;
|
|
71
|
+
return `[tower] ${name}: ${describeTowerUnavailable(reading.why)} -- failing open, spawning as with the tower off`;
|
|
72
|
+
}
|
|
73
|
+
const v = reading.verdict;
|
|
74
|
+
if (v.state !== 'holding')
|
|
75
|
+
return null;
|
|
76
|
+
const why = `${describeTowerHold(v)} since ${v.since}`;
|
|
77
|
+
if (outcome === 'tower_hold')
|
|
78
|
+
return `[tower] holding ${name}: ${why}`;
|
|
79
|
+
if (admission.mode === 'observe') {
|
|
80
|
+
const taken = outcome === 'spawn' ? 'spawned' : 'left waiting for a host slot';
|
|
81
|
+
return `[tower] observe: enforce would hold ${name} (${why}); decision taken: ${taken}`;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Log the admission (once per distinct line) and record the focus's spawn
|
|
87
|
+
* intent for the tower's next pass. Never throws: admission bookkeeping must
|
|
88
|
+
* not cost a spawn.
|
|
89
|
+
*/
|
|
90
|
+
export function noteTowerAdmission(focus, admission, outcome, nowMs = Date.now(), source = 'ready') {
|
|
91
|
+
try {
|
|
92
|
+
// Open demand only: a spawned focus's demand is met (its team holds the slot).
|
|
93
|
+
recordSpawnIntent(focus.focus_id, outcome === 'tower_hold' || outcome === 'capacity', nowMs, source);
|
|
94
|
+
const message = towerAdmissionMessage(focus, admission, outcome);
|
|
95
|
+
const failingOpen = admission.passNotStanding !== null || admission.reading?.status === 'unavailable';
|
|
96
|
+
if (message)
|
|
97
|
+
logOnce(focus.focus_id, message, failingOpen ? 'warn' : 'info');
|
|
98
|
+
else
|
|
99
|
+
lastLogged.delete(focus.focus_id);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Bookkeeping only.
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The order the spawn pass offers ready foci to the host governor: in enforce,
|
|
107
|
+
* focus rank order (lowest priority_rank first, stable); otherwise the order the
|
|
108
|
+
* API returned them, exactly as before the tower.
|
|
109
|
+
*/
|
|
110
|
+
export function orderForTower(foci, mode) {
|
|
111
|
+
if (mode !== 'enforce')
|
|
112
|
+
return [...foci];
|
|
113
|
+
const rank = (f) => f.priority_rank ?? Number.MAX_SAFE_INTEGER;
|
|
114
|
+
return [...foci].map((f, i) => ({ f, i })).sort((a, b) => rank(a.f) - rank(b.f) || a.i - b.i).map((x) => x.f);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A spawn pass's offer: opens the pass's demand record over every focus it
|
|
118
|
+
* offers (tower-spawn-intent.ts beginSpawnIntentPass -- a focus some earlier
|
|
119
|
+
* gate stops is committed as not wanting) and returns them in orderForTower's
|
|
120
|
+
* order. The pass's runner commits it (focus/focus-poller-spawn.ts).
|
|
121
|
+
*/
|
|
122
|
+
export function offerForTower(source, foci, idOf, mode) {
|
|
123
|
+
beginSpawnIntentPass(source, foci.map(idOf));
|
|
124
|
+
return orderForTower(foci, mode);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The pending-spawn pass's tower check (a queued directive -- e.g. a review --
|
|
128
|
+
* on an armed focus): consulted after the cooldown and before the host cap,
|
|
129
|
+
* exactly where the ready pass consults it. True = held; the directive stays
|
|
130
|
+
* queued.
|
|
131
|
+
*/
|
|
132
|
+
export function pendingSpawnHeldByTower(focus, atHostCapacity, tower, nowMs) {
|
|
133
|
+
const admission = decideTowerAdmission(focus, tower, nowMs);
|
|
134
|
+
noteTowerAdmission(focus, admission, admission.holds ? 'tower_hold' : atHostCapacity ? 'capacity' : 'spawn', nowMs, 'pending');
|
|
135
|
+
return admission.holds;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=tower-admission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-admission.js","sourceRoot":"","sources":["../../src/tower/tower-admission.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tower graph, judged for one product's pass: which armed foci wait on an
|
|
3
|
+
* unlanded depends_on predecessor, which are joined by an excludes edge to
|
|
4
|
+
* which other foci, and which cannot be judged at all.
|
|
5
|
+
*
|
|
6
|
+
* depends_on (from -> to): `to` waits until `from` has LANDED
|
|
7
|
+
* (tower/focus-landed.ts, the definition the PRD frontier shares). A
|
|
8
|
+
* predecessor that has definitely not landed holds the successor with
|
|
9
|
+
* `waits_on`; one whose landed state git could not answer -- with none
|
|
10
|
+
* definitely unlanded -- leaves the successor UNAVAILABLE (no verdict, fail
|
|
11
|
+
* open), never holding.
|
|
12
|
+
* excludes (a <-> b): each side lists the other with the edge's evidence;
|
|
13
|
+
* tower-verdicts.ts holds whichever is reached second while the first runs or
|
|
14
|
+
* is cleared.
|
|
15
|
+
*
|
|
16
|
+
* Git is read only for a predecessor whose deliveries say it could have landed.
|
|
17
|
+
*/
|
|
18
|
+
import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
|
|
19
|
+
import type { TowerProductState } from '../queries/tower/tower-state.js';
|
|
20
|
+
import type { TowerComputeInput } from './tower-verdicts.js';
|
|
21
|
+
export type TowerGraphInputs = Pick<TowerComputeInput, 'waitsOn' | 'excludes' | 'unavailableFocusIds'>;
|
|
22
|
+
export declare function judgeTowerGraph(state: Pick<TowerProductState, 'foci' | 'edges' | 'graphFoci'>, containmentOf: (focus: TowerProductState['graphFoci'][number]) => FocusBranchContainment): TowerGraphInputs;
|
|
23
|
+
//# sourceMappingURL=tower-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-graph.d.ts","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAA4C,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,UAAU,GAAG,qBAAqB,CAAC,CAAC;AAEvG,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC,EAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,sBAAsB,GACvF,gBAAgB,CA0ClB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/focus-landed.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
|
|
3
|
+
// packages/daemon/src/tower/tower-state-ingestion.test.ts
|
|
4
|
+
// PINNED-BY-END
|
|
5
|
+
import { judgeFocusLanded } from './focus-landed.js';
|
|
6
|
+
export function judgeTowerGraph(state, containmentOf) {
|
|
7
|
+
const info = new Map(state.graphFoci.map((f) => [f.focusId, f]));
|
|
8
|
+
const landedCache = new Map();
|
|
9
|
+
const landed = (focusId) => {
|
|
10
|
+
const cached = landedCache.get(focusId);
|
|
11
|
+
if (cached)
|
|
12
|
+
return cached;
|
|
13
|
+
const f = info.get(focusId);
|
|
14
|
+
let result;
|
|
15
|
+
if (!f)
|
|
16
|
+
result = 'unknown';
|
|
17
|
+
else if (judgeFocusLanded(f.deliveryStatuses, 'contained') !== 'landed')
|
|
18
|
+
result = 'not_landed';
|
|
19
|
+
else
|
|
20
|
+
result = judgeFocusLanded(f.deliveryStatuses, containmentOf(f));
|
|
21
|
+
landedCache.set(focusId, result);
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
const nameOf = (focusId) => info.get(focusId)?.focusName ?? focusId.slice(0, 8);
|
|
25
|
+
const waitsOn = new Map();
|
|
26
|
+
const excludes = new Map();
|
|
27
|
+
const unavailableFocusIds = new Set();
|
|
28
|
+
const armed = new Set(state.foci.map((f) => f.focusId));
|
|
29
|
+
for (const focusId of armed) {
|
|
30
|
+
const predecessors = state.edges
|
|
31
|
+
.filter((e) => e.kind === 'depends_on' && e.toFocusId === focusId)
|
|
32
|
+
.map((e) => e.fromFocusId)
|
|
33
|
+
.sort((a, b) => nameOf(a).localeCompare(nameOf(b)));
|
|
34
|
+
const unlanded = predecessors.find((p) => landed(p) === 'not_landed');
|
|
35
|
+
if (unlanded)
|
|
36
|
+
waitsOn.set(focusId, { focusId: unlanded, focusName: nameOf(unlanded) });
|
|
37
|
+
else if (predecessors.some((p) => landed(p) === 'unknown'))
|
|
38
|
+
unavailableFocusIds.add(focusId);
|
|
39
|
+
}
|
|
40
|
+
for (const e of state.edges) {
|
|
41
|
+
if (e.kind !== 'excludes')
|
|
42
|
+
continue;
|
|
43
|
+
const add = (self, other) => {
|
|
44
|
+
const list = excludes.get(self) ?? [];
|
|
45
|
+
list.push({ otherFocusId: other, otherFocusName: nameOf(other), evidence: e.evidence });
|
|
46
|
+
excludes.set(self, list);
|
|
47
|
+
};
|
|
48
|
+
add(e.fromFocusId, e.toFocusId);
|
|
49
|
+
add(e.toFocusId, e.fromFocusId);
|
|
50
|
+
}
|
|
51
|
+
return { waitsOn, excludes, unavailableFocusIds };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tower-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-graph.js","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tower's status per product, published on the daemon heartbeat as
|
|
3
|
+
* `metadata.tower` ({ [productId]: { mode, pass } }; product-scoped,
|
|
4
|
+
* docs/heartbeat-metadata-audit.md) -- what the dashboard needs to say whether
|
|
5
|
+
* the product's tower is running at all:
|
|
6
|
+
*
|
|
7
|
+
* mode -- TELORA_TOWER_MODE on this daemon. `off`: there is no tower; the
|
|
8
|
+
* dashboard shows no tower line.
|
|
9
|
+
* pass -- this daemon's pass standing for the product (tower-pass-standing.ts).
|
|
10
|
+
* Anything but `ok` means admission fails open on every focus of the
|
|
11
|
+
* product, whatever verdicts they carry -- the dashboard says so even
|
|
12
|
+
* when NO focus carries a verdict (the all-missing case after a start
|
|
13
|
+
* or a failed pass).
|
|
14
|
+
*
|
|
15
|
+
* Pure over its reads; bound at the composition root
|
|
16
|
+
* (composition/runtime-heartbeat-context.ts).
|
|
17
|
+
*/
|
|
18
|
+
import type { TowerAdmissionDeps } from './tower-admission.js';
|
|
19
|
+
import type { TowerPassStanding } from './tower-pass-standing.js';
|
|
20
|
+
import type { TowerMode } from '@telora/daemon-core';
|
|
21
|
+
export interface TowerHeartbeatStatus {
|
|
22
|
+
mode: TowerMode;
|
|
23
|
+
pass: TowerPassStanding;
|
|
24
|
+
}
|
|
25
|
+
export declare function buildTowerStatusByProduct(products: ReadonlyArray<{
|
|
26
|
+
id: string;
|
|
27
|
+
}>, tower: TowerAdmissionDeps): Record<string, TowerHeartbeatStatus>;
|
|
28
|
+
//# sourceMappingURL=tower-heartbeat-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-heartbeat-status.d.ts","sourceRoot":"","sources":["../../src/tower/tower-heartbeat-status.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,EACvC,KAAK,EAAE,kBAAkB,GACxB,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAKtC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/tower-heartbeat-status.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
export function buildTowerStatusByProduct(products, tower) {
|
|
5
|
+
const mode = tower.mode();
|
|
6
|
+
const out = {};
|
|
7
|
+
for (const p of products)
|
|
8
|
+
out[p.id] = { mode, pass: tower.passStanding(p.id) };
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tower-heartbeat-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-heartbeat-status.js","sourceRoot":"","sources":["../../src/tower/tower-heartbeat-status.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,sEAAsE;AACtE,gBAAgB;AA6BhB,MAAM,UAAU,yBAAyB,CACvC,QAAuC,EACvC,KAAyB;IAEzB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAyC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC/E,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tower's rollout mode, TELORA_TOWER_MODE (declared, typed and validated in
|
|
3
|
+
* @telora/daemon-core env-config.ts): off | observe | enforce, default observe.
|
|
4
|
+
* See docs/runbook-tower.md for what each mode does and how a host moves from
|
|
5
|
+
* observe to enforce.
|
|
6
|
+
*/
|
|
7
|
+
import { type TowerMode } from '@telora/daemon-core';
|
|
8
|
+
export declare function resolveTowerMode(env?: NodeJS.ProcessEnv): TowerMode;
|
|
9
|
+
//# sourceMappingURL=tower-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-mode.d.ts","sourceRoot":"","sources":["../../src/tower/tower-mode.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEjF,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,CAIhF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/tower-production-pass.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* The tower's rollout mode, TELORA_TOWER_MODE (declared, typed and validated in
|
|
6
|
+
* @telora/daemon-core env-config.ts): off | observe | enforce, default observe.
|
|
7
|
+
* See docs/runbook-tower.md for what each mode does and how a host moves from
|
|
8
|
+
* observe to enforce.
|
|
9
|
+
*/
|
|
10
|
+
import { isTowerMode, loadEnvConfig } from '@telora/daemon-core';
|
|
11
|
+
export function resolveTowerMode(env = process.env) {
|
|
12
|
+
// env-config validates the value; the guard narrows its inferred string type.
|
|
13
|
+
const mode = loadEnvConfig(env).TELORA_TOWER_MODE;
|
|
14
|
+
return isTowerMode(mode) ? mode : 'observe';
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=tower-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-mode.js","sourceRoot":"","sources":["../../src/tower/tower-mode.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,qEAAqE;AACrE,gBAAgB;AAEhB;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAC;AAEjF,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,8EAA8E;IAC9E,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC;IAClD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type TowerPassStanding = 'ok' | 'failed' | 'not_run';
|
|
2
|
+
/** Record one product pass's outcome (tower-pass.ts runTowerPass). */
|
|
3
|
+
export declare function recordTowerPassOutcome(productId: string, ok: boolean, nowMs?: number): void;
|
|
4
|
+
/** The product's pass standing now. A focus with no product cannot be judged: not_run. */
|
|
5
|
+
export declare function towerPassStanding(productId: string | null | undefined, nowMs?: number): TowerPassStanding;
|
|
6
|
+
/** Test-only reset. */
|
|
7
|
+
export declare function resetTowerPassStanding(): void;
|
|
8
|
+
//# sourceMappingURL=tower-pass-standing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-pass-standing.d.ts","sourceRoot":"","sources":["../../src/tower/tower-pass-standing.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;AAI5D,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,GAAE,MAAmB,GAAG,IAAI,CAEvG;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,GAAE,MAAmB,GAAG,iBAAiB,CAMrH;AAED,uBAAuB;AACvB,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/tower-entrypoints.test.ts,
|
|
3
|
+
// packages/daemon/src/tower/tower-heartbeat-status.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
|
|
4
|
+
// packages/daemon/src/tower/tower-prd-arm.test.ts,
|
|
5
|
+
// packages/daemon/src/tower/tower-ready-row-ingestion.test.ts,
|
|
6
|
+
// packages/daemon/src/tower/tower-spawn-modes.test.ts
|
|
7
|
+
// PINNED-BY-END
|
|
8
|
+
/**
|
|
9
|
+
* Whether this daemon's tower pass for a product is STANDING -- the condition
|
|
10
|
+
* under which admission may obey a stored verdict at all.
|
|
11
|
+
*
|
|
12
|
+
* A stored verdict was written by some pass; it is only as good as the pass
|
|
13
|
+
* that keeps confirming it. When this process's most recent pass for the
|
|
14
|
+
* product failed -- or no pass for it has succeeded yet -- a still-fresh
|
|
15
|
+
* holding verdict in the database is a leftover, not a decision: admission
|
|
16
|
+
* fails open on it IMMEDIATELY (tower-admission.ts), rather than enforcing it
|
|
17
|
+
* until it ages out of the freshness bound. Another product's standing is
|
|
18
|
+
* untouched.
|
|
19
|
+
*
|
|
20
|
+
* ok -- the most recent pass for the product succeeded, within the
|
|
21
|
+
* freshness bound (TOWER_VERDICT_MAX_AGE_MS).
|
|
22
|
+
* failed -- the most recent pass for the product threw.
|
|
23
|
+
* not_run -- no pass for the product has succeeded within the bound (daemon
|
|
24
|
+
* start before the first pass, or a pass that stopped running).
|
|
25
|
+
*
|
|
26
|
+
* A leaf: in-process state, written by tower-pass.ts and read by admission
|
|
27
|
+
* through the spawn passes' deps (composition/spawn-pass-deps.ts).
|
|
28
|
+
*/
|
|
29
|
+
import { TOWER_VERDICT_MAX_AGE_MS } from '@telora/daemon-core';
|
|
30
|
+
const lastOutcome = new Map();
|
|
31
|
+
/** Record one product pass's outcome (tower-pass.ts runTowerPass). */
|
|
32
|
+
export function recordTowerPassOutcome(productId, ok, nowMs = Date.now()) {
|
|
33
|
+
lastOutcome.set(productId, { ok, atMs: nowMs });
|
|
34
|
+
}
|
|
35
|
+
/** The product's pass standing now. A focus with no product cannot be judged: not_run. */
|
|
36
|
+
export function towerPassStanding(productId, nowMs = Date.now()) {
|
|
37
|
+
if (!productId)
|
|
38
|
+
return 'not_run';
|
|
39
|
+
const last = lastOutcome.get(productId);
|
|
40
|
+
if (!last)
|
|
41
|
+
return 'not_run';
|
|
42
|
+
if (!last.ok)
|
|
43
|
+
return 'failed';
|
|
44
|
+
return nowMs - last.atMs > TOWER_VERDICT_MAX_AGE_MS ? 'not_run' : 'ok';
|
|
45
|
+
}
|
|
46
|
+
/** Test-only reset. */
|
|
47
|
+
export function resetTowerPassStanding() {
|
|
48
|
+
lastOutcome.clear();
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=tower-pass-standing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tower-pass-standing.js","sourceRoot":"","sources":["../../src/tower/tower-pass-standing.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,kEAAkE;AAClE,4GAA4G;AAC5G,qDAAqD;AACrD,iEAAiE;AACjE,wDAAwD;AACxD,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyC,CAAC;AAErE,sEAAsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,EAAW,EAAE,QAAgB,IAAI,CAAC,GAAG,EAAE;IAC/F,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,SAAoC,EAAE,QAAgB,IAAI,CAAC,GAAG,EAAE;IAChG,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,sBAAsB;IACpC,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}
|