@mjasnikovs/pi-task 0.38.29 → 0.38.31
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/index.js +2 -0
- 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 +85 -16
- package/dist/shared/command-watchdog.js +115 -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 +192 -165
- 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 +124 -55
- package/dist/task/child-runner.js +298 -90
- 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 +30 -8
- 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-guards.d.ts +26 -0
- package/dist/task/implementation-guards.js +177 -0
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +39 -31
- package/dist/task/implementation-turn.js +41 -28
- 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 +27 -8
- package/dist/task/loop-detector.js +38 -14
- 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 +89 -66
- 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 +196 -252
- 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 +13 -12
- package/dist/workers/focused-extractor.js +27 -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 +65 -96
- package/dist/workers/pi-worker-core.js +93 -181
- 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 +27 -30
- package/dist/workers/single-read-guard.js +36 -36
- 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 +54 -56
- package/dist/workers/worker-profiles.js +63 -39
- package/package.json +10 -8
|
@@ -1,47 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* final-gate-fix — the bounded, model-driven fix pass
|
|
3
|
-
*
|
|
2
|
+
* final-gate-fix — the bounded, model-driven fix pass the FINAL integration
|
|
3
|
+
* gate's resolution picker offers as its second card.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* write-enabled child (read, edit, bash) is seeded with the gate's exact failure
|
|
14
|
-
* (command + exit code + output tail), fixes the defect in place, and the gate
|
|
15
|
-
* itself is re-run as the only arbiter — the child's self-report is never
|
|
16
|
-
* trusted. The user always chooses this path from the picker ("Leave failed"
|
|
17
|
-
* stays the recommended default), and attempts are capped so a non-converging
|
|
18
|
-
* loop hands control back to a person.
|
|
5
|
+
* This mirrors the per-task graduated-resolution shape (lint-fix.ts) and shares
|
|
6
|
+
* its child ladder through `runFixChild`: a write-enabled child limited to
|
|
7
|
+
* `read,edit,bash` is seeded with the gate's own failure text, edits in place,
|
|
8
|
+
* and then the gate is RE-RUN. The child's self-report can only end an attempt
|
|
9
|
+
* early as BLOCKED; it can never produce a PASS. `run-final-gate.ts` keeps
|
|
10
|
+
* "Leave failed" as the recommended card and stops offering Autofix after
|
|
11
|
+
* MAX_FINAL_GATE_AUTOFIX attempts, so a non-converging loop hands control back
|
|
12
|
+
* to a person.
|
|
19
13
|
*
|
|
20
14
|
* CHEAT GUARD (deterministic): the cheapest way for a fix child to "converge" is
|
|
21
15
|
* to remove the failing command itself — delete the `test` script, drop the
|
|
22
|
-
* Makefile target — so the gate discovers nothing and vacuously passes.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* the
|
|
26
|
-
*
|
|
27
|
-
*
|
|
16
|
+
* Makefile target — so the gate discovers nothing and vacuously passes. The
|
|
17
|
+
* discovered gate commands are therefore snapshotted before the child runs; a
|
|
18
|
+
* previously-discovered command that is no longer discoverable afterwards
|
|
19
|
+
* rejects the attempt and discards its edits, and so does one whose resolved
|
|
20
|
+
* BODY narrowed. A fix may change what a command DOES, never make it disappear
|
|
21
|
+
* or shrink what it covers.
|
|
28
22
|
*
|
|
29
|
-
* WRITE-GUARD STACK
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* rejects the attempt) → shrink guard (above) → probe-gaming scan over the added
|
|
36
|
-
* lines (a fix that SAYS it games a check rejects the attempt). Diff capture for
|
|
37
|
-
* every write-capable gate child lives at the gate-deps seam, keyed on the
|
|
38
|
-
* child's TOOLS, so the next write-capable kind cannot run invisibly either.
|
|
23
|
+
* WRITE-GUARD STACK, in the order `runFinalGateAutofix` runs it: frozen-path
|
|
24
|
+
* revert (only when a freeze set is wired) → deletion guard (a tracked file
|
|
25
|
+
* deleted without relocation rejects the attempt) → shrink guard → scope-shrink
|
|
26
|
+
* guard → probe-gaming scan over the added lines. Diff capture is NOT here: it
|
|
27
|
+
* lives at the gate-child seam, where a `/\b(?:edit|bash|write)\b/` test on the
|
|
28
|
+
* child's TOOLS decides it, so any future write-capable kind is logged too.
|
|
39
29
|
*
|
|
40
|
-
* The frozen-path deny is implemented but NOT wired by gate-deps
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* legitimate whole-repo fix
|
|
44
|
-
*
|
|
30
|
+
* The frozen-path deny is implemented here but NOT wired by gate-deps — the
|
|
31
|
+
* `finalGateFix` wiring there passes every other dep and omits these two.
|
|
32
|
+
* Per-task frozen fences are task-SCOPED, so their union across a run's specs
|
|
33
|
+
* can fence off a file a legitimate whole-repo fix has to touch. It activates
|
|
34
|
+
* only when a run-GLOBAL freeze source exists.
|
|
45
35
|
*/
|
|
46
36
|
import { parseFixMarker, runFixChild } from './fix-child.js';
|
|
47
37
|
import { findForbiddenDeletions, diffIgnoredSnapshots, ignoredWriteTrailLine, ignoredWriteUnobservedNote } from './write-guard.js';
|
|
@@ -51,13 +41,15 @@ import { findNarrowedCommands, narrowingRejectionText } from './command-shrink.j
|
|
|
51
41
|
export const FINAL_FIX_TOOLS = 'read,edit,bash';
|
|
52
42
|
/**
|
|
53
43
|
* How many fix passes the user may launch from the picker before the option is
|
|
54
|
-
* withdrawn
|
|
55
|
-
* full model child plus a full gate re-run — after this many that still FAIL,
|
|
56
|
-
*
|
|
44
|
+
* withdrawn. Same value as the per-task MAX_AUTO_AUTOFIX budget. Each attempt is
|
|
45
|
+
* a full model child plus a full gate re-run — after this many that still FAIL,
|
|
46
|
+
* `run-final-gate.ts` drops the Autofix card and only Leave-failed / Accept
|
|
47
|
+
* remain, so a person breaks the loop.
|
|
57
48
|
*/
|
|
58
49
|
export const MAX_FINAL_GATE_AUTOFIX = 3;
|
|
59
|
-
/** Picker labels/values.
|
|
60
|
-
*
|
|
50
|
+
/** Picker labels/values. Each label starts with its own value word, so
|
|
51
|
+
* `classifyFinalGateAnswer` accepts the value token and the label alike;
|
|
52
|
+
* anything else is free text and becomes autofix guidance. */
|
|
61
53
|
export const FINAL_LEAVE_VALUE = 'fail';
|
|
62
54
|
export const FINAL_ACCEPT_VALUE = 'accept';
|
|
63
55
|
export const FINAL_AUTOFIX_VALUE = 'autofix';
|
|
@@ -66,9 +58,9 @@ export const FINAL_ACCEPT_LABEL = 'Accept — complete the run anyway';
|
|
|
66
58
|
export const FINAL_AUTOFIX_LABEL = 'Autofix — run a bounded fix pass and re-run the gate';
|
|
67
59
|
/**
|
|
68
60
|
* Map a final-gate picker answer to an action. Dismissal (undefined/empty) and
|
|
69
|
-
* an explicit leave stay "leave"
|
|
70
|
-
*
|
|
71
|
-
*
|
|
61
|
+
* an explicit leave both stay "leave". Free text becomes autofix guidance; the
|
|
62
|
+
* caller's `choice.action === 'autofix' && canAutofix` test demotes autofix back
|
|
63
|
+
* to leave when the card was not offered.
|
|
72
64
|
*/
|
|
73
65
|
export function classifyFinalGateAnswer(answer) {
|
|
74
66
|
if (answer === undefined)
|
|
@@ -85,10 +77,11 @@ export function classifyFinalGateAnswer(answer) {
|
|
|
85
77
|
return { action: 'autofix', guidance: t };
|
|
86
78
|
}
|
|
87
79
|
/**
|
|
88
|
-
* The gate's fail reason
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* discovered-command sets, so a reason
|
|
80
|
+
* The gate's fail reason carries the failing command in backticks — final-gate
|
|
81
|
+
* mints `` `<label>` exited <status> — <tail> ``, with a `lockfile check: ` or
|
|
82
|
+
* `launch script: ` prefix on two of the sections. Extract it for reporting
|
|
83
|
+
* only; the shrink guard compares the FULL discovered-command sets, so a reason
|
|
84
|
+
* this cannot parse still guards.
|
|
92
85
|
*/
|
|
93
86
|
export function exitedCommandFromReason(reason) {
|
|
94
87
|
const m = /`([^`]+)`\s+exited\b/.exec(reason);
|
|
@@ -96,11 +89,11 @@ export function exitedCommandFromReason(reason) {
|
|
|
96
89
|
}
|
|
97
90
|
/**
|
|
98
91
|
* Build the fix child's prompt. Generic by construction: the only project facts
|
|
99
|
-
* in it are the gate's own failure text
|
|
100
|
-
* discovered manifest
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* child is told to fix all of them.
|
|
92
|
+
* in it are the gate's own failure text, whose command labels come from the
|
|
93
|
+
* project's discovered manifest. The seed may carry SEVERAL failures — the gate
|
|
94
|
+
* runs every section and aggregates, emitting "N failures (ranked, most
|
|
95
|
+
* load-bearing first)" — and it reports `ok` only when that list is empty, so
|
|
96
|
+
* the child is told to fix all of them.
|
|
104
97
|
*/
|
|
105
98
|
export function buildFinalFixPrompt(failReason) {
|
|
106
99
|
return [
|
|
@@ -144,41 +137,28 @@ export function buildFinalFixPrompt(failReason) {
|
|
|
144
137
|
' FINAL-GATE-FIX: BLOCKED <why you could not fix it>'
|
|
145
138
|
].join('\n');
|
|
146
139
|
}
|
|
147
|
-
/**
|
|
148
|
-
*
|
|
149
|
-
* concluding and bash output can echo the words). No marker → treated as DONE:
|
|
150
|
-
* the gate re-run is the arbiter either way, so a missing marker only skips the
|
|
151
|
-
* early-out on a self-declared BLOCKED.
|
|
152
|
-
*/
|
|
140
|
+
/** This pass's marker word, parsed by the shared `parseFixMarker` (last match
|
|
141
|
+
* wins; no marker → DONE). */
|
|
153
142
|
export function parseFinalFixMarker(text) {
|
|
154
143
|
return parseFixMarker('FINAL-GATE-FIX', text);
|
|
155
144
|
}
|
|
156
145
|
/**
|
|
157
|
-
* STRANDED SUB-FIXES
|
|
158
|
-
*
|
|
159
|
-
* A fix attempt that does not converge keeps its edits: they are NOT discarded
|
|
160
|
-
* (only a guard trip discards), and `deps.commit` runs only on `fix.ok`. So a
|
|
161
|
-
* partial fix that genuinely repaired something sits in the working tree, uncommitted,
|
|
162
|
-
* and if the user then ACCEPTs the FAIL the run completes around it — leaving HEAD
|
|
163
|
-
* broken while the repair is invisible unless someone runs `git status`.
|
|
146
|
+
* STRANDED SUB-FIXES.
|
|
164
147
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* by default.
|
|
148
|
+
* An attempt that does not converge KEEPS its edits — only a guard trip
|
|
149
|
+
* discards — and the caller commits only on `fix.ok`. So a partial fix that
|
|
150
|
+
* genuinely repaired something sits uncommitted in the working tree while HEAD
|
|
151
|
+
* still carries the defect, invisible unless someone runs `git status`.
|
|
170
152
|
*
|
|
171
|
-
* The rule: a partial fix is either committed
|
|
172
|
-
* explicitly surfaced — never silently stranded.
|
|
153
|
+
* The rule: a partial fix is either committed as its own named commit or
|
|
154
|
+
* explicitly surfaced — never silently stranded. `run-final-gate.ts` calls
|
|
155
|
+
* `commitStranded` on BOTH terminal outcomes, accept and leave-failed, so an
|
|
156
|
+
* unattended run that ends on LEAVE does not leave real repairs one `git
|
|
157
|
+
* checkout` from gone.
|
|
173
158
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* app work today — were left dirty in the tree, one `git checkout` from gone, after
|
|
178
|
-
* an UNATTENDED run nobody was watching. So EVERY terminal non-converged outcome
|
|
179
|
-
* commits them now, not just ACCEPT. Only guard-CLEAN edits qualify: an attempt a
|
|
180
|
-
* write-guard rejected without discarding leaves REJECTED edits in the tree, and
|
|
181
|
-
* those are never committed (the guard is not weakened to make committing easier).
|
|
159
|
+
* Only guard-CLEAN edits qualify. `AutofixLedger.mayCommitTree()` goes false
|
|
160
|
+
* once a guard has rejected an attempt whose edits could not be discarded, and
|
|
161
|
+
* never flips back: the guard is not weakened to make committing easier.
|
|
182
162
|
*/
|
|
183
163
|
/** Commit subject for partial fixes committed alongside a terminal gate FAIL. */
|
|
184
164
|
export const STRANDED_FIX_COMMIT = (runId, outcome = 'accepted') => `FINAL GATE PARTIAL FIX (${runId}) — ${outcome === 'accepted' ?
|
|
@@ -198,10 +178,11 @@ export function strandedFixNote(paths) {
|
|
|
198
178
|
+ `checkout — the run's outcome is recorded in the gate trail either way.`);
|
|
199
179
|
}
|
|
200
180
|
/**
|
|
201
|
-
* Run one bounded final-gate fix attempt: snapshot discovery
|
|
202
|
-
*
|
|
203
|
-
* scan
|
|
204
|
-
* runChild propagates
|
|
181
|
+
* Run one bounded final-gate fix attempt: snapshot discovery and ignored paths →
|
|
182
|
+
* child → frozen-path revert → deletion guard → shrink guard → scope-shrink
|
|
183
|
+
* guard → probe scan → gate re-run. Never throws for an outcome; only a user
|
|
184
|
+
* cancel inside runChild propagates, and the caller's USER_CANCELLED path
|
|
185
|
+
* handles that.
|
|
205
186
|
*/
|
|
206
187
|
export async function runFinalGateAutofix(deps) {
|
|
207
188
|
const before = deps.discoverLabels(deps.cwd);
|
|
@@ -210,7 +191,7 @@ export async function runFinalGateAutofix(deps) {
|
|
|
210
191
|
// ignored files are untracked, so git alone cannot tell a file this pass wrote
|
|
211
192
|
// from one that was already sitting in the worktree.
|
|
212
193
|
const ignoredBefore = deps.ignoredSnapshot ? await deps.ignoredSnapshot() : null;
|
|
213
|
-
// The
|
|
194
|
+
// The child ladder is task/fix-child.ts, shared with the per-task pass.
|
|
214
195
|
const end = await runFixChild({
|
|
215
196
|
runChild: deps.runChild,
|
|
216
197
|
tools: FINAL_FIX_TOOLS,
|
|
@@ -241,12 +222,13 @@ export async function runFinalGateAutofix(deps) {
|
|
|
241
222
|
guardTripped: true,
|
|
242
223
|
editsDiscarded: deps.discard !== undefined
|
|
243
224
|
});
|
|
244
|
-
// (Diff capture — what the pass changed, durably — happens
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
225
|
+
// (Diff capture — what the pass changed, durably — happens in gate-child.ts,
|
|
226
|
+
// which logs the tree changes of any child whose TOOLS include edit/bash/
|
|
227
|
+
// write; here only the guards act on them.)
|
|
228
|
+
// FROZEN-PATH WRITE-DENY: undo the child's edits to any path a task's spec
|
|
229
|
+
// froze, before anything downstream can act on them — the same mechanical
|
|
230
|
+
// revert the per-task passes carry, not prompt framing. Non-fatal: the rest
|
|
231
|
+
// of the fix survives, only the frozen edits are undone.
|
|
250
232
|
if (deps.frozenPaths && deps.revertFrozen) {
|
|
251
233
|
const frozen = await deps.frozenPaths();
|
|
252
234
|
if (frozen.length > 0) {
|
|
@@ -256,8 +238,10 @@ export async function runFinalGateAutofix(deps) {
|
|
|
256
238
|
}
|
|
257
239
|
}
|
|
258
240
|
}
|
|
259
|
-
// DELETION GUARD (post-revert state): a tracked file the pass deleted
|
|
260
|
-
//
|
|
241
|
+
// DELETION GUARD (post-revert state): a tracked file the pass deleted is a
|
|
242
|
+
// completed task's committed deliverable destroyed — reject the attempt. A
|
|
243
|
+
// deletion paired with an added file of the SAME BASENAME is a relocation and
|
|
244
|
+
// passes, as do the regenerable artifacts write-guard.ts exempts.
|
|
261
245
|
const changes = deps.treeChanges ? await deps.treeChanges() : null;
|
|
262
246
|
if (changes) {
|
|
263
247
|
const gone = findForbiddenDeletions(changes);
|
|
@@ -280,14 +264,12 @@ export async function runFinalGateAutofix(deps) {
|
|
|
280
264
|
await deps.discard(deps.cwd);
|
|
281
265
|
return rejected(`fix pass removed the gate's own command(s) (${vanished.join(', ')})`);
|
|
282
266
|
}
|
|
283
|
-
// SCOPE-SHRINK GUARD
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
// the
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
// mechanical shapes, measured at 3 hits in 274 manifest-touching corpus
|
|
290
|
-
// commits, all three read by hand as real narrowings).
|
|
267
|
+
// SCOPE-SHRINK GUARD: the label surviving is not enough. A child can keep
|
|
268
|
+
// `bun run test` and rewrite its BODY to run a subdirectory instead of the
|
|
269
|
+
// repository — the set difference above stays empty while the suite stops
|
|
270
|
+
// covering what the gate is meant to measure, and the re-run then goes green
|
|
271
|
+
// and reports "converged". So compare the resolved bodies too
|
|
272
|
+
// (command-shrink.ts holds the mechanical narrowing shapes).
|
|
291
273
|
if (deps.discoverBodies) {
|
|
292
274
|
const addedByFix = new Set((changes?.added ?? []).map(p => p.replace(/^\.\//, '')));
|
|
293
275
|
const narrowed = findNarrowedCommands(bodiesBefore, deps.discoverBodies(deps.cwd), {
|
|
@@ -304,10 +286,10 @@ export async function runFinalGateAutofix(deps) {
|
|
|
304
286
|
return r;
|
|
305
287
|
}
|
|
306
288
|
}
|
|
307
|
-
// PROBE SCAN
|
|
308
|
-
// rather than meet the requirement reject the attempt
|
|
309
|
-
//
|
|
310
|
-
//
|
|
289
|
+
// PROBE SCAN: added lines whose own stated purpose is to make a check pass
|
|
290
|
+
// rather than meet the requirement reject the attempt. Nothing downstream of
|
|
291
|
+
// this pass would judge such a finding — the gate re-run only sees exit
|
|
292
|
+
// codes.
|
|
311
293
|
if (deps.probeScan) {
|
|
312
294
|
const findings = await deps.probeScan();
|
|
313
295
|
if (findings.length > 0) {
|
|
@@ -326,15 +308,14 @@ export async function runFinalGateAutofix(deps) {
|
|
|
326
308
|
if (!fin.ok) {
|
|
327
309
|
return withIgnored({ ok: false, reason: `did not converge: ${fin.reason}`, gate: fin });
|
|
328
310
|
}
|
|
329
|
-
// IGNORED-DEPENDENCY DOWNGRADE
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
//
|
|
336
|
-
//
|
|
337
|
-
// overwhelming majority — 1 of 68 recorded child logs) pays nothing.
|
|
311
|
+
// IGNORED-DEPENDENCY DOWNGRADE. The gate says PASS; this decides whether the
|
|
312
|
+
// PASS belongs to the REPOSITORY or only to this worktree. Mechanical, never
|
|
313
|
+
// judgement: move the ignored files the pass wrote aside, re-run the gate
|
|
314
|
+
// once, put them back. Still passing ⇒ incidental, the PASS stands. Failing ⇒
|
|
315
|
+
// the checks were passing on state no fresh clone has, which is UNOBSERVED
|
|
316
|
+
// (final-gate.ts unobservedVerdict), not a FAIL — the fix is real, it just
|
|
317
|
+
// did not ship. Guarded on a non-empty `ignoredWrites`, so a pass that wrote
|
|
318
|
+
// no ignored paths runs no extra gate.
|
|
338
319
|
let ignoredDependent;
|
|
339
320
|
if (ignoredWrites.length > 0 && deps.gateWithoutIgnored) {
|
|
340
321
|
const passesWithout = await deps.gateWithoutIgnored(ignoredWrites);
|
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* final-gate-progress — the non-progress classifier for the final-gate autofix
|
|
2
|
+
* final-gate-progress — the non-progress classifier for the final-gate autofix
|
|
3
|
+
* loop. `AutofixLedger.judge` is its only caller.
|
|
3
4
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* uncommitted in the working tree.
|
|
12
|
-
*
|
|
13
|
-
* The rule this encodes: an attempt that CHANGED the tree and re-ran the gate, and
|
|
14
|
-
* got the same first failure back as the previous attempt, is evidence about the
|
|
15
|
-
* CHECK, not about the fix. Two identical post-fix results ⇒ the check is
|
|
16
|
-
* env-shaped/unfalsifiable in this environment ⇒ stop paying for it: demote that
|
|
17
|
-
* one check to UNOBSERVED-with-debt (durable, so the NEXT run's gate re-checks it)
|
|
18
|
-
* and let the REMAINING checks decide whether the gate converged. Run 14 replay:
|
|
19
|
-
* checks 2 and 3 were fixed by attempts 1–2, so the run converges with the boot
|
|
20
|
-
* check carried as debt instead of failing with the repairs stranded.
|
|
5
|
+
* The rule: an attempt that CHANGED the tree and re-ran the gate, and got the
|
|
6
|
+
* same ranked-first failure back as the previous attempt, is evidence about the
|
|
7
|
+
* CHECK, not about the fix. A check that survives two post-fix results
|
|
8
|
+
* identically is unfalsifiable in this environment, so stop paying for it —
|
|
9
|
+
* demote that ONE check to UNOBSERVED-with-debt and let the remaining checks
|
|
10
|
+
* decide whether the gate converged. The debt is appended to the ledger file
|
|
11
|
+
* under `.pi-tasks/`, so it outlives the run and the next gate re-checks it.
|
|
21
12
|
*
|
|
22
13
|
* Deliberately conservative:
|
|
23
|
-
* - It never fires on attempt 1
|
|
24
|
-
*
|
|
25
|
-
* - It never fires when the attempt changed nothing
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* - It demotes exactly the one repeated
|
|
29
|
-
* pass for real
|
|
30
|
-
* next run's gate.
|
|
14
|
+
* - It never fires on attempt 1: `previousSignature` is null until an attempt
|
|
15
|
+
* has produced one, and null returns false.
|
|
16
|
+
* - It never fires when the attempt changed nothing. The caller passes
|
|
17
|
+
* `edited` as "the gate re-ran AND the tree is dirty", and a guard-rejected
|
|
18
|
+
* attempt returns before the re-run, so its `gate` is undefined.
|
|
19
|
+
* - It demotes exactly the one repeated signature. Every other failure still
|
|
20
|
+
* has to pass for real.
|
|
31
21
|
*/
|
|
32
22
|
/**
|
|
33
23
|
* Comparison key for a gate failure entry: lowercased, volatile substrings erased,
|
|
@@ -51,7 +41,7 @@ export interface NonProgressInput {
|
|
|
51
41
|
* attempt that edited and re-tested says anything about falsifiability. */
|
|
52
42
|
edited: boolean;
|
|
53
43
|
/**
|
|
54
|
-
* Did a PROBE return this failure after OBSERVING?
|
|
44
|
+
* Did a PROBE return this failure after OBSERVING? Read off
|
|
55
45
|
* `FinalGateOutcome.observedFailures` by exact text identity — never re-derived
|
|
56
46
|
* from the failure string.
|
|
57
47
|
*
|
|
@@ -64,24 +54,17 @@ export interface NonProgressInput {
|
|
|
64
54
|
* here: it edited the tree, the gate re-ran, and returned the same first failure
|
|
65
55
|
* as the previous attempt.
|
|
66
56
|
*
|
|
67
|
-
* …EXCEPT when
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* own outcome, with the reason. What was left was a second, blind judgment of the
|
|
73
|
-
* same question, made DOWNSTREAM from the evidence — and its only reachable effect
|
|
74
|
-
* was to overrule a probe that DID look.
|
|
75
|
-
*
|
|
76
|
-
* It has to be overruled, because a deterministic un-fixed defect emits an
|
|
77
|
-
* IDENTICAL failure by definition. String equality therefore reads reproducibility
|
|
78
|
-
* as evidence against the instrument, which is backwards for every project type: a
|
|
79
|
-
* CLI that exits 2 twice, a build that fails on the same symbol twice, a C++ plugin
|
|
80
|
-
* missing the same export twice. mx5 run 21 is the one recorded instance and it
|
|
81
|
-
* released a product whose every page was blank as a `completed` run.
|
|
57
|
+
* …EXCEPT when a probe OBSERVED the failure, which is checked FIRST and wins
|
|
58
|
+
* outright. A probe that looked and saw the defect has already answered the
|
|
59
|
+
* question this rule guesses at, and it answered it where the evidence is. A
|
|
60
|
+
* probe that could NOT look reports that as its own outcome instead, so it never
|
|
61
|
+
* reaches `observedFailures`.
|
|
82
62
|
*
|
|
83
|
-
* The
|
|
84
|
-
*
|
|
63
|
+
* The observed guard has to win, because a deterministic un-fixed defect emits an
|
|
64
|
+
* IDENTICAL failure by definition. Without it, string equality reads
|
|
65
|
+
* reproducibility as evidence against the instrument — a CLI that exits 2 twice,
|
|
66
|
+
* a build that fails on the same symbol twice — and demotes a real, still-broken
|
|
67
|
+
* check to debt.
|
|
85
68
|
*/
|
|
86
69
|
export declare function isNonProgress(input: NonProgressInput): boolean;
|
|
87
70
|
/**
|
|
@@ -89,6 +72,6 @@ export declare function isNonProgress(input: NonProgressInput): boolean;
|
|
|
89
72
|
* what still has to pass for the gate to converge; empty ⇒ converged-with-debt.
|
|
90
73
|
*/
|
|
91
74
|
export declare function applyDemotions(failures: string[], demoted: ReadonlySet<string>): string[];
|
|
92
|
-
/** The debt reason recorded for a demoted check
|
|
93
|
-
*
|
|
75
|
+
/** The debt reason recorded for a demoted check. One function so the ledger entry
|
|
76
|
+
* and the wording the user reads cannot drift apart. */
|
|
94
77
|
export declare function unobservedDebtReason(detail: string): string;
|
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* final-gate-progress — the non-progress classifier for the final-gate autofix
|
|
2
|
+
* final-gate-progress — the non-progress classifier for the final-gate autofix
|
|
3
|
+
* loop. `AutofixLedger.judge` is its only caller.
|
|
3
4
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* uncommitted in the working tree.
|
|
12
|
-
*
|
|
13
|
-
* The rule this encodes: an attempt that CHANGED the tree and re-ran the gate, and
|
|
14
|
-
* got the same first failure back as the previous attempt, is evidence about the
|
|
15
|
-
* CHECK, not about the fix. Two identical post-fix results ⇒ the check is
|
|
16
|
-
* env-shaped/unfalsifiable in this environment ⇒ stop paying for it: demote that
|
|
17
|
-
* one check to UNOBSERVED-with-debt (durable, so the NEXT run's gate re-checks it)
|
|
18
|
-
* and let the REMAINING checks decide whether the gate converged. Run 14 replay:
|
|
19
|
-
* checks 2 and 3 were fixed by attempts 1–2, so the run converges with the boot
|
|
20
|
-
* check carried as debt instead of failing with the repairs stranded.
|
|
5
|
+
* The rule: an attempt that CHANGED the tree and re-ran the gate, and got the
|
|
6
|
+
* same ranked-first failure back as the previous attempt, is evidence about the
|
|
7
|
+
* CHECK, not about the fix. A check that survives two post-fix results
|
|
8
|
+
* identically is unfalsifiable in this environment, so stop paying for it —
|
|
9
|
+
* demote that ONE check to UNOBSERVED-with-debt and let the remaining checks
|
|
10
|
+
* decide whether the gate converged. The debt is appended to the ledger file
|
|
11
|
+
* under `.pi-tasks/`, so it outlives the run and the next gate re-checks it.
|
|
21
12
|
*
|
|
22
13
|
* Deliberately conservative:
|
|
23
|
-
* - It never fires on attempt 1
|
|
24
|
-
*
|
|
25
|
-
* - It never fires when the attempt changed nothing
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* - It demotes exactly the one repeated
|
|
29
|
-
* pass for real
|
|
30
|
-
* next run's gate.
|
|
14
|
+
* - It never fires on attempt 1: `previousSignature` is null until an attempt
|
|
15
|
+
* has produced one, and null returns false.
|
|
16
|
+
* - It never fires when the attempt changed nothing. The caller passes
|
|
17
|
+
* `edited` as "the gate re-ran AND the tree is dirty", and a guard-rejected
|
|
18
|
+
* attempt returns before the re-run, so its `gate` is undefined.
|
|
19
|
+
* - It demotes exactly the one repeated signature. Every other failure still
|
|
20
|
+
* has to pass for real.
|
|
31
21
|
*/
|
|
32
22
|
/**
|
|
33
23
|
* Volatile substrings that differ between two runs of the SAME failing check —
|
|
@@ -60,12 +50,18 @@ const VOLATILE = [
|
|
|
60
50
|
* A bare `:NNNN` port, which the localhost/`port N` rules above do not reach (a
|
|
61
51
|
* failure that just says "no listener on :3000").
|
|
62
52
|
*
|
|
63
|
-
* NOT applied when the colon follows a SOURCE LOCATION
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
53
|
+
* NOT applied when the colon follows a SOURCE LOCATION. A failure detail embeds
|
|
54
|
+
* the failing command's output tail verbatim (final-gate.ts interpolates
|
|
55
|
+
* `r.tail`), and tsc/eslint/bun-test tails are mostly `file:line`. Collapsing
|
|
56
|
+
* those would make two DIFFERENT defects in one file compare equal, which reads
|
|
57
|
+
* as non-progress and demotes a genuinely fixable check. A moved error is
|
|
58
|
+
* progress.
|
|
59
|
+
*
|
|
60
|
+
* The exemption covers the FILE:LINE colon only. Measured: `src/db.ts:41` and
|
|
61
|
+
* `src/db.ts:88` keep their line numbers and stay different, but the COLUMN in
|
|
62
|
+
* `Cart.tsx:88:12` normalises to `cart.tsx:88:<port>` — the prefix at that colon
|
|
63
|
+
* is the bare `88`, which is neither a path nor a filename. Two defects that
|
|
64
|
+
* differ only in column therefore compare equal.
|
|
69
65
|
*/
|
|
70
66
|
const BARE_PORT = /(\S*?):(\d{2,5})\b/g;
|
|
71
67
|
/** A path (has a separator) or a filename with an extension ⇒ a source location. */
|
|
@@ -97,24 +93,17 @@ export function rankedFirstFailure(outcome) {
|
|
|
97
93
|
* here: it edited the tree, the gate re-ran, and returned the same first failure
|
|
98
94
|
* as the previous attempt.
|
|
99
95
|
*
|
|
100
|
-
* …EXCEPT when
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* own outcome, with the reason. What was left was a second, blind judgment of the
|
|
106
|
-
* same question, made DOWNSTREAM from the evidence — and its only reachable effect
|
|
107
|
-
* was to overrule a probe that DID look.
|
|
108
|
-
*
|
|
109
|
-
* It has to be overruled, because a deterministic un-fixed defect emits an
|
|
110
|
-
* IDENTICAL failure by definition. String equality therefore reads reproducibility
|
|
111
|
-
* as evidence against the instrument, which is backwards for every project type: a
|
|
112
|
-
* CLI that exits 2 twice, a build that fails on the same symbol twice, a C++ plugin
|
|
113
|
-
* missing the same export twice. mx5 run 21 is the one recorded instance and it
|
|
114
|
-
* released a product whose every page was blank as a `completed` run.
|
|
96
|
+
* …EXCEPT when a probe OBSERVED the failure, which is checked FIRST and wins
|
|
97
|
+
* outright. A probe that looked and saw the defect has already answered the
|
|
98
|
+
* question this rule guesses at, and it answered it where the evidence is. A
|
|
99
|
+
* probe that could NOT look reports that as its own outcome instead, so it never
|
|
100
|
+
* reaches `observedFailures`.
|
|
115
101
|
*
|
|
116
|
-
* The
|
|
117
|
-
*
|
|
102
|
+
* The observed guard has to win, because a deterministic un-fixed defect emits an
|
|
103
|
+
* IDENTICAL failure by definition. Without it, string equality reads
|
|
104
|
+
* reproducibility as evidence against the instrument — a CLI that exits 2 twice,
|
|
105
|
+
* a build that fails on the same symbol twice — and demotes a real, still-broken
|
|
106
|
+
* check to debt.
|
|
118
107
|
*/
|
|
119
108
|
export function isNonProgress(input) {
|
|
120
109
|
if (input.observed === true)
|
|
@@ -134,8 +123,8 @@ export function applyDemotions(failures, demoted) {
|
|
|
134
123
|
return [...failures];
|
|
135
124
|
return failures.filter(f => !demoted.has(normalizeFailureDetail(f)));
|
|
136
125
|
}
|
|
137
|
-
/** The debt reason recorded for a demoted check
|
|
138
|
-
*
|
|
126
|
+
/** The debt reason recorded for a demoted check. One function so the ledger entry
|
|
127
|
+
* and the wording the user reads cannot drift apart. */
|
|
139
128
|
export function unobservedDebtReason(detail) {
|
|
140
129
|
return (`final gate check UNOBSERVED — ${detail.trim().slice(0, 200)} — `
|
|
141
130
|
+ 'repeated identically across two fix attempts that both changed the tree and '
|