@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
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* The grill phase generates one clarifying question per KNOWN-UNKNOWN and lets a
|
|
5
5
|
* `grill-auto` child either auto-answer it (ANSWER → the user never sees it) or
|
|
6
6
|
* surface it (UNKNOWN → asked). The dangerous class is an integration / build-
|
|
7
|
-
* wiring unknown — "how is this plugin wired into the build", "
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* wiring unknown — "how is this plugin wired into the build", "where does the
|
|
8
|
+
* loader hook in" — which `grill-auto` will happily auto-answer with a GUESS. A
|
|
9
|
+
* wrong guess there is structural: the build still runs, and ships something the
|
|
10
|
+
* wiring never actually connected.
|
|
11
11
|
*
|
|
12
12
|
* This classifier identifies that class so the orchestrator can route it: try to
|
|
13
13
|
* resolve it from fetched docs first, and if nothing grounded the answer, surface
|
|
@@ -24,5 +24,11 @@
|
|
|
24
24
|
* surfaced to the user rather than auto-answered. Requires BOTH a tooling-surface
|
|
25
25
|
* mention and wiring intent, so benign questions ("which log format?", "what
|
|
26
26
|
* default page size?", "which file holds the auth handler?") do not trip it.
|
|
27
|
+
*
|
|
28
|
+
* Both factors are lexical, so the boundary is not exact in either direction. A
|
|
29
|
+
* bare `how is/are` counts as wiring intent, so "how is the plugin named?" trips
|
|
30
|
+
* it; and a wiring question phrased without one of the intent words — "should the
|
|
31
|
+
* import structure in the HTML entry change" — does not. Erring toward surfacing
|
|
32
|
+
* is the safe direction: the cost is one question the user waves through.
|
|
27
33
|
*/
|
|
28
34
|
export declare function isIntegrationUnknown(question: string): boolean;
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* The grill phase generates one clarifying question per KNOWN-UNKNOWN and lets a
|
|
5
5
|
* `grill-auto` child either auto-answer it (ANSWER → the user never sees it) or
|
|
6
6
|
* surface it (UNKNOWN → asked). The dangerous class is an integration / build-
|
|
7
|
-
* wiring unknown — "how is this plugin wired into the build", "
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* wiring unknown — "how is this plugin wired into the build", "where does the
|
|
8
|
+
* loader hook in" — which `grill-auto` will happily auto-answer with a GUESS. A
|
|
9
|
+
* wrong guess there is structural: the build still runs, and ships something the
|
|
10
|
+
* wiring never actually connected.
|
|
11
11
|
*
|
|
12
12
|
* This classifier identifies that class so the orchestrator can route it: try to
|
|
13
13
|
* resolve it from fetched docs first, and if nothing grounded the answer, surface
|
|
@@ -30,6 +30,12 @@ const WIRING_INTENT_RE = /\b(?:wir(?:e|ed|ing)|integrat(?:e|ed|es|ing|ion)|hook(
|
|
|
30
30
|
* surfaced to the user rather than auto-answered. Requires BOTH a tooling-surface
|
|
31
31
|
* mention and wiring intent, so benign questions ("which log format?", "what
|
|
32
32
|
* default page size?", "which file holds the auth handler?") do not trip it.
|
|
33
|
+
*
|
|
34
|
+
* Both factors are lexical, so the boundary is not exact in either direction. A
|
|
35
|
+
* bare `how is/are` counts as wiring intent, so "how is the plugin named?" trips
|
|
36
|
+
* it; and a wiring question phrased without one of the intent words — "should the
|
|
37
|
+
* import structure in the HTML entry change" — does not. Erring toward surfacing
|
|
38
|
+
* is the safe direction: the cost is one question the user waves through.
|
|
33
39
|
*/
|
|
34
40
|
export function isIntegrationUnknown(question) {
|
|
35
41
|
if (!question)
|
|
@@ -3,14 +3,11 @@
|
|
|
3
3
|
* directives a user writes into a raw task prompt, so a downstream rewrite (refine)
|
|
4
4
|
* cannot silently drop them.
|
|
5
5
|
*
|
|
6
|
-
* The failure this closes
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* ZERO pi-worker-fetch calls. A user who explicitly asks for web search must get
|
|
12
|
-
* web search; the model's paraphrase is not allowed to quietly demote it to
|
|
13
|
-
* "research from local files".
|
|
6
|
+
* The failure this closes: a raw prompt saying "research X VIA WEB SEARCH" can be
|
|
7
|
+
* rewritten well in every other respect while the "via web search" instruction
|
|
8
|
+
* vanishes from the refined spec. Nothing downstream then asks for web search, so
|
|
9
|
+
* none happens. A user who explicitly names a tool must get that tool; a
|
|
10
|
+
* paraphrase is not allowed to quietly demote it to "research from local files".
|
|
14
11
|
*
|
|
15
12
|
* The mechanism is the lever, the prompt is the belt: refine is HANDED the
|
|
16
13
|
* directives as a MUST-PRESERVE block (prompt), and — because a weak model still
|
|
@@ -3,14 +3,11 @@
|
|
|
3
3
|
* directives a user writes into a raw task prompt, so a downstream rewrite (refine)
|
|
4
4
|
* cannot silently drop them.
|
|
5
5
|
*
|
|
6
|
-
* The failure this closes
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* ZERO pi-worker-fetch calls. A user who explicitly asks for web search must get
|
|
12
|
-
* web search; the model's paraphrase is not allowed to quietly demote it to
|
|
13
|
-
* "research from local files".
|
|
6
|
+
* The failure this closes: a raw prompt saying "research X VIA WEB SEARCH" can be
|
|
7
|
+
* rewritten well in every other respect while the "via web search" instruction
|
|
8
|
+
* vanishes from the refined spec. Nothing downstream then asks for web search, so
|
|
9
|
+
* none happens. A user who explicitly names a tool must get that tool; a
|
|
10
|
+
* paraphrase is not allowed to quietly demote it to "research from local files".
|
|
14
11
|
*
|
|
15
12
|
* The mechanism is the lever, the prompt is the belt: refine is HANDED the
|
|
16
13
|
* directives as a MUST-PRESERVE block (prompt), and — because a weak model still
|
|
@@ -5,45 +5,41 @@ export interface GrepOnlyVerifyFinding {
|
|
|
5
5
|
lines: string[];
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Scan a composed spec's VERIFY block:
|
|
9
|
-
*
|
|
10
|
-
* contains any execution command,
|
|
11
|
-
*
|
|
8
|
+
* Scan a composed spec's VERIFY block: one finding per runnable source file the
|
|
9
|
+
* block inspects, each carrying the verbatim lines that inspect it. Empty when
|
|
10
|
+
* the block contains any execution command, when the spec has no fenced VERIFY
|
|
11
|
+
* block, or when nothing runnable is inspected (doc/config-only tasks).
|
|
12
12
|
*/
|
|
13
13
|
export declare function findGrepOnlyVerify(spec: string): GrepOnlyVerifyFinding[];
|
|
14
14
|
/** One VERIFY command, classified by what it can observe. */
|
|
15
15
|
export interface VerifyCommandClass {
|
|
16
16
|
/** The command line, verbatim. */
|
|
17
17
|
raw: string;
|
|
18
|
-
/** Every pipeline segment is
|
|
19
|
-
* files and can never observe the deliverable's behaviour. */
|
|
18
|
+
/** Every pipeline segment's head is in STATIC_HEADS (grep/test/tsc/…) — it
|
|
19
|
+
* inspects files and can never observe the deliverable's behaviour. */
|
|
20
20
|
staticOnly: boolean;
|
|
21
21
|
/**
|
|
22
|
-
* The command
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `/api` + static `dist/`") is exactly what it cannot see.
|
|
22
|
+
* The command names an HTTP request (`curl`, `wget`, an http(s) URL,
|
|
23
|
+
* `fetch(`), a port probe (`nc -z`, `ss -`, `lsof`, `localhost`,
|
|
24
|
+
* `127.0.0.1`) or `playwright`. Executing something is not enough:
|
|
25
|
+
* `bun run start` and `node -e "…package.json…"` are both false here — they
|
|
26
|
+
* run, yet observe only a file's contents.
|
|
28
27
|
*/
|
|
29
28
|
observesBehaviour: boolean;
|
|
30
29
|
}
|
|
31
30
|
/**
|
|
32
31
|
* Classify each command of a spec's VERIFY block. Shares `segmentHead` with the
|
|
33
32
|
* grep-theater detector, so "static" means one thing across the two measures.
|
|
34
|
-
* Empty when the spec has no
|
|
33
|
+
* Empty when the spec has no fenced VERIFY block.
|
|
35
34
|
*/
|
|
36
35
|
export declare function classifyVerifyCommands(spec: string): VerifyCommandClass[];
|
|
37
36
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* the prompt body
|
|
37
|
+
* Prepended to the SECOND `runWithEmphasisRetry` attempt when the first critique
|
|
38
|
+
* rewrite still leaves `findGrepOnlyVerify` non-empty. The generic emphasis line
|
|
39
|
+
* would claim the previous attempt had no VERIFY block, which is wrong here — it
|
|
40
|
+
* had one. The defect block naming the exact files stays in the prompt body
|
|
41
|
+
* underneath the hint.
|
|
42
42
|
*/
|
|
43
43
|
export declare const GREP_THEATER_RETRY_HINT: string;
|
|
44
|
-
/**
|
|
45
|
-
* Render the findings as a defect block for the critique rewrite: VERIFY must
|
|
46
|
-
* EXECUTE the runnable deliverable and assert an observable outcome of THAT
|
|
47
|
-
* run, not grep its source.
|
|
48
|
-
*/
|
|
44
|
+
/** Render the findings as the defect block handed to the critique rewrite. */
|
|
49
45
|
export declare function grepOnlyVerifyDefectText(findings: GrepOnlyVerifyFinding[]): string;
|
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Grep-theater VERIFY detector
|
|
2
|
+
* Grep-theater VERIFY detector, wired as the `grep-theater` compose-critique
|
|
3
|
+
* probe in `critique-probes.ts`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* fires when the VERIFY block (a) grep/cat-asserts the SOURCE of a runnable
|
|
12
|
-
* file (.ts/.js/.sh — a build script, server, CLI entry) and (b) contains NO
|
|
13
|
-
* execution command at all — every command is static inspection (grep, test,
|
|
14
|
-
* ls, cat, tsc --noEmit, eslint, prettier). Any real execution anywhere in the
|
|
15
|
-
* block (bun/node/npm run/test, curl, ./script) means the deliverable-runs
|
|
16
|
-
* question is at worst partially covered, and we step aside — the guard may
|
|
17
|
-
* only cost time, never work, so recall is floored at the unambiguous
|
|
18
|
-
* all-static case rather than chasing which command exercises which file.
|
|
5
|
+
* A finding fires when the spec's VERIFY block (a) inspects the source of a
|
|
6
|
+
* TypeScript/JavaScript/shell file with grep/rg/cat/head/tail/wc and (b)
|
|
7
|
+
* contains no execution command at all — every pipeline segment's head is in
|
|
8
|
+
* STATIC_HEADS. One unknown head anywhere in the block (bun, node, npm, yarn,
|
|
9
|
+
* pnpm, curl, `./script`, python3) counts as execution and the whole block is
|
|
10
|
+
* skipped. Recall is therefore floored at the unambiguous all-static case
|
|
11
|
+
* instead of deciding which command exercises which file.
|
|
19
12
|
*/
|
|
20
13
|
import { parseVerifyBlock } from './spec-validation.js';
|
|
21
|
-
/** Commands that only inspect —
|
|
14
|
+
/** Commands that only inspect — a segment headed by one never runs the deliverable. */
|
|
22
15
|
const STATIC_HEADS = new Set([
|
|
23
16
|
'grep',
|
|
24
17
|
'rg',
|
|
@@ -57,25 +50,33 @@ const STATIC_HEADS = new Set([
|
|
|
57
50
|
'prettier',
|
|
58
51
|
'biome'
|
|
59
52
|
]);
|
|
60
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* A bare path token ending in a runnable-source extension: ts, tsx, js, jsx,
|
|
55
|
+
* mjs, cjs, mts, cts, sh. The character class holds no quote, so a quoted
|
|
56
|
+
* `'build.ts'` never matches.
|
|
57
|
+
*/
|
|
61
58
|
const RUNNABLE_SRC_RE = /^[\w@./-]+\.(?:ts|tsx|js|jsx|mjs|cjs|mts|cts|sh)$/;
|
|
62
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Heads whose file arguments count as "inspecting the source of". The other
|
|
61
|
+
* STATIC_HEADS (sed, awk, jq, ls, diff, file …) keep a block static but name
|
|
62
|
+
* no target of their own.
|
|
63
|
+
*/
|
|
63
64
|
const INSPECT_HEADS = new Set(['grep', 'rg', 'cat', 'head', 'tail', 'wc']);
|
|
64
65
|
/**
|
|
65
|
-
* Shell-control noise that precedes (or IS) a segment without being a command
|
|
66
|
-
* `if grep -q x f; then` splits into
|
|
67
|
-
* `… || { echo FAIL; exit 1; }` yields `{ echo
|
|
68
|
-
*
|
|
69
|
-
*
|
|
66
|
+
* Shell-control noise that precedes (or IS) a segment without being a command.
|
|
67
|
+
* `if grep -q x f; then` splits into `if grep -q x f` plus a bare ` then`;
|
|
68
|
+
* `… || { echo FAIL; exit 1; }` yields ` { echo FAIL`, ` exit 1` and ` }`.
|
|
69
|
+
* An unknown head counts as execution and skips the whole block, so treating
|
|
70
|
+
* these tokens as heads would blind the detector on any guarded grep.
|
|
70
71
|
*/
|
|
71
72
|
const CONTROL_PREFIX = new Set(['if', 'elif', 'while', 'until', 'then', 'else', 'do', '!']);
|
|
72
73
|
const CONTROL_ONLY = new Set(['}', ')', 'fi', 'done', 'esac']);
|
|
73
74
|
/**
|
|
74
|
-
* The effective head of one pipeline segment:
|
|
75
|
-
*
|
|
76
|
-
* to the tool they invoke
|
|
77
|
-
* `bun`/`npm`/`yarn`/`pnpm`/`node` stay as themselves
|
|
78
|
-
*
|
|
75
|
+
* The effective head of one pipeline segment: leading `(`/`{`/`!`,
|
|
76
|
+
* shell-control prefixes, VAR=val assignments and `timeout N` are skipped;
|
|
77
|
+
* `bunx`/`npx` resolve to the tool they invoke, so `bunx tsc --noEmit` stays
|
|
78
|
+
* static. `bun`/`npm`/`yarn`/`pnpm`/`node` stay as themselves and are absent
|
|
79
|
+
* from STATIC_HEADS, so whatever they run is execution.
|
|
79
80
|
*/
|
|
80
81
|
function segmentHead(segment) {
|
|
81
82
|
const tokens = segment.split(/\s+/).filter(t => t.length > 0);
|
|
@@ -112,10 +113,10 @@ function segmentHead(segment) {
|
|
|
112
113
|
return { head, args: tokens.slice(i + 1) };
|
|
113
114
|
}
|
|
114
115
|
/**
|
|
115
|
-
* Scan a composed spec's VERIFY block:
|
|
116
|
-
*
|
|
117
|
-
* contains any execution command,
|
|
118
|
-
*
|
|
116
|
+
* Scan a composed spec's VERIFY block: one finding per runnable source file the
|
|
117
|
+
* block inspects, each carrying the verbatim lines that inspect it. Empty when
|
|
118
|
+
* the block contains any execution command, when the spec has no fenced VERIFY
|
|
119
|
+
* block, or when nothing runnable is inspected (doc/config-only tasks).
|
|
119
120
|
*/
|
|
120
121
|
export function findGrepOnlyVerify(spec) {
|
|
121
122
|
const cmds = parseVerifyBlock(spec);
|
|
@@ -123,9 +124,10 @@ export function findGrepOnlyVerify(spec) {
|
|
|
123
124
|
return [];
|
|
124
125
|
const inspected = new Map();
|
|
125
126
|
for (const { raw } of cmds) {
|
|
126
|
-
// Split into pipeline segments
|
|
127
|
-
//
|
|
128
|
-
//
|
|
127
|
+
// Split into pipeline segments. A mis-split — a quoted `&&` making a
|
|
128
|
+
// fake segment — leaves a segment whose head is unknown, which counts
|
|
129
|
+
// as execution and skips the block. The error direction is a MISSED
|
|
130
|
+
// finding, never a false one.
|
|
129
131
|
for (const segment of raw.split(/&&|\|\||;|\|/)) {
|
|
130
132
|
const s = segmentHead(segment);
|
|
131
133
|
if (s === null)
|
|
@@ -152,7 +154,7 @@ const BEHAVIOUR_RE = /\bcurl\b|\bwget\b|\bhttpie?\b|https?:\/\/|\bnc\s+-z\b|\bss
|
|
|
152
154
|
/**
|
|
153
155
|
* Classify each command of a spec's VERIFY block. Shares `segmentHead` with the
|
|
154
156
|
* grep-theater detector, so "static" means one thing across the two measures.
|
|
155
|
-
* Empty when the spec has no
|
|
157
|
+
* Empty when the spec has no fenced VERIFY block.
|
|
156
158
|
*/
|
|
157
159
|
export function classifyVerifyCommands(spec) {
|
|
158
160
|
const cmds = parseVerifyBlock(spec);
|
|
@@ -171,10 +173,11 @@ export function classifyVerifyCommands(spec) {
|
|
|
171
173
|
});
|
|
172
174
|
}
|
|
173
175
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* the prompt body
|
|
176
|
+
* Prepended to the SECOND `runWithEmphasisRetry` attempt when the first critique
|
|
177
|
+
* rewrite still leaves `findGrepOnlyVerify` non-empty. The generic emphasis line
|
|
178
|
+
* would claim the previous attempt had no VERIFY block, which is wrong here — it
|
|
179
|
+
* had one. The defect block naming the exact files stays in the prompt body
|
|
180
|
+
* underneath the hint.
|
|
178
181
|
*/
|
|
179
182
|
export const GREP_THEATER_RETRY_HINT = '[SYSTEM NOTE: Your previous rewrite still shipped a VERIFY block whose only signal '
|
|
180
183
|
+ 'on the runnable deliverable is grep-on-source — every command is static inspection '
|
|
@@ -183,11 +186,7 @@ export const GREP_THEATER_RETRY_HINT = '[SYSTEM NOTE: Your previous rewrite stil
|
|
|
183
186
|
+ 'deliverable (e.g. `bun <script>.ts`, `bun run <script>`, start it and curl it) and '
|
|
184
187
|
+ 'assert an observable outcome of that run (exit code, a file the run produces, a '
|
|
185
188
|
+ 'served response). Keep greps only as additions to the run, never as the only signal.]';
|
|
186
|
-
/**
|
|
187
|
-
* Render the findings as a defect block for the critique rewrite: VERIFY must
|
|
188
|
-
* EXECUTE the runnable deliverable and assert an observable outcome of THAT
|
|
189
|
-
* run, not grep its source.
|
|
190
|
-
*/
|
|
189
|
+
/** Render the findings as the defect block handed to the critique rewrite. */
|
|
191
190
|
export function grepOnlyVerifyDefectText(findings) {
|
|
192
191
|
return [
|
|
193
192
|
'GREP-THEATER VERIFY — every command in the VERIFY block is static inspection',
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
export interface AbsenceAssertion {
|
|
2
|
-
/** The
|
|
2
|
+
/** The trimmed fragment the assertion was read out of: the whole VERIFY
|
|
3
|
+
* line, or only the condition when it came from an `if` header. */
|
|
3
4
|
line: string;
|
|
4
5
|
/** The path or grep pattern asserted absent (quotes stripped). */
|
|
5
6
|
target: string;
|
|
6
7
|
kind: 'path' | 'pattern';
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
|
-
* All absence assertions in the spec's VERIFY block.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* All absence assertions in the spec's VERIFY block. An `if` line contributes
|
|
11
|
+
* its condition's POSITIVE probes only when a LATER line reaches
|
|
12
|
+
* `exit <nonzero>`: the body scan starts at the next command, so a one-line
|
|
13
|
+
* `if …; then exit 1; fi` yields nothing. Every other line contributes its
|
|
14
|
+
* NEGATED probes. Empty when the spec has no fenced VERIFY block.
|
|
12
15
|
*/
|
|
13
16
|
export declare function findAbsenceAssertions(spec: string): AbsenceAssertion[];
|
|
14
17
|
export interface AbsenceConflict {
|
|
@@ -25,12 +28,14 @@ export interface AbsenceConflictContext {
|
|
|
25
28
|
/** The cross-slice contract registry text ('' when absent). */
|
|
26
29
|
contracts: string;
|
|
27
30
|
}
|
|
28
|
-
/**
|
|
31
|
+
/** Every absence assertion that collides with the plan. disk, sibling and
|
|
32
|
+
* contract are tested independently, so one assertion can yield three. */
|
|
29
33
|
export declare function findAbsenceConflicts(spec: string, ctx: AbsenceConflictContext): AbsenceConflict[];
|
|
30
|
-
/** The
|
|
31
|
-
*
|
|
34
|
+
/** The defect block handed to the critique rewrite. Self-contained: it names
|
|
35
|
+
* each conflict, why it is one, and the reconciliation to apply. */
|
|
32
36
|
export declare function absenceProbeText(conflicts: AbsenceConflict[]): string;
|
|
33
|
-
/** Parse SIBLING titles out of
|
|
34
|
-
*
|
|
35
|
-
* own deliverables. ''
|
|
37
|
+
/** Parse SIBLING titles out of `buildScopeFence`'s listing, whose rows read
|
|
38
|
+
* `[N] head` and `[N] (THIS STEP) head`. The "(THIS STEP)" row is dropped — a
|
|
39
|
+
* task may legitimately assert about its own deliverables. '' and undefined
|
|
40
|
+
* (a bare /task with no plan) yield none. */
|
|
36
41
|
export declare function siblingTitlesFromPlanContext(planContext: string | undefined): string[];
|
|
@@ -1,47 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* verify-reconcile — deterministic reconciliation of a spec's VERIFY assertions
|
|
3
|
-
* against the
|
|
3
|
+
* against the plan. Wired as the `plan-contradiction` critique probe.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* scope fence ("do NOT build other steps' work") leaked into the verify script
|
|
10
|
-
* as "other steps' work must be ABSENT". Verify then correctly FAILed at run
|
|
11
|
-
* end, the user accepted it as debt, and the final-gate autofix treated the
|
|
12
|
-
* debt as an instruction and `rm`'d the sibling's deliverable.
|
|
5
|
+
* A sibling step's deliverable is a fact about the tree this task runs in, never
|
|
6
|
+
* a valid absence target. A VERIFY line asserting it is missing is a guaranteed
|
|
7
|
+
* run-end FAIL, and an automated fixer handed that FAIL can "resolve" it by
|
|
8
|
+
* deleting the sibling's work. The defect has to die at spec time instead.
|
|
13
9
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* Two shapes read as "this must be absent":
|
|
11
|
+
* - an `if` whose condition holds a POSITIVE existence probe (`[ -f P ]`,
|
|
12
|
+
* `test -e P`, `grep PAT …`) and whose body reaches `exit <nonzero>`;
|
|
13
|
+
* - a NEGATED probe anywhere else (`[ ! -f P ]`, `test ! -f P`,
|
|
14
|
+
* `! grep PAT …`), `|| exit`-guarded or standing alone.
|
|
15
|
+
* `grep -v` / `--invert-match` is a filter, not a probe, and is skipped; so is
|
|
16
|
+
* a target starting with `-` or `$`.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* - `if <cond>; then … exit 1; fi` where <cond> contains a POSITIVE existence
|
|
21
|
-
* probe (`[ -f P ]`, `test -e P`, `grep PAT …`): P/PAT must be absent or the
|
|
22
|
-
* verify fails.
|
|
23
|
-
* - a standalone / `|| exit`-guarded NEGATED probe (`[ ! -f P ]`,
|
|
24
|
-
* `test ! -f P`, `! grep PAT …`): same meaning outside an if-header.
|
|
25
|
-
* `grep -v` occurrences are filters, not probes, and are skipped.
|
|
26
|
-
*
|
|
27
|
-
* A detected absence target is a CONFLICT when the plan pins it elsewhere:
|
|
28
|
-
* - 'disk' — the path already exists in the worktree at spec time (a
|
|
29
|
-
* sibling shipped it; asserting its absence is a guaranteed
|
|
30
|
-
* future FAIL);
|
|
18
|
+
* A detected target is a CONFLICT when the plan pins it elsewhere:
|
|
19
|
+
* - 'disk' — the path exists in the worktree at spec time;
|
|
31
20
|
* - 'sibling' — a SIBLING task's title names it;
|
|
32
21
|
* - 'contract' — the cross-slice contract registry quotes it.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
22
|
+
* The three are checked independently, so one assertion can raise all three.
|
|
23
|
+
*
|
|
24
|
+
* Matching: pattern targets by case-insensitive substring; path targets by
|
|
25
|
+
* full-path substring or a word-bounded basename. No similarity thresholds and
|
|
26
|
+
* no all-words matching — all-words matches `bun:sql` against a "Bun SQL
|
|
27
|
+
* connection" title, where substring does not.
|
|
36
28
|
*
|
|
37
|
-
* The finding is a PROBE, not a gate: it forces the critique rewrite and
|
|
38
|
-
*
|
|
39
|
-
*
|
|
29
|
+
* The finding is a PROBE, not a gate: it only forces the critique rewrite, and
|
|
30
|
+
* `absenceProbeText` tells that rewrite to KEEP an absence check when the GOAL
|
|
31
|
+
* explicitly deletes the artifact.
|
|
40
32
|
*/
|
|
41
33
|
import { parseVerifyBlock } from './spec-validation.js';
|
|
42
34
|
/** A quoted or bare shell word. */
|
|
43
35
|
const SHELL_WORD = `"[^"]+"|'[^']+'|[^\\s\\]&|;)]+`;
|
|
44
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* A `-f`/`-e`/`-d` existence probe, with or without a leading `test`. The three
|
|
38
|
+
* `(!?)` groups cover every place a negation can sit — before the `[`, inside
|
|
39
|
+
* it, and before the flag — so the caller can tell `[ ! -f P ]` from `[ -f P ]`.
|
|
40
|
+
*/
|
|
45
41
|
const EXIST_RE = new RegExp(`(!?)\\s*(?:\\[\\[?\\s*)?(!?)\\s*(?:test\\s+)?(!?)\\s*-[efd]\\s+(${SHELL_WORD})`, 'g');
|
|
46
42
|
/** grep probes: optional leading `!`, flags, then the first pattern argument. */
|
|
47
43
|
const GREP_RE = new RegExp(`(!\\s+)?\\bgrep\\s+((?:-{1,2}[\\w=,.-]+\\s+)*)(${SHELL_WORD})`, 'g');
|
|
@@ -80,9 +76,11 @@ function assertionsInFragment(fragment, positiveMeansAbsent) {
|
|
|
80
76
|
return out;
|
|
81
77
|
}
|
|
82
78
|
/**
|
|
83
|
-
* All absence assertions in the spec's VERIFY block.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
79
|
+
* All absence assertions in the spec's VERIFY block. An `if` line contributes
|
|
80
|
+
* its condition's POSITIVE probes only when a LATER line reaches
|
|
81
|
+
* `exit <nonzero>`: the body scan starts at the next command, so a one-line
|
|
82
|
+
* `if …; then exit 1; fi` yields nothing. Every other line contributes its
|
|
83
|
+
* NEGATED probes. Empty when the spec has no fenced VERIFY block.
|
|
86
84
|
*/
|
|
87
85
|
export function findAbsenceAssertions(spec) {
|
|
88
86
|
const cmds = parseVerifyBlock(spec);
|
|
@@ -93,8 +91,10 @@ export function findAbsenceAssertions(spec) {
|
|
|
93
91
|
for (let i = 0; i < lines.length; i++) {
|
|
94
92
|
const ifm = /^if\s+(.+?)(?:;\s*then\b.*)?$/.exec(lines[i]);
|
|
95
93
|
if (ifm) {
|
|
96
|
-
// Collect the block body up to the matching fi
|
|
97
|
-
//
|
|
94
|
+
// Collect the block body up to the matching `fi`, counting nested
|
|
95
|
+
// `if`s. A nested if is never scanned as a condition of its own —
|
|
96
|
+
// its lines just extend the outer body, so an `exit 1` inside it
|
|
97
|
+
// arms the OUTER condition.
|
|
98
98
|
let depth = 1;
|
|
99
99
|
let body = '';
|
|
100
100
|
let j = i + 1;
|
|
@@ -138,7 +138,8 @@ function namesTarget(haystack, a) {
|
|
|
138
138
|
return false;
|
|
139
139
|
return new RegExp(`\\b${escapeRe(base)}\\b`, 'i').test(haystack);
|
|
140
140
|
}
|
|
141
|
-
/**
|
|
141
|
+
/** Every absence assertion that collides with the plan. disk, sibling and
|
|
142
|
+
* contract are tested independently, so one assertion can yield three. */
|
|
142
143
|
export function findAbsenceConflicts(spec, ctx) {
|
|
143
144
|
const out = [];
|
|
144
145
|
for (const a of findAbsenceAssertions(spec)) {
|
|
@@ -160,8 +161,8 @@ export function findAbsenceConflicts(spec, ctx) {
|
|
|
160
161
|
}
|
|
161
162
|
return out;
|
|
162
163
|
}
|
|
163
|
-
/** The
|
|
164
|
-
*
|
|
164
|
+
/** The defect block handed to the critique rewrite. Self-contained: it names
|
|
165
|
+
* each conflict, why it is one, and the reconciliation to apply. */
|
|
165
166
|
export function absenceProbeText(conflicts) {
|
|
166
167
|
const what = {
|
|
167
168
|
disk: 'ALREADY EXISTS in the worktree (a prior task shipped it)',
|
|
@@ -182,9 +183,10 @@ export function absenceProbeText(conflicts) {
|
|
|
182
183
|
"exact artifact — then say so in the check's comment."
|
|
183
184
|
].join('\n');
|
|
184
185
|
}
|
|
185
|
-
/** Parse SIBLING titles out of
|
|
186
|
-
*
|
|
187
|
-
* own deliverables. ''
|
|
186
|
+
/** Parse SIBLING titles out of `buildScopeFence`'s listing, whose rows read
|
|
187
|
+
* `[N] head` and `[N] (THIS STEP) head`. The "(THIS STEP)" row is dropped — a
|
|
188
|
+
* task may legitimately assert about its own deliverables. '' and undefined
|
|
189
|
+
* (a bare /task with no plan) yield none. */
|
|
188
190
|
export function siblingTitlesFromPlanContext(planContext) {
|
|
189
191
|
if (!planContext)
|
|
190
192
|
return [];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** The observe-only contract handed to the child. The same string as
|
|
2
|
+
* verify-work's VERIFY_TOOLS, so both passes are told the same thing. */
|
|
2
3
|
declare const RESOLUTION_TOOLS = "read,bash";
|
|
3
4
|
/** Which card the picker tints RECOMMENDED. */
|
|
4
5
|
export type ResolutionRecommendation = 'autofix' | 'accept';
|
|
@@ -11,18 +12,19 @@ export interface ResolutionOutcome {
|
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
14
|
* Build the resolution research child's prompt. Pure, so the wording is
|
|
14
|
-
* unit-tested without spawning pi. The contract: investigate the real
|
|
15
|
-
* and end on exactly one RESOLUTION
|
|
15
|
+
* unit-tested without spawning pi. The contract it states: investigate the real
|
|
16
|
+
* workspace and end on exactly one `VERIFY-RESOLUTION:` line.
|
|
16
17
|
*/
|
|
17
18
|
export declare function buildResolutionPrompt(spec: string, failReason: string): string;
|
|
18
19
|
/**
|
|
19
|
-
* Parse the child's recommendation
|
|
20
|
-
* `VERIFY-RESOLUTION: AUTOFIX|ACCEPT` marker
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Parse the child's recommendation out of the LAST
|
|
21
|
+
* `VERIFY-RESOLUTION: AUTOFIX|ACCEPT` marker, case-insensitively. Last match
|
|
22
|
+
* wins: the model reasons before concluding, and a bash command it runs can
|
|
23
|
+
* print the token back, so an earlier occurrence is not the verdict.
|
|
23
24
|
*
|
|
24
|
-
* No marker →
|
|
25
|
-
*
|
|
25
|
+
* No marker → AUTOFIX (re-do rather than bless), with a rationale saying the
|
|
26
|
+
* research was inconclusive. A marker with no trailing sentence gets a stock
|
|
27
|
+
* rationale, so `rationale` is never empty.
|
|
26
28
|
*/
|
|
27
29
|
export declare function parseResolutionVerdict(text: string): ResolutionOutcome;
|
|
28
30
|
export declare const ACCEPT_VALUE = "accept";
|
|
@@ -37,10 +39,10 @@ export interface ResolutionChoice {
|
|
|
37
39
|
guidance?: string;
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
|
-
* The two cards for the picker,
|
|
41
|
-
* renderer
|
|
42
|
-
* tokens; remote buttons
|
|
43
|
-
* accepts both.
|
|
42
|
+
* The two cards for the picker, model-recommended one FIRST because the boxed
|
|
43
|
+
* renderer marks index 0 as the recommended card (bridge.ts `askLocal` passes
|
|
44
|
+
* `recommended: i === 0`). Values are the bare tokens; remote buttons carry the
|
|
45
|
+
* labels — {@link classifyResolutionAnswer} accepts both.
|
|
44
46
|
*/
|
|
45
47
|
export declare function resolutionOptions(recommend: ResolutionRecommendation): {
|
|
46
48
|
label: string;
|
|
@@ -48,10 +50,11 @@ export declare function resolutionOptions(recommend: ResolutionRecommendation):
|
|
|
48
50
|
recommended: boolean;
|
|
49
51
|
}[];
|
|
50
52
|
/**
|
|
51
|
-
* Map a picker answer to an action.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* Map a picker answer to an action. undefined or blank is a dismissal (cancel).
|
|
54
|
+
* A LEADING `accept`/`autofix` word matches, which covers both the bare card
|
|
55
|
+
* values and the remote button labels. Anything else becomes an AUTOFIX carrying
|
|
56
|
+
* that text as guidance — including a sentence that mentions "accept" further
|
|
57
|
+
* along, since the user is steering the re-run, not blessing the artifact.
|
|
55
58
|
*/
|
|
56
59
|
export declare function classifyResolutionAnswer(answer: string | undefined): ResolutionChoice;
|
|
57
60
|
export interface ResolutionDeps {
|
|
@@ -67,9 +70,10 @@ export interface ResolutionDeps {
|
|
|
67
70
|
}
|
|
68
71
|
/**
|
|
69
72
|
* Research a verify FAIL and return which action to recommend. Never throws
|
|
70
|
-
*
|
|
71
|
-
* reports a clean "cancelled — resume"
|
|
72
|
-
*
|
|
73
|
+
* except on a user cancel, which propagates so the loop's USER_CANCELLED handler
|
|
74
|
+
* reports a clean "cancelled — resume". A child crash returns AUTOFIX with a
|
|
75
|
+
* "could not run" rationale; since AUTOFIX is the unattended path, a crash here
|
|
76
|
+
* costs an implementation re-run rather than a prompt.
|
|
73
77
|
*/
|
|
74
78
|
export declare function researchResolution(deps: ResolutionDeps): Promise<ResolutionOutcome>;
|
|
75
79
|
export { RESOLUTION_TOOLS };
|