@mjasnikovs/pi-task 0.38.28 → 0.38.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/config.d.ts +70 -70
- package/dist/config/config.js +26 -35
- package/dist/config/extension-list.d.ts +6 -5
- package/dist/config/extension-list.js +3 -2
- package/dist/config/reasoning-args.d.ts +9 -7
- package/dist/config/reasoning-args.js +12 -10
- package/dist/config/reasoning.d.ts +44 -105
- package/dist/config/reasoning.js +27 -704
- package/dist/config/register.d.ts +34 -48
- package/dist/config/register.js +41 -51
- package/dist/config/tool-list.d.ts +16 -16
- package/dist/config/tool-list.js +1 -1
- package/dist/remote/bridge.d.ts +19 -10
- package/dist/remote/bridge.js +3 -2
- package/dist/remote/broadcast.js +3 -1
- package/dist/remote/events.js +12 -11
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/protocol.d.ts +6 -3
- package/dist/remote/protocol.js +2 -1
- package/dist/remote/push.d.ts +16 -16
- package/dist/remote/push.js +27 -27
- package/dist/remote/register.d.ts +3 -3
- package/dist/remote/register.js +17 -19
- package/dist/remote/server.d.ts +9 -8
- package/dist/remote/server.js +15 -14
- package/dist/remote/session-state.d.ts +5 -4
- package/dist/remote/session-state.js +8 -5
- package/dist/remote/sw.d.ts +7 -6
- package/dist/remote/sw.js +7 -6
- package/dist/remote/tailscale.d.ts +4 -2
- package/dist/remote/tailscale.js +4 -2
- package/dist/remote/ui-highlight.js +6 -5
- package/dist/remote/ui-render.js +4 -4
- package/dist/remote/ui-script.js +24 -24
- package/dist/remote/ui-styles.d.ts +1 -1
- package/dist/remote/ui-styles.js +10 -13
- package/dist/remote/ui-tools.js +9 -6
- package/dist/shared/child-extensions.d.ts +29 -17
- package/dist/shared/child-extensions.js +29 -17
- package/dist/shared/child-output.d.ts +30 -24
- package/dist/shared/child-output.js +25 -17
- package/dist/shared/child-process.d.ts +47 -40
- package/dist/shared/child-process.js +50 -59
- package/dist/shared/command-watchdog.d.ts +22 -16
- package/dist/shared/command-watchdog.js +28 -21
- package/dist/shared/fs-text.d.ts +16 -10
- package/dist/shared/fs-text.js +16 -10
- package/dist/shared/git-runner.d.ts +25 -25
- package/dist/shared/git-runner.js +25 -25
- package/dist/shared/leaked-tool-call.d.ts +17 -11
- package/dist/shared/leaked-tool-call.js +23 -15
- package/dist/shared/model-endpoint.d.ts +29 -16
- package/dist/shared/model-endpoint.js +33 -21
- package/dist/shared/pi-invocation.d.ts +7 -4
- package/dist/shared/pi-invocation.js +12 -7
- package/dist/shared/pkg-version.d.ts +13 -5
- package/dist/shared/pkg-version.js +13 -5
- package/dist/shared/reasoning-capability.d.ts +35 -24
- package/dist/shared/reasoning-capability.js +35 -24
- package/dist/shared/stream-watchdog.d.ts +60 -44
- package/dist/shared/stream-watchdog.js +62 -45
- package/dist/task/accept-debt.d.ts +41 -43
- package/dist/task/accept-debt.js +73 -65
- package/dist/task/api-synthesis.d.ts +24 -21
- package/dist/task/api-synthesis.js +32 -26
- package/dist/task/apis-contract.d.ts +32 -64
- package/dist/task/apis-contract.js +32 -64
- package/dist/task/artifact-closure.d.ts +27 -13
- package/dist/task/artifact-closure.js +95 -67
- package/dist/task/auto-commit.d.ts +46 -35
- package/dist/task/auto-commit.js +51 -38
- package/dist/task/auto-io.d.ts +45 -25
- package/dist/task/auto-io.js +57 -29
- package/dist/task/auto-orchestrator.d.ts +26 -24
- package/dist/task/auto-orchestrator.js +178 -162
- package/dist/task/auto-prompts.d.ts +36 -24
- package/dist/task/auto-prompts.js +40 -26
- package/dist/task/autofix-ledger.d.ts +27 -25
- package/dist/task/autofix-ledger.js +29 -26
- package/dist/task/batch-test-task.d.ts +20 -12
- package/dist/task/batch-test-task.js +67 -60
- package/dist/task/boot-probe.d.ts +60 -44
- package/dist/task/boot-probe.js +91 -72
- package/dist/task/cancel-input.d.ts +30 -16
- package/dist/task/cancel-input.js +20 -11
- package/dist/task/cancel-points.d.ts +27 -20
- package/dist/task/cancel-points.js +30 -22
- package/dist/task/child-runner.d.ts +46 -51
- package/dist/task/child-runner.js +48 -49
- package/dist/task/child-status.d.ts +23 -16
- package/dist/task/child-status.js +23 -16
- package/dist/task/clamp-output.js +12 -5
- package/dist/task/command-run.d.ts +31 -28
- package/dist/task/command-run.js +44 -35
- package/dist/task/command-shrink.d.ts +25 -18
- package/dist/task/command-shrink.js +37 -31
- package/dist/task/command-watchdog.d.ts +9 -6
- package/dist/task/command-watchdog.js +21 -15
- package/dist/task/context-attribution.d.ts +34 -26
- package/dist/task/context-attribution.js +34 -26
- package/dist/task/context-silence.d.ts +39 -29
- package/dist/task/context-silence.js +35 -25
- package/dist/task/context-usage.d.ts +25 -7
- package/dist/task/context-usage.js +21 -6
- package/dist/task/contracts.d.ts +8 -4
- package/dist/task/contracts.js +25 -17
- package/dist/task/coverage-loop.d.ts +22 -18
- package/dist/task/coverage-loop.js +35 -30
- package/dist/task/critique-probes.d.ts +13 -14
- package/dist/task/critique-probes.js +50 -39
- package/dist/task/debug-log.d.ts +13 -5
- package/dist/task/debug-log.js +32 -20
- package/dist/task/decompose-fidelity.d.ts +11 -9
- package/dist/task/decompose-fidelity.js +38 -33
- package/dist/task/decompose-granularity.d.ts +41 -38
- package/dist/task/decompose-granularity.js +41 -38
- package/dist/task/deep-render-check.d.ts +22 -14
- package/dist/task/deep-render-check.js +40 -31
- package/dist/task/dropped-input.d.ts +12 -7
- package/dist/task/dropped-input.js +5 -2
- package/dist/task/enforce-attribution.d.ts +38 -47
- package/dist/task/enforce-attribution.js +46 -52
- package/dist/task/enforce-guidelines.d.ts +31 -20
- package/dist/task/enforce-guidelines.js +32 -21
- package/dist/task/enrichment.d.ts +7 -2
- package/dist/task/enrichment.js +26 -14
- package/dist/task/env-notes.d.ts +16 -7
- package/dist/task/env-notes.js +48 -31
- package/dist/task/env-template-closure.d.ts +4 -4
- package/dist/task/env-template-closure.js +42 -34
- package/dist/task/external-context.d.ts +28 -21
- package/dist/task/external-context.js +17 -12
- package/dist/task/failure-classifier.d.ts +4 -5
- package/dist/task/failure-classifier.js +6 -7
- package/dist/task/file-inventory.d.ts +15 -11
- package/dist/task/file-inventory.js +25 -22
- package/dist/task/final-gate-fix.d.ts +74 -86
- package/dist/task/final-gate-fix.js +97 -116
- package/dist/task/final-gate-progress.d.ts +29 -46
- package/dist/task/final-gate-progress.js +40 -51
- package/dist/task/final-gate.d.ts +64 -97
- package/dist/task/final-gate.js +192 -199
- package/dist/task/fix-child.d.ts +21 -27
- package/dist/task/fix-child.js +21 -27
- package/dist/task/foreign-path.d.ts +6 -5
- package/dist/task/foreign-path.js +0 -0
- package/dist/task/frozen-conflict.d.ts +9 -10
- package/dist/task/frozen-conflict.js +61 -64
- package/dist/task/frozen-path-guard.d.ts +35 -14
- package/dist/task/frozen-path-guard.js +56 -39
- package/dist/task/gate-child.d.ts +27 -28
- package/dist/task/gate-child.js +37 -35
- package/dist/task/gate-deps.d.ts +34 -27
- package/dist/task/gate-deps.js +169 -159
- package/dist/task/gate-tally.d.ts +77 -80
- package/dist/task/gate-tally.js +65 -68
- package/dist/task/git-state-guard.d.ts +15 -11
- package/dist/task/git-state-guard.js +76 -66
- package/dist/task/impl-widget.d.ts +25 -16
- package/dist/task/impl-widget.js +27 -17
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +34 -31
- package/dist/task/implementation-turn.js +29 -27
- package/dist/task/inline-markdown.d.ts +20 -7
- package/dist/task/inline-markdown.js +15 -6
- package/dist/task/launch-config-gap.js +25 -39
- package/dist/task/launch-contract.d.ts +18 -21
- package/dist/task/launch-contract.js +28 -30
- package/dist/task/launch-manifest.d.ts +6 -2
- package/dist/task/launch-manifest.js +35 -34
- package/dist/task/ledger.js +16 -14
- package/dist/task/lint-fix.d.ts +6 -8
- package/dist/task/lint-fix.js +67 -69
- package/dist/task/loop-detector.d.ts +9 -8
- package/dist/task/loop-detector.js +16 -12
- package/dist/task/mid-run-input.d.ts +17 -15
- package/dist/task/mid-run-input.js +17 -15
- package/dist/task/orchestrator.d.ts +24 -28
- package/dist/task/orchestrator.js +62 -64
- package/dist/task/orientation.d.ts +18 -23
- package/dist/task/orientation.js +24 -31
- package/dist/task/owned-freeze-conflict.d.ts +21 -20
- package/dist/task/owned-freeze-conflict.js +52 -85
- package/dist/task/owned-freeze-reassign.d.ts +40 -60
- package/dist/task/owned-freeze-reassign.js +41 -61
- package/dist/task/parsers.d.ts +4 -2
- package/dist/task/parsers.js +4 -4
- package/dist/task/phases.d.ts +41 -48
- package/dist/task/phases.js +180 -248
- package/dist/task/plan-io.d.ts +6 -7
- package/dist/task/plan-io.js +6 -7
- package/dist/task/plan-orchestrator.d.ts +10 -8
- package/dist/task/plan-orchestrator.js +14 -10
- package/dist/task/plan-prompts.d.ts +6 -5
- package/dist/task/plan-prompts.js +6 -5
- package/dist/task/plan-readonly.d.ts +4 -5
- package/dist/task/plan-readonly.js +4 -5
- package/dist/task/plan-rounds.d.ts +17 -29
- package/dist/task/plan-rounds.js +21 -34
- package/dist/task/plan-session.d.ts +58 -72
- package/dist/task/plan-session.js +61 -83
- package/dist/task/probe-gaming.d.ts +28 -27
- package/dist/task/probe-gaming.js +0 -0
- package/dist/task/prohibition-probe.d.ts +14 -16
- package/dist/task/prompts.d.ts +3 -4
- package/dist/task/prompts.js +17 -26
- package/dist/task/qa-transcript.d.ts +15 -22
- package/dist/task/qa-transcript.js +15 -21
- package/dist/task/question-box.d.ts +17 -13
- package/dist/task/question-box.js +19 -15
- package/dist/task/question-dedup.d.ts +6 -7
- package/dist/task/question-dedup.js +13 -14
- package/dist/task/question-dialog.d.ts +22 -32
- package/dist/task/question-dialog.js +22 -32
- package/dist/task/question-source.d.ts +18 -44
- package/dist/task/question-source.js +22 -51
- package/dist/task/refuted-constraint.d.ts +11 -31
- package/dist/task/refuted-constraint.js +27 -51
- package/dist/task/regenerable-artifacts.d.ts +12 -31
- package/dist/task/regenerable-artifacts.js +12 -31
- package/dist/task/render-check.d.ts +11 -22
- package/dist/task/render-check.js +33 -46
- package/dist/task/repo-health-check.d.ts +10 -14
- package/dist/task/repo-health-check.js +17 -23
- package/dist/task/requirements.d.ts +38 -71
- package/dist/task/requirements.js +78 -126
- package/dist/task/research-fanout-budget.d.ts +51 -88
- package/dist/task/research-fanout-budget.js +51 -88
- package/dist/task/research-worker.d.ts +33 -36
- package/dist/task/research-worker.js +39 -61
- package/dist/task/resume-gap.d.ts +14 -15
- package/dist/task/root-cause-repair.d.ts +9 -9
- package/dist/task/root-cause-repair.js +28 -40
- package/dist/task/run-bracket.d.ts +10 -13
- package/dist/task/run-end.d.ts +12 -22
- package/dist/task/run-end.js +8 -16
- package/dist/task/run-final-gate.d.ts +19 -21
- package/dist/task/run-final-gate.js +62 -80
- package/dist/task/runner-globs.d.ts +12 -13
- package/dist/task/runner-globs.js +12 -13
- package/dist/task/runner-resolve.d.ts +9 -9
- package/dist/task/runner-resolve.js +22 -23
- package/dist/task/script-escape.d.ts +10 -12
- package/dist/task/script-escape.js +13 -14
- package/dist/task/serve-entry.d.ts +1 -1
- package/dist/task/serve-entry.js +22 -25
- package/dist/task/service-blocks.js +4 -2
- package/dist/task/shipped-source.d.ts +11 -29
- package/dist/task/shipped-source.js +11 -29
- package/dist/task/skip-escape.js +10 -14
- package/dist/task/spec-urls.d.ts +26 -65
- package/dist/task/spec-urls.js +26 -65
- package/dist/task/spec-validation.d.ts +17 -20
- package/dist/task/spec-validation.js +17 -20
- package/dist/task/stall-detector.d.ts +23 -30
- package/dist/task/stall-detector.js +23 -30
- package/dist/task/stream-watchdog.d.ts +14 -12
- package/dist/task/stream-watchdog.js +14 -12
- package/dist/task/substitution-probe.d.ts +17 -20
- package/dist/task/substitution-probe.js +17 -20
- package/dist/task/task-gates.d.ts +36 -41
- package/dist/task/task-gates.js +95 -106
- package/dist/task/task-io.d.ts +4 -4
- package/dist/task/task-io.js +4 -4
- package/dist/task/task-parsers.js +4 -3
- package/dist/task/task-provenance.d.ts +2 -2
- package/dist/task/task-provenance.js +11 -13
- package/dist/task/task-types.d.ts +4 -3
- package/dist/task/terminal-outcome.d.ts +14 -16
- package/dist/task/terminal-outcome.js +12 -14
- package/dist/task/test-assembly.d.ts +13 -20
- package/dist/task/test-assembly.js +13 -20
- package/dist/task/timings.d.ts +5 -3
- package/dist/task/timings.js +5 -3
- package/dist/task/title-label.d.ts +9 -4
- package/dist/task/title-label.js +9 -4
- package/dist/task/type-only-answer.d.ts +44 -52
- package/dist/task/type-only-answer.js +44 -52
- package/dist/task/unfailable-command.d.ts +18 -24
- package/dist/task/unfailable-command.js +21 -27
- package/dist/task/unknown-routing.d.ts +10 -4
- package/dist/task/unknown-routing.js +10 -4
- package/dist/task/user-directives.d.ts +5 -8
- package/dist/task/user-directives.js +5 -8
- package/dist/task/verify-quality.d.ts +18 -22
- package/dist/task/verify-quality.js +45 -46
- package/dist/task/verify-reconcile.d.ts +15 -10
- package/dist/task/verify-reconcile.js +45 -43
- package/dist/task/verify-resolution.d.ts +24 -20
- package/dist/task/verify-resolution.js +51 -50
- package/dist/task/verify-work.d.ts +59 -66
- package/dist/task/verify-work.js +101 -138
- package/dist/task/widget.d.ts +15 -14
- package/dist/task/widget.js +22 -17
- package/dist/task/wiring-claims.d.ts +25 -32
- package/dist/task/wiring-claims.js +30 -35
- package/dist/task/write-guard.d.ts +39 -39
- package/dist/task/write-guard.js +48 -51
- package/dist/task/yolo.d.ts +34 -30
- package/dist/task/yolo.js +42 -37
- package/dist/workers/abstention.d.ts +21 -41
- package/dist/workers/abstention.js +27 -48
- package/dist/workers/brave-search.d.ts +4 -3
- package/dist/workers/brave-search.js +5 -2
- package/dist/workers/brave-warning.d.ts +7 -4
- package/dist/workers/brave-warning.js +19 -7
- package/dist/workers/ddg-search.d.ts +6 -6
- package/dist/workers/ddg-search.js +18 -12
- package/dist/workers/docs-cache.js +5 -2
- package/dist/workers/docs-chunk.d.ts +30 -37
- package/dist/workers/docs-chunk.js +37 -41
- package/dist/workers/docs-core.d.ts +28 -44
- package/dist/workers/docs-core.js +25 -44
- package/dist/workers/docs-index.js +4 -3
- package/dist/workers/docs-lookup.d.ts +15 -22
- package/dist/workers/docs-lookup.js +12 -21
- package/dist/workers/docs-project.d.ts +15 -9
- package/dist/workers/docs-project.js +17 -10
- package/dist/workers/docs-resolve.d.ts +19 -20
- package/dist/workers/docs-resolve.js +35 -32
- package/dist/workers/docs-retrieve.d.ts +5 -6
- package/dist/workers/docs-retrieve.js +18 -15
- package/dist/workers/exa-search.d.ts +9 -6
- package/dist/workers/exa-search.js +23 -12
- package/dist/workers/fetch-core.d.ts +13 -16
- package/dist/workers/fetch-core.js +23 -23
- package/dist/workers/focused-extractor.d.ts +12 -12
- package/dist/workers/focused-extractor.js +16 -19
- package/dist/workers/html-clean.js +24 -14
- package/dist/workers/http-request.d.ts +28 -20
- package/dist/workers/http-request.js +22 -17
- package/dist/workers/npm-version.d.ts +28 -11
- package/dist/workers/npm-version.js +24 -15
- package/dist/workers/phantom-imports.d.ts +15 -12
- package/dist/workers/phantom-imports.js +30 -24
- package/dist/workers/pi-worker-core.d.ts +86 -54
- package/dist/workers/pi-worker-core.js +112 -112
- 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 +23 -10
- package/dist/workers/reasoning-warning.d.ts +18 -17
- package/dist/workers/reasoning-warning.js +22 -20
- package/dist/workers/research-cache.js +50 -78
- package/dist/workers/search-core.js +7 -5
- package/dist/workers/search-types.d.ts +10 -9
- package/dist/workers/search-types.js +9 -8
- package/dist/workers/session-hint.d.ts +13 -14
- package/dist/workers/session-hint.js +8 -9
- package/dist/workers/shared.d.ts +21 -25
- package/dist/workers/shared.js +0 -0
- package/dist/workers/single-read-extension.d.ts +14 -7
- package/dist/workers/single-read-extension.js +14 -7
- package/dist/workers/single-read-guard.d.ts +25 -28
- package/dist/workers/single-read-guard.js +32 -32
- package/dist/workers/typeonly-log.d.ts +12 -9
- package/dist/workers/typeonly-log.js +29 -33
- package/dist/workers/worker-channels.d.ts +15 -23
- package/dist/workers/worker-channels.js +15 -23
- package/dist/workers/worker-failure.d.ts +38 -46
- package/dist/workers/worker-failure.js +31 -39
- package/dist/workers/worker-kill.d.ts +25 -26
- package/dist/workers/worker-kill.js +16 -19
- package/dist/workers/worker-profiles.d.ts +43 -53
- package/dist/workers/worker-profiles.js +30 -38
- package/package.json +10 -8
|
@@ -1,69 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* enforce-attribution — decide whether an enforce-pass re-verify FAIL can possibly
|
|
3
|
-
* be the ENFORCE COMMIT's fault
|
|
3
|
+
* be the ENFORCE COMMIT's fault.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* full, one line:
|
|
5
|
+
* THE FAILURE CLASS. An enforce commit can be one line:
|
|
7
6
|
*
|
|
8
7
|
* - setApiError((usersData).error ?? 'Failed to load users')
|
|
9
8
|
* + setApiError(usersData.error ?? 'Failed to load users')
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* touches it
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* one correct change destroyed, one permanent false verify-FAIL debt written
|
|
18
|
-
* against work that was fine, and the change re-made anyway.
|
|
10
|
+
* and the differential re-verify can still FAIL — on a test in a file that change
|
|
11
|
+
* cannot reach, because the runner bundles per story and the import graph never
|
|
12
|
+
* touches it. The differential reverts the enforce commit anyway. The defect was
|
|
13
|
+
* real and PRE-EXISTING, a later pass fixes it and re-makes the identical change,
|
|
14
|
+
* and the cost is one correct edit destroyed plus a false verify-FAIL debt written
|
|
15
|
+
* against work that was fine.
|
|
19
16
|
*
|
|
20
|
-
* The mechanism
|
|
21
|
-
* channel (root-cause-repair.ts)
|
|
22
|
-
* TASK's own commit
|
|
23
|
-
* the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* enforce commit did.
|
|
17
|
+
* The mechanism is not broken; it is asked the wrong question. The root-cause
|
|
18
|
+
* channel (root-cause-repair.ts) attributes against `scope: 'committed'` — the
|
|
19
|
+
* TASK's own commit — concludes "this task touched the file", and falls through to
|
|
20
|
+
* the conservative revert. But at THIS seam the differential is deciding whether to
|
|
21
|
+
* discard the ENFORCE COMMIT. The causal question is therefore *"could the enforce
|
|
22
|
+
* diff have caused this?"*, never *"could the task have?"*: reverting the enforce
|
|
23
|
+
* commit can only ever repair damage the enforce commit did.
|
|
28
24
|
*
|
|
29
25
|
* So the filter here is mechanical and one-sided:
|
|
30
26
|
*
|
|
31
|
-
* - the files the FAIL text NAMES are extracted
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* that
|
|
27
|
+
* - the files the FAIL text NAMES are extracted, paths AND bare basenames. This
|
|
28
|
+
* is not belt-and-braces: run against root-cause-repair.ts's own
|
|
29
|
+
* `PATH_TOKEN_RE`, a reason naming `MyListings.spec.tsx:186` matches NOTHING,
|
|
30
|
+
* because that pattern needs a `/`. Basenames are not optional here;
|
|
35
31
|
* - each is compared against the enforce commit's own file set, by path suffix
|
|
36
32
|
* and by RELATED STEM (`Admin.tsx` ~ `Admin.spec.tsx` ~ `Admin.stories.tsx`),
|
|
37
33
|
* so a regression in a touched file's own test still counts as overlap;
|
|
38
34
|
* - DISJOINT ⇒ keep the edits and route the defect. Anything else — an unknown
|
|
39
|
-
* enforce diff, a FAIL text naming no file at all, any overlap —
|
|
40
|
-
*
|
|
35
|
+
* or empty enforce diff, a FAIL text naming no file at all, any overlap —
|
|
36
|
+
* reverts. Never keep on ignorance.
|
|
41
37
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
38
|
+
* Run across every branch: a disjoint reason KEEPs and names the file to blame;
|
|
39
|
+
* an overlap by path and an overlap by related stem (`Admin.spec.tsx` against a
|
|
40
|
+
* touched `src/client/pages/Admin.tsx`) both REVERT with the overlap recorded;
|
|
41
|
+
* and a reason naming no file, a null enforce diff and an empty one all REVERT.
|
|
42
|
+
* Exactly one branch keeps, and it requires positive evidence.
|
|
44
43
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* (`scripts/live-enforce-attribution-ab.ts`):
|
|
44
|
+
* Keeping the edits must not mean losing the finding: the caller still records the
|
|
45
|
+
* debt and still queues the repair.
|
|
48
46
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* — with no path and no `.tsx` anywhere. Those 11 fall through to the revert.
|
|
47
|
+
* THE HONEST WEAKNESS. This only fires when the FAIL text names a file. A type
|
|
48
|
+
* error does — the compiler prints the path — but a failing unit test often names
|
|
49
|
+
* the UNIT instead ("The MyListings component test fails"), with no path and no
|
|
50
|
+
* extension anywhere. Confirmed: that reason extracts nothing and REVERTs with
|
|
51
|
+
* `no-file-named`, which is exactly the behaviour that shipped before this filter
|
|
52
|
+
* existed.
|
|
56
53
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* shipped rule is deliberately the conservative half of that trade: a miss costs
|
|
62
|
-
* exactly the behaviour that shipped before, while a false KEEP would ship a real
|
|
63
|
-
* regression. A stem-widened extractor (accept a bare identifier matching a tracked
|
|
64
|
-
* file's stem) reaches 40/40 with 0 errors in the same data and is NOT wired — see
|
|
65
|
-
* VALIDATION-DEBT.md, it resolves prose nouns to files and its FP mode was never
|
|
66
|
-
* exercised.
|
|
54
|
+
* That is the deliberate half of the trade: a miss changes nothing, while a false
|
|
55
|
+
* KEEP would ship a real regression. Widening the extractor to accept a bare
|
|
56
|
+
* identifier matching a tracked file's stem would catch more, and is NOT wired: it
|
|
57
|
+
* resolves prose nouns to files, and its false-positive mode is unexercised.
|
|
67
58
|
*/
|
|
68
59
|
/**
|
|
69
60
|
* The comparable stem of a file name: the base name with its extension and any
|
|
@@ -1,84 +1,78 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* enforce-attribution — decide whether an enforce-pass re-verify FAIL can possibly
|
|
3
|
-
* be the ENFORCE COMMIT's fault
|
|
3
|
+
* be the ENFORCE COMMIT's fault.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* full, one line:
|
|
5
|
+
* THE FAILURE CLASS. An enforce commit can be one line:
|
|
7
6
|
*
|
|
8
7
|
* - setApiError((usersData).error ?? 'Failed to load users')
|
|
9
8
|
* + setApiError(usersData.error ?? 'Failed to load users')
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* touches it
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* one correct change destroyed, one permanent false verify-FAIL debt written
|
|
18
|
-
* against work that was fine, and the change re-made anyway.
|
|
10
|
+
* and the differential re-verify can still FAIL — on a test in a file that change
|
|
11
|
+
* cannot reach, because the runner bundles per story and the import graph never
|
|
12
|
+
* touches it. The differential reverts the enforce commit anyway. The defect was
|
|
13
|
+
* real and PRE-EXISTING, a later pass fixes it and re-makes the identical change,
|
|
14
|
+
* and the cost is one correct edit destroyed plus a false verify-FAIL debt written
|
|
15
|
+
* against work that was fine.
|
|
19
16
|
*
|
|
20
|
-
* The mechanism
|
|
21
|
-
* channel (root-cause-repair.ts)
|
|
22
|
-
* TASK's own commit
|
|
23
|
-
* the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* enforce commit did.
|
|
17
|
+
* The mechanism is not broken; it is asked the wrong question. The root-cause
|
|
18
|
+
* channel (root-cause-repair.ts) attributes against `scope: 'committed'` — the
|
|
19
|
+
* TASK's own commit — concludes "this task touched the file", and falls through to
|
|
20
|
+
* the conservative revert. But at THIS seam the differential is deciding whether to
|
|
21
|
+
* discard the ENFORCE COMMIT. The causal question is therefore *"could the enforce
|
|
22
|
+
* diff have caused this?"*, never *"could the task have?"*: reverting the enforce
|
|
23
|
+
* commit can only ever repair damage the enforce commit did.
|
|
28
24
|
*
|
|
29
25
|
* So the filter here is mechanical and one-sided:
|
|
30
26
|
*
|
|
31
|
-
* - the files the FAIL text NAMES are extracted
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* that
|
|
27
|
+
* - the files the FAIL text NAMES are extracted, paths AND bare basenames. This
|
|
28
|
+
* is not belt-and-braces: run against root-cause-repair.ts's own
|
|
29
|
+
* `PATH_TOKEN_RE`, a reason naming `MyListings.spec.tsx:186` matches NOTHING,
|
|
30
|
+
* because that pattern needs a `/`. Basenames are not optional here;
|
|
35
31
|
* - each is compared against the enforce commit's own file set, by path suffix
|
|
36
32
|
* and by RELATED STEM (`Admin.tsx` ~ `Admin.spec.tsx` ~ `Admin.stories.tsx`),
|
|
37
33
|
* so a regression in a touched file's own test still counts as overlap;
|
|
38
34
|
* - DISJOINT ⇒ keep the edits and route the defect. Anything else — an unknown
|
|
39
|
-
* enforce diff, a FAIL text naming no file at all, any overlap —
|
|
40
|
-
*
|
|
35
|
+
* or empty enforce diff, a FAIL text naming no file at all, any overlap —
|
|
36
|
+
* reverts. Never keep on ignorance.
|
|
41
37
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
38
|
+
* Run across every branch: a disjoint reason KEEPs and names the file to blame;
|
|
39
|
+
* an overlap by path and an overlap by related stem (`Admin.spec.tsx` against a
|
|
40
|
+
* touched `src/client/pages/Admin.tsx`) both REVERT with the overlap recorded;
|
|
41
|
+
* and a reason naming no file, a null enforce diff and an empty one all REVERT.
|
|
42
|
+
* Exactly one branch keeps, and it requires positive evidence.
|
|
44
43
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* (`scripts/live-enforce-attribution-ab.ts`):
|
|
44
|
+
* Keeping the edits must not mean losing the finding: the caller still records the
|
|
45
|
+
* debt and still queues the repair.
|
|
48
46
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* — with no path and no `.tsx` anywhere. Those 11 fall through to the revert.
|
|
47
|
+
* THE HONEST WEAKNESS. This only fires when the FAIL text names a file. A type
|
|
48
|
+
* error does — the compiler prints the path — but a failing unit test often names
|
|
49
|
+
* the UNIT instead ("The MyListings component test fails"), with no path and no
|
|
50
|
+
* extension anywhere. Confirmed: that reason extracts nothing and REVERTs with
|
|
51
|
+
* `no-file-named`, which is exactly the behaviour that shipped before this filter
|
|
52
|
+
* existed.
|
|
56
53
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* shipped rule is deliberately the conservative half of that trade: a miss costs
|
|
62
|
-
* exactly the behaviour that shipped before, while a false KEEP would ship a real
|
|
63
|
-
* regression. A stem-widened extractor (accept a bare identifier matching a tracked
|
|
64
|
-
* file's stem) reaches 40/40 with 0 errors in the same data and is NOT wired — see
|
|
65
|
-
* VALIDATION-DEBT.md, it resolves prose nouns to files and its FP mode was never
|
|
66
|
-
* exercised.
|
|
54
|
+
* That is the deliberate half of the trade: a miss changes nothing, while a false
|
|
55
|
+
* KEEP would ship a real regression. Widening the extractor to accept a bare
|
|
56
|
+
* identifier matching a tracked file's stem would catch more, and is NOT wired: it
|
|
57
|
+
* resolves prose nouns to files, and its false-positive mode is unexercised.
|
|
67
58
|
*/
|
|
68
59
|
/** A path-like token: at least one separator, ending in a file name. */
|
|
69
60
|
const PATH_TOKEN_RE = /(?:[\w.@~-]+\/)+[\w.@-]+\.\w+/g;
|
|
70
61
|
/**
|
|
71
|
-
* A bare file name with a code-ish extension. Deliberately extension-gated
|
|
72
|
-
* ungated `\w+\.\w
|
|
73
|
-
*
|
|
74
|
-
*
|
|
62
|
+
* A bare file name with a code-ish extension. Deliberately extension-gated, and
|
|
63
|
+
* the gate does real work: run against an ungated `\w+\.\w+`, the prose "e.g.", a
|
|
64
|
+
* version "v1.2", the object access `usersData.error` and method chains like
|
|
65
|
+
* `page.locator` or `cy.get` ALL match, and every one would be a phantom "named
|
|
66
|
+
* file". Through this pattern none of them extract anything, while
|
|
67
|
+
* `MyListings.spec.tsx:186` and `src/server/routes/photos.ts` both do.
|
|
75
68
|
*/
|
|
76
69
|
const BARE_FILE_RE = /\b[\w@-]+(?:\.[\w@-]+)*\.(?:tsx?|jsx?|mtsx?|ctsx?|mjs|cjs|vue|svelte|astro|py|go|rs|rb|java|kt|kts|cs|php|swift|scala|c|h|cc|cpp|hpp|css|scss|sass|less|html?|json|jsonc|ya?ml|toml|sql|sh|bash|zsh|md|mdx|prisma|graphql|gql|proto|lock)\b/g;
|
|
77
70
|
/** Line/column suffixes and decoration a reason wraps a file name in. */
|
|
78
71
|
const TRAILING_POSITION_RE = /:(\d+)(?::(\d+))?$/;
|
|
79
72
|
/** Suffixes that make a file a sibling of another (test/story/type companions). */
|
|
80
73
|
const COMPANION_SUFFIXES = ['.spec', '.test', '.stories', '.story', '.d', '.min'];
|
|
81
|
-
/** A pathological reason cannot make this scan unbounded
|
|
74
|
+
/** A pathological reason cannot make this scan unbounded — 60 names in yields 24
|
|
75
|
+
* out. */
|
|
82
76
|
const MAX_NAMED = 24;
|
|
83
77
|
/** Strip `./`, leading slashes and surrounding whitespace. */
|
|
84
78
|
function normalisePath(p) {
|
|
@@ -6,20 +6,25 @@ export declare const GUIDELINE_FILENAMES: readonly ["AGENTS.md", "CLAUDE.md"];
|
|
|
6
6
|
* The fix pass gets exactly two tools: `read` and `edit`. Deliberately no
|
|
7
7
|
* `write`, `grep`, `find`, or `ls`.
|
|
8
8
|
*
|
|
9
|
-
* - No `write
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* - No `write`, and `edit` cannot substitute for it: pi's edit tool calls
|
|
10
|
+
* `access(absolutePath)` FIRST and throws `Could not edit file: <path>. Error
|
|
11
|
+
* code: ENOENT.` before it ever reads. So the pass cannot create a new file at
|
|
12
|
+
* all. This is the load-bearing removal — a model that cannot run lint, tsc or
|
|
13
|
+
* tests will otherwise write scratch "runner" scripts by the hundred hoping to
|
|
14
|
+
* execute them, and dropping `write` is what stops that.
|
|
14
15
|
* - No `grep`/`find`/`ls` → the pass cannot enumerate or roam the tree; it is
|
|
15
16
|
* handed the explicit, closed list of changed files (see captureCommitDiff) and is
|
|
16
17
|
* told to edit only those.
|
|
17
18
|
* - `read` IS allowed: the model genuinely needs it — to re-read a file after
|
|
18
19
|
* editing to confirm the fix landed, and to read a neighbouring file for the
|
|
19
|
-
* correct import
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* correct import or type when bringing the change into compliance. Denied that,
|
|
21
|
+
* it fabricates imports instead.
|
|
22
|
+
*
|
|
23
|
+
* But `read` has NO per-path sandbox in pi. Its resolver only joins the path to
|
|
24
|
+
* cwd and tries filename variants — checked, `/etc/hostname` resolves to
|
|
25
|
+
* `/etc/hostname` and `../../../` escapes upward, with no confinement test
|
|
26
|
+
* anywhere. So "only the changed files" is ENFORCED for edits, by the closed
|
|
27
|
+
* file list the prompt scopes them to, and is a soft instruction for reads.
|
|
23
28
|
*/
|
|
24
29
|
declare const ENFORCE_TOOLS = "read,edit";
|
|
25
30
|
/**
|
|
@@ -27,13 +32,15 @@ declare const ENFORCE_TOOLS = "read,edit";
|
|
|
27
32
|
* files and report violations but CANNOT edit, create, or run anything.
|
|
28
33
|
*
|
|
29
34
|
* This is the "no signal ⇒ no license to rewrite logic" half of the gate. When a
|
|
30
|
-
* task ships no
|
|
31
|
-
* VERIFY, or
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* task ships no behavioural verification to guard a destructive edit — no runnable
|
|
36
|
+
* VERIFY, or a verify gate that never produced a genuine clean pass — there is
|
|
37
|
+
* nothing to revert against if the fix pass makes things worse. A weak model handed
|
|
38
|
+
* `read,edit` in that state can degrade a working tree and still report CLEAN,
|
|
39
|
+
* because nothing is able to contradict it.
|
|
40
|
+
*
|
|
41
|
+
* Demoted to `read` alone it cannot change anything, and still names the real
|
|
42
|
+
* violation. So with no signal to check against, the pass reports the violation as
|
|
43
|
+
* a warning instead of editing.
|
|
37
44
|
*/
|
|
38
45
|
declare const ENFORCE_FLAG_TOOLS = "read";
|
|
39
46
|
export interface GuidelineDoc {
|
|
@@ -52,9 +59,13 @@ export interface EnforceOutcome {
|
|
|
52
59
|
reason?: string;
|
|
53
60
|
}
|
|
54
61
|
/**
|
|
55
|
-
* Read the guideline files that live directly in `cwd` (AGENTS.md, CLAUDE.md)
|
|
56
|
-
*
|
|
57
|
-
*
|
|
62
|
+
* Read the guideline files that live directly in `cwd` (AGENTS.md, CLAUDE.md),
|
|
63
|
+
* concatenated under a `## <name>` header each, in that order.
|
|
64
|
+
*
|
|
65
|
+
* Returns null when none exist OR all are empty — the caller treats either as a
|
|
66
|
+
* pass. cwd-only by design, with no walk up to the git root: run from a
|
|
67
|
+
* subdirectory holding only its own AGENTS.md, a CLAUDE.md one level up is not
|
|
68
|
+
* picked up.
|
|
58
69
|
*/
|
|
59
70
|
export declare function discoverGuidelines(cwd: string, readFile?: (p: string) => Promise<string>): Promise<GuidelineDoc | null>;
|
|
60
71
|
/**
|
|
@@ -143,7 +154,7 @@ export interface EnforcementDeps {
|
|
|
143
154
|
* - `'edit'` (default): `read,edit` — the model fixes violations in place. The
|
|
144
155
|
* caller is responsible for guarding those edits with a differential
|
|
145
156
|
* verification check (revert on regression), because a bare edit pass
|
|
146
|
-
* trashes working code
|
|
157
|
+
* trashes working code.
|
|
147
158
|
* - `'flag'`: `read` only — the model reports violations but cannot touch the
|
|
148
159
|
* tree. Used when there is no verification signal to guard an edit against.
|
|
149
160
|
*/
|
|
@@ -34,20 +34,25 @@ export const GUIDELINE_FILENAMES = ['AGENTS.md', 'CLAUDE.md'];
|
|
|
34
34
|
* The fix pass gets exactly two tools: `read` and `edit`. Deliberately no
|
|
35
35
|
* `write`, `grep`, `find`, or `ls`.
|
|
36
36
|
*
|
|
37
|
-
* - No `write
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
37
|
+
* - No `write`, and `edit` cannot substitute for it: pi's edit tool calls
|
|
38
|
+
* `access(absolutePath)` FIRST and throws `Could not edit file: <path>. Error
|
|
39
|
+
* code: ENOENT.` before it ever reads. So the pass cannot create a new file at
|
|
40
|
+
* all. This is the load-bearing removal — a model that cannot run lint, tsc or
|
|
41
|
+
* tests will otherwise write scratch "runner" scripts by the hundred hoping to
|
|
42
|
+
* execute them, and dropping `write` is what stops that.
|
|
42
43
|
* - No `grep`/`find`/`ls` → the pass cannot enumerate or roam the tree; it is
|
|
43
44
|
* handed the explicit, closed list of changed files (see captureCommitDiff) and is
|
|
44
45
|
* told to edit only those.
|
|
45
46
|
* - `read` IS allowed: the model genuinely needs it — to re-read a file after
|
|
46
47
|
* editing to confirm the fix landed, and to read a neighbouring file for the
|
|
47
|
-
* correct import
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* correct import or type when bringing the change into compliance. Denied that,
|
|
49
|
+
* it fabricates imports instead.
|
|
50
|
+
*
|
|
51
|
+
* But `read` has NO per-path sandbox in pi. Its resolver only joins the path to
|
|
52
|
+
* cwd and tries filename variants — checked, `/etc/hostname` resolves to
|
|
53
|
+
* `/etc/hostname` and `../../../` escapes upward, with no confinement test
|
|
54
|
+
* anywhere. So "only the changed files" is ENFORCED for edits, by the closed
|
|
55
|
+
* file list the prompt scopes them to, and is a soft instruction for reads.
|
|
51
56
|
*/
|
|
52
57
|
const ENFORCE_TOOLS = 'read,edit';
|
|
53
58
|
/**
|
|
@@ -55,19 +60,25 @@ const ENFORCE_TOOLS = 'read,edit';
|
|
|
55
60
|
* files and report violations but CANNOT edit, create, or run anything.
|
|
56
61
|
*
|
|
57
62
|
* This is the "no signal ⇒ no license to rewrite logic" half of the gate. When a
|
|
58
|
-
* task ships no
|
|
59
|
-
* VERIFY, or
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* task ships no behavioural verification to guard a destructive edit — no runnable
|
|
64
|
+
* VERIFY, or a verify gate that never produced a genuine clean pass — there is
|
|
65
|
+
* nothing to revert against if the fix pass makes things worse. A weak model handed
|
|
66
|
+
* `read,edit` in that state can degrade a working tree and still report CLEAN,
|
|
67
|
+
* because nothing is able to contradict it.
|
|
68
|
+
*
|
|
69
|
+
* Demoted to `read` alone it cannot change anything, and still names the real
|
|
70
|
+
* violation. So with no signal to check against, the pass reports the violation as
|
|
71
|
+
* a warning instead of editing.
|
|
65
72
|
*/
|
|
66
73
|
const ENFORCE_FLAG_TOOLS = 'read';
|
|
67
74
|
/**
|
|
68
|
-
* Read the guideline files that live directly in `cwd` (AGENTS.md, CLAUDE.md)
|
|
69
|
-
*
|
|
70
|
-
*
|
|
75
|
+
* Read the guideline files that live directly in `cwd` (AGENTS.md, CLAUDE.md),
|
|
76
|
+
* concatenated under a `## <name>` header each, in that order.
|
|
77
|
+
*
|
|
78
|
+
* Returns null when none exist OR all are empty — the caller treats either as a
|
|
79
|
+
* pass. cwd-only by design, with no walk up to the git root: run from a
|
|
80
|
+
* subdirectory holding only its own AGENTS.md, a CLAUDE.md one level up is not
|
|
81
|
+
* picked up.
|
|
71
82
|
*/
|
|
72
83
|
export async function discoverGuidelines(cwd, readFile = p => fsp.readFile(p, 'utf8')) {
|
|
73
84
|
const files = [];
|
|
@@ -90,7 +101,7 @@ export async function discoverGuidelines(cwd, readFile = p => fsp.readFile(p, 'u
|
|
|
90
101
|
return { files, text: sections.join('\n\n') };
|
|
91
102
|
}
|
|
92
103
|
/**
|
|
93
|
-
* Render the deterministic probe-gaming findings
|
|
104
|
+
* Render the deterministic probe-gaming findings as a prompt block, or
|
|
94
105
|
* an empty array when there are none. Shared by the edit and flag prompts: the
|
|
95
106
|
* finding is a concrete diff line whose stated purpose is to make a check pass
|
|
96
107
|
* rather than meet the requirement — the reliable lever the prompt rule leans on.
|
|
@@ -230,7 +241,7 @@ export function classifyEnforceChildFailure(r) {
|
|
|
230
241
|
return null;
|
|
231
242
|
switch (failure.kind) {
|
|
232
243
|
case 'stalled':
|
|
233
|
-
//
|
|
244
|
+
// Otherwise a long silence is reported as a user cancel.
|
|
234
245
|
return 'model server unreachable — the child produced no output and the model endpoint did not respond';
|
|
235
246
|
case 'command-timeout': {
|
|
236
247
|
// Its text is truncated mid-run — the verdict in it is partial and
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Research enrichment — extract package names
|
|
3
|
-
* orchestrator can fan out
|
|
2
|
+
* Research enrichment — extract package names, URLs and named external services
|
|
3
|
+
* from text so the orchestrator can fan out lookups before the research phase.
|
|
4
|
+
*
|
|
5
|
+
* Everything here is order-preserving and deduped. Run on a mixed input: the
|
|
6
|
+
* denylisted shell names are dropped, a URL's trailing sentence punctuation is
|
|
7
|
+
* stripped, docs targets stop at ENRICH_CAP while version targets continue to
|
|
8
|
+
* ENRICH_VERSION_CAP, and the version list is a strict superset of the docs list.
|
|
4
9
|
*/
|
|
5
10
|
export declare function extractEnrichTargets(text: string): {
|
|
6
11
|
/** Packages that get a (heavy) docs fetch — capped at ENRICH_CAP. */
|
package/dist/task/enrichment.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Research enrichment — extract package names
|
|
3
|
-
* orchestrator can fan out
|
|
2
|
+
* Research enrichment — extract package names, URLs and named external services
|
|
3
|
+
* from text so the orchestrator can fan out lookups before the research phase.
|
|
4
|
+
*
|
|
5
|
+
* Everything here is order-preserving and deduped. Run on a mixed input: the
|
|
6
|
+
* denylisted shell names are dropped, a URL's trailing sentence punctuation is
|
|
7
|
+
* stripped, docs targets stop at ENRICH_CAP while version targets continue to
|
|
8
|
+
* ENRICH_VERSION_CAP, and the version list is a strict superset of the docs list.
|
|
4
9
|
*/
|
|
5
10
|
const ENRICH_PKG_RE = /`((?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*)`/g;
|
|
6
11
|
const ENRICH_URL_RE = /https?:\/\/[^\s)`>]+/g;
|
|
@@ -21,12 +26,15 @@ const ENRICH_DENYLIST = new Set([
|
|
|
21
26
|
'rm'
|
|
22
27
|
]);
|
|
23
28
|
const ENRICH_CAP = 3;
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
29
|
+
// Two different caps because the two lookups cost very different things. A docs
|
|
30
|
+
// or URL fetch is a worker spawn plus a page fetch, so those stay at ENRICH_CAP.
|
|
31
|
+
// A live npm VERSION lookup is one cheap registry GET, so it can cover far more:
|
|
32
|
+
// every dependency a task explicitly names should get a grounded latest-version
|
|
33
|
+
// block, not just the first ENRICH_CAP of them.
|
|
34
|
+
//
|
|
35
|
+
// With a single cap, a task naming several runtime deps leaves the later ones with
|
|
36
|
+
// no live version at all, and a question about one of them falls back to whatever
|
|
37
|
+
// the model remembers.
|
|
30
38
|
const ENRICH_VERSION_CAP = 12;
|
|
31
39
|
const ENRICH_SERVICE_HEADER = 'EXTERNAL-DEPENDENCIES';
|
|
32
40
|
const ENRICH_HEADER_LINE_RE = /^[A-Z][A-Z0-9 -]+$/;
|
|
@@ -43,10 +51,11 @@ function parseServices(text) {
|
|
|
43
51
|
const trimmed = line.trim();
|
|
44
52
|
if (trimmed === '')
|
|
45
53
|
break;
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// ends the section
|
|
54
|
+
// A repeated EXTERNAL-DEPENDENCIES line is not a section terminator: the
|
|
55
|
+
// model sometimes emits the header twice in a row, and treating the second
|
|
56
|
+
// one as the end would drop every bullet under it. Skip it and keep
|
|
57
|
+
// reading. Any OTHER all-caps header still ends the section, and so does a
|
|
58
|
+
// blank line — both confirmed.
|
|
50
59
|
if (trimmed === ENRICH_SERVICE_HEADER)
|
|
51
60
|
continue;
|
|
52
61
|
if (ENRICH_HEADER_LINE_RE.test(trimmed))
|
|
@@ -55,8 +64,11 @@ function parseServices(text) {
|
|
|
55
64
|
if (!m)
|
|
56
65
|
continue;
|
|
57
66
|
const name = m[1].trim();
|
|
58
|
-
// Dedupe by name
|
|
59
|
-
//
|
|
67
|
+
// Dedupe by name, case-insensitively, because the model duplicates bullets
|
|
68
|
+
// as well as headers. The FIRST occurrence's query is kept, and only
|
|
69
|
+
// uniques count against the cap — so a duplicate cannot crowd out a real
|
|
70
|
+
// service. Confirmed: `Stripe` and a later `stripe` collapse to one entry
|
|
71
|
+
// carrying the first query.
|
|
60
72
|
const key = name.toLowerCase();
|
|
61
73
|
if (seen.has(key))
|
|
62
74
|
continue;
|
package/dist/task/env-notes.d.ts
CHANGED
|
@@ -4,16 +4,20 @@ export interface EnvNote {
|
|
|
4
4
|
origin: string;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
* Parse the stored file into fact+origin records.
|
|
8
|
-
*
|
|
7
|
+
* Parse the stored file into fact+origin records. A line with no separator parses
|
|
8
|
+
* with an empty origin rather than being dropped, so a cache written before
|
|
9
|
+
* provenance existed still reads — and `buildEnvNotesBlock` renders those as
|
|
10
|
+
* "origin unrecorded" instead of silently claiming an author.
|
|
9
11
|
*/
|
|
10
12
|
export declare function parseEnvNotes(raw: string): EnvNote[];
|
|
11
13
|
export declare function envNotesFile(cwd: string): string;
|
|
12
14
|
/** The raw stored file ('' when none were recorded yet). Parse with parseEnvNotes. */
|
|
13
15
|
export declare function readEnvNotes(cwd: string): Promise<string>;
|
|
14
16
|
/**
|
|
15
|
-
* Pull `ENV-NOTE: <fact>` lines out of a child's answer text
|
|
16
|
-
*
|
|
17
|
+
* Pull `ENV-NOTE: <fact>` lines out of a child's answer text: trimmed,
|
|
18
|
+
* deduplicated case-insensitively, and dropped when empty or over
|
|
19
|
+
* MAX_NOTE_LENGTH. Run: a `VERDICT:` line and even a near-miss `ENV-NOTES:` line
|
|
20
|
+
* match nothing, so a verdict cannot leak into the fact cache.
|
|
17
21
|
*/
|
|
18
22
|
export declare function extractEnvNotes(text: string): string[];
|
|
19
23
|
/** True when a fact reads like a standing excuse (see EXCUSE_PATTERNS). */
|
|
@@ -21,9 +25,14 @@ export declare function isExcuseNote(fact: string): boolean;
|
|
|
21
25
|
/**
|
|
22
26
|
* Append newly discovered facts to the cache, deduplicated against what is
|
|
23
27
|
* already there (case-insensitive fact match), keeping the newest MAX_NOTES.
|
|
24
|
-
* Each new fact is stamped with the `origin` task that recorded it; a fact
|
|
25
|
-
*
|
|
26
|
-
* established it
|
|
28
|
+
* Each new fact is stamped with the `origin` task that recorded it; a fact already
|
|
29
|
+
* present keeps its ORIGINAL origin, so provenance traces to whoever first
|
|
30
|
+
* established it. Confirmed by re-appending the same fact under a different task:
|
|
31
|
+
* one entry survives, still carrying the first writer.
|
|
32
|
+
*
|
|
33
|
+
* Tabs in an emitted fact are normalised to spaces before storage, which is what
|
|
34
|
+
* keeps the separator unambiguous. The cap holds too — sixty further facts leave
|
|
35
|
+
* MAX_NOTES stored. Failures are swallowed: the cache is a sharpener, never a
|
|
27
36
|
* blocker.
|
|
28
37
|
*/
|
|
29
38
|
export declare function appendEnvNotes(cwd: string, notes: string[], origin?: string): Promise<void>;
|