@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,23 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* coverage-loop — the MONOTONIC replacement rule for /task-auto's decompose
|
|
3
|
-
* coverage gate
|
|
3
|
+
* coverage gate.
|
|
4
4
|
*
|
|
5
|
-
* The failure this closes:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* the verdict INCOMPLETE forever.
|
|
5
|
+
* The failure this closes: a coverage retry regenerates the WHOLE plan, so it is a
|
|
6
|
+
* fresh stochastic roll rather than an edit. Adopt it on a size floor alone and a
|
|
7
|
+
* retry that DROPPED a previously-covered area but kept the title count replaces
|
|
8
|
+
* the better plan — and since the loop ships whatever the last round produced, the
|
|
9
|
+
* dropped area is gone with only a toast.
|
|
10
|
+
*
|
|
11
|
+
* The shape that makes this bite: a requirement no task can ever "own" — a
|
|
12
|
+
* prohibition, say — keeps the verdict INCOMPLETE forever, so the loop keeps
|
|
13
|
+
* rolling until a worse plan happens to come up last.
|
|
15
14
|
*
|
|
16
15
|
* The rule here makes replacement monotone: coverage can only hold or grow across
|
|
17
16
|
* rounds. A retry is adopted ONLY when it drops no requirement the current plan
|
|
18
|
-
* already owns
|
|
19
|
-
* working plan at exhaustion is the best-covered one seen
|
|
20
|
-
* plan" is automatically "ship the best"
|
|
17
|
+
* already owns — its owned-set must be a superset. Because adoption is monotone,
|
|
18
|
+
* the working plan at exhaustion is the best-covered one seen, so "ship the
|
|
19
|
+
* working plan" is automatically "ship the best" and never "ship the last".
|
|
20
|
+
*
|
|
21
|
+
* Each rule was run. A retry dropping one owned requirement is rejected naming
|
|
22
|
+
* it; a strict superset is adopted; a retry that grows while covering nothing new
|
|
23
|
+
* is rejected as "no coverage gain"; and with no requirement signal at all, a
|
|
24
|
+
* retry leaving MORE areas uncovered is rejected while one leaving fewer is taken.
|
|
21
25
|
*
|
|
22
26
|
* Spec-shape-agnostic: the only inputs are title counts and the set of
|
|
23
27
|
* requirement INDICES a task owns (from the host-side coverage map). No feature
|
|
@@ -28,8 +32,12 @@
|
|
|
28
32
|
// titles and requirement quotes, so overlap on them would falsely connect a
|
|
29
33
|
// requirement to any plan. Stopped so grounding keys on the DISTINCTIVE nouns
|
|
30
34
|
// (json, dead-letter, serialize, symlink…) that actually name a deliverable.
|
|
35
|
+
//
|
|
36
|
+
// Confirmed: titles built only from these words own NOTHING, while titles naming
|
|
37
|
+
// `JSON output` and `dead-letter queue` own the matching requirements.
|
|
38
|
+
//
|
|
31
39
|
// English function words + generic task verbs + generic project nouns — all
|
|
32
|
-
// domain-agnostic
|
|
40
|
+
// domain-agnostic.
|
|
33
41
|
const COVERAGE_STOPWORDS = new Set([
|
|
34
42
|
// function words
|
|
35
43
|
'the',
|
|
@@ -151,13 +159,13 @@ function contentTokens(s) {
|
|
|
151
159
|
* DETERMINISTIC owned-set for the monotonic guard — grounded in requirement↔title
|
|
152
160
|
* token overlap, NOT the coverage-map model's `TASK n` verdict.
|
|
153
161
|
*
|
|
154
|
-
* Why this exists
|
|
162
|
+
* Why this exists: the model
|
|
155
163
|
* over-credits ownership — it mapped a "--json output" requirement to a generic
|
|
156
164
|
* "scaffold + argument parser" task, so a plan with NO --json task still reported
|
|
157
165
|
* owning it. A guard that trusts those numbers is blind to the very drop it must
|
|
158
|
-
* catch
|
|
166
|
+
* catch. Grounding coverage in whether a task
|
|
159
167
|
* TITLE actually shares a distinctive token with the requirement makes the
|
|
160
|
-
* drop-signal independent of the model's rubber-stamp
|
|
168
|
+
* drop-signal independent of the model's rubber-stamp.
|
|
161
169
|
*
|
|
162
170
|
* A requirement is "covered" when some title shares a DISTINCTIVE token with it —
|
|
163
171
|
* distinctive meaning the token is not shared across more than half the ownable
|
|
@@ -244,31 +252,28 @@ export function decideAdoption(current, retry, hasRequirements) {
|
|
|
244
252
|
}
|
|
245
253
|
// Growth must PAY FOR ITSELF. Past this point the retry's owned-set is a
|
|
246
254
|
// superset, so an equal size means the sets are IDENTICAL — the retry
|
|
247
|
-
// covers nothing new. Adopting it anyway
|
|
248
|
-
//
|
|
249
|
-
//
|
|
255
|
+
// covers nothing new. Adopting it anyway lets a plan inflate round after
|
|
256
|
+
// round with the owned-set pinned, every step logged as "preserves owned
|
|
257
|
+
// coverage".
|
|
250
258
|
//
|
|
251
259
|
// The old rule could not object, by construction: groundedCoverage is
|
|
252
260
|
// monotone in the title set (titleTokens is a union over titles; df/maxDF
|
|
253
261
|
// depend only on the quotes), and coverageRepromptHint asks the model for
|
|
254
262
|
// "every task your previous list already had ... PLUS" — a superset. So
|
|
255
263
|
// `dropped` is structurally empty whenever the model obeys the hint and the
|
|
256
|
-
// guard adopted unconditionally
|
|
257
|
-
// adopted;
|
|
264
|
+
// guard adopted unconditionally. A retry that is a strict superset is
|
|
265
|
+
// always adopted; an independently-sampled one often is not — the guard has
|
|
258
266
|
// power, just not against the shape the prompt requests).
|
|
259
267
|
//
|
|
260
268
|
// REJECT, never break. Rejection keeps the smaller plan and lets the loop
|
|
261
269
|
// reprompt again; breaking here forfeits a later round that would have
|
|
262
|
-
// gained
|
|
263
|
-
// loses the 25th requirement). "No gain this round" is not "no gain ever".
|
|
270
|
+
// gained: a later round can add the requirement a tied round did not. "No gain this round" is not "no gain ever".
|
|
264
271
|
//
|
|
265
272
|
// Safety is structural, not statistical: this branch is reachable only when
|
|
266
273
|
// the retry covers NO MORE than the current plan, so it can never decline a
|
|
267
|
-
// strictly better one.
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
// that one rep never fired this clause); plan size 41.8 → 38.8, which is
|
|
271
|
-
// NOT significant (sign 15/8, p=0.21) — the win is removing pathological
|
|
274
|
+
// strictly better one. It removes plans inflated by a retry that added
|
|
275
|
+
// titles without adding coverage, and leaves coverage itself alone — the
|
|
276
|
+
// win is removing pathological
|
|
272
277
|
// inflation, not shrinking plans generally.
|
|
273
278
|
if (retry.covered.size <= current.covered.size
|
|
274
279
|
&& retry.titles.length > current.titles.length) {
|
|
@@ -6,21 +6,20 @@
|
|
|
6
6
|
* the deterministic half of critique: the triage child judges taste, these decide
|
|
7
7
|
* facts.
|
|
8
8
|
*
|
|
9
|
-
* Why a table.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* (1 of 6).
|
|
9
|
+
* Why a table. Longhand, a probe has to appear three times in `phaseCritique`:
|
|
10
|
+
* once as a detect/format/log ritual, once as a term in the conjunction that lets
|
|
11
|
+
* a CLEAN triage short-circuit, and once in the array merged into the rewrite.
|
|
12
|
+
* Adding one then means three coordinated edits, and forgetting the SECOND is
|
|
13
|
+
* silent and severe — a CLEAN triage ships a spec carrying a defect the scanner
|
|
14
|
+
* already found, which is precisely what each probe exists to prevent. Wiring like
|
|
15
|
+
* that is also the part tests rarely cover, because the scanners are the
|
|
16
|
+
* interesting half.
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* a
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* As a table the override and the merge are DERIVED from the rows:
|
|
19
|
+
* `collectCritiqueDefects` returns `forced: blocks.length > 0`, so "every probe
|
|
20
|
+
* blocks a CLEAN short-circuit" is structurally true rather than something a
|
|
21
|
+
* reviewer must check. Same move as `PROBE_ADAPTERS` (verify-work.ts) and
|
|
22
|
+
* `CLOSURE_SCANS` (final-gate.ts).
|
|
24
23
|
*/
|
|
25
24
|
/** Everything the probes read. Assembled once by the critique phase. */
|
|
26
25
|
export interface CritiqueProbeContext {
|
|
@@ -6,21 +6,20 @@
|
|
|
6
6
|
* the deterministic half of critique: the triage child judges taste, these decide
|
|
7
7
|
* facts.
|
|
8
8
|
*
|
|
9
|
-
* Why a table.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* (1 of 6).
|
|
9
|
+
* Why a table. Longhand, a probe has to appear three times in `phaseCritique`:
|
|
10
|
+
* once as a detect/format/log ritual, once as a term in the conjunction that lets
|
|
11
|
+
* a CLEAN triage short-circuit, and once in the array merged into the rewrite.
|
|
12
|
+
* Adding one then means three coordinated edits, and forgetting the SECOND is
|
|
13
|
+
* silent and severe — a CLEAN triage ships a spec carrying a defect the scanner
|
|
14
|
+
* already found, which is precisely what each probe exists to prevent. Wiring like
|
|
15
|
+
* that is also the part tests rarely cover, because the scanners are the
|
|
16
|
+
* interesting half.
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* a
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* As a table the override and the merge are DERIVED from the rows:
|
|
19
|
+
* `collectCritiqueDefects` returns `forced: blocks.length > 0`, so "every probe
|
|
20
|
+
* blocks a CLEAN short-circuit" is structurally true rather than something a
|
|
21
|
+
* reviewer must check. Same move as `PROBE_ADAPTERS` (verify-work.ts) and
|
|
22
|
+
* `CLOSURE_SCANS` (final-gate.ts).
|
|
24
23
|
*/
|
|
25
24
|
import { existsSync } from 'node:fs';
|
|
26
25
|
import { resolve } from 'node:path';
|
|
@@ -40,22 +39,28 @@ function probe(row) {
|
|
|
40
39
|
*/
|
|
41
40
|
export const CRITIQUE_PROBES = [
|
|
42
41
|
probe({
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
42
|
+
// A required VERIFY check wrapped in a skip-announcing `||` fallback
|
|
43
|
+
// (`… || echo "skipping (tool absent)"`) lets the check pass while never
|
|
44
|
+
// running. Confirmed: that exact line makes the collector force a rewrite.
|
|
46
45
|
id: 'skip-escape',
|
|
47
46
|
detect: ctx => findSkipEscapes(ctx.spec),
|
|
48
47
|
text: f => skipEscapeDefectText(f),
|
|
49
48
|
log: f => `skip-escape flagged in VERIFY: ${f.length} line(s)`
|
|
50
49
|
}),
|
|
51
50
|
probe({
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
51
|
+
// The generation-side complement of the verify-side boundary check: a spec
|
|
52
|
+
// that INFERS a wiring specific (a tidy mount table) the design never
|
|
53
|
+
// pinned.
|
|
54
|
+
//
|
|
55
|
+
// Handing the registry to the model alone is a weak catcher, because its
|
|
56
|
+
// attention goes to the obvious VERIFY weakness rather than to
|
|
57
|
+
// path-composition reasoning. So this scanner NAMES the inferred mount
|
|
58
|
+
// mappings and juxtaposes the verbatim pinned facts, forcing a focused
|
|
59
|
+
// reconciliation.
|
|
60
|
+
//
|
|
61
|
+
// Grounding is the registry plus any design doc the spec or refined text
|
|
62
|
+
// @-references. No registry means nothing to contradict, and the row
|
|
63
|
+
// returns no findings at all.
|
|
59
64
|
id: 'synthesized-wiring',
|
|
60
65
|
detect: ctx => ctx.registryRaw.trim().length > 0 ?
|
|
61
66
|
findSynthesizedWiring(ctx.spec, ctx.registryRaw + '\n' + readReferencedDocs(ctx.cwd, ctx.refined, ctx.spec), ctx.registryRaw)
|
|
@@ -64,11 +69,11 @@ export const CRITIQUE_PROBES = [
|
|
|
64
69
|
log: f => `synthesized wiring flagged in spec: ${f.map(w => w.line).join(' | ')}`
|
|
65
70
|
}),
|
|
66
71
|
probe({
|
|
67
|
-
//
|
|
72
|
+
// A VERIFY line asserting the ABSENCE of an artifact
|
|
68
73
|
// the plan pins elsewhere — a path a prior task already shipped, a sibling
|
|
69
|
-
// title's deliverable, a contract-pinned boundary.
|
|
70
|
-
//
|
|
71
|
-
|
|
74
|
+
// title's deliverable, a contract-pinned boundary. A scope fence can
|
|
75
|
+
// leak into a sibling's verify as "the admin page must NOT exist"
|
|
76
|
+
//; the guaranteed FAIL became an accepted debt
|
|
72
77
|
// that the final-gate autofix then "fixed" by deleting the sibling's work.
|
|
73
78
|
// It must die here, at spec time. Delete-tasks keep their check by
|
|
74
79
|
// declaring the delete.
|
|
@@ -83,14 +88,20 @@ export const CRITIQUE_PROBES = [
|
|
|
83
88
|
+ f.map(c => `${c.assertion.target} (${c.against})`).join(' | ')
|
|
84
89
|
}),
|
|
85
90
|
probe({
|
|
86
|
-
//
|
|
87
|
-
// `tsconfig.json`
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// An unsatisfiable pair: the spec FREEZES a path outright ("Do NOT modify
|
|
92
|
+
// `tsconfig.json` — handled in steps 1-2") while something also says the
|
|
93
|
+
// deliverable requires editing that same path. The freeze always comes from
|
|
94
|
+
// the spec; the requirement may come from the spec's own body OR from the
|
|
95
|
+
// RESEARCH it was composed from, since compose can drop the nuance while
|
|
96
|
+
// keeping both the freeze and the file creation.
|
|
97
|
+
//
|
|
98
|
+
// Shipped as-is, the created files turn the repo-wide static check
|
|
99
|
+
// permanently red and no task is allowed to fix it — every later task burns
|
|
100
|
+
// its AUTOFIX rounds on it. The rewrite must grant scoped ownership or drop
|
|
101
|
+
// the creation.
|
|
102
|
+
//
|
|
103
|
+
// Confirmed: a freeze alone yields nothing; a freeze plus a
|
|
104
|
+
// requires-edit statement in the same spec yields one conflict.
|
|
94
105
|
id: 'frozen-conflict',
|
|
95
106
|
detect: ctx => findFrozenPathConflicts(ctx.spec, ctx.research),
|
|
96
107
|
text: f => frozenConflictProbeText(f),
|
|
@@ -98,7 +109,7 @@ export const CRITIQUE_PROBES = [
|
|
|
98
109
|
+ f.map(c => c.path).join(' | ')
|
|
99
110
|
}),
|
|
100
111
|
probe({
|
|
101
|
-
//
|
|
112
|
+
// A VERIFY block that grep-asserts the SOURCE of a
|
|
102
113
|
// runnable deliverable while every command in the block is static
|
|
103
114
|
// inspection — the build script "verified" by three greps that was never
|
|
104
115
|
// run, shipping broken for 14 tasks. VERIFY must EXECUTE the artifact and
|
|
@@ -107,7 +118,7 @@ export const CRITIQUE_PROBES = [
|
|
|
107
118
|
detect: ctx => findGrepOnlyVerify(ctx.spec),
|
|
108
119
|
text: f => grepOnlyVerifyDefectText(f),
|
|
109
120
|
log: f => `grep-theater VERIFY flagged in spec: ${f.map(x => x.target).join(' | ')}`,
|
|
110
|
-
// Detector-backed closure:
|
|
121
|
+
// Detector-backed closure: a rewrite can ignore the injected
|
|
111
122
|
// defect and re-shipped the grep-only block.
|
|
112
123
|
unresolvedProblem: {
|
|
113
124
|
name: 'verify_grep_theater',
|
|
@@ -115,7 +126,7 @@ export const CRITIQUE_PROBES = [
|
|
|
115
126
|
}
|
|
116
127
|
}),
|
|
117
128
|
probe({
|
|
118
|
-
//
|
|
129
|
+
// A spec that DICTATES a check script which
|
|
119
130
|
// cannot fail — `"lint": "… || true"`, or a checker laundered through an
|
|
120
131
|
// inverted grep. Whatever task implements that spec writes the disarmed
|
|
121
132
|
// script into package.json, and from then on every gate that runs it
|
package/dist/task/debug-log.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { type DebugLogLevel } from '../config/config.js';
|
|
2
2
|
/**
|
|
3
3
|
* Escape hatch for reproducing a user's bug without walking them through
|
|
4
|
-
* /task-config. Follows the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* /task-config. Follows the `PI_TASK_*` instrumentation convention this codebase
|
|
5
|
+
* already uses in nine places, `PI_TASK_TYPEONLY_LOG` among them.
|
|
6
|
+
*
|
|
7
|
+
* An unrecognised value is IGNORED rather than treated as `off` — a typo in an env
|
|
8
|
+
* var must not silently throw the trail away. Run: `full` and `off` both take
|
|
9
|
+
* effect, surrounding whitespace is tolerated, and `verbose` falls through to the
|
|
10
|
+
* saved config instead of resolving to anything.
|
|
8
11
|
*/
|
|
9
12
|
export declare const DEBUG_LOG_ENV = "PI_TASK_DEBUG_LOG";
|
|
10
13
|
/** A trail line's kind — see the module note. Producers default to `'event'`. */
|
|
@@ -15,7 +18,9 @@ export type DebugLine = 'event' | 'stream';
|
|
|
15
18
|
* line instead of at the next restart.
|
|
16
19
|
*/
|
|
17
20
|
export declare function debugLogLevel(getEnv?: (k: string) => string | undefined): DebugLogLevel;
|
|
18
|
-
/** Whether a line of this kind should be written at `level`.
|
|
21
|
+
/** Whether a line of this kind should be written at `level`. The whole matrix:
|
|
22
|
+
* `off` writes nothing, `full` writes both kinds, `events` writes events and
|
|
23
|
+
* drops stream. */
|
|
19
24
|
export declare function shouldLogDebug(kind: DebugLine, level: DebugLogLevel): boolean;
|
|
20
25
|
/**
|
|
21
26
|
* A timestamped fire-and-forget appender for one trail file, level-gated.
|
|
@@ -30,5 +35,8 @@ export declare function makeDebugAppender(logPath: string, appendFile?: (p: stri
|
|
|
30
35
|
* Wrap a raw append in the level gate. Returns `undefined` when the level is
|
|
31
36
|
* `off`, so callers that hold an OPTIONAL `logDebug` leave it unset and every
|
|
32
37
|
* `logDebug?.(…)` in the pipeline short-circuits before it formats a string.
|
|
38
|
+
*
|
|
39
|
+
* Run: undefined at `off`, a function otherwise, and at `events` it writes an
|
|
40
|
+
* event line while dropping a stream one.
|
|
33
41
|
*/
|
|
34
42
|
export declare function gateDebugWriter(write: (msg: string) => void, getEnv?: (k: string) => string | undefined): ((msg: string, kind?: DebugLine) => void) | undefined;
|
package/dist/task/debug-log.js
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One place that decides whether a `.pi-tasks/*-debug.log` line gets written.
|
|
3
3
|
*
|
|
4
|
-
* THE TRAIL IS WRITE-ONLY. Nothing
|
|
5
|
-
* globs `TASK_NNNN.md` and skips everything else, and
|
|
6
|
-
* copies the bytes across a `reset --hard` without
|
|
7
|
-
* is a `logDebug?.(…)` / `log(…)` side effect
|
|
8
|
-
* this gate cannot change what a run DOES —
|
|
4
|
+
* THE TRAIL IS WRITE-ONLY in production. Nothing under src/ reads these files
|
|
5
|
+
* back: `task-io.ts` globs `TASK_NNNN.md` and skips everything else, and
|
|
6
|
+
* auto-commit's `snapshotTrail` copies the bytes across a `reset --hard` without
|
|
7
|
+
* ever parsing them. Every producer is a `logDebug?.(…)` / `log(…)` side effect
|
|
8
|
+
* whose return value is discarded. So this gate cannot change what a run DOES —
|
|
9
|
+
* only what it can explain afterwards. (Tests do read the trail back, which is why
|
|
10
|
+
* `flushPlanDebug` exists.)
|
|
9
11
|
*
|
|
10
12
|
* TWO KINDS OF LINE, and the distinction is the whole point of having three levels
|
|
11
13
|
* rather than a boolean:
|
|
12
14
|
*
|
|
13
|
-
* 'stream' — what the child model said, and what its tools returned.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* 'stream' — what the child model said, and what its tools returned. It is the
|
|
16
|
+
* bulk of the bytes by a wide margin, and it is REPRODUCIBLE: re-run
|
|
17
|
+
* the child and you get it again. Useful while actively debugging,
|
|
18
|
+
* worthless as a record.
|
|
17
19
|
*
|
|
18
20
|
* 'event' — a decision or a guard action: which phase started, why a worker was
|
|
19
21
|
* retried or degraded, what the git-state guard restored, what a
|
|
20
|
-
* write-capable child changed on disk, why a gate returned FAIL.
|
|
21
|
-
* lines per task, and NOT reproducible — it is the only
|
|
22
|
-
* guard fired at all.
|
|
23
|
-
*
|
|
22
|
+
* write-capable child changed on disk, why a gate returned FAIL. A
|
|
23
|
+
* handful of lines per task, and NOT reproducible — it is the only
|
|
24
|
+
* record that the guard fired at all. If a final-fix child deletes a
|
|
25
|
+
* source file, the `tree changes:` line is the only way anyone can
|
|
26
|
+
* tell.
|
|
24
27
|
*
|
|
25
|
-
* Hence the default is `events`, not `off
|
|
26
|
-
* chatter, not the audit trail.
|
|
28
|
+
* Hence the shipped default is `events`, not `off` (DEFAULT_DEBUG_LOGS in
|
|
29
|
+
* config.ts): the quiet default users want costs the chatter, not the audit trail.
|
|
30
|
+
* A machine-local `"debugLogs": "off"` still wins — this is a default, not a floor.
|
|
27
31
|
*/
|
|
28
32
|
import * as fsp from 'node:fs/promises';
|
|
29
33
|
import { getConfig, sanitizeDebugLogs } from '../config/config.js';
|
|
30
34
|
/**
|
|
31
35
|
* Escape hatch for reproducing a user's bug without walking them through
|
|
32
|
-
* /task-config. Follows the
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
+
* /task-config. Follows the `PI_TASK_*` instrumentation convention this codebase
|
|
37
|
+
* already uses in nine places, `PI_TASK_TYPEONLY_LOG` among them.
|
|
38
|
+
*
|
|
39
|
+
* An unrecognised value is IGNORED rather than treated as `off` — a typo in an env
|
|
40
|
+
* var must not silently throw the trail away. Run: `full` and `off` both take
|
|
41
|
+
* effect, surrounding whitespace is tolerated, and `verbose` falls through to the
|
|
42
|
+
* saved config instead of resolving to anything.
|
|
36
43
|
*/
|
|
37
44
|
export const DEBUG_LOG_ENV = 'PI_TASK_DEBUG_LOG';
|
|
38
45
|
/**
|
|
@@ -49,7 +56,9 @@ export function debugLogLevel(getEnv = k => process.env[k]) {
|
|
|
49
56
|
return raw;
|
|
50
57
|
return getConfig().debugLogs;
|
|
51
58
|
}
|
|
52
|
-
/** Whether a line of this kind should be written at `level`.
|
|
59
|
+
/** Whether a line of this kind should be written at `level`. The whole matrix:
|
|
60
|
+
* `off` writes nothing, `full` writes both kinds, `events` writes events and
|
|
61
|
+
* drops stream. */
|
|
53
62
|
export function shouldLogDebug(kind, level) {
|
|
54
63
|
if (level === 'off')
|
|
55
64
|
return false;
|
|
@@ -76,6 +85,9 @@ export function makeDebugAppender(logPath, appendFile = (p, data) => fsp.appendF
|
|
|
76
85
|
* Wrap a raw append in the level gate. Returns `undefined` when the level is
|
|
77
86
|
* `off`, so callers that hold an OPTIONAL `logDebug` leave it unset and every
|
|
78
87
|
* `logDebug?.(…)` in the pipeline short-circuits before it formats a string.
|
|
88
|
+
*
|
|
89
|
+
* Run: undefined at `off`, a function otherwise, and at `events` it writes an
|
|
90
|
+
* event line while dropping a stream one.
|
|
79
91
|
*/
|
|
80
92
|
export function gateDebugWriter(write, getEnv) {
|
|
81
93
|
if (debugLogLevel(getEnv) === 'off')
|
|
@@ -7,15 +7,17 @@ export interface SourcedTitle {
|
|
|
7
7
|
/**
|
|
8
8
|
* Split a decompose title into its base and its GROUNDED source citations.
|
|
9
9
|
*
|
|
10
|
-
* PLURAL, because the model emits plural
|
|
11
|
-
* citation and a
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* which of course
|
|
16
|
-
* fabricated one
|
|
17
|
-
*
|
|
18
|
-
* matching plus the `$` anchor
|
|
10
|
+
* PLURAL, because the model emits plural: the prompt asks for one trailing
|
|
11
|
+
* citation and a real share of titles carry more than one.
|
|
12
|
+
*
|
|
13
|
+
* A single anchored pattern cannot read them. Run on `[source: "A"] [source: "B"]`,
|
|
14
|
+
* `\[source:\s*"(.+)"\]$` captures the superstring `A"] [source: "B` — from the
|
|
15
|
+
* FIRST clause to the LAST quote — which is of course not in the document, so two
|
|
16
|
+
* real citations become one fabricated one and both are discarded. Making the
|
|
17
|
+
* quantifier LAZY changes nothing: `(.+?)` against the same input captures the
|
|
18
|
+
* identical superstring, because leftmost-first matching plus the `$` anchor
|
|
19
|
+
* expands it across the later clauses just the same. Peeling from the end with
|
|
20
|
+
* lastIndexOf is what actually works — confirmed, both citations come back.
|
|
19
21
|
*
|
|
20
22
|
* An absent clause yields no sources; a fabricated (ungrounded) one is dropped
|
|
21
23
|
* — exactly like keepGroundedContracts rejects a paraphrased quote.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* decompose-fidelity — verbatim fidelity of plan derivations
|
|
2
|
+
* decompose-fidelity — verbatim fidelity of plan derivations.
|
|
3
3
|
*
|
|
4
|
-
* The failure this closes:
|
|
5
|
-
* "guards + tests"
|
|
4
|
+
* The failure this closes: a design's milestone line ends in an additive
|
|
5
|
+
* constraint — "… guards + tests" — and the decomposed title carries everything
|
|
6
6
|
* BUT the "+ tests" suffix. A title is ALL a per-task pipeline ever sees, so a
|
|
7
|
-
* silently dropped
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* derives from.
|
|
7
|
+
* silently dropped fragment vanishes from the whole run, and the dropped thing is
|
|
8
|
+
* disproportionately the instrument that would have caught the bug. Decompose
|
|
9
|
+
* paraphrases freely, and without this nothing compares a title to the spec line
|
|
10
|
+
* it derives from.
|
|
11
11
|
*
|
|
12
12
|
* Mechanism (contracts.ts pattern, applied to decompose itself): the decompose
|
|
13
13
|
* prompt asks each task line to cite its origin as a trailing
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
* 3. RE-ATTACHES the missing fragments to the title verbatim.
|
|
21
21
|
*
|
|
22
22
|
* Scope is deliberately the additive-suffix class (`+`-joined fragments): those
|
|
23
|
-
* are constraints by construction, so re-attachment can never inject noise
|
|
24
|
-
*
|
|
25
|
-
* already says, never fabrication.
|
|
23
|
+
* are constraints by construction, so re-attachment can never inject noise the
|
|
24
|
+
* cited line does not demand — worst case is redundancy with what the title
|
|
25
|
+
* already says, never fabrication. In practice not even that: a title that
|
|
26
|
+
* already carries the fragment restores nothing, and the singular/plural
|
|
27
|
+
* allowance means "a test" counts as covering "tests". Whole-line paraphrase drift is NOT judged here
|
|
26
28
|
* (a title is a paraphrase by design); requirement-level coverage owns that.
|
|
27
29
|
* No similarity thresholds anywhere: grounding is exact normalised substring,
|
|
28
30
|
* presence is exact word membership (with a singular/plural `s` allowance).
|
|
@@ -45,17 +47,15 @@ const SOURCE_RE = /^\[source:\s*"([\s\S]*)"\s*\]$/i;
|
|
|
45
47
|
*
|
|
46
48
|
* BACKTICKS ARE THE SAME CLASS and were the larger half. A code span renders as
|
|
47
49
|
* bare text, so `3. **Invites** — create/validate/redeem, \`/join/:token\` page.`
|
|
48
|
-
* comes back as `Invites — create/validate/redeem, /join/:token page.`
|
|
49
|
-
*
|
|
50
|
-
* 107/216 grounded with backticks kept, 216/216 with them dropped.
|
|
50
|
+
* comes back as `Invites — create/validate/redeem, /join/:token page.` Screening
|
|
51
|
+
* every spec line in its RENDERED form is what makes those quotes match at all.
|
|
51
52
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* CEILING real spec
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* check: CEILING raw 216/216, CEILING rendered 216/216, FLOOR 0/216.
|
|
53
|
+
* The two directions this has to hold in, both run:
|
|
54
|
+
* FLOOR a real spec line with ONE content word altered must NOT be grounded —
|
|
55
|
+
* changing `sessions` to `tokens`, or `redeem` to `revoke`, drops it.
|
|
56
|
+
* CEILING a real spec line quoted without its markup MUST be grounded — both the
|
|
57
|
+
* `2. **Auth** —` numbering-and-bold case and the backticked
|
|
58
|
+
* `` `/join/:token` `` case still match.
|
|
59
59
|
*/
|
|
60
60
|
function demark(s) {
|
|
61
61
|
return s
|
|
@@ -69,10 +69,13 @@ function demark(s) {
|
|
|
69
69
|
* Undo the backslash-escaping a model applies to a quote it is putting INSIDE a
|
|
70
70
|
* double-quoted clause. `[source: "… \`import { sql } from \\"bun\\"\` gotcha …"]`
|
|
71
71
|
* is a faithful copy of a line the document stores with plain quotes; the
|
|
72
|
-
* backslashes are an artefact of the delimiter, not content
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
72
|
+
* backslashes are an artefact of the delimiter, not content, so without this an
|
|
73
|
+
* otherwise-faithful quote fails to match for that reason alone.
|
|
74
|
+
*
|
|
75
|
+
* Only `\"` is undone — no other escape sequence is interpreted, so this cannot
|
|
76
|
+
* rewrite a quote into something the document happens to contain. Confirmed both
|
|
77
|
+
* ways: the escaped-quote citation grounds, and a citation carrying a literal
|
|
78
|
+
* `\n` does not.
|
|
76
79
|
*/
|
|
77
80
|
function unescapeQuotes(s) {
|
|
78
81
|
return s.replace(/\\"/g, '"');
|
|
@@ -80,15 +83,17 @@ function unescapeQuotes(s) {
|
|
|
80
83
|
/**
|
|
81
84
|
* Split a decompose title into its base and its GROUNDED source citations.
|
|
82
85
|
*
|
|
83
|
-
* PLURAL, because the model emits plural
|
|
84
|
-
* citation and a
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* which of course
|
|
89
|
-
* fabricated one
|
|
90
|
-
*
|
|
91
|
-
* matching plus the `$` anchor
|
|
86
|
+
* PLURAL, because the model emits plural: the prompt asks for one trailing
|
|
87
|
+
* citation and a real share of titles carry more than one.
|
|
88
|
+
*
|
|
89
|
+
* A single anchored pattern cannot read them. Run on `[source: "A"] [source: "B"]`,
|
|
90
|
+
* `\[source:\s*"(.+)"\]$` captures the superstring `A"] [source: "B` — from the
|
|
91
|
+
* FIRST clause to the LAST quote — which is of course not in the document, so two
|
|
92
|
+
* real citations become one fabricated one and both are discarded. Making the
|
|
93
|
+
* quantifier LAZY changes nothing: `(.+?)` against the same input captures the
|
|
94
|
+
* identical superstring, because leftmost-first matching plus the `$` anchor
|
|
95
|
+
* expands it across the later clauses just the same. Peeling from the end with
|
|
96
|
+
* lastIndexOf is what actually works — confirmed, both citations come back.
|
|
92
97
|
*
|
|
93
98
|
* An absent clause yields no sources; a fabricated (ungrounded) one is dropped
|
|
94
99
|
* — exactly like keepGroundedContracts rejects a paraphrased quote.
|