@lazyingart/agintiflow 0.20.270 → 0.20.272
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/package.json +1 -1
- package/scripts/smoke-dynamic-step-budget.js +75 -0
- package/scripts/smoke-progressive-tool-selection.js +22 -1
- package/scripts/smoke-scs-evidence-visibility.js +28 -0
- package/src/agent-runner.js +118 -12
- package/src/progressive-tool-selection.js +10 -4
- package/src/scs-evidence.js +16 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.272",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -5485,6 +5485,65 @@ try {
|
|
|
5485
5485
|
runtime: postProducerRuntime,
|
|
5486
5486
|
})}`
|
|
5487
5487
|
);
|
|
5488
|
+
const failedAfterProducerState = structuredClone(staleGeneratedDeckState);
|
|
5489
|
+
failedAfterProducerState.meta.goalContract.taskGoal = failedAfterProducerState.goal;
|
|
5490
|
+
failedAfterProducerState.meta.projectVerification.mutationHistory.splice(1, 0, {
|
|
5491
|
+
revision: 8,
|
|
5492
|
+
toolName: "apply_patch",
|
|
5493
|
+
paths: ["TASK.md"],
|
|
5494
|
+
});
|
|
5495
|
+
failedAfterProducerState.meta.projectVerification.testRuns.push({
|
|
5496
|
+
command: generatedDeckValidator,
|
|
5497
|
+
at: "2026-08-27T19:05:00.000Z",
|
|
5498
|
+
mutationRevision: 10,
|
|
5499
|
+
privateMutationRevision: 0,
|
|
5500
|
+
passed: false,
|
|
5501
|
+
failureEvidenceVersion: 2,
|
|
5502
|
+
failureSignature: "fresh-generated-deck-visible-text",
|
|
5503
|
+
failureSummary: "acceptance failed: deck omits source-grounded phrase: single reader",
|
|
5504
|
+
});
|
|
5505
|
+
await fs.writeFile(
|
|
5506
|
+
path.join(workspace, "TASK.md"),
|
|
5507
|
+
"Treat source_brief.md, measurements.csv, prompt.txt, and TASK.md as immutable.\n",
|
|
5508
|
+
"utf8"
|
|
5509
|
+
);
|
|
5510
|
+
const failedAfterProducerPacket = await buildFailedTestRecoveryPacket(
|
|
5511
|
+
{
|
|
5512
|
+
provider: "deepseek",
|
|
5513
|
+
taskProfile: "slides",
|
|
5514
|
+
commandCwd: workspace,
|
|
5515
|
+
goal: failedAfterProducerState.goal,
|
|
5516
|
+
},
|
|
5517
|
+
failedAfterProducerState
|
|
5518
|
+
);
|
|
5519
|
+
assert(
|
|
5520
|
+
JSON.stringify(failedAfterProducerPacket.repairPaths) ===
|
|
5521
|
+
JSON.stringify(["build_deck.py"]),
|
|
5522
|
+
"a fresh generated-artifact failure dropped its latest mutable producer or retained an explicitly immutable input"
|
|
5523
|
+
);
|
|
5524
|
+
failedAfterProducerState.meta.failedTestRecoveryPacket = {
|
|
5525
|
+
packetVersion: 15,
|
|
5526
|
+
content: failedAfterProducerPacket.content,
|
|
5527
|
+
paths: failedAfterProducerPacket.paths,
|
|
5528
|
+
repairPaths: failedAfterProducerPacket.repairPaths,
|
|
5529
|
+
mutationRevision: 10,
|
|
5530
|
+
failureSignature: "fresh-generated-deck-visible-text",
|
|
5531
|
+
generatedAt: "2026-08-27T19:05:01.000Z",
|
|
5532
|
+
};
|
|
5533
|
+
const failedAfterProducerRuntime = nextStepRuntimeConfig(
|
|
5534
|
+
{
|
|
5535
|
+
provider: "deepseek",
|
|
5536
|
+
taskProfile: "slides",
|
|
5537
|
+
commandCwd: workspace,
|
|
5538
|
+
goal: failedAfterProducerState.goal,
|
|
5539
|
+
},
|
|
5540
|
+
failedAfterProducerState
|
|
5541
|
+
);
|
|
5542
|
+
assert(
|
|
5543
|
+
JSON.stringify(failedAfterProducerRuntime.testFailureRepairContextPaths) ===
|
|
5544
|
+
JSON.stringify(["build_deck.py"]),
|
|
5545
|
+
"failed-test recovery forced immutable evidence reads instead of grounding the canonical producer"
|
|
5546
|
+
);
|
|
5488
5547
|
const immutableOnlyRepairState = {
|
|
5489
5548
|
goal: "Treat service_ctl.py as immutable read-only source evidence and finish from existing results.",
|
|
5490
5549
|
meta: {
|
|
@@ -6265,6 +6324,22 @@ try {
|
|
|
6265
6324
|
})?.category === "repeated-no-progress-call",
|
|
6266
6325
|
"a third identical unchanged shell probe was not blocked"
|
|
6267
6326
|
);
|
|
6327
|
+
assert(
|
|
6328
|
+
repeatedNoProgressToolBlock(repeatedProbeState, "run_command", repeatedProbeArgs, {
|
|
6329
|
+
commandCwd: workspace,
|
|
6330
|
+
generatedArtifactProducerPending: true,
|
|
6331
|
+
generatedArtifactProducerCommand: repeatedProbeArgs.command,
|
|
6332
|
+
}) === null,
|
|
6333
|
+
"the exact authoritative generated-artifact producer remained blocked by stale no-progress history"
|
|
6334
|
+
);
|
|
6335
|
+
assert(
|
|
6336
|
+
repeatedNoProgressToolBlock(repeatedProbeState, "run_command", repeatedProbeArgs, {
|
|
6337
|
+
commandCwd: workspace,
|
|
6338
|
+
generatedArtifactProducerPending: true,
|
|
6339
|
+
generatedArtifactProducerCommand: "python3 build_deck.py",
|
|
6340
|
+
})?.category === "repeated-no-progress-call",
|
|
6341
|
+
"a mismatched generated-artifact producer disabled the ordinary no-progress guard"
|
|
6342
|
+
);
|
|
6268
6343
|
const repeatedFailureState = {
|
|
6269
6344
|
meta: {
|
|
6270
6345
|
toolLoop: {
|
|
@@ -1685,7 +1685,10 @@ assert(
|
|
|
1685
1685
|
"a pending exact verifier did not activate the constrained project-command phase"
|
|
1686
1686
|
);
|
|
1687
1687
|
const exactVerifierTools = selectProgressiveTools(allTools, {
|
|
1688
|
-
config:
|
|
1688
|
+
config: {
|
|
1689
|
+
...exactVerifierRuntime,
|
|
1690
|
+
convergenceSuppressedToolNames: ["run_command"],
|
|
1691
|
+
},
|
|
1689
1692
|
goal: `Run ${exactVerifier}.`,
|
|
1690
1693
|
profile: "security",
|
|
1691
1694
|
});
|
|
@@ -1754,6 +1757,7 @@ const generatedArtifactProducerTools = selectProgressiveTools(allTools, {
|
|
|
1754
1757
|
testFailureRepairMutationRequired: true,
|
|
1755
1758
|
generatedArtifactProducerPending: true,
|
|
1756
1759
|
generatedArtifactProducerCommand: "python3 build_deck.py",
|
|
1760
|
+
convergenceSuppressedToolNames: ["run_command"],
|
|
1757
1761
|
},
|
|
1758
1762
|
goal: "Rebuild the generated presentation before rerunning its validator.",
|
|
1759
1763
|
profile: "slides",
|
|
@@ -1768,6 +1772,22 @@ assertStrict.deepEqual(
|
|
|
1768
1772
|
["python3 build_deck.py"],
|
|
1769
1773
|
"the generated-artifact producer command was not schema-constrained"
|
|
1770
1774
|
);
|
|
1775
|
+
const disabledGeneratedArtifactProducerTools = selectProgressiveTools(allTools, {
|
|
1776
|
+
config: {
|
|
1777
|
+
provider: "localllm",
|
|
1778
|
+
allowShellTool: false,
|
|
1779
|
+
generatedArtifactProducerPending: true,
|
|
1780
|
+
generatedArtifactProducerCommand: "python3 build_deck.py",
|
|
1781
|
+
convergenceSuppressedToolNames: ["run_command"],
|
|
1782
|
+
},
|
|
1783
|
+
goal: "Rebuild the generated presentation.",
|
|
1784
|
+
profile: "slides",
|
|
1785
|
+
});
|
|
1786
|
+
sameNames(
|
|
1787
|
+
disabledGeneratedArtifactProducerTools,
|
|
1788
|
+
["finish"],
|
|
1789
|
+
"an authoritative producer phase bypassed an explicit shell capability disable"
|
|
1790
|
+
);
|
|
1771
1791
|
|
|
1772
1792
|
const mutationOnlyFailedTestRepairTools = selectProgressiveTools(allTools, {
|
|
1773
1793
|
config: {
|
|
@@ -3523,6 +3543,7 @@ const pendingTestTools = selectProgressiveTools(allTools, {
|
|
|
3523
3543
|
provider: "localllm",
|
|
3524
3544
|
testVerificationPending: true,
|
|
3525
3545
|
testVerificationCommand: "python -m unittest discover -s tests -v",
|
|
3546
|
+
convergenceSuppressedToolNames: ["run_command"],
|
|
3526
3547
|
},
|
|
3527
3548
|
goal: "Verify the canonical mutation.",
|
|
3528
3549
|
profile: "data",
|
|
@@ -70,6 +70,24 @@ const wrappedImmutableSourceContract = deriveScsTaskContract({
|
|
|
70
70
|
taskProfile: "slides",
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
const actionWrappedImmutableSourceContract = deriveScsTaskContract({
|
|
74
|
+
goal: [
|
|
75
|
+
"Continue the exact task. Do not",
|
|
76
|
+
"modify source_brief.md, measurements.csv, prompt.txt, or TASK.md.",
|
|
77
|
+
"Repair build_deck.py and rebuild output/deck.pptx.",
|
|
78
|
+
].join("\n"),
|
|
79
|
+
taskProfile: "slides",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const pathWrappedImmutableSourceContract = deriveScsTaskContract({
|
|
83
|
+
goal: [
|
|
84
|
+
"Continue the exact task. Do not modify",
|
|
85
|
+
"source_brief.md, measurements.csv, prompt.txt, or TASK.md.",
|
|
86
|
+
"Repair build_deck.py and rebuild output/deck.pptx.",
|
|
87
|
+
].join("\n"),
|
|
88
|
+
taskProfile: "slides",
|
|
89
|
+
});
|
|
90
|
+
|
|
73
91
|
const recoveryInstructionContract = deriveScsTaskContract({
|
|
74
92
|
goal: [
|
|
75
93
|
"Use the retained source and these two failures: the tests invoke ../service_ctl.py, while `python3 service_ctl.py start --state-dir .runtime` fails. Preserve the lifecycle assertions rather than replacing them, repair service_ctl.py, and remove the accidental untracked resume-after-git-baseline-recovery-dev-prompt.txt.",
|
|
@@ -173,6 +191,16 @@ assert(
|
|
|
173
191
|
),
|
|
174
192
|
"an immutable source path leaked into exact output requirements"
|
|
175
193
|
);
|
|
194
|
+
for (const contract of [
|
|
195
|
+
actionWrappedImmutableSourceContract,
|
|
196
|
+
pathWrappedImmutableSourceContract,
|
|
197
|
+
]) {
|
|
198
|
+
assert.deepEqual(
|
|
199
|
+
contract.excludedOutputPaths.sort(),
|
|
200
|
+
["TASK.md", "measurements.csv", "prompt.txt", "source_brief.md"].sort(),
|
|
201
|
+
"a negative action or its governed path list lost protection across a line wrap"
|
|
202
|
+
);
|
|
203
|
+
}
|
|
176
204
|
assert(
|
|
177
205
|
recoveryInstructionContract.excludedOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt") &&
|
|
178
206
|
!recoveryInstructionContract.exactOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt"),
|
package/src/agent-runner.js
CHANGED
|
@@ -4085,6 +4085,7 @@ async function applyContinuationPrompt(state, config, observers) {
|
|
|
4085
4085
|
packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
|
|
4086
4086
|
content: retainedTestEvidence.content,
|
|
4087
4087
|
paths: retainedTestEvidence.paths,
|
|
4088
|
+
repairPaths: retainedTestEvidence.repairPaths,
|
|
4088
4089
|
mutationRevision: Number(currentFailure?.mutationRevision || 0),
|
|
4089
4090
|
failureSignature: String(currentFailure?.failureSignature || ""),
|
|
4090
4091
|
command: String(currentFailure?.command || ""),
|
|
@@ -6624,6 +6625,64 @@ function safeRecoveryEvidencePath(value = "") {
|
|
|
6624
6625
|
return PLAIN_TEXT_FILE_EXTENSIONS.has(path.extname(candidate).toLowerCase()) ? candidate : "";
|
|
6625
6626
|
}
|
|
6626
6627
|
|
|
6628
|
+
function failedTestMutationRepairPaths(
|
|
6629
|
+
config = {},
|
|
6630
|
+
state = {},
|
|
6631
|
+
testRun = {},
|
|
6632
|
+
excludedPaths = []
|
|
6633
|
+
) {
|
|
6634
|
+
const verification = state.meta?.projectVerification || {};
|
|
6635
|
+
const history = Array.isArray(verification.mutationHistory)
|
|
6636
|
+
? verification.mutationHistory
|
|
6637
|
+
: verification.lastMutation
|
|
6638
|
+
? [verification.lastMutation]
|
|
6639
|
+
: [];
|
|
6640
|
+
const maximumRevision = Math.max(
|
|
6641
|
+
0,
|
|
6642
|
+
Number(testRun?.mutationRevision ?? verification.mutationRevision ?? 0)
|
|
6643
|
+
);
|
|
6644
|
+
const taskGoal = String(
|
|
6645
|
+
state.meta?.goalContract?.taskGoal || state.goal || config.goal || ""
|
|
6646
|
+
).trim();
|
|
6647
|
+
const activeTaskHash = taskGoal ? hashForLog(taskGoal) : "";
|
|
6648
|
+
const repairPaths = [];
|
|
6649
|
+
for (const mutation of [...history].reverse()) {
|
|
6650
|
+
if (
|
|
6651
|
+
Number(mutation?.revision || 0) > maximumRevision ||
|
|
6652
|
+
!["apply_patch", "write_file"].includes(String(mutation?.toolName || "")) ||
|
|
6653
|
+
(activeTaskHash && mutation?.taskHash && mutation.taskHash !== activeTaskHash)
|
|
6654
|
+
) {
|
|
6655
|
+
continue;
|
|
6656
|
+
}
|
|
6657
|
+
for (const candidate of Array.isArray(mutation?.paths) ? mutation.paths : []) {
|
|
6658
|
+
const safePath = safeRecoveryEvidencePath(candidate);
|
|
6659
|
+
if (
|
|
6660
|
+
!safePath ||
|
|
6661
|
+
pathLooksLikeTestSource(safePath) ||
|
|
6662
|
+
isPrivateVerificationEvidencePath(safePath) ||
|
|
6663
|
+
filterExplicitlyExcludedOutputPaths([safePath], excludedPaths).length === 0 ||
|
|
6664
|
+
repairPaths.includes(safePath)
|
|
6665
|
+
) {
|
|
6666
|
+
continue;
|
|
6667
|
+
}
|
|
6668
|
+
repairPaths.push(safePath);
|
|
6669
|
+
if (repairPaths.length >= 6) return repairPaths;
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
return repairPaths;
|
|
6673
|
+
}
|
|
6674
|
+
|
|
6675
|
+
function failedTestCanonicalRepairPaths(state = {}) {
|
|
6676
|
+
const packet = state.meta?.failedTestRecoveryPacket || {};
|
|
6677
|
+
const preferred = Array.isArray(packet.repairPaths) && packet.repairPaths.length
|
|
6678
|
+
? packet.repairPaths
|
|
6679
|
+
: packet.paths;
|
|
6680
|
+
return (Array.isArray(preferred) ? preferred : [])
|
|
6681
|
+
.map(safeRecoveryEvidencePath)
|
|
6682
|
+
.filter(Boolean)
|
|
6683
|
+
.filter((item, index, items) => items.indexOf(item) === index);
|
|
6684
|
+
}
|
|
6685
|
+
|
|
6627
6686
|
function recoveryEvidenceDependencies(sourcePath = "", content = "") {
|
|
6628
6687
|
const dependencies = [];
|
|
6629
6688
|
const append = (candidate) => {
|
|
@@ -6984,8 +7043,17 @@ export async function buildFailedTestRecoveryPacket(config = {}, state = {}) {
|
|
|
6984
7043
|
]
|
|
6985
7044
|
.map(safeRecoveryEvidencePath)
|
|
6986
7045
|
.filter(Boolean);
|
|
7046
|
+
const mutationRepairPaths = failedTestMutationRepairPaths(
|
|
7047
|
+
config,
|
|
7048
|
+
state,
|
|
7049
|
+
testRun,
|
|
7050
|
+
taskContract.excludedOutputPaths || []
|
|
7051
|
+
);
|
|
6987
7052
|
const mutationEvidencePaths = new Set(
|
|
6988
|
-
|
|
7053
|
+
[
|
|
7054
|
+
...mutationRepairPaths,
|
|
7055
|
+
...(Array.isArray(verification.lastMutation?.paths) ? verification.lastMutation.paths : []),
|
|
7056
|
+
]
|
|
6989
7057
|
.map(safeRecoveryEvidencePath)
|
|
6990
7058
|
.filter(Boolean)
|
|
6991
7059
|
);
|
|
@@ -7476,8 +7544,33 @@ export async function buildFailedTestRecoveryPacket(config = {}, state = {}) {
|
|
|
7476
7544
|
at: new Date().toISOString(),
|
|
7477
7545
|
focuses: diagnosticFocuses,
|
|
7478
7546
|
};
|
|
7547
|
+
const evidencePaths = [...seen].filter((item) =>
|
|
7548
|
+
excerpts.some((excerpt) => excerpt.startsWith(`### ${item}\n`))
|
|
7549
|
+
);
|
|
7550
|
+
const diagnosticRepairPaths = diagnosticFocuses
|
|
7551
|
+
.map((focus) => safeRecoveryEvidencePath(focus?.path))
|
|
7552
|
+
.filter(Boolean);
|
|
7553
|
+
const preferredRepairPaths = [
|
|
7554
|
+
...diagnosticRepairPaths,
|
|
7555
|
+
...mutationRepairPaths,
|
|
7556
|
+
]
|
|
7557
|
+
.filter((item, index, items) => items.indexOf(item) === index)
|
|
7558
|
+
.filter((item) => evidencePaths.includes(item));
|
|
7559
|
+
const fallbackRepairPaths = evidencePaths
|
|
7560
|
+
.filter((item) => !pathLooksLikeTestSource(item))
|
|
7561
|
+
.filter(
|
|
7562
|
+
(item) =>
|
|
7563
|
+
filterExplicitlyExcludedOutputPaths(
|
|
7564
|
+
[item],
|
|
7565
|
+
taskContract.excludedOutputPaths || []
|
|
7566
|
+
).length > 0
|
|
7567
|
+
);
|
|
7479
7568
|
return {
|
|
7480
|
-
paths:
|
|
7569
|
+
paths: evidencePaths,
|
|
7570
|
+
repairPaths: (preferredRepairPaths.length
|
|
7571
|
+
? preferredRepairPaths
|
|
7572
|
+
: fallbackRepairPaths
|
|
7573
|
+
).slice(0, 6),
|
|
7481
7574
|
content: [
|
|
7482
7575
|
`Bounded failed-test evidence packet v${FAILED_TEST_RECOVERY_PACKET_VERSION}. These are exact current workspace excerpts selected from the discovered test and its local dependencies. Use them to calculate the producing transformation; do not restart broad discovery.`,
|
|
7483
7576
|
testRun.command ? `Verification command: ${testRun.command}` : "",
|
|
@@ -7841,6 +7934,23 @@ function noProgressOutcomeFingerprint(toolResult = {}) {
|
|
|
7841
7934
|
|
|
7842
7935
|
export function repeatedNoProgressToolBlock(state, toolName, args = {}, config = {}) {
|
|
7843
7936
|
if (toolName !== "run_command" || expectedRepeatedObservationCommand(args.command)) return null;
|
|
7937
|
+
const requestedCommand = projectTestCommandKey(
|
|
7938
|
+
normalizeLeadingWorkspaceCd(args.command, config)
|
|
7939
|
+
);
|
|
7940
|
+
const pendingProducerCommand = projectTestCommandKey(
|
|
7941
|
+
normalizeLeadingWorkspaceCd(config.generatedArtifactProducerCommand, config)
|
|
7942
|
+
);
|
|
7943
|
+
if (
|
|
7944
|
+
config.generatedArtifactProducerPending === true &&
|
|
7945
|
+
requestedCommand &&
|
|
7946
|
+
requestedCommand === pendingProducerCommand
|
|
7947
|
+
) {
|
|
7948
|
+
// A persisted session can contain no-progress history from a runtime that
|
|
7949
|
+
// did not yet credit generated-artifact rebuilds as mutations. The current
|
|
7950
|
+
// exact producer contract is authoritative and gets one executable route;
|
|
7951
|
+
// unrelated repeated probes remain guarded below.
|
|
7952
|
+
return null;
|
|
7953
|
+
}
|
|
7844
7954
|
const toolLoop = state.meta?.toolLoop || {};
|
|
7845
7955
|
const signature = staticToolCallSignature(toolName, args || {}, {
|
|
7846
7956
|
commandCwd: config.commandCwd,
|
|
@@ -11659,9 +11769,7 @@ export function nextStepRuntimeConfig(config = {}, state = {}) {
|
|
|
11659
11769
|
);
|
|
11660
11770
|
});
|
|
11661
11771
|
const recoveryPacketPaths = currentRecoveryPacket
|
|
11662
|
-
? (
|
|
11663
|
-
? state.meta.failedTestRecoveryPacket.paths
|
|
11664
|
-
: [])
|
|
11772
|
+
? failedTestCanonicalRepairPaths(state)
|
|
11665
11773
|
.map(safeRecoveryEvidencePath)
|
|
11666
11774
|
.filter(Boolean)
|
|
11667
11775
|
.filter((item, index, items) => items.indexOf(item) === index)
|
|
@@ -13403,9 +13511,7 @@ function requiredDeclarationIdentitiesForPatch(state = {}, targetPath = "") {
|
|
|
13403
13511
|
}
|
|
13404
13512
|
|
|
13405
13513
|
function requiredSymbolRepairPath(state = {}, owner = "") {
|
|
13406
|
-
const sourcePaths = (state
|
|
13407
|
-
.map((item) => safeRecoveryEvidencePath(item))
|
|
13408
|
-
.filter(Boolean)
|
|
13514
|
+
const sourcePaths = failedTestCanonicalRepairPaths(state)
|
|
13409
13515
|
.filter((item) => !/(?:^|\/)tests?(?:\/|$)/i.test(item));
|
|
13410
13516
|
const ownerBasename = String(owner || "")
|
|
13411
13517
|
.split(".")
|
|
@@ -16525,7 +16631,7 @@ async function recordToolContractViolation({
|
|
|
16525
16631
|
const completedRequestedPaths = requestedCalls
|
|
16526
16632
|
.map((call) => call.path)
|
|
16527
16633
|
.filter((item) => item && completedArtifacts.has(item));
|
|
16528
|
-
const repairPaths = (state
|
|
16634
|
+
const repairPaths = failedTestCanonicalRepairPaths(state)
|
|
16529
16635
|
.map((item) => String(item || "").replace(/\\/g, "/"))
|
|
16530
16636
|
.filter((item) => item && !/(?:^|\/)tests?(?:\/|$)/i.test(item))
|
|
16531
16637
|
.slice(0, 6);
|
|
@@ -17406,9 +17512,7 @@ export function recoverUnavailableVerificationRerunAsCanonicalRead(
|
|
|
17406
17512
|
...(Array.isArray(config.testFailureRepairPatchTargets)
|
|
17407
17513
|
? config.testFailureRepairPatchTargets.map((target) => target?.path)
|
|
17408
17514
|
: []),
|
|
17409
|
-
...(
|
|
17410
|
-
? state.meta.failedTestRecoveryPacket.paths
|
|
17411
|
-
: []),
|
|
17515
|
+
...failedTestCanonicalRepairPaths(state),
|
|
17412
17516
|
]
|
|
17413
17517
|
.map(safeRecoveryEvidencePath)
|
|
17414
17518
|
.filter(Boolean)
|
|
@@ -19193,6 +19297,7 @@ async function runAgentOnceUnlocked(config) {
|
|
|
19193
19297
|
packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
|
|
19194
19298
|
content: recoveryEvidence.content,
|
|
19195
19299
|
paths: recoveryEvidence.paths,
|
|
19300
|
+
repairPaths: recoveryEvidence.repairPaths,
|
|
19196
19301
|
mutationRevision: Number(currentFailure.mutationRevision || 0),
|
|
19197
19302
|
failureSignature: String(currentFailure.failureSignature || ""),
|
|
19198
19303
|
command: String(currentFailure.command || ""),
|
|
@@ -20471,6 +20576,7 @@ async function runAgentOnceUnlocked(config) {
|
|
|
20471
20576
|
packetVersion: FAILED_TEST_RECOVERY_PACKET_VERSION,
|
|
20472
20577
|
content: recoveryEvidence.content,
|
|
20473
20578
|
paths: recoveryEvidence.paths,
|
|
20579
|
+
repairPaths: recoveryEvidence.repairPaths,
|
|
20474
20580
|
mutationRevision: Number(currentFailure.mutationRevision || 0),
|
|
20475
20581
|
failureSignature: String(currentFailure.failureSignature || ""),
|
|
20476
20582
|
command: String(currentFailure.command || ""),
|
|
@@ -1938,7 +1938,10 @@ export function selectProgressiveTools(
|
|
|
1938
1938
|
}
|
|
1939
1939
|
|
|
1940
1940
|
if (config.generatedArtifactProducerPending === true) {
|
|
1941
|
-
|
|
1941
|
+
// An authoritative producer phase supersedes a stale convergence marker.
|
|
1942
|
+
// Keep explicit capability disables effective by selecting from the real
|
|
1943
|
+
// enabled baseline rather than from the convergence-pruned surface.
|
|
1944
|
+
const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
|
|
1942
1945
|
const producerCommand = constrainRunCommand(
|
|
1943
1946
|
available.get("run_command"),
|
|
1944
1947
|
config.generatedArtifactProducerCommand,
|
|
@@ -1954,8 +1957,11 @@ export function selectProgressiveTools(
|
|
|
1954
1957
|
typeof config.testFailureStalemateCommand === "string" &&
|
|
1955
1958
|
config.testFailureStalemateCommand.trim()
|
|
1956
1959
|
) {
|
|
1960
|
+
const mandatoryAvailable = new Map(
|
|
1961
|
+
baselineEnabled.map(({ name, tool }) => [name, tool])
|
|
1962
|
+
);
|
|
1957
1963
|
const verificationCommand = constrainRunCommand(
|
|
1958
|
-
|
|
1964
|
+
mandatoryAvailable.get("run_command"),
|
|
1959
1965
|
config.testFailureStalemateCommand,
|
|
1960
1966
|
"Run this exact retained failing verifier once to refresh stale evidence after repeated semantic repair rejections. This is a bounded stalemate escape hatch, not permission to rerun arbitrary commands or loop unchanged tests."
|
|
1961
1967
|
);
|
|
@@ -2053,7 +2059,7 @@ export function selectProgressiveTools(
|
|
|
2053
2059
|
}
|
|
2054
2060
|
|
|
2055
2061
|
if (config.requiredProjectCommandPending === true) {
|
|
2056
|
-
const available = new Map(
|
|
2062
|
+
const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
|
|
2057
2063
|
const requiredCommand = constrainRunCommand(
|
|
2058
2064
|
available.get("run_command"),
|
|
2059
2065
|
config.requiredProjectCommand,
|
|
@@ -2063,7 +2069,7 @@ export function selectProgressiveTools(
|
|
|
2063
2069
|
}
|
|
2064
2070
|
|
|
2065
2071
|
if (config.testVerificationPending === true) {
|
|
2066
|
-
const available = new Map(
|
|
2072
|
+
const available = new Map(baselineEnabled.map(({ name, tool }) => [name, tool]));
|
|
2067
2073
|
const verificationCommand = constrainRunCommand(
|
|
2068
2074
|
available.get("run_command"),
|
|
2069
2075
|
config.testVerificationCommand,
|
package/src/scs-evidence.js
CHANGED
|
@@ -542,12 +542,26 @@ export function filterExplicitlyExcludedOutputPaths(paths = [], exclusions = [])
|
|
|
542
542
|
}
|
|
543
543
|
|
|
544
544
|
export function inferExplicitlyExcludedOutputPaths(goal = "") {
|
|
545
|
+
const extensionPattern = "md|txt|json|jsonl|ndjson|ya?ml|html|css|js|ts|tsx|jsx|py|sh|csv|tex|svg|png|jpe?g|webp|mp4|mov|pdf|docx";
|
|
545
546
|
// Preserve coordinated path lists that wrap after a comma. Prompt and task
|
|
546
547
|
// files commonly format "do not modify a, b,\nc, or d" across lines; splitting
|
|
547
548
|
// that text first drops the governing negative action from the continuation.
|
|
548
|
-
const
|
|
549
|
+
const negativePrefix = "(?:do\\s+not|don't|dont|must\\s+not|should\\s+not|never)";
|
|
550
|
+
const negativeAction = "(?:run|rerun|re-run|execut(?:e|ed|ing)|creat(?:e|ed|ing)|recreat(?:e|ed|ing)|writ(?:e|ten|ing)|generat(?:e|ed|ing)|sav(?:e|ed|ing)|output|touch|modif(?:y|ied|ying)|edit(?:ed|ing)?|stage|commit)";
|
|
551
|
+
const wrappedNegativeAction = new RegExp(
|
|
552
|
+
`(\\b${negativePrefix}\\b)\\s*\\r?\\n\\s*(?=${negativeAction}\\b)`,
|
|
553
|
+
"giu"
|
|
554
|
+
);
|
|
555
|
+
const wrappedNegativePath = new RegExp(
|
|
556
|
+
`(\\b${negativePrefix}\\b[^.!?。!?;;\\n]{0,180}\\b${negativeAction}\\b)\\s*\\r?\\n\\s*` +
|
|
557
|
+
`(?=\\S{1,260}\\.(?:${extensionPattern})\\b)`,
|
|
558
|
+
"giu"
|
|
559
|
+
);
|
|
560
|
+
const source = String(goal || "")
|
|
561
|
+
.replace(/([,,、])\s*\r?\n\s*/gu, "$1 ")
|
|
562
|
+
.replace(wrappedNegativeAction, "$1 ")
|
|
563
|
+
.replace(wrappedNegativePath, "$1 ");
|
|
549
564
|
if (!source.trim()) return [];
|
|
550
|
-
const extensionPattern = "md|txt|json|jsonl|ndjson|ya?ml|html|css|js|ts|tsx|jsx|py|sh|csv|tex|svg|png|jpe?g|webp|mp4|mov|pdf|docx";
|
|
551
565
|
const pathPattern = new RegExp(
|
|
552
566
|
'((?:~|\\.{1,2}|/|[A-Za-z0-9_\\-\\u4e00-\\u9fff])[\\w./~\\-\\u4e00-\\u9fff]{0,260}\\.(?:' +
|
|
553
567
|
extensionPattern +
|