@mjasnikovs/pi-task 0.38.29 → 0.38.30
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/dist/config/config.d.ts +70 -70
- package/dist/config/config.js +26 -35
- package/dist/config/extension-list.d.ts +6 -5
- package/dist/config/extension-list.js +3 -2
- package/dist/config/reasoning-args.d.ts +9 -7
- package/dist/config/reasoning-args.js +12 -10
- package/dist/config/reasoning.d.ts +44 -105
- package/dist/config/reasoning.js +27 -704
- package/dist/config/register.d.ts +34 -48
- package/dist/config/register.js +41 -51
- package/dist/config/tool-list.d.ts +16 -16
- package/dist/config/tool-list.js +1 -1
- package/dist/remote/bridge.d.ts +19 -10
- package/dist/remote/bridge.js +3 -2
- package/dist/remote/broadcast.js +3 -1
- package/dist/remote/events.js +12 -11
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/protocol.d.ts +6 -3
- package/dist/remote/protocol.js +2 -1
- package/dist/remote/push.d.ts +16 -16
- package/dist/remote/push.js +27 -27
- package/dist/remote/register.d.ts +3 -3
- package/dist/remote/register.js +17 -19
- package/dist/remote/server.d.ts +9 -8
- package/dist/remote/server.js +15 -14
- package/dist/remote/session-state.d.ts +5 -4
- package/dist/remote/session-state.js +8 -5
- package/dist/remote/sw.d.ts +7 -6
- package/dist/remote/sw.js +7 -6
- package/dist/remote/tailscale.d.ts +4 -2
- package/dist/remote/tailscale.js +4 -2
- package/dist/remote/ui-highlight.js +6 -5
- package/dist/remote/ui-render.js +4 -4
- package/dist/remote/ui-script.js +24 -24
- package/dist/remote/ui-styles.d.ts +1 -1
- package/dist/remote/ui-styles.js +10 -13
- package/dist/remote/ui-tools.js +9 -6
- package/dist/shared/child-extensions.d.ts +29 -17
- package/dist/shared/child-extensions.js +29 -17
- package/dist/shared/child-output.d.ts +30 -24
- package/dist/shared/child-output.js +25 -17
- package/dist/shared/child-process.d.ts +47 -40
- package/dist/shared/child-process.js +50 -59
- package/dist/shared/command-watchdog.d.ts +22 -16
- package/dist/shared/command-watchdog.js +28 -21
- package/dist/shared/fs-text.d.ts +16 -10
- package/dist/shared/fs-text.js +16 -10
- package/dist/shared/git-runner.d.ts +25 -25
- package/dist/shared/git-runner.js +25 -25
- package/dist/shared/leaked-tool-call.d.ts +17 -11
- package/dist/shared/leaked-tool-call.js +23 -15
- package/dist/shared/model-endpoint.d.ts +29 -16
- package/dist/shared/model-endpoint.js +33 -21
- package/dist/shared/pi-invocation.d.ts +7 -4
- package/dist/shared/pi-invocation.js +12 -7
- package/dist/shared/pkg-version.d.ts +13 -5
- package/dist/shared/pkg-version.js +13 -5
- package/dist/shared/reasoning-capability.d.ts +35 -24
- package/dist/shared/reasoning-capability.js +35 -24
- package/dist/shared/stream-watchdog.d.ts +60 -44
- package/dist/shared/stream-watchdog.js +62 -45
- package/dist/task/accept-debt.d.ts +41 -43
- package/dist/task/accept-debt.js +73 -65
- package/dist/task/api-synthesis.d.ts +24 -21
- package/dist/task/api-synthesis.js +32 -26
- package/dist/task/apis-contract.d.ts +32 -64
- package/dist/task/apis-contract.js +32 -64
- package/dist/task/artifact-closure.d.ts +27 -13
- package/dist/task/artifact-closure.js +95 -67
- package/dist/task/auto-commit.d.ts +46 -35
- package/dist/task/auto-commit.js +51 -38
- package/dist/task/auto-io.d.ts +45 -25
- package/dist/task/auto-io.js +57 -29
- package/dist/task/auto-orchestrator.d.ts +26 -24
- package/dist/task/auto-orchestrator.js +178 -162
- package/dist/task/auto-prompts.d.ts +36 -24
- package/dist/task/auto-prompts.js +40 -26
- package/dist/task/autofix-ledger.d.ts +27 -25
- package/dist/task/autofix-ledger.js +29 -26
- package/dist/task/batch-test-task.d.ts +20 -12
- package/dist/task/batch-test-task.js +67 -60
- package/dist/task/boot-probe.d.ts +60 -44
- package/dist/task/boot-probe.js +91 -72
- package/dist/task/cancel-input.d.ts +30 -16
- package/dist/task/cancel-input.js +20 -11
- package/dist/task/cancel-points.d.ts +27 -20
- package/dist/task/cancel-points.js +30 -22
- package/dist/task/child-runner.d.ts +46 -51
- package/dist/task/child-runner.js +48 -49
- package/dist/task/child-status.d.ts +23 -16
- package/dist/task/child-status.js +23 -16
- package/dist/task/clamp-output.js +12 -5
- package/dist/task/command-run.d.ts +31 -28
- package/dist/task/command-run.js +44 -35
- package/dist/task/command-shrink.d.ts +25 -18
- package/dist/task/command-shrink.js +37 -31
- package/dist/task/command-watchdog.d.ts +9 -6
- package/dist/task/command-watchdog.js +21 -15
- package/dist/task/context-attribution.d.ts +34 -26
- package/dist/task/context-attribution.js +34 -26
- package/dist/task/context-silence.d.ts +39 -29
- package/dist/task/context-silence.js +35 -25
- package/dist/task/context-usage.d.ts +16 -9
- package/dist/task/context-usage.js +16 -9
- package/dist/task/contracts.d.ts +8 -4
- package/dist/task/contracts.js +25 -17
- package/dist/task/coverage-loop.d.ts +22 -18
- package/dist/task/coverage-loop.js +35 -30
- package/dist/task/critique-probes.d.ts +13 -14
- package/dist/task/critique-probes.js +50 -39
- package/dist/task/debug-log.d.ts +13 -5
- package/dist/task/debug-log.js +32 -20
- package/dist/task/decompose-fidelity.d.ts +11 -9
- package/dist/task/decompose-fidelity.js +38 -33
- package/dist/task/decompose-granularity.d.ts +41 -38
- package/dist/task/decompose-granularity.js +41 -38
- package/dist/task/deep-render-check.d.ts +22 -14
- package/dist/task/deep-render-check.js +40 -31
- package/dist/task/dropped-input.d.ts +12 -7
- package/dist/task/dropped-input.js +5 -2
- package/dist/task/enforce-attribution.d.ts +38 -47
- package/dist/task/enforce-attribution.js +46 -52
- package/dist/task/enforce-guidelines.d.ts +31 -20
- package/dist/task/enforce-guidelines.js +32 -21
- package/dist/task/enrichment.d.ts +7 -2
- package/dist/task/enrichment.js +26 -14
- package/dist/task/env-notes.d.ts +16 -7
- package/dist/task/env-notes.js +48 -31
- package/dist/task/env-template-closure.d.ts +4 -4
- package/dist/task/env-template-closure.js +42 -34
- package/dist/task/external-context.d.ts +28 -21
- package/dist/task/external-context.js +17 -12
- package/dist/task/failure-classifier.d.ts +4 -5
- package/dist/task/failure-classifier.js +6 -7
- package/dist/task/file-inventory.d.ts +15 -11
- package/dist/task/file-inventory.js +25 -22
- package/dist/task/final-gate-fix.d.ts +74 -86
- package/dist/task/final-gate-fix.js +97 -116
- package/dist/task/final-gate-progress.d.ts +29 -46
- package/dist/task/final-gate-progress.js +40 -51
- package/dist/task/final-gate.d.ts +64 -97
- package/dist/task/final-gate.js +192 -199
- package/dist/task/fix-child.d.ts +21 -27
- package/dist/task/fix-child.js +21 -27
- package/dist/task/foreign-path.d.ts +6 -5
- package/dist/task/foreign-path.js +0 -0
- package/dist/task/frozen-conflict.d.ts +9 -10
- package/dist/task/frozen-conflict.js +61 -64
- package/dist/task/frozen-path-guard.d.ts +35 -14
- package/dist/task/frozen-path-guard.js +56 -39
- package/dist/task/gate-child.d.ts +27 -28
- package/dist/task/gate-child.js +36 -35
- package/dist/task/gate-deps.d.ts +34 -27
- package/dist/task/gate-deps.js +169 -159
- package/dist/task/gate-tally.d.ts +77 -80
- package/dist/task/gate-tally.js +65 -68
- package/dist/task/git-state-guard.d.ts +15 -11
- package/dist/task/git-state-guard.js +76 -66
- package/dist/task/impl-widget.d.ts +25 -16
- package/dist/task/impl-widget.js +27 -17
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +34 -31
- package/dist/task/implementation-turn.js +29 -27
- package/dist/task/inline-markdown.d.ts +20 -7
- package/dist/task/inline-markdown.js +15 -6
- package/dist/task/launch-config-gap.js +25 -39
- package/dist/task/launch-contract.d.ts +18 -21
- package/dist/task/launch-contract.js +28 -30
- package/dist/task/launch-manifest.d.ts +6 -2
- package/dist/task/launch-manifest.js +35 -34
- package/dist/task/ledger.js +16 -14
- package/dist/task/lint-fix.d.ts +6 -8
- package/dist/task/lint-fix.js +67 -69
- package/dist/task/loop-detector.d.ts +9 -8
- package/dist/task/loop-detector.js +16 -12
- package/dist/task/mid-run-input.d.ts +17 -15
- package/dist/task/mid-run-input.js +17 -15
- package/dist/task/orchestrator.d.ts +24 -28
- package/dist/task/orchestrator.js +62 -64
- package/dist/task/orientation.d.ts +18 -23
- package/dist/task/orientation.js +24 -31
- package/dist/task/owned-freeze-conflict.d.ts +21 -20
- package/dist/task/owned-freeze-conflict.js +52 -85
- package/dist/task/owned-freeze-reassign.d.ts +40 -60
- package/dist/task/owned-freeze-reassign.js +41 -61
- package/dist/task/parsers.d.ts +4 -2
- package/dist/task/parsers.js +4 -4
- package/dist/task/phases.d.ts +41 -48
- package/dist/task/phases.js +179 -248
- package/dist/task/plan-io.d.ts +6 -7
- package/dist/task/plan-io.js +6 -7
- package/dist/task/plan-orchestrator.d.ts +10 -8
- package/dist/task/plan-orchestrator.js +14 -10
- package/dist/task/plan-prompts.d.ts +6 -5
- package/dist/task/plan-prompts.js +6 -5
- package/dist/task/plan-readonly.d.ts +4 -5
- package/dist/task/plan-readonly.js +4 -5
- package/dist/task/plan-rounds.d.ts +17 -29
- package/dist/task/plan-rounds.js +21 -34
- package/dist/task/plan-session.d.ts +58 -72
- package/dist/task/plan-session.js +61 -83
- package/dist/task/probe-gaming.d.ts +28 -27
- package/dist/task/probe-gaming.js +0 -0
- package/dist/task/prohibition-probe.d.ts +14 -16
- package/dist/task/prompts.d.ts +3 -4
- package/dist/task/prompts.js +17 -26
- package/dist/task/qa-transcript.d.ts +15 -22
- package/dist/task/qa-transcript.js +15 -21
- package/dist/task/question-box.d.ts +17 -13
- package/dist/task/question-box.js +19 -15
- package/dist/task/question-dedup.d.ts +6 -7
- package/dist/task/question-dedup.js +13 -14
- package/dist/task/question-dialog.d.ts +22 -32
- package/dist/task/question-dialog.js +22 -32
- package/dist/task/question-source.d.ts +18 -44
- package/dist/task/question-source.js +22 -51
- package/dist/task/refuted-constraint.d.ts +11 -31
- package/dist/task/refuted-constraint.js +27 -51
- package/dist/task/regenerable-artifacts.d.ts +12 -31
- package/dist/task/regenerable-artifacts.js +12 -31
- package/dist/task/render-check.d.ts +11 -22
- package/dist/task/render-check.js +33 -46
- package/dist/task/repo-health-check.d.ts +10 -14
- package/dist/task/repo-health-check.js +17 -23
- package/dist/task/requirements.d.ts +38 -71
- package/dist/task/requirements.js +78 -126
- package/dist/task/research-fanout-budget.d.ts +51 -88
- package/dist/task/research-fanout-budget.js +51 -88
- package/dist/task/research-worker.d.ts +29 -39
- package/dist/task/research-worker.js +37 -61
- package/dist/task/resume-gap.d.ts +14 -15
- package/dist/task/root-cause-repair.d.ts +9 -9
- package/dist/task/root-cause-repair.js +28 -40
- package/dist/task/run-bracket.d.ts +10 -13
- package/dist/task/run-end.d.ts +12 -22
- package/dist/task/run-end.js +8 -16
- package/dist/task/run-final-gate.d.ts +19 -21
- package/dist/task/run-final-gate.js +62 -80
- package/dist/task/runner-globs.d.ts +12 -13
- package/dist/task/runner-globs.js +12 -13
- package/dist/task/runner-resolve.d.ts +9 -9
- package/dist/task/runner-resolve.js +22 -23
- package/dist/task/script-escape.d.ts +10 -12
- package/dist/task/script-escape.js +13 -14
- package/dist/task/serve-entry.d.ts +1 -1
- package/dist/task/serve-entry.js +22 -25
- package/dist/task/service-blocks.js +4 -2
- package/dist/task/shipped-source.d.ts +11 -29
- package/dist/task/shipped-source.js +11 -29
- package/dist/task/skip-escape.js +10 -14
- package/dist/task/spec-urls.d.ts +26 -65
- package/dist/task/spec-urls.js +26 -65
- package/dist/task/spec-validation.d.ts +17 -20
- package/dist/task/spec-validation.js +17 -20
- package/dist/task/stall-detector.d.ts +23 -30
- package/dist/task/stall-detector.js +23 -30
- package/dist/task/stream-watchdog.d.ts +14 -12
- package/dist/task/stream-watchdog.js +14 -12
- package/dist/task/substitution-probe.d.ts +17 -20
- package/dist/task/substitution-probe.js +17 -20
- package/dist/task/task-gates.d.ts +36 -41
- package/dist/task/task-gates.js +95 -106
- package/dist/task/task-io.d.ts +4 -4
- package/dist/task/task-io.js +4 -4
- package/dist/task/task-parsers.js +4 -3
- package/dist/task/task-provenance.d.ts +2 -2
- package/dist/task/task-provenance.js +11 -13
- package/dist/task/task-types.d.ts +4 -3
- package/dist/task/terminal-outcome.d.ts +14 -16
- package/dist/task/terminal-outcome.js +12 -14
- package/dist/task/test-assembly.d.ts +13 -20
- package/dist/task/test-assembly.js +13 -20
- package/dist/task/timings.d.ts +5 -3
- package/dist/task/timings.js +5 -3
- package/dist/task/title-label.d.ts +9 -4
- package/dist/task/title-label.js +9 -4
- package/dist/task/type-only-answer.d.ts +44 -52
- package/dist/task/type-only-answer.js +44 -52
- package/dist/task/unfailable-command.d.ts +18 -24
- package/dist/task/unfailable-command.js +21 -27
- package/dist/task/unknown-routing.d.ts +10 -4
- package/dist/task/unknown-routing.js +10 -4
- package/dist/task/user-directives.d.ts +5 -8
- package/dist/task/user-directives.js +5 -8
- package/dist/task/verify-quality.d.ts +18 -22
- package/dist/task/verify-quality.js +45 -46
- package/dist/task/verify-reconcile.d.ts +15 -10
- package/dist/task/verify-reconcile.js +45 -43
- package/dist/task/verify-resolution.d.ts +24 -20
- package/dist/task/verify-resolution.js +51 -50
- package/dist/task/verify-work.d.ts +59 -66
- package/dist/task/verify-work.js +101 -138
- package/dist/task/widget.d.ts +15 -14
- package/dist/task/widget.js +22 -17
- package/dist/task/wiring-claims.d.ts +25 -32
- package/dist/task/wiring-claims.js +30 -35
- package/dist/task/write-guard.d.ts +39 -39
- package/dist/task/write-guard.js +48 -51
- package/dist/task/yolo.d.ts +34 -30
- package/dist/task/yolo.js +42 -37
- package/dist/workers/abstention.d.ts +21 -41
- package/dist/workers/abstention.js +27 -48
- package/dist/workers/brave-search.d.ts +4 -3
- package/dist/workers/brave-search.js +5 -2
- package/dist/workers/brave-warning.d.ts +7 -4
- package/dist/workers/brave-warning.js +19 -7
- package/dist/workers/ddg-search.d.ts +6 -6
- package/dist/workers/ddg-search.js +18 -12
- package/dist/workers/docs-cache.js +5 -2
- package/dist/workers/docs-chunk.d.ts +30 -37
- package/dist/workers/docs-chunk.js +37 -41
- package/dist/workers/docs-core.d.ts +28 -44
- package/dist/workers/docs-core.js +25 -44
- package/dist/workers/docs-index.js +4 -3
- package/dist/workers/docs-lookup.d.ts +15 -22
- package/dist/workers/docs-lookup.js +12 -21
- package/dist/workers/docs-project.d.ts +15 -9
- package/dist/workers/docs-project.js +17 -10
- package/dist/workers/docs-resolve.d.ts +19 -20
- package/dist/workers/docs-resolve.js +35 -32
- package/dist/workers/docs-retrieve.d.ts +5 -6
- package/dist/workers/docs-retrieve.js +18 -15
- package/dist/workers/exa-search.d.ts +9 -6
- package/dist/workers/exa-search.js +23 -12
- package/dist/workers/fetch-core.d.ts +13 -16
- package/dist/workers/fetch-core.js +23 -23
- package/dist/workers/focused-extractor.d.ts +12 -12
- package/dist/workers/focused-extractor.js +16 -19
- package/dist/workers/html-clean.js +24 -14
- package/dist/workers/http-request.d.ts +28 -20
- package/dist/workers/http-request.js +22 -17
- package/dist/workers/npm-version.d.ts +28 -11
- package/dist/workers/npm-version.js +24 -15
- package/dist/workers/phantom-imports.d.ts +15 -12
- package/dist/workers/phantom-imports.js +30 -24
- package/dist/workers/pi-worker-core.d.ts +69 -71
- package/dist/workers/pi-worker-core.js +100 -109
- package/dist/workers/pi-worker-docs.d.ts +24 -19
- package/dist/workers/pi-worker-docs.js +67 -76
- package/dist/workers/pi-worker-fetch.d.ts +7 -3
- package/dist/workers/pi-worker-fetch.js +27 -19
- package/dist/workers/pi-worker-search.js +12 -8
- package/dist/workers/pi-worker.d.ts +9 -4
- package/dist/workers/pi-worker.js +21 -14
- package/dist/workers/reasoning-warning.d.ts +18 -17
- package/dist/workers/reasoning-warning.js +22 -20
- package/dist/workers/research-cache.js +50 -78
- package/dist/workers/search-core.js +7 -5
- package/dist/workers/search-types.d.ts +10 -9
- package/dist/workers/search-types.js +9 -8
- package/dist/workers/session-hint.d.ts +13 -14
- package/dist/workers/session-hint.js +8 -9
- package/dist/workers/shared.d.ts +21 -25
- package/dist/workers/shared.js +0 -0
- package/dist/workers/single-read-extension.d.ts +14 -7
- package/dist/workers/single-read-extension.js +14 -7
- package/dist/workers/single-read-guard.d.ts +25 -28
- package/dist/workers/single-read-guard.js +32 -32
- package/dist/workers/typeonly-log.d.ts +12 -9
- package/dist/workers/typeonly-log.js +29 -33
- package/dist/workers/worker-channels.d.ts +15 -23
- package/dist/workers/worker-channels.js +15 -23
- package/dist/workers/worker-failure.d.ts +38 -46
- package/dist/workers/worker-failure.js +31 -39
- package/dist/workers/worker-kill.d.ts +25 -26
- package/dist/workers/worker-kill.js +16 -19
- package/dist/workers/worker-profiles.d.ts +43 -53
- package/dist/workers/worker-profiles.js +30 -38
- package/package.json +10 -8
package/dist/task/final-gate.js
CHANGED
|
@@ -2,48 +2,47 @@
|
|
|
2
2
|
* final-gate — the run-level integration gate /task-auto runs ONCE, after every
|
|
3
3
|
* task is checked off and before the run is declared complete.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* tasks verified. Per-task repo-health closes the static half; nothing ever ran
|
|
10
|
-
* the project's own test/build commands against the finished whole.
|
|
5
|
+
* Every other gate in this extension is per-task, so a run can finish with each
|
|
6
|
+
* slice individually blessed while the ASSEMBLED project is dead. Per-task
|
|
7
|
+
* repo-health covers the static half; nothing else runs the project's own
|
|
8
|
+
* test/build/start commands against the finished whole.
|
|
11
9
|
*
|
|
12
|
-
* Like repo-health-check
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
10
|
+
* Like repo-health-check, whose discovery style it mirrors, it is deterministic:
|
|
11
|
+
* no model, no per-file narrowing. It discovers the project's OWN commands and
|
|
12
|
+
* lets their REAL exit codes decide. `runFinalIntegrationGate` runs the sections
|
|
13
|
+
* in this order:
|
|
16
14
|
*
|
|
17
|
-
* - static analysis
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* exit 0 → PASS (CLI-style),
|
|
28
|
-
* the
|
|
29
|
-
*
|
|
15
|
+
* - static analysis (runRepoHealthCheck), then
|
|
16
|
+
* - the launch-contract diff and the `pre-discovery` closure scans, which need
|
|
17
|
+
* no runner at all, then
|
|
18
|
+
* - lockfile↔manifest consistency — a lockfile can carry a dependency no
|
|
19
|
+
* committed manifest declares, so the tree tests green here while a FRESH
|
|
20
|
+
* CHECKOUT cannot install; each ecosystem's own non-mutating "is the lock in
|
|
21
|
+
* sync" command decides, then
|
|
22
|
+
* - the project's own test and build commands, verbatim and unaided, then
|
|
23
|
+
* - the declared launch scripts, one-shot, then
|
|
24
|
+
* - one boot exercise of the start command. No ports, URLs or framework
|
|
25
|
+
* knowledge: fast non-zero exit → FAIL, quick exit 0 → PASS (CLI-style),
|
|
26
|
+
* still alive after the grace window → PASS, and the whole process group is
|
|
27
|
+
* killed, because scripts spawn children and a leaked child server masks
|
|
28
|
+
* every later boot check with a port collision, then
|
|
29
|
+
* - the blindness guard and the `post-boot` closure scans.
|
|
30
|
+
*
|
|
31
|
+
* EVERY section runs and the failures AGGREGATE into one ranked list; nothing
|
|
32
|
+
* early-returns on the first failure.
|
|
30
33
|
*
|
|
31
34
|
* Environment-gap safety, same contract as repo-health-check: a command that
|
|
32
35
|
* CANNOT run (ENOENT, exit 127 = command-not-found inside the script chain, or a
|
|
33
|
-
* timeout) is an environment problem, not a code fault —
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* (accept / leave failed), so a genuine external gap can still be overridden.
|
|
36
|
+
* timeout) is an environment problem, not a code fault — SKIPPED, never failed.
|
|
37
|
+
* Only a command that actually ran and exited non-zero fails the gate, and the
|
|
38
|
+
* reason carries the tail of its real output so the user and a resume fix can act
|
|
39
|
+
* on it. A test suite that needs a database still fails here when the database is
|
|
40
|
+
* reachable-but-mis-wired, and the caller puts a human on that decision, so a
|
|
41
|
+
* genuine external gap can be overridden.
|
|
40
42
|
*
|
|
41
|
-
* A skip is never silent
|
|
42
|
-
*
|
|
43
|
-
* cancel it.
|
|
44
|
-
* scripts/boot-skip-baserate.ts base rate, shipped gate, before the change
|
|
45
|
-
* scripts/boot-skip-verdict-ab.ts two-armed deterministic A/B + invariants
|
|
46
|
-
* scripts/boot-skip-fp-suite.ts zero-FP arms over every local repo
|
|
43
|
+
* A skip is never silent: a DISCOVERED boot command that never ran is its own
|
|
44
|
+
* verdict, kept outside the tally's dynamic counters so nothing else the gate
|
|
45
|
+
* observed can cancel it.
|
|
47
46
|
*/
|
|
48
47
|
import { existsSync, readFileSync } from 'node:fs';
|
|
49
48
|
import * as path from 'node:path';
|
|
@@ -69,35 +68,33 @@ import { VERIFY_FAIL_PREFIX } from './verify-work.js';
|
|
|
69
68
|
* manifest that exists wins, mirroring discoverHealthCommands. Empty means
|
|
70
69
|
* "nothing to run" — the static half may still gate.
|
|
71
70
|
*
|
|
72
|
-
* THE MANIFEST ALLOWLIST BELOW IS NARROW, AND THAT IS A KNOWN
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* rather than as a PASS (see
|
|
76
|
-
*
|
|
71
|
+
* THE MANIFEST ALLOWLIST BELOW IS NARROW, AND THAT IS A KNOWN GAP: a project with
|
|
72
|
+
* no package.json, Makefile, Cargo.toml, go.mod or pyproject.toml discovers
|
|
73
|
+
* NOTHING here, and so does a package.json whose only script is named something
|
|
74
|
+
* else. That outcome is reported as UNOBSERVED rather than as a PASS (see
|
|
75
|
+
* unobservedVerdict), which makes the blindness loud — it does not remove it.
|
|
77
76
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* minutes of hang. Full numbers, the reproduction rig, and why no pre-execution
|
|
86
|
-
* filter can separate a fabricated command from a real one:
|
|
87
|
-
* scripts/harvest-verified-tooling-step0.ts. DO NOT re-propose the harvest without
|
|
88
|
-
* first fixing the PROVENANCE of `## verified tooling` (record cwd + exit code at
|
|
89
|
-
* authoring time); widening this allowlist tool-by-tool is not the fix either.
|
|
77
|
+
* DO NOT close the gap by harvesting each task's own `## verified tooling`
|
|
78
|
+
* section. That section is the parsed output of a model child (phases.ts writes
|
|
79
|
+
* it from the verify-tooling worker), and despite its name nothing records the
|
|
80
|
+
* cwd the command was tried in or the code it exited with — so a fabricated
|
|
81
|
+
* command is indistinguishable from a real one before it runs, and running it is
|
|
82
|
+
* how the gate would find out. Fix that provenance first. Widening this allowlist
|
|
83
|
+
* tool-by-tool is not the fix either.
|
|
90
84
|
*/
|
|
91
85
|
export function discoverIntegrationCommands(cwd) {
|
|
92
86
|
if (existsSync(path.join(cwd, 'package.json'))) {
|
|
93
87
|
const s = packageScripts(cwd);
|
|
94
88
|
const cmds = [];
|
|
95
|
-
// Every test-shaped script, not just the one literally named `test
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// `test
|
|
99
|
-
//
|
|
100
|
-
//
|
|
89
|
+
// Every test-shaped script, not just the one literally named `test`: a
|
|
90
|
+
// project's only browser-executing suite is often `test:ct` or similar, and
|
|
91
|
+
// looking for `test` alone never runs it. Plain `test` leads, then every
|
|
92
|
+
// `test:`/`test_`/`test-` prefixed name in declaration order (Array#sort is
|
|
93
|
+
// stable), then `build`. Measured on a manifest declaring test:ct, build,
|
|
94
|
+
// test_unit, test-e2e, test, testing and pretest, the result is exactly
|
|
95
|
+
// test, test:ct, test_unit, test-e2e, build — `testing` and `pretest` do
|
|
96
|
+
// not match. Env-gap SKIP still applies per command: a suite whose browser
|
|
97
|
+
// or runtime is absent skips rather than fails (see runGateCommand).
|
|
101
98
|
const testNames = Object.keys(s).filter(n => n === 'test' || /^test[:_-]/.test(n));
|
|
102
99
|
testNames.sort((a, b) => a === 'test' ? -1
|
|
103
100
|
: b === 'test' ? 1
|
|
@@ -141,11 +138,18 @@ export function discoverIntegrationCommands(cwd) {
|
|
|
141
138
|
}
|
|
142
139
|
/**
|
|
143
140
|
* Per-ecosystem lockfile↔manifest consistency checks. A check applies only when
|
|
144
|
-
* BOTH the manifest and its lockfile exist
|
|
145
|
-
* and every command is
|
|
146
|
-
* with the manifest" form
|
|
147
|
-
*
|
|
148
|
-
* the
|
|
141
|
+
* BOTH the manifest and its lockfile exist — no lockfile means nothing to verify
|
|
142
|
+
* — and every command is that ecosystem's own non-mutating "is the lock in sync
|
|
143
|
+
* with the manifest" form.
|
|
144
|
+
*
|
|
145
|
+
* Four of the six were run against real throwaway projects, in sync and then with
|
|
146
|
+
* one dependency added to the manifest only. Each exited 0 in sync and non-zero
|
|
147
|
+
* on the desync, and left the lockfile byte-identical either way:
|
|
148
|
+
* `bun install --frozen-lockfile --dry-run` 0/1, `npm ci --dry-run` 0/1 (and it
|
|
149
|
+
* does not remove node_modules), `cargo metadata --locked` 0/101,
|
|
150
|
+
* `uv lock --check` 0/1. The `go` and `poetry` rows could not be run here — those
|
|
151
|
+
* binaries are not installed on this box — so they are asserted, not measured.
|
|
152
|
+
* A desync does reach the network; only the in-sync path is offline.
|
|
149
153
|
*/
|
|
150
154
|
const LOCKFILE_CHECKS = [
|
|
151
155
|
{
|
|
@@ -200,11 +204,11 @@ export function discoverGateCommandLabels(cwd) {
|
|
|
200
204
|
* The RESOLVED BODY of every discoverable gate command, keyed by the same label
|
|
201
205
|
* `discoverGateCommandLabels` produces.
|
|
202
206
|
*
|
|
203
|
-
* The label is what the gate CALLS; the body is what actually runs.
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
207
|
+
* The label is what the gate CALLS; the body is what actually runs. A fix pass
|
|
208
|
+
* can rewrite `scripts.test` to run one subdirectory and leave the label
|
|
209
|
+
* `bun run test` identical, so the label guard sees nothing while the suite stops
|
|
210
|
+
* covering the repository. The shrink guard compares these bodies (see
|
|
211
|
+
* command-shrink.ts).
|
|
208
212
|
*
|
|
209
213
|
* A command with no indirection (`cargo test --quiet`, `pytest -q`) resolves to
|
|
210
214
|
* itself: it cannot be narrowed without changing the label, which the label
|
|
@@ -260,7 +264,7 @@ async function runGateCommand(cwd, [bin, args], timeoutMs, extraGapRe,
|
|
|
260
264
|
envOverride,
|
|
261
265
|
/** The spawner. Injected so the gate's own tests can script a verdict. */
|
|
262
266
|
run = spawnCommand, signal) {
|
|
263
|
-
// Runner resolution
|
|
267
|
+
// Runner resolution: a login-shell-stripped PATH left `bun`
|
|
264
268
|
// unspawnable, so every dynamic check skipped and the gate went blind. The
|
|
265
269
|
// resolved binary is spawned, and its directory rides on the child's PATH so
|
|
266
270
|
// the SCRIPT CHAIN can re-invoke the runner (`bun run test` runs `bun test`
|
|
@@ -280,46 +284,44 @@ run = spawnCommand, signal) {
|
|
|
280
284
|
return verdict;
|
|
281
285
|
}
|
|
282
286
|
// `runVerifyCommandLine` and its outcome type live in command-run.ts with the
|
|
283
|
-
// other command drivers; re-exported
|
|
287
|
+
// other command drivers; re-exported because the gate's own test suite reaches
|
|
288
|
+
// them through this module.
|
|
284
289
|
export { runVerifyCommandLine } from './command-run.js';
|
|
285
|
-
// The two verdict predicates — the
|
|
290
|
+
// The two verdict predicates — the full-blindness FAIL and the third,
|
|
286
291
|
// non-blocking UNOBSERVED verdict — live with the counters they read, in
|
|
287
|
-
// gate-tally.ts (GateTally). Re-exported
|
|
292
|
+
// gate-tally.ts (GateTally). Re-exported for the gate's own test suite.
|
|
288
293
|
export { observabilityGapFailure, unobservedVerdict };
|
|
289
|
-
// File → introducing-task provenance
|
|
290
|
-
//
|
|
291
|
-
// existing importers keep working.
|
|
294
|
+
// File → introducing-task provenance lives in task-provenance.ts, next to the
|
|
295
|
+
// cross-task deletion guards that use it; re-exported for the gate's own tests.
|
|
292
296
|
export { taskThatIntroduced };
|
|
293
|
-
// The boot probe
|
|
294
|
-
// src
|
|
295
|
-
//
|
|
296
|
-
// working unchanged. Same pattern as taskThatIntroduced above.
|
|
297
|
+
// The boot probe lives in boot-probe.ts. This module is its ONLY importer inside
|
|
298
|
+
// src/, so these re-exports exist for consumers outside it; of them, the gate's
|
|
299
|
+
// own test suite currently reaches only `bootSkipVerdict` through here.
|
|
297
300
|
export { discoverBootCommand, detectsServedApp, runBootCheck, runBootSection, bootSkipVerdict, nonLaunchScriptReason, rejectedLaunchScript, parseSsListeners, parseNetstatListeners, parseLsofListeners, pickFreePort, preferredDeclaredPort, canEnumerateListeners };
|
|
298
301
|
// The ACCEPT-debt re-check (`deriveOpenDebts`, `rerunDebtVerifyCommand`) lives in
|
|
299
|
-
// accept-debt.ts with the ledger it reads and writes; re-exported
|
|
300
|
-
// orchestrator
|
|
302
|
+
// accept-debt.ts with the ledger it reads and writes; re-exported because
|
|
303
|
+
// auto-orchestrator.ts imports `deriveOpenDebts` through this module.
|
|
301
304
|
export { deriveOpenDebts, rerunDebtVerifyCommand };
|
|
302
305
|
/**
|
|
303
306
|
* The run-level closure scans, in emission order within their stage.
|
|
304
307
|
*
|
|
305
308
|
* ONLY checks of this shape belong here. Four other checks in this gate are
|
|
306
|
-
* deliberately NOT rows: repo-health returns {ok, reason} and formats inline;
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* UN-COUNTS a dynamic observation; and the boot check is
|
|
310
|
-
* port-binding
|
|
311
|
-
* more escape hatches than content.
|
|
309
|
+
* deliberately NOT rows: repo-health returns {ok, reason} and formats inline; the
|
|
310
|
+
* launch-contract diff branches on manifest kind and can emit a NOTE instead of a
|
|
311
|
+
* failure; the launch config-gap produces neither a failure nor a note but
|
|
312
|
+
* UN-COUNTS a dynamic observation (`tally.unobserve()`); and the boot check is
|
|
313
|
+
* async, stateful and port-binding. Squeezing any of those in would mean a row
|
|
314
|
+
* type with more escape hatches than content.
|
|
312
315
|
*/
|
|
313
316
|
const CLOSURE_SCANS = [
|
|
314
317
|
{
|
|
315
|
-
// Serve-entry closure
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
//
|
|
319
|
-
//
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
// no runnable command at all must still fail this, not report UNOBSERVED.
|
|
318
|
+
// Serve-entry closure: the tree builds a server app, expects to serve (SPA
|
|
319
|
+
// fallback, a static read, a design clause), and NOTHING anywhere starts a
|
|
320
|
+
// listener — a module that ends at `export {app}` cannot be started at all.
|
|
321
|
+
// Static and synchronous, and unlike the boot check it is decidable in
|
|
322
|
+
// exactly the environment where a boot would skip. Hence `pre-discovery`: a
|
|
323
|
+
// project with no runnable command must still fail this rather than report
|
|
324
|
+
// UNOBSERVED.
|
|
323
325
|
id: 'serve-entry',
|
|
324
326
|
stage: 'pre-discovery',
|
|
325
327
|
rank: 0,
|
|
@@ -330,13 +332,12 @@ const CLOSURE_SCANS = [
|
|
|
330
332
|
}
|
|
331
333
|
},
|
|
332
334
|
{
|
|
333
|
-
// Artifact-production closure
|
|
334
|
-
//
|
|
335
|
-
//
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
// referencer + missing path.
|
|
335
|
+
// Artifact-production closure: a runtime file reference with NO producer
|
|
336
|
+
// anywhere ships silently — a server reading `dist/index.html` that no build
|
|
337
|
+
// step emits 404s every request behind a fully green plan. Deterministic
|
|
338
|
+
// scan of the shipped tree: literal references only, positive producer
|
|
339
|
+
// evidence required (artifact-closure.ts). Each dangle names the referencer
|
|
340
|
+
// and the missing path.
|
|
340
341
|
id: 'dangling-artifact',
|
|
341
342
|
stage: 'post-boot',
|
|
342
343
|
rank: 0,
|
|
@@ -346,16 +347,15 @@ const CLOSURE_SCANS = [
|
|
|
346
347
|
}
|
|
347
348
|
},
|
|
348
349
|
{
|
|
349
|
-
// Env-template closure
|
|
350
|
-
//
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
//
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
//
|
|
358
|
-
// Inert on any tree with no tracked template (ENOENT = pass).
|
|
350
|
+
// Env-template closure: a shipped source file requires an env var the
|
|
351
|
+
// shipped template never mentions. Without this the only symptom is the
|
|
352
|
+
// script's own non-zero exit, which an autofix can silence by writing the
|
|
353
|
+
// GITIGNORED `.env` — leaving a committed tree that still cannot run and
|
|
354
|
+
// nothing at run end saying why. Same shape and rank as the
|
|
355
|
+
// dangling-artifact scan: name the ARTIFACT that is wrong, statically,
|
|
356
|
+
// rather than only the command that failed. The formatter needs the
|
|
357
|
+
// template set as well as the finding, which is why scan and format are one
|
|
358
|
+
// row. Inert on any tree with no tracked template.
|
|
359
359
|
id: 'env-template',
|
|
360
360
|
stage: 'post-boot',
|
|
361
361
|
rank: 0,
|
|
@@ -400,17 +400,16 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
400
400
|
return inertClosure();
|
|
401
401
|
}
|
|
402
402
|
}, trackedFiles: trackedFilesFn = trackedFiles } = opts;
|
|
403
|
-
// ASYNC
|
|
404
|
-
//
|
|
405
|
-
// paint and a cancel can reach the child.
|
|
403
|
+
// ASYNC so the event loop keeps turning while the project's own lint runs: a
|
|
404
|
+
// loader can paint and a cancel can reach the child.
|
|
406
405
|
const stat = await runRepoHealthCheck(cwd, {
|
|
407
406
|
run: runCmd,
|
|
408
407
|
...(opts.signal === undefined ? {} : { signal: opts.signal })
|
|
409
408
|
});
|
|
410
|
-
// Debts are derived
|
|
411
|
-
// shape (GateTally.verdict)
|
|
412
|
-
//
|
|
413
|
-
//
|
|
409
|
+
// Debts are derived ONCE, before any section runs, and ride on every verdict
|
|
410
|
+
// shape (GateTally.verdict). `reason` stays purely mechanical because it seeds
|
|
411
|
+
// the autofix child's prompt, and a write-enabled child reads a recorded claim
|
|
412
|
+
// as an instruction.
|
|
414
413
|
const debts = await deriveOpenDebts(cwd, stat.ok, runCmd, opts.signal);
|
|
415
414
|
// Every section below RECORDS into the tally (failures ranked, the four
|
|
416
415
|
// dynamic counters, the notes) and the verdict is assembled ONCE at the end —
|
|
@@ -422,20 +421,20 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
422
421
|
// entered the ledger through EITHER altitude.
|
|
423
422
|
if (!stat.ok)
|
|
424
423
|
tally.fail(`${VERIFY_FAIL_PREFIX['static-checks']} ${stat.reason}`);
|
|
425
|
-
// Launch-contract diff
|
|
426
|
-
//
|
|
427
|
-
//
|
|
428
|
-
//
|
|
424
|
+
// Launch-contract diff: a design can declare scripts that fall through
|
|
425
|
+
// decompose and ship missing, unchecked. Diff the plan-time-extracted declared
|
|
426
|
+
// scripts against the manifest; a missing one is a launch-surface defect.
|
|
427
|
+
// FP-safe: an empty declared list means nothing was grounded, so no check runs.
|
|
429
428
|
//
|
|
430
|
-
// THE DIFF
|
|
431
|
-
//
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
429
|
+
// THE DIFF MUST NOT RUN WITHOUT A MANIFEST. `packageScripts` catches and
|
|
430
|
+
// returns {}, so diffing against its keys makes a project with NO package.json
|
|
431
|
+
// indistinguishable from one with no scripts — every declared script reported
|
|
432
|
+
// missing, naming a file the project was never meant to have. The extractor
|
|
433
|
+
// upstream scrapes any design that says "script", nothing about it is
|
|
434
|
+
// npm-shaped, and this text seeds the autofix child's prompt, so on a
|
|
435
|
+
// CMake/cargo project the repair it invites is to write a package.json.
|
|
437
436
|
// readLaunchManifest resolves package.json, else a Makefile's targets, else
|
|
438
|
-
// nothing — and nothing means
|
|
437
|
+
// nothing — and nothing means a note, never a failure and never a silent pass.
|
|
439
438
|
const declared = await readDeclaredScripts(cwd);
|
|
440
439
|
if (declared.length > 0) {
|
|
441
440
|
const manifest = readLaunchManifest(cwd);
|
|
@@ -476,33 +475,31 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
476
475
|
tally.ran(label);
|
|
477
476
|
}
|
|
478
477
|
}
|
|
479
|
-
// EXECUTE the launch contract
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
//
|
|
488
|
-
// bug" note excused the exact scripts that shipped broken).
|
|
478
|
+
// EXECUTE the launch contract: every declared script that is neither
|
|
479
|
+
// boot-class (the boot check below owns those) nor already covered by the
|
|
480
|
+
// integration commands above RUNS as a one-shot, in declared order. Existence
|
|
481
|
+
// is not launchability — a script can be present in the manifest and throw on
|
|
482
|
+
// its first call. The env-gap contract extends to missing external
|
|
483
|
+
// INFRASTRUCTURE here (no DB or daemon on this box → skip, not fail), and a
|
|
484
|
+
// skip whose script also carries a standing EXCUSE note is surfaced as an
|
|
485
|
+
// UNOBSERVED warning: the note may be covering a real defect the gate could
|
|
486
|
+
// not reach.
|
|
489
487
|
if (declared.length > 0) {
|
|
490
488
|
const covered = cmds.flatMap(([bin, args]) => (bin === 'bun' || bin === 'npm') && args[0] === 'run' && args[1] ? [args[1]] : []);
|
|
491
489
|
const skippedLaunch = [];
|
|
492
|
-
// A declared script the manifest doesn't expose is already a
|
|
493
|
-
// failure above; executing it too would double-report
|
|
494
|
-
//
|
|
495
|
-
//
|
|
496
|
-
//
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
// own A/B, not a free rider on an inertness fix.
|
|
490
|
+
// A declared script the manifest doesn't expose is already a
|
|
491
|
+
// launch-contract failure above; executing it too would double-report.
|
|
492
|
+
// EXECUTION STAYS npm-ONLY: the runner below is literally `bun run <name>`,
|
|
493
|
+
// so on a Makefile project `present` is empty from `packageScripts` and
|
|
494
|
+
// every declared target is skipped rather than run through the wrong tool.
|
|
495
|
+
// The diff above does speak Makefile; widening the RUNNER to match is a
|
|
496
|
+
// separate change.
|
|
500
497
|
const present = new Set(Object.keys(packageScripts(cwd)).map(s => s.toLowerCase()));
|
|
501
498
|
const scripts = packageScripts(cwd);
|
|
502
|
-
// CONFIG-GAP INPUTS
|
|
503
|
-
//
|
|
504
|
-
//
|
|
505
|
-
//
|
|
499
|
+
// CONFIG-GAP INPUTS, read once: the tracked file list and the union of every
|
|
500
|
+
// tracked env template's declared variables. Both are empty on a non-git tree
|
|
501
|
+
// or one with no template, which makes the whole check inert there — a
|
|
502
|
+
// project with no template gains no excuse. See launch-config-gap.ts.
|
|
506
503
|
const closure = envClosure(cwd);
|
|
507
504
|
const trackedForGap = closure.templates.length > 0 ? (trackedFilesFn(cwd) ?? []) : [];
|
|
508
505
|
const launchTimeout = Math.min(timeoutMs, 180_000);
|
|
@@ -521,17 +518,16 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
521
518
|
}
|
|
522
519
|
tally.observed();
|
|
523
520
|
if (r.outcome === 'fail') {
|
|
524
|
-
// A CONFIG GAP IS NOT A CODE FAULT
|
|
525
|
-
//
|
|
526
|
-
//
|
|
527
|
-
//
|
|
528
|
-
//
|
|
529
|
-
//
|
|
530
|
-
//
|
|
531
|
-
// reasons fails again with the values present and stays a FAIL
|
|
521
|
+
// A CONFIG GAP IS NOT A CODE FAULT. A script can exit non-zero only
|
|
522
|
+
// because a variable its own committed template DECLARES is absent
|
|
523
|
+
// from this box, where the only way to supply it is a gitignored
|
|
524
|
+
// `.env` no commit can contain. findLaunchConfigGap decides the
|
|
525
|
+
// static half; the dynamic half is this re-run with the variables
|
|
526
|
+
// supplied as synthetic placeholders, and the reclassification
|
|
527
|
+
// happens ONLY if that exits 0. A script that fails for its own
|
|
528
|
+
// reasons fails again with the values present and stays a FAIL: an
|
|
532
529
|
// absent variable is not a licence to ignore an exit code the code
|
|
533
|
-
// caused. Nothing is parsed from the child's stderr
|
|
534
|
-
// the project's, not the harness's.
|
|
530
|
+
// caused. Nothing is parsed from the child's stderr.
|
|
535
531
|
const gap = findLaunchConfigGap({
|
|
536
532
|
cwd,
|
|
537
533
|
script: name,
|
|
@@ -570,41 +566,38 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
570
566
|
}
|
|
571
567
|
}
|
|
572
568
|
}
|
|
573
|
-
// Boot + render ALWAYS runs
|
|
574
|
-
// construction
|
|
575
|
-
//
|
|
576
|
-
//
|
|
577
|
-
//
|
|
578
|
-
// commands that did run cannot cancel it.
|
|
569
|
+
// Boot + render ALWAYS runs. It is independent of test results by
|
|
570
|
+
// construction and carries the run's most load-bearing signal, so its failures
|
|
571
|
+
// rank FIRST in the aggregate and earlier failures cannot shadow it. A boot
|
|
572
|
+
// that never RAN is its own verdict, kept outside the tally's dynamic counters
|
|
573
|
+
// on purpose, so the test/build commands that did run cannot cancel it.
|
|
579
574
|
//
|
|
580
|
-
// ZERO DISCOVERY IS UNOBSERVED, NEVER A PASS (see unobservedVerdict
|
|
581
|
-
// zero-attempts branch of GateTally.verdict). Nothing
|
|
582
|
-
// ran, so the blindness guard below
|
|
583
|
-
//
|
|
584
|
-
//
|
|
585
|
-
//
|
|
586
|
-
//
|
|
587
|
-
//
|
|
588
|
-
//
|
|
589
|
-
//
|
|
590
|
-
//
|
|
591
|
-
//
|
|
592
|
-
//
|
|
593
|
-
// checked and was fine".
|
|
575
|
+
// ZERO DISCOVERY IS UNOBSERVED, NEVER A PASS (see unobservedVerdict and the
|
|
576
|
+
// zero-attempts branch of GateTally.verdict). Nothing discovered means nothing
|
|
577
|
+
// ran, so the blindness guard below cannot fire either —
|
|
578
|
+
// `observabilityGapFailure` returns null the moment `attempted === 0`. Calling
|
|
579
|
+
// that a PASS makes "we never checked" read identically to "we checked and it
|
|
580
|
+
// was fine", and a run can ship that verdict while carrying open verify-FAIL
|
|
581
|
+
// debt. The outcome stays `ok: true` and non-blocking, but is labelled,
|
|
582
|
+
// trailed and carried as debt by the caller. It needs no new command source, so
|
|
583
|
+
// unlike the harvest refused at discoverIntegrationCommands it cannot inject a
|
|
584
|
+
// fabricated failure. The inert-contract note rides on it: a non-npm project
|
|
585
|
+
// carrying a launch contract usually discovers no command either, and that is
|
|
586
|
+
// exactly the run whose silence must not read as "the contract was checked and
|
|
587
|
+
// was fine".
|
|
594
588
|
//
|
|
595
|
-
// This return sits AFTER the launch-script loop, not before it
|
|
596
|
-
//
|
|
597
|
-
// integration command
|
|
598
|
-
//
|
|
599
|
-
//
|
|
600
|
-
// before the boot `else` branch and the post-boot closure scans, whose stage is a
|
|
601
|
-
// statement about when they are meaningful.
|
|
589
|
+
// This return sits AFTER the launch-script loop, not before it. Firing first, a
|
|
590
|
+
// DECLARED launch script would never run on a tree with no discoverable
|
|
591
|
+
// integration command. The condition asks the TALLY — no attempt and no failure
|
|
592
|
+
// — rather than asking discovery, so both paths see the same state. It still
|
|
593
|
+
// returns before the boot section and the post-boot closure scans.
|
|
602
594
|
if (!boot && tally.silent())
|
|
603
595
|
return tally.verdict(debts);
|
|
604
596
|
// The boot CONCEPT lives in boot-probe.ts (runBootSection): discovery,
|
|
605
597
|
// served-app detection, the probe defaults, the boot check, orphan-port
|
|
606
598
|
// recovery, the port-holder diagnosis, the skip verdict and the
|
|
607
|
-
// rejected-launch-script branch.
|
|
599
|
+
// rejected-launch-script branch. What is left here is only the recording of
|
|
600
|
+
// its result into the tally.
|
|
608
601
|
const bootSection = await runBootSection(cwd, {
|
|
609
602
|
...(planText === undefined ? {} : { planText }),
|
|
610
603
|
...(bootGraceMs === undefined ? {} : { graceMs: bootGraceMs }),
|
|
@@ -628,17 +621,17 @@ export async function runFinalIntegrationGate(cwd, opts = {}) {
|
|
|
628
621
|
tally.ran(bootSection.ranLabel);
|
|
629
622
|
for (const w of bootSection.warnings)
|
|
630
623
|
tally.warn(w);
|
|
631
|
-
// Full-skip blindness guard
|
|
632
|
-
//
|
|
633
|
-
//
|
|
634
|
-
//
|
|
624
|
+
// Full-skip blindness guard: commands were discovered but every one skipped →
|
|
625
|
+
// rank-0 failure, never a static-only PASS. Runner resolvability is checked
|
|
626
|
+
// through resolveRunner so the failure text can name the missing runner when
|
|
627
|
+
// that is the cause.
|
|
635
628
|
const gap = tally.blindness(b => resolveRunner(b).ok);
|
|
636
629
|
if (gap)
|
|
637
630
|
tally.fail(gap, 0);
|
|
638
631
|
// The remaining run-level closure scans — "the shipped tree references or
|
|
639
|
-
// requires something it does not contain" — after every dynamic section,
|
|
640
|
-
//
|
|
641
|
-
// 'post-boot').
|
|
632
|
+
// requires something it does not contain" — after every dynamic section, which
|
|
633
|
+
// is where their failures sit in the aggregate's within-rank order
|
|
634
|
+
// (CLOSURE_SCANS: 'post-boot').
|
|
642
635
|
runClosureScans('post-boot', { cwd, planText }, (t, r) => tally.fail(t, r));
|
|
643
636
|
return tally.verdict(debts);
|
|
644
637
|
}
|