@mjasnikovs/pi-task 0.38.29 → 0.38.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/config.d.ts +70 -70
- package/dist/config/config.js +26 -35
- package/dist/config/extension-list.d.ts +6 -5
- package/dist/config/extension-list.js +3 -2
- package/dist/config/reasoning-args.d.ts +9 -7
- package/dist/config/reasoning-args.js +12 -10
- package/dist/config/reasoning.d.ts +44 -105
- package/dist/config/reasoning.js +27 -704
- package/dist/config/register.d.ts +34 -48
- package/dist/config/register.js +41 -51
- package/dist/config/tool-list.d.ts +16 -16
- package/dist/config/tool-list.js +1 -1
- package/dist/index.js +2 -0
- package/dist/remote/bridge.d.ts +19 -10
- package/dist/remote/bridge.js +3 -2
- package/dist/remote/broadcast.js +3 -1
- package/dist/remote/events.js +12 -11
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/protocol.d.ts +6 -3
- package/dist/remote/protocol.js +2 -1
- package/dist/remote/push.d.ts +16 -16
- package/dist/remote/push.js +27 -27
- package/dist/remote/register.d.ts +3 -3
- package/dist/remote/register.js +17 -19
- package/dist/remote/server.d.ts +9 -8
- package/dist/remote/server.js +15 -14
- package/dist/remote/session-state.d.ts +5 -4
- package/dist/remote/session-state.js +8 -5
- package/dist/remote/sw.d.ts +7 -6
- package/dist/remote/sw.js +7 -6
- package/dist/remote/tailscale.d.ts +4 -2
- package/dist/remote/tailscale.js +4 -2
- package/dist/remote/ui-highlight.js +6 -5
- package/dist/remote/ui-render.js +4 -4
- package/dist/remote/ui-script.js +24 -24
- package/dist/remote/ui-styles.d.ts +1 -1
- package/dist/remote/ui-styles.js +10 -13
- package/dist/remote/ui-tools.js +9 -6
- package/dist/shared/child-extensions.d.ts +29 -17
- package/dist/shared/child-extensions.js +29 -17
- package/dist/shared/child-output.d.ts +30 -24
- package/dist/shared/child-output.js +25 -17
- package/dist/shared/child-process.d.ts +47 -40
- package/dist/shared/child-process.js +50 -59
- package/dist/shared/command-watchdog.d.ts +85 -16
- package/dist/shared/command-watchdog.js +115 -21
- package/dist/shared/fs-text.d.ts +16 -10
- package/dist/shared/fs-text.js +16 -10
- package/dist/shared/git-runner.d.ts +25 -25
- package/dist/shared/git-runner.js +25 -25
- package/dist/shared/leaked-tool-call.d.ts +17 -11
- package/dist/shared/leaked-tool-call.js +23 -15
- package/dist/shared/model-endpoint.d.ts +29 -16
- package/dist/shared/model-endpoint.js +33 -21
- package/dist/shared/pi-invocation.d.ts +7 -4
- package/dist/shared/pi-invocation.js +12 -7
- package/dist/shared/pkg-version.d.ts +13 -5
- package/dist/shared/pkg-version.js +13 -5
- package/dist/shared/reasoning-capability.d.ts +35 -24
- package/dist/shared/reasoning-capability.js +35 -24
- package/dist/shared/stream-watchdog.d.ts +60 -44
- package/dist/shared/stream-watchdog.js +62 -45
- package/dist/task/accept-debt.d.ts +41 -43
- package/dist/task/accept-debt.js +73 -65
- package/dist/task/api-synthesis.d.ts +24 -21
- package/dist/task/api-synthesis.js +32 -26
- package/dist/task/apis-contract.d.ts +32 -64
- package/dist/task/apis-contract.js +32 -64
- package/dist/task/artifact-closure.d.ts +27 -13
- package/dist/task/artifact-closure.js +95 -67
- package/dist/task/auto-commit.d.ts +46 -35
- package/dist/task/auto-commit.js +51 -38
- package/dist/task/auto-io.d.ts +45 -25
- package/dist/task/auto-io.js +57 -29
- package/dist/task/auto-orchestrator.d.ts +26 -24
- package/dist/task/auto-orchestrator.js +192 -165
- package/dist/task/auto-prompts.d.ts +36 -24
- package/dist/task/auto-prompts.js +40 -26
- package/dist/task/autofix-ledger.d.ts +27 -25
- package/dist/task/autofix-ledger.js +29 -26
- package/dist/task/batch-test-task.d.ts +20 -12
- package/dist/task/batch-test-task.js +67 -60
- package/dist/task/boot-probe.d.ts +60 -44
- package/dist/task/boot-probe.js +91 -72
- package/dist/task/cancel-input.d.ts +30 -16
- package/dist/task/cancel-input.js +20 -11
- package/dist/task/cancel-points.d.ts +27 -20
- package/dist/task/cancel-points.js +30 -22
- package/dist/task/child-runner.d.ts +124 -55
- package/dist/task/child-runner.js +298 -90
- package/dist/task/child-status.d.ts +23 -16
- package/dist/task/child-status.js +23 -16
- package/dist/task/clamp-output.js +12 -5
- package/dist/task/command-run.d.ts +31 -28
- package/dist/task/command-run.js +44 -35
- package/dist/task/command-shrink.d.ts +25 -18
- package/dist/task/command-shrink.js +37 -31
- package/dist/task/command-watchdog.d.ts +9 -6
- package/dist/task/command-watchdog.js +21 -15
- package/dist/task/context-attribution.d.ts +34 -26
- package/dist/task/context-attribution.js +34 -26
- package/dist/task/context-silence.d.ts +39 -29
- package/dist/task/context-silence.js +35 -25
- package/dist/task/context-usage.d.ts +16 -9
- package/dist/task/context-usage.js +16 -9
- package/dist/task/contracts.d.ts +8 -4
- package/dist/task/contracts.js +25 -17
- package/dist/task/coverage-loop.d.ts +22 -18
- package/dist/task/coverage-loop.js +35 -30
- package/dist/task/critique-probes.d.ts +13 -14
- package/dist/task/critique-probes.js +50 -39
- package/dist/task/debug-log.d.ts +13 -5
- package/dist/task/debug-log.js +32 -20
- package/dist/task/decompose-fidelity.d.ts +11 -9
- package/dist/task/decompose-fidelity.js +38 -33
- package/dist/task/decompose-granularity.d.ts +41 -38
- package/dist/task/decompose-granularity.js +41 -38
- package/dist/task/deep-render-check.d.ts +22 -14
- package/dist/task/deep-render-check.js +40 -31
- package/dist/task/dropped-input.d.ts +12 -7
- package/dist/task/dropped-input.js +5 -2
- package/dist/task/enforce-attribution.d.ts +38 -47
- package/dist/task/enforce-attribution.js +46 -52
- package/dist/task/enforce-guidelines.d.ts +31 -20
- package/dist/task/enforce-guidelines.js +32 -21
- package/dist/task/enrichment.d.ts +7 -2
- package/dist/task/enrichment.js +26 -14
- package/dist/task/env-notes.d.ts +16 -7
- package/dist/task/env-notes.js +48 -31
- package/dist/task/env-template-closure.d.ts +4 -4
- package/dist/task/env-template-closure.js +42 -34
- package/dist/task/external-context.d.ts +28 -21
- package/dist/task/external-context.js +17 -12
- package/dist/task/failure-classifier.d.ts +4 -5
- package/dist/task/failure-classifier.js +30 -8
- package/dist/task/file-inventory.d.ts +15 -11
- package/dist/task/file-inventory.js +25 -22
- package/dist/task/final-gate-fix.d.ts +74 -86
- package/dist/task/final-gate-fix.js +97 -116
- package/dist/task/final-gate-progress.d.ts +29 -46
- package/dist/task/final-gate-progress.js +40 -51
- package/dist/task/final-gate.d.ts +64 -97
- package/dist/task/final-gate.js +192 -199
- package/dist/task/fix-child.d.ts +21 -27
- package/dist/task/fix-child.js +21 -27
- package/dist/task/foreign-path.d.ts +6 -5
- package/dist/task/foreign-path.js +0 -0
- package/dist/task/frozen-conflict.d.ts +9 -10
- package/dist/task/frozen-conflict.js +61 -64
- package/dist/task/frozen-path-guard.d.ts +35 -14
- package/dist/task/frozen-path-guard.js +56 -39
- package/dist/task/gate-child.d.ts +27 -28
- package/dist/task/gate-child.js +36 -35
- package/dist/task/gate-deps.d.ts +34 -27
- package/dist/task/gate-deps.js +169 -159
- package/dist/task/gate-tally.d.ts +77 -80
- package/dist/task/gate-tally.js +65 -68
- package/dist/task/git-state-guard.d.ts +15 -11
- package/dist/task/git-state-guard.js +76 -66
- package/dist/task/impl-widget.d.ts +25 -16
- package/dist/task/impl-widget.js +27 -17
- package/dist/task/implementation-guards.d.ts +26 -0
- package/dist/task/implementation-guards.js +177 -0
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +39 -31
- package/dist/task/implementation-turn.js +41 -28
- package/dist/task/inline-markdown.d.ts +20 -7
- package/dist/task/inline-markdown.js +15 -6
- package/dist/task/launch-config-gap.js +25 -39
- package/dist/task/launch-contract.d.ts +18 -21
- package/dist/task/launch-contract.js +28 -30
- package/dist/task/launch-manifest.d.ts +6 -2
- package/dist/task/launch-manifest.js +35 -34
- package/dist/task/ledger.js +16 -14
- package/dist/task/lint-fix.d.ts +6 -8
- package/dist/task/lint-fix.js +67 -69
- package/dist/task/loop-detector.d.ts +27 -8
- package/dist/task/loop-detector.js +38 -14
- package/dist/task/mid-run-input.d.ts +17 -15
- package/dist/task/mid-run-input.js +17 -15
- package/dist/task/orchestrator.d.ts +24 -28
- package/dist/task/orchestrator.js +89 -66
- package/dist/task/orientation.d.ts +18 -23
- package/dist/task/orientation.js +24 -31
- package/dist/task/owned-freeze-conflict.d.ts +21 -20
- package/dist/task/owned-freeze-conflict.js +52 -85
- package/dist/task/owned-freeze-reassign.d.ts +40 -60
- package/dist/task/owned-freeze-reassign.js +41 -61
- package/dist/task/parsers.d.ts +4 -2
- package/dist/task/parsers.js +4 -4
- package/dist/task/phases.d.ts +41 -48
- package/dist/task/phases.js +196 -252
- package/dist/task/plan-io.d.ts +6 -7
- package/dist/task/plan-io.js +6 -7
- package/dist/task/plan-orchestrator.d.ts +10 -8
- package/dist/task/plan-orchestrator.js +14 -10
- package/dist/task/plan-prompts.d.ts +6 -5
- package/dist/task/plan-prompts.js +6 -5
- package/dist/task/plan-readonly.d.ts +4 -5
- package/dist/task/plan-readonly.js +4 -5
- package/dist/task/plan-rounds.d.ts +17 -29
- package/dist/task/plan-rounds.js +21 -34
- package/dist/task/plan-session.d.ts +58 -72
- package/dist/task/plan-session.js +61 -83
- package/dist/task/probe-gaming.d.ts +28 -27
- package/dist/task/probe-gaming.js +0 -0
- package/dist/task/prohibition-probe.d.ts +14 -16
- package/dist/task/prompts.d.ts +3 -4
- package/dist/task/prompts.js +17 -26
- package/dist/task/qa-transcript.d.ts +15 -22
- package/dist/task/qa-transcript.js +15 -21
- package/dist/task/question-box.d.ts +17 -13
- package/dist/task/question-box.js +19 -15
- package/dist/task/question-dedup.d.ts +6 -7
- package/dist/task/question-dedup.js +13 -14
- package/dist/task/question-dialog.d.ts +22 -32
- package/dist/task/question-dialog.js +22 -32
- package/dist/task/question-source.d.ts +18 -44
- package/dist/task/question-source.js +22 -51
- package/dist/task/refuted-constraint.d.ts +11 -31
- package/dist/task/refuted-constraint.js +27 -51
- package/dist/task/regenerable-artifacts.d.ts +12 -31
- package/dist/task/regenerable-artifacts.js +12 -31
- package/dist/task/render-check.d.ts +11 -22
- package/dist/task/render-check.js +33 -46
- package/dist/task/repo-health-check.d.ts +10 -14
- package/dist/task/repo-health-check.js +17 -23
- package/dist/task/requirements.d.ts +38 -71
- package/dist/task/requirements.js +78 -126
- package/dist/task/research-fanout-budget.d.ts +51 -88
- package/dist/task/research-fanout-budget.js +51 -88
- package/dist/task/research-worker.d.ts +29 -39
- package/dist/task/research-worker.js +37 -61
- package/dist/task/resume-gap.d.ts +14 -15
- package/dist/task/root-cause-repair.d.ts +9 -9
- package/dist/task/root-cause-repair.js +28 -40
- package/dist/task/run-bracket.d.ts +10 -13
- package/dist/task/run-end.d.ts +12 -22
- package/dist/task/run-end.js +8 -16
- package/dist/task/run-final-gate.d.ts +19 -21
- package/dist/task/run-final-gate.js +62 -80
- package/dist/task/runner-globs.d.ts +12 -13
- package/dist/task/runner-globs.js +12 -13
- package/dist/task/runner-resolve.d.ts +9 -9
- package/dist/task/runner-resolve.js +22 -23
- package/dist/task/script-escape.d.ts +10 -12
- package/dist/task/script-escape.js +13 -14
- package/dist/task/serve-entry.d.ts +1 -1
- package/dist/task/serve-entry.js +22 -25
- package/dist/task/service-blocks.js +4 -2
- package/dist/task/shipped-source.d.ts +11 -29
- package/dist/task/shipped-source.js +11 -29
- package/dist/task/skip-escape.js +10 -14
- package/dist/task/spec-urls.d.ts +26 -65
- package/dist/task/spec-urls.js +26 -65
- package/dist/task/spec-validation.d.ts +17 -20
- package/dist/task/spec-validation.js +17 -20
- package/dist/task/stall-detector.d.ts +23 -30
- package/dist/task/stall-detector.js +23 -30
- package/dist/task/stream-watchdog.d.ts +14 -12
- package/dist/task/stream-watchdog.js +14 -12
- package/dist/task/substitution-probe.d.ts +17 -20
- package/dist/task/substitution-probe.js +17 -20
- package/dist/task/task-gates.d.ts +36 -41
- package/dist/task/task-gates.js +95 -106
- package/dist/task/task-io.d.ts +4 -4
- package/dist/task/task-io.js +4 -4
- package/dist/task/task-parsers.js +4 -3
- package/dist/task/task-provenance.d.ts +2 -2
- package/dist/task/task-provenance.js +11 -13
- package/dist/task/task-types.d.ts +4 -3
- package/dist/task/terminal-outcome.d.ts +14 -16
- package/dist/task/terminal-outcome.js +12 -14
- package/dist/task/test-assembly.d.ts +13 -20
- package/dist/task/test-assembly.js +13 -20
- package/dist/task/timings.d.ts +5 -3
- package/dist/task/timings.js +5 -3
- package/dist/task/title-label.d.ts +9 -4
- package/dist/task/title-label.js +9 -4
- package/dist/task/type-only-answer.d.ts +44 -52
- package/dist/task/type-only-answer.js +44 -52
- package/dist/task/unfailable-command.d.ts +18 -24
- package/dist/task/unfailable-command.js +21 -27
- package/dist/task/unknown-routing.d.ts +10 -4
- package/dist/task/unknown-routing.js +10 -4
- package/dist/task/user-directives.d.ts +5 -8
- package/dist/task/user-directives.js +5 -8
- package/dist/task/verify-quality.d.ts +18 -22
- package/dist/task/verify-quality.js +45 -46
- package/dist/task/verify-reconcile.d.ts +15 -10
- package/dist/task/verify-reconcile.js +45 -43
- package/dist/task/verify-resolution.d.ts +24 -20
- package/dist/task/verify-resolution.js +51 -50
- package/dist/task/verify-work.d.ts +59 -66
- package/dist/task/verify-work.js +101 -138
- package/dist/task/widget.d.ts +15 -14
- package/dist/task/widget.js +22 -17
- package/dist/task/wiring-claims.d.ts +25 -32
- package/dist/task/wiring-claims.js +30 -35
- package/dist/task/write-guard.d.ts +39 -39
- package/dist/task/write-guard.js +48 -51
- package/dist/task/yolo.d.ts +34 -30
- package/dist/task/yolo.js +42 -37
- package/dist/workers/abstention.d.ts +21 -41
- package/dist/workers/abstention.js +27 -48
- package/dist/workers/brave-search.d.ts +4 -3
- package/dist/workers/brave-search.js +5 -2
- package/dist/workers/brave-warning.d.ts +7 -4
- package/dist/workers/brave-warning.js +19 -7
- package/dist/workers/ddg-search.d.ts +6 -6
- package/dist/workers/ddg-search.js +18 -12
- package/dist/workers/docs-cache.js +5 -2
- package/dist/workers/docs-chunk.d.ts +30 -37
- package/dist/workers/docs-chunk.js +37 -41
- package/dist/workers/docs-core.d.ts +28 -44
- package/dist/workers/docs-core.js +25 -44
- package/dist/workers/docs-index.js +4 -3
- package/dist/workers/docs-lookup.d.ts +15 -22
- package/dist/workers/docs-lookup.js +12 -21
- package/dist/workers/docs-project.d.ts +15 -9
- package/dist/workers/docs-project.js +17 -10
- package/dist/workers/docs-resolve.d.ts +19 -20
- package/dist/workers/docs-resolve.js +35 -32
- package/dist/workers/docs-retrieve.d.ts +5 -6
- package/dist/workers/docs-retrieve.js +18 -15
- package/dist/workers/exa-search.d.ts +9 -6
- package/dist/workers/exa-search.js +23 -12
- package/dist/workers/fetch-core.d.ts +13 -16
- package/dist/workers/fetch-core.js +23 -23
- package/dist/workers/focused-extractor.d.ts +13 -12
- package/dist/workers/focused-extractor.js +27 -19
- package/dist/workers/html-clean.js +24 -14
- package/dist/workers/http-request.d.ts +28 -20
- package/dist/workers/http-request.js +22 -17
- package/dist/workers/npm-version.d.ts +28 -11
- package/dist/workers/npm-version.js +24 -15
- package/dist/workers/phantom-imports.d.ts +15 -12
- package/dist/workers/phantom-imports.js +30 -24
- package/dist/workers/pi-worker-core.d.ts +65 -96
- package/dist/workers/pi-worker-core.js +93 -181
- package/dist/workers/pi-worker-docs.d.ts +24 -19
- package/dist/workers/pi-worker-docs.js +67 -76
- package/dist/workers/pi-worker-fetch.d.ts +7 -3
- package/dist/workers/pi-worker-fetch.js +27 -19
- package/dist/workers/pi-worker-search.js +12 -8
- package/dist/workers/pi-worker.d.ts +9 -4
- package/dist/workers/pi-worker.js +21 -14
- package/dist/workers/reasoning-warning.d.ts +18 -17
- package/dist/workers/reasoning-warning.js +22 -20
- package/dist/workers/research-cache.js +50 -78
- package/dist/workers/search-core.js +7 -5
- package/dist/workers/search-types.d.ts +10 -9
- package/dist/workers/search-types.js +9 -8
- package/dist/workers/session-hint.d.ts +13 -14
- package/dist/workers/session-hint.js +8 -9
- package/dist/workers/shared.d.ts +21 -25
- package/dist/workers/shared.js +0 -0
- package/dist/workers/single-read-extension.d.ts +14 -7
- package/dist/workers/single-read-extension.js +14 -7
- package/dist/workers/single-read-guard.d.ts +27 -30
- package/dist/workers/single-read-guard.js +36 -36
- package/dist/workers/typeonly-log.d.ts +12 -9
- package/dist/workers/typeonly-log.js +29 -33
- package/dist/workers/worker-channels.d.ts +15 -23
- package/dist/workers/worker-channels.js +15 -23
- package/dist/workers/worker-failure.d.ts +38 -46
- package/dist/workers/worker-failure.js +31 -39
- package/dist/workers/worker-kill.d.ts +25 -26
- package/dist/workers/worker-kill.js +16 -19
- package/dist/workers/worker-profiles.d.ts +54 -56
- package/dist/workers/worker-profiles.js +63 -39
- package/package.json +10 -8
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project orientation core — a bounded snapshot of the few files
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* read 87×, src/types/index.ts 82×, and 55% of all worker reads were repeats of
|
|
8
|
-
* a file another worker in the same task had already read.
|
|
2
|
+
* Project orientation core — a bounded snapshot of the few files a research worker
|
|
3
|
+
* re-reads cold to learn "what is this project" (manifest, config, domain types,
|
|
4
|
+
* schema, entrypoints, API surface). The four research workers are separate child
|
|
5
|
+
* processes with no shared memory, so without this each one reads the same hot
|
|
6
|
+
* files for itself.
|
|
9
7
|
*
|
|
10
|
-
* This module picks that
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* the
|
|
14
|
-
*
|
|
8
|
+
* This module picks that core from the file inventory (repo-agnostic, by path
|
|
9
|
+
* convention) and reads it ONCE in the parent. The caller folds the block into a
|
|
10
|
+
* prompt: refine gets a tier-0/1 subset, and phases.ts prepends the full block to
|
|
11
|
+
* the two READ-HEAVY research workers (`worker:files`, `worker:apis`) — not to all
|
|
12
|
+
* four. It is purely additive: nothing is blocked, so a worker can still read
|
|
13
|
+
* anything it wants; orientation only removes the need to.
|
|
15
14
|
*
|
|
16
15
|
* Bounded by design — the snapshot can never overflow the prompt regardless of
|
|
17
16
|
* repo size: a hard total byte budget, a per-file cap (one huge file can't eat
|
|
@@ -20,23 +19,19 @@
|
|
|
20
19
|
* core; reading takes an injectable reader so it can be exercised without a repo.
|
|
21
20
|
*/
|
|
22
21
|
/**
|
|
23
|
-
* Total bytes
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* exceed it.
|
|
22
|
+
* Total bytes the emitted orientation block may occupy. This is the real overflow
|
|
23
|
+
* guard: it bounds the block regardless of repo size, and because the snapshot is
|
|
24
|
+
* prepended to each read-heavy worker it also caps the prefill those workers pay.
|
|
25
|
+
* Selection stops as soon as adding a file would exceed it.
|
|
28
26
|
*/
|
|
29
27
|
export declare const ORIENTATION_BYTE_BUDGET: number;
|
|
30
28
|
/** A single file larger than this is skipped (read by the worker as before). */
|
|
31
29
|
export declare const ORIENTATION_PER_FILE_MAX: number;
|
|
32
30
|
/**
|
|
33
31
|
* Backstop file-count cap — a guard against a pathological repo with hundreds of
|
|
34
|
-
* tiny core files packing the byte budget into noise, NOT a normal-case limit.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* yields only ~6 orientation candidates because leaf source is filtered out). An
|
|
38
|
-
* earlier cap of 16 wrongly bound before the budget — e.g. it dropped 5 core
|
|
39
|
-
* files on a 165-file repo while leaving 17KB of budget unused.
|
|
32
|
+
* tiny core files packing the byte budget into noise, NOT a normal-case limit. Set
|
|
33
|
+
* high enough that the byte budget binds first: whenever this cap is what stops
|
|
34
|
+
* selection, budget is left unspent and core files are dropped for no reason.
|
|
40
35
|
*/
|
|
41
36
|
export declare const ORIENTATION_MAX_FILES = 40;
|
|
42
37
|
/**
|
package/dist/task/orientation.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project orientation core — a bounded snapshot of the few files
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* read 87×, src/types/index.ts 82×, and 55% of all worker reads were repeats of
|
|
8
|
-
* a file another worker in the same task had already read.
|
|
2
|
+
* Project orientation core — a bounded snapshot of the few files a research worker
|
|
3
|
+
* re-reads cold to learn "what is this project" (manifest, config, domain types,
|
|
4
|
+
* schema, entrypoints, API surface). The four research workers are separate child
|
|
5
|
+
* processes with no shared memory, so without this each one reads the same hot
|
|
6
|
+
* files for itself.
|
|
9
7
|
*
|
|
10
|
-
* This module picks that
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* the
|
|
14
|
-
*
|
|
8
|
+
* This module picks that core from the file inventory (repo-agnostic, by path
|
|
9
|
+
* convention) and reads it ONCE in the parent. The caller folds the block into a
|
|
10
|
+
* prompt: refine gets a tier-0/1 subset, and phases.ts prepends the full block to
|
|
11
|
+
* the two READ-HEAVY research workers (`worker:files`, `worker:apis`) — not to all
|
|
12
|
+
* four. It is purely additive: nothing is blocked, so a worker can still read
|
|
13
|
+
* anything it wants; orientation only removes the need to.
|
|
15
14
|
*
|
|
16
15
|
* Bounded by design — the snapshot can never overflow the prompt regardless of
|
|
17
16
|
* repo size: a hard total byte budget, a per-file cap (one huge file can't eat
|
|
@@ -20,23 +19,19 @@
|
|
|
20
19
|
* core; reading takes an injectable reader so it can be exercised without a repo.
|
|
21
20
|
*/
|
|
22
21
|
/**
|
|
23
|
-
* Total bytes
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* exceed it.
|
|
22
|
+
* Total bytes the emitted orientation block may occupy. This is the real overflow
|
|
23
|
+
* guard: it bounds the block regardless of repo size, and because the snapshot is
|
|
24
|
+
* prepended to each read-heavy worker it also caps the prefill those workers pay.
|
|
25
|
+
* Selection stops as soon as adding a file would exceed it.
|
|
28
26
|
*/
|
|
29
27
|
export const ORIENTATION_BYTE_BUDGET = 40 * 1024;
|
|
30
28
|
/** A single file larger than this is skipped (read by the worker as before). */
|
|
31
29
|
export const ORIENTATION_PER_FILE_MAX = 12 * 1024;
|
|
32
30
|
/**
|
|
33
31
|
* Backstop file-count cap — a guard against a pathological repo with hundreds of
|
|
34
|
-
* tiny core files packing the byte budget into noise, NOT a normal-case limit.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* yields only ~6 orientation candidates because leaf source is filtered out). An
|
|
38
|
-
* earlier cap of 16 wrongly bound before the budget — e.g. it dropped 5 core
|
|
39
|
-
* files on a 165-file repo while leaving 17KB of budget unused.
|
|
32
|
+
* tiny core files packing the byte budget into noise, NOT a normal-case limit. Set
|
|
33
|
+
* high enough that the byte budget binds first: whenever this cap is what stops
|
|
34
|
+
* selection, budget is left unspent and core files are dropped for no reason.
|
|
40
35
|
*/
|
|
41
36
|
export const ORIENTATION_MAX_FILES = 40;
|
|
42
37
|
/** Code/config/doc extensions worth pre-reading; everything else is ignored. */
|
|
@@ -100,10 +95,9 @@ function depth(p) {
|
|
|
100
95
|
*/
|
|
101
96
|
export function orientationTier(path) {
|
|
102
97
|
const lower = path.toLowerCase();
|
|
103
|
-
// Never orient on vendored/build output or tests: a dependency's
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
// and zod-schemas.test.ts both crowded out genuinely hot project files). A
|
|
98
|
+
// Never orient on vendored/build output or tests: a dependency's package.json
|
|
99
|
+
// is tier 0 by basename and a `*.test.ts` under `src/types/` is tier 2, so
|
|
100
|
+
// either would outrank the project's own files and eat the budget. A
|
|
107
101
|
// git-ls-files inventory won't list these anyway; this is belt-and-braces.
|
|
108
102
|
if (/(^|\/)(node_modules|dist|build|out|vendor|\.git|coverage)\//.test(lower))
|
|
109
103
|
return null;
|
|
@@ -167,10 +161,9 @@ export async function buildOrientation(inventoryPaths, readFile, opts = {}) {
|
|
|
167
161
|
const supplied = new Set();
|
|
168
162
|
const parts = [];
|
|
169
163
|
// Budget the *emitted* block, not just the raw content: the per-file fence
|
|
170
|
-
// (`--- path ---\n` + the `\n\n` join) and the fixed wrapper add up across
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
// so the final block is guaranteed ≤ byteBudget.
|
|
164
|
+
// (`--- path ---\n` + the `\n\n` join) and the fixed wrapper add up across many
|
|
165
|
+
// files, so a content-only budget lets the block overrun. Seeding `used` with
|
|
166
|
+
// the wrapper makes `Buffer.byteLength(block) <= byteBudget` an invariant.
|
|
174
167
|
const HEADER = `PROJECT ORIENTATION (full contents of the project's core files — `
|
|
175
168
|
+ `already provided, do not re-read these)\n`;
|
|
176
169
|
const TRAILER = '\n\n';
|
|
@@ -9,13 +9,11 @@ export interface CategoryFreeze {
|
|
|
9
9
|
/**
|
|
10
10
|
* One unsatisfiable pair, keyed by the REQUIREMENT rather than by the path.
|
|
11
11
|
*
|
|
12
|
-
* Grouping
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* obligation names and grants only what it needs — which is what keeps
|
|
18
|
-
* `inv-no-spec-inflation` satisfiable at all.
|
|
12
|
+
* Grouping this way bounds the resolution. A requirement naming several frozen
|
|
13
|
+
* files would otherwise yield one finding per file, and a spec that states its
|
|
14
|
+
* freeze in CONSTRAINTS and again in ACCEPTANCE would yield each of those twice.
|
|
15
|
+
* Per requirement, the resolution is told which files that ONE obligation names
|
|
16
|
+
* and grants only what it needs.
|
|
19
17
|
*/
|
|
20
18
|
export interface OwnedFreezeConflict {
|
|
21
19
|
/** The owned requirement line, verbatim. */
|
|
@@ -55,14 +53,13 @@ export interface OwnedFreezeOptions {
|
|
|
55
53
|
/**
|
|
56
54
|
* Is this repo-relative token an existing SOURCE file of the tree the spec
|
|
57
55
|
* will run against? Supplied by the caller (compose knows its cwd; the
|
|
58
|
-
*
|
|
56
|
+
* usual implementation is "tracked by git" — see `trackedSourceOracle`).
|
|
59
57
|
*
|
|
60
|
-
* Two false-positive classes die here
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* token counts (the broad reading, reported alongside at STEP 0).
|
|
58
|
+
* Two false-positive classes die here: build outputs (`dist/app.css` — named
|
|
59
|
+
* by the same clause that names the real file, but not something anyone
|
|
60
|
+
* edits), and files a task is about to CREATE, which a freeze on the existing
|
|
61
|
+
* tree does not block. Omitted → every path-shaped token counts, which is the
|
|
62
|
+
* broad reading.
|
|
66
63
|
*/
|
|
67
64
|
isSource?: (p: string) => boolean;
|
|
68
65
|
}
|
|
@@ -75,7 +72,7 @@ export interface OwnedFreezeOptions {
|
|
|
75
72
|
*/
|
|
76
73
|
export declare function findOwnedFreezeConflicts(spec: string | null | undefined, opts?: OwnedFreezeOptions): OwnedFreezeConflict[];
|
|
77
74
|
/**
|
|
78
|
-
* The
|
|
75
|
+
* The production `isSource` oracle: a token counts only when git tracks it in
|
|
79
76
|
* `cwd`. Tracked ⇒ it exists, it is not a build output, and it is not ignored —
|
|
80
77
|
* exactly the "source file" the category freezes talk about. `git` missing or
|
|
81
78
|
* the tree not a repo ⇒ every token counts (the broad reading), so the detector
|
|
@@ -86,10 +83,14 @@ export declare function trackedSourceOracle(lsFiles: (p: string) => {
|
|
|
86
83
|
exitCode: number;
|
|
87
84
|
}): (p: string) => boolean;
|
|
88
85
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
86
|
+
* A forced-rewrite defect block in the shape the CRITIQUE_PROBES entries use:
|
|
87
|
+
* MANDATORY, self-contained, naming the exact resolutions. Prose surrender and
|
|
88
|
+
* silently dropping the requirement are called out as non-resolutions — narrowing
|
|
89
|
+
* the clause and freezing its file are both ways a rewrite makes the
|
|
90
|
+
* contradiction disappear without satisfying the requirement.
|
|
91
|
+
*
|
|
92
|
+
* UNWIRED. Nothing in src/ or test/ calls this. The shipped resolution is the
|
|
93
|
+
* DETACH in `owned-freeze-reassign.ts`, which needs no model rewrite; this text
|
|
94
|
+
* is what a rewrite-based resolution would say if one were ever added.
|
|
94
95
|
*/
|
|
95
96
|
export declare function ownedFreezeConflictProbeText(conflicts: OwnedFreezeConflict[]): string;
|
|
@@ -1,79 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* owned-freeze-conflict —
|
|
3
|
-
*
|
|
4
|
-
* written by the same spec.
|
|
2
|
+
* owned-freeze-conflict — an unsatisfiable spec pair: an AUTHORITATIVE owned
|
|
3
|
+
* requirement whose file falls inside a CATEGORY freeze written by the same spec.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `docker-compose.dev.yml`, …, or any source files outside of `package.json`",
|
|
12
|
-
* and the spec's ACCEPTANCE/VERIFY converted the behavioural half of the clause
|
|
13
|
-
* ("serves `/api` + static `dist/`") into a string-match on `package.json`. The
|
|
14
|
-
* only file that could implement it — `src/server/index.ts` — was frozen. The
|
|
15
|
-
* requirement was structurally unsatisfiable inside its owning task, VERIFY
|
|
16
|
-
* PASSed honestly, and the app shipped with no static route.
|
|
5
|
+
* THE SHAPE. A spec carries a design clause verbatim under CONSTRAINTS, marked
|
|
6
|
+
* AUTHORITATIVE, whose behavioural half can only be satisfied inside one file —
|
|
7
|
+
* and the same spec freezes a category of files that covers that file. The task's
|
|
8
|
+
* own VERIFY can then only assert strings in the files it is allowed to touch, so
|
|
9
|
+
* it PASSes honestly while the requirement is never met.
|
|
17
10
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* behavioural claim matches none of them.
|
|
11
|
+
* WHY frozen-conflict.ts does not see it. Its freeze side needs a NAMED path
|
|
12
|
+
* (`pathNamedIn`), and a category freeze names a CLASS instead. Its statement side
|
|
13
|
+
* must match one of a fixed set of registration phrasings, and a plain behavioural
|
|
14
|
+
* claim matches none of them.
|
|
23
15
|
*
|
|
24
16
|
* HIGH-PRECISION BY CONSTRUCTION — the statement side needs no NLP:
|
|
25
17
|
* - owned requirement lines are MACHINE-MARKED. `appendOwnedConstraints`
|
|
26
|
-
* stamps every
|
|
27
|
-
* design (AUTHORITATIVE;
|
|
28
|
-
*
|
|
29
|
-
*
|
|
18
|
+
* (requirements.ts) stamps every bullet it appends with "— owned requirement
|
|
19
|
+
* from the source design (AUTHORITATIVE; satisfy it in this task, do not
|
|
20
|
+
* narrow it)". When compose folded the quote in by itself the marker is
|
|
21
|
+
* absent, so the caller may also pass the run's ledger entries and the quote
|
|
22
|
+
* is matched verbatim against the spec text.
|
|
30
23
|
* - the requirement names its path literally, so the intersection is lexical.
|
|
31
|
-
* - category freezes are a small closed lexical set ("any source files
|
|
32
|
-
*
|
|
33
|
-
*
|
|
24
|
+
* - category freezes are a small closed lexical set ("any source files outside
|
|
25
|
+
* of X", "any files other than X", "only X may be modified", "no files
|
|
26
|
+
* outside X").
|
|
34
27
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `
|
|
38
|
-
* step (`phases.ts`, right after `appendOwnedConstraints`) and resolves a finding
|
|
28
|
+
* WHERE IT RUNS, AND WHY IT CANNOT RUN EARLIER. `owned-freeze-reassign.ts`
|
|
29
|
+
* consumes this detector inside `critiquePhase`, immediately after
|
|
30
|
+
* `appendOwnedConstraints` — the last spec-producing step. It resolves a finding
|
|
39
31
|
* by BOOKKEEPING: the requirement leaves the task that cannot satisfy it and is
|
|
40
32
|
* claimed later by the task whose refined prompt says it writes the frozen file.
|
|
41
|
-
* The quote is never edited
|
|
42
|
-
* (scripts/owned-freeze-reassign-ab.ts) PASSes on the corpus with five
|
|
43
|
-
* invariants. The rewrite lever recorded below stays REFUTED and unwired.
|
|
44
|
-
*
|
|
45
|
-
* ── The critique-REWRITE seam FAILED its A/B, 2026-08-04. ────────────────────
|
|
46
|
-
*
|
|
47
|
-
* The detector is precise — 1 finding over 58 real composed specs, and it is the
|
|
48
|
-
* true positive (scripts/owned-freeze-conflict-fp-suite.ts, PASS; STEP 0 in
|
|
49
|
-
* scripts/owned-vs-freeze-baserate.ts). What failed is the LEVER built on it,
|
|
50
|
-
* for two independent reasons, both measured:
|
|
33
|
+
* The quote itself is never edited.
|
|
51
34
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* is a PARAPHRASE ("The server watch command must match the contract exactly:
|
|
57
|
-
* `…` — serves `/api` + static `dist/`"), so neither the stamp nor the
|
|
58
|
-
* verbatim quote is there to match. Live: 0/40 compose drafts carried a
|
|
59
|
-
* detectable pair while 11/40 carried the clause semantically. A critique-
|
|
60
|
-
* time probe cannot see the shape it was designed for.
|
|
61
|
-
* 2. THE REWRITE RESOLVES IT BY DELETING THE REQUIREMENT. Forced through the
|
|
62
|
-
* controlled critique seam on run 18's real TASK_0023 draft (n=20/arm):
|
|
63
|
-
* pair-present 8/20 → 0/20, but the resolution was scoped ownership in only
|
|
64
|
-
* 9/20 — the other 11/20 removed the AUTHORITATIVE clause outright and
|
|
65
|
-
* rationalised it ("this references an existing file; no edits are required
|
|
66
|
-
* or permitted"), with 0 of the 11 reassigning it to the task that owns the
|
|
67
|
-
* file. VERIFY behaviour-observation was 6/20 in BOTH arms: the delivered
|
|
68
|
-
* spec still verifies the requirement by grepping `package.json`.
|
|
35
|
+
* A critique-time probe cannot work, because `critiquePhase` calls
|
|
36
|
+
* `critiqueWithFallback` BEFORE `appendOwnedConstraints`: when critique runs, the
|
|
37
|
+
* stamped line does not exist yet, and compose's own folding is a paraphrase, so
|
|
38
|
+
* neither the stamp nor a verbatim quote is there to match.
|
|
69
39
|
*
|
|
70
|
-
*
|
|
71
|
-
* as the run-16 lever's delivery metric, one level down. Anything built here
|
|
72
|
-
* next has to act AFTER the braces, where the pair actually exists, and cannot
|
|
73
|
-
* be a model rewrite: the braces are the last spec-producing step.
|
|
74
|
-
*
|
|
75
|
-
* It is a pure text function so the base rate, the FP suite and the live A/B all
|
|
76
|
-
* measure the same object.
|
|
40
|
+
* It is a pure text function, so a test measures the same object production does.
|
|
77
41
|
*/
|
|
78
42
|
import { PROHIBITION_RE } from './prohibition-probe.js';
|
|
79
43
|
import { pathNamedIn } from './frozen-path-guard.js';
|
|
@@ -87,14 +51,14 @@ const OWNED_MARKER_RE = /owned\s+requirement\s+from\s+the\s+source\s+design/i;
|
|
|
87
51
|
* Modification verbs, shared by the active and passive freeze families. Scoped
|
|
88
52
|
* to modification exactly as `PROHIBITION_RE` is: a "do not CREATE any files
|
|
89
53
|
* other than X" line is a creation ban and freezes no existing file, so it must
|
|
90
|
-
* never be read as a category freeze
|
|
54
|
+
* never be read as a category freeze.
|
|
91
55
|
*/
|
|
92
56
|
const MOD_VERB = 'modif|touch|edit|chang|alter|rewrit|overwrit';
|
|
93
57
|
/**
|
|
94
58
|
* A category noun phrase with an exception: "any source files outside of X",
|
|
95
|
-
* "any existing file other than X", "no files except X". `\w+` slots absorb
|
|
96
|
-
* qualifiers
|
|
97
|
-
*
|
|
59
|
+
* "any existing file other than X", "no files except X". The `\w+` slots absorb
|
|
60
|
+
* qualifiers like source/existing/other, and are bounded so the phrase cannot
|
|
61
|
+
* span a whole paragraph.
|
|
98
62
|
*/
|
|
99
63
|
const CATEGORY_NOUN = String.raw `(?:any|no)\s+(?:\w+\s+){0,3}?files?\b`;
|
|
100
64
|
const EXCEPT_KEYWORD = String.raw `(?:outside(?:\s+of)?|other\s+than|except(?:\s+for)?|besides|apart\s+from|beyond)`;
|
|
@@ -108,8 +72,8 @@ const ACTIVE_CATEGORY_RE = new RegExp(String.raw `\b(?:do\s+not|do\s+NOT|don'?t|
|
|
|
108
72
|
+ String.raw `(?:(?!\b(?:creat|add|introduc|generat)\w*\b)[\s\S]){0,200}?`
|
|
109
73
|
+ String.raw `\b${CATEGORY_NOUN}[^\n]{0,40}?\b${EXCEPT_KEYWORD}\b`, 'i');
|
|
110
74
|
/**
|
|
111
|
-
* Passive family: "No files other than `package.json` are modified." —
|
|
112
|
-
* ACCEPTANCE line, identical in force to
|
|
75
|
+
* Passive family: "No files other than `package.json` are modified." — the shape
|
|
76
|
+
* an ACCEPTANCE line takes, identical in force to a CONSTRAINTS freeze.
|
|
113
77
|
*/
|
|
114
78
|
const PASSIVE_CATEGORY_RE = new RegExp(String.raw `\b${CATEGORY_NOUN}[^\n]{0,40}?\b${EXCEPT_KEYWORD}\b`
|
|
115
79
|
+ String.raw `[^\n]{0,120}?\b(?:are|is|may|must|should|can|will)\s+(?:be\s+|been\s+)?(?:${MOD_VERB})\w*`, 'i');
|
|
@@ -147,8 +111,8 @@ function tokensWithOrigin(text) {
|
|
|
147
111
|
continue;
|
|
148
112
|
}
|
|
149
113
|
// A leading `/` is a route literal or an absolute path — never a
|
|
150
|
-
// repo-relative source file
|
|
151
|
-
//
|
|
114
|
+
// repo-relative source file. Behavioural clauses routinely name routes
|
|
115
|
+
// (`/api`) beside the file that serves them.
|
|
152
116
|
if (token.startsWith('/'))
|
|
153
117
|
continue;
|
|
154
118
|
const n = token.replace(/^\.\//, '').replace(/\/+$/, '');
|
|
@@ -164,8 +128,7 @@ function tokensWithOrigin(text) {
|
|
|
164
128
|
* Does the requirement claim anything about the files it names BEYOND quoting a
|
|
165
129
|
* command that mentions them?
|
|
166
130
|
*
|
|
167
|
-
* This is what separates
|
|
168
|
-
* TASK_0023, which are otherwise the same shape:
|
|
131
|
+
* This is what separates two build-contract clauses of the same shape:
|
|
169
132
|
*
|
|
170
133
|
* "**Client CSS:** `bunx @tailwindcss/cli -i src/client/index.css -o dist/app.css`"
|
|
171
134
|
* "**Server:** `bun run --watch src/server/index.ts` — serves `/api` + static `dist/`."
|
|
@@ -191,7 +154,7 @@ function hasClaimOutsideCommand(requirement) {
|
|
|
191
154
|
* The clause the exception keyword governs: from the keyword to the first
|
|
192
155
|
* clause break (an em dash, a semicolon, or a sentence end). Everything else on
|
|
193
156
|
* the line — notably the "— all engine modules (`document.ts`, …) must remain
|
|
194
|
-
* untouched" tail of
|
|
157
|
+
* untouched" tail of a freeze — is NOT an exemption.
|
|
195
158
|
*/
|
|
196
159
|
function exemptClause(line) {
|
|
197
160
|
const m = new RegExp(String.raw `\b${EXCEPT_KEYWORD}\b`, 'i').exec(line);
|
|
@@ -231,8 +194,8 @@ const basename = (p) => p.slice(p.lastIndexOf('/') + 1);
|
|
|
231
194
|
* Is `p` inside the freeze — i.e. NOT one of the exempted paths, a file under
|
|
232
195
|
* an exempted directory, or the same file spelled shorter?
|
|
233
196
|
*
|
|
234
|
-
* The last clause is load-bearing.
|
|
235
|
-
* `src/components/Canvas.tsx` while its owned requirement quotes
|
|
197
|
+
* The last clause is load-bearing. A spec can exempt
|
|
198
|
+
* `src/components/Canvas.tsx` while its owned requirement quotes a design's
|
|
236
199
|
* table cell, which says just `Canvas.tsx` — the same file, and the spec is
|
|
237
200
|
* correctly formed. A bare basename is matched against the exempted paths'
|
|
238
201
|
* basenames; a path WITH a directory must match exactly or by prefix, so
|
|
@@ -300,8 +263,8 @@ export function findOwnedFreezeConflicts(spec, opts = {}) {
|
|
|
300
263
|
if (named.length === 0)
|
|
301
264
|
continue;
|
|
302
265
|
// One finding per requirement: the FIRST freeze that covers any of its
|
|
303
|
-
// files. A spec that restates the same freeze under ACCEPTANCE
|
|
304
|
-
//
|
|
266
|
+
// files. A spec that restates the same freeze under ACCEPTANCE must not
|
|
267
|
+
// double the rewrite's work.
|
|
305
268
|
for (const f of freezes) {
|
|
306
269
|
const paths = named.filter(p => insideFreeze(p, [...f.exempt, ...granted]));
|
|
307
270
|
if (paths.length === 0)
|
|
@@ -313,7 +276,7 @@ export function findOwnedFreezeConflicts(spec, opts = {}) {
|
|
|
313
276
|
return out;
|
|
314
277
|
}
|
|
315
278
|
/**
|
|
316
|
-
* The
|
|
279
|
+
* The production `isSource` oracle: a token counts only when git tracks it in
|
|
317
280
|
* `cwd`. Tracked ⇒ it exists, it is not a build output, and it is not ignored —
|
|
318
281
|
* exactly the "source file" the category freezes talk about. `git` missing or
|
|
319
282
|
* the tree not a repo ⇒ every token counts (the broad reading), so the detector
|
|
@@ -332,11 +295,15 @@ export function trackedSourceOracle(lsFiles) {
|
|
|
332
295
|
};
|
|
333
296
|
}
|
|
334
297
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
298
|
+
* A forced-rewrite defect block in the shape the CRITIQUE_PROBES entries use:
|
|
299
|
+
* MANDATORY, self-contained, naming the exact resolutions. Prose surrender and
|
|
300
|
+
* silently dropping the requirement are called out as non-resolutions — narrowing
|
|
301
|
+
* the clause and freezing its file are both ways a rewrite makes the
|
|
302
|
+
* contradiction disappear without satisfying the requirement.
|
|
303
|
+
*
|
|
304
|
+
* UNWIRED. Nothing in src/ or test/ calls this. The shipped resolution is the
|
|
305
|
+
* DETACH in `owned-freeze-reassign.ts`, which needs no model rewrite; this text
|
|
306
|
+
* is what a rewrite-based resolution would say if one were ever added.
|
|
340
307
|
*/
|
|
341
308
|
export function ownedFreezeConflictProbeText(conflicts) {
|
|
342
309
|
const items = conflicts.map(c => `- the spec carries the AUTHORITATIVE owned requirement `
|
|
@@ -1,69 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* owned-freeze-reassign — the DETERMINISTIC resolution for the owned/freeze
|
|
3
|
-
* unsatisfiable pair
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* -ab.ts, 20 trials/arm): forcing the pair through the critique seam drives
|
|
10
|
-
* pair-present 8/20 → 0/20, but 11 of the 20 resolutions DELETE the
|
|
11
|
-
* AUTHORITATIVE clause instead of moving it, and the delivered VERIFY still
|
|
12
|
-
* greps `package.json` in both arms (6/20). Removal of the pair is not
|
|
13
|
-
* satisfaction of the requirement.
|
|
3
|
+
* unsatisfiable pair: an AUTHORITATIVE owned requirement whose only implementing
|
|
4
|
+
* file the same spec FREEZES. No model, no prose edit. The requirement text is
|
|
5
|
+
* never altered — only which task's ledger entry carries it, so "resolution by
|
|
6
|
+
* deletion" is structurally impossible. That is the whole point: a model asked to
|
|
7
|
+
* remove a contradiction can satisfy the request by deleting the requirement, and
|
|
8
|
+
* removal of the pair is not satisfaction of the requirement.
|
|
14
9
|
*
|
|
15
10
|
* ── THE MECHANISM: DETACH, then CLAIM ───────────────────────────────────────
|
|
16
11
|
*
|
|
17
12
|
* Two steps, each run where the information it needs actually exists:
|
|
18
13
|
*
|
|
19
|
-
* DETACH at the conflicting task's own critique (right after
|
|
20
|
-
*
|
|
21
|
-
* entry is marked `pending: [frozen paths]` in the
|
|
22
|
-
* stamped bullet is dropped from this spec. It is now
|
|
23
|
-
* nobody; `ownedForTitle` skips it; the quote is still there,
|
|
24
|
-
* byte.
|
|
25
|
-
* CLAIM at every LATER task's compose, before the belt block is built: if
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* ── WHY NOT "PICK THE TARGET AT DETACH TIME", WHICH IS WHAT nexttask2.md ASKS ─
|
|
31
|
-
*
|
|
32
|
-
* nexttask2.md's branch 1 is "if exactly one OTHER task in the plan names path
|
|
33
|
-
* `P` — its title or its spec's file list contains `P` — move the requirement
|
|
34
|
-
* there". Measured over all 60 recorded composed specs on disk
|
|
35
|
-
* (scripts/owned-freeze-reassign-baserate.ts), on the one conflict the corpus
|
|
36
|
-
* contains (mx5 run 19 TASK_0015, path `src/server/index.ts`):
|
|
14
|
+
* DETACH at the conflicting task's own critique (`critiquePhase`, right after
|
|
15
|
+
* `appendOwnedConstraints` stamps the bullet, which is the first moment
|
|
16
|
+
* the pair exists): the entry is marked `pending: [frozen paths]` in the
|
|
17
|
+
* ledger and its stamped bullet is dropped from this spec. It is now
|
|
18
|
+
* owned by nobody; `ownedForTitle` skips it; the quote is still there,
|
|
19
|
+
* byte for byte.
|
|
20
|
+
* CLAIM at every LATER task's compose, before the belt block is built: if that
|
|
21
|
+
* task's REFINED PROMPT shows a write intent on one of the pending
|
|
22
|
+
* paths, the entry becomes that task's own — belt into its compose,
|
|
23
|
+
* braces onto its spec. First claimant wins.
|
|
37
24
|
*
|
|
38
|
-
*
|
|
39
|
-
* FILES-only 7 candidates TASK_0016 … TASK_0025
|
|
40
|
-
* either 8 candidates → "exactly one" NEVER holds
|
|
25
|
+
* ── WHY NOT "PICK THE TARGET AT DETACH TIME" ─────────────────────────────────
|
|
41
26
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* route on server". A path-lexical target rule at detach time is therefore
|
|
48
|
-
* BLIND IN PRODUCTION (0 candidates), the same way the run-18 critique probe was.
|
|
27
|
+
* The obvious rule is "if exactly one OTHER task in the plan names path `P`, move
|
|
28
|
+
* the requirement there". It needs COMPOSED SPECS, and at the conflicting task's
|
|
29
|
+
* compose the later tasks are still bare plan titles. A plan title describes a
|
|
30
|
+
* slice of behaviour, not a file list, so a path-lexical target rule at detach
|
|
31
|
+
* time finds nothing to point at.
|
|
49
32
|
*
|
|
50
|
-
* The claimant knows what the planner did not. By its own compose
|
|
51
|
-
* a
|
|
52
|
-
* `
|
|
53
|
-
*
|
|
54
|
-
* TASK_0017. Nothing else in the plan claims it — six other specs mention the
|
|
55
|
-
* path, all of them to fence themselves off it.
|
|
33
|
+
* The claimant knows what the planner did not. By its own compose the later task
|
|
34
|
+
* has a REFINED prompt, which does say which files it will write — and
|
|
35
|
+
* `writeIntent` reads exactly that, while its negation fence keeps every sibling
|
|
36
|
+
* that merely mentions the path in order to fence itself off it.
|
|
56
37
|
*
|
|
57
|
-
* ── WHY NOT
|
|
38
|
+
* ── WHY NOT CARRY IT AS CROSS-CUTTING ────────────────────────────────────────
|
|
58
39
|
*
|
|
59
40
|
* The cross-cutting channel is for prohibitions and product-wide rules
|
|
60
|
-
* (`isCrossCuttingRequirement`; `accountCoverage` only routes those there).
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* an obligation that quietly evaporated.
|
|
41
|
+
* (`isCrossCuttingRequirement`; `accountCoverage` only routes those there). A
|
|
42
|
+
* task-specific deliverable clause carried that way lands in every task that has
|
|
43
|
+
* not run yet, none of which owns the file — spec inflation dressed as a fix. An
|
|
44
|
+
* entry nobody claims stays `pending` and `unclaimedPendingRequirements` surfaces
|
|
45
|
+
* it at the end of the run (run-final-gate.ts), so it becomes a debt the run can
|
|
46
|
+
* see rather than an obligation that quietly evaporated.
|
|
67
47
|
*/
|
|
68
48
|
import { type OwnedFreezeOptions } from './owned-freeze-conflict.js';
|
|
69
49
|
import { type OwnedRequirement } from './requirements.js';
|
|
@@ -96,11 +76,10 @@ export interface DetachResult {
|
|
|
96
76
|
* Does this text CLAIM a write on `p` — a create/modify verb reaching a mention
|
|
97
77
|
* of the path, not fenced by a negation?
|
|
98
78
|
*
|
|
99
|
-
* The negation half is not decoration.
|
|
100
|
-
*
|
|
101
|
-
* this slice (e.g
|
|
102
|
-
*
|
|
103
|
-
* run 19's 26 refined prompts yield exactly the two tasks that do write it.
|
|
79
|
+
* The negation half is not decoration. A refined prompt routinely names the files
|
|
80
|
+
* its task must NOT touch, in the same sentence as a write verb — "Do not create
|
|
81
|
+
* or modify any other files outside this slice (e.g. no changes to `X`)". Without
|
|
82
|
+
* the fence check, every such sibling claims `X`.
|
|
104
83
|
*/
|
|
105
84
|
export declare function writeIntent(text: string, p: string): boolean;
|
|
106
85
|
/**
|
|
@@ -124,8 +103,9 @@ export interface ClaimResult {
|
|
|
124
103
|
* pending paths its refined prompt writes. Run at the START of compose, so the
|
|
125
104
|
* claimed obligation rides the same belt block every owned requirement does.
|
|
126
105
|
*
|
|
127
|
-
* First claimant wins
|
|
128
|
-
*
|
|
106
|
+
* First claimant wins: `delete entry.pending` runs before the entry is retitled,
|
|
107
|
+
* so a later task finds nothing pending to take. The test named
|
|
108
|
+
* `inv-single-owner` pins that.
|
|
129
109
|
*/
|
|
130
110
|
export declare function claimPendingRequirements(args: {
|
|
131
111
|
/** The claiming task's refined prompt — the text that says what it will write. */
|