@lazyingart/agintiflow 0.20.263 → 0.20.265
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-coding-tools.js +38 -0
- package/scripts/smoke-deep-research.js +89 -0
- package/scripts/smoke-dynamic-step-budget.js +401 -6
- package/scripts/smoke-local-failure-recovery.js +3 -3
- package/scripts/smoke-progressive-tool-selection.js +251 -22
- package/scripts/smoke-scs-evidence-visibility.js +27 -0
- package/src/agent-runner.js +498 -44
- package/src/command-policy.js +10 -1
- package/src/model-client.js +33 -1
- package/src/permission-advice.js +39 -10
- package/src/progressive-tool-selection.js +62 -4
- package/src/scs-evidence.js +34 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.265",
|
|
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",
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
genericArtifactFilenameBlock,
|
|
9
9
|
modelTimeoutExhaustionRoute,
|
|
10
10
|
modelTimeoutRetryRoute,
|
|
11
|
+
normalizeNoMatchQueryResult,
|
|
11
12
|
applyModelTimeoutRetryRoute,
|
|
12
13
|
recoverFocusedTextRewriteWithWritingSpecialist,
|
|
13
14
|
repairModelMessageHistory,
|
|
@@ -956,6 +957,33 @@ try {
|
|
|
956
957
|
);
|
|
957
958
|
assert(readonlyVersionPipelinePolicy.allowed, "read-only version probe pipelines should not require package-install-policy=allow");
|
|
958
959
|
assert(readonlyVersionPipelinePolicy.category === "read-only", "read-only version probe pipelines should be classified as read-only");
|
|
960
|
+
const pgrepNoMatchPolicy = evaluateCommandPolicy(
|
|
961
|
+
"pgrep -af gateway_service",
|
|
962
|
+
dockerWorkspaceNoInstallsPolicy
|
|
963
|
+
);
|
|
964
|
+
assert(
|
|
965
|
+
pgrepNoMatchPolicy.allowed &&
|
|
966
|
+
pgrepNoMatchPolicy.category === "read-only" &&
|
|
967
|
+
pgrepNoMatchPolicy.noMatchExitIsSuccess === true,
|
|
968
|
+
"pgrep should be a read-only query whose no-match exit is meaningful evidence"
|
|
969
|
+
);
|
|
970
|
+
const pgrepNoMatchResult = normalizeNoMatchQueryResult(
|
|
971
|
+
{ ok: false, exitCode: 1, stdout: "", stderr: "" },
|
|
972
|
+
pgrepNoMatchPolicy
|
|
973
|
+
);
|
|
974
|
+
assert(
|
|
975
|
+
pgrepNoMatchResult.ok === true &&
|
|
976
|
+
pgrepNoMatchResult.noMatch === true &&
|
|
977
|
+
pgrepNoMatchResult.semanticOutcome === "no-match",
|
|
978
|
+
"pgrep exit 1 with no diagnostics should normalize to successful no-match evidence"
|
|
979
|
+
);
|
|
980
|
+
assert(
|
|
981
|
+
normalizeNoMatchQueryResult(
|
|
982
|
+
{ ok: false, exitCode: 2, stdout: "", stderr: "invalid option" },
|
|
983
|
+
pgrepNoMatchPolicy
|
|
984
|
+
).ok === false,
|
|
985
|
+
"an actual pgrep error was incorrectly normalized as no-match evidence"
|
|
986
|
+
);
|
|
959
987
|
const readonlyDiffSlicePolicy = evaluateCommandPolicy(
|
|
960
988
|
"git diff -- src/agent-runner.js | sed -n '1,240p'",
|
|
961
989
|
dockerWorkspaceNoInstallsPolicy
|
|
@@ -1000,6 +1028,16 @@ try {
|
|
|
1000
1028
|
);
|
|
1001
1029
|
assert(pythonUnittestPolicy.allowed, "stdlib python unittest should be allowed without package installs");
|
|
1002
1030
|
assert(pythonUnittestPolicy.category === "test", "stdlib python unittest should be classified as test");
|
|
1031
|
+
const pythonNoBytecodeAcceptancePolicy = evaluateCommandPolicy(
|
|
1032
|
+
"PYTHONDONTWRITEBYTECODE=1 python3 /tmp/devops_sensor_gateway_contract.py",
|
|
1033
|
+
dockerWorkspaceNoInstallsPolicy
|
|
1034
|
+
);
|
|
1035
|
+
assert(
|
|
1036
|
+
pythonNoBytecodeAcceptancePolicy.allowed &&
|
|
1037
|
+
pythonNoBytecodeAcceptancePolicy.category === "test" &&
|
|
1038
|
+
pythonNoBytecodeAcceptancePolicy.substantiveTest === true,
|
|
1039
|
+
"a no-bytecode Python acceptance command should retain substantive test classification"
|
|
1040
|
+
);
|
|
1003
1041
|
const pythonDemoPolicy = evaluateCommandPolicy("python3 demo.py 2>&1", dockerWorkspaceNoInstallsPolicy);
|
|
1004
1042
|
assert(pythonDemoPolicy.allowed, "workspace-local python demo script should be allowed without package installs");
|
|
1005
1043
|
assert(pythonDemoPolicy.category === "toolchain", "workspace-local python demo script should be classified as toolchain");
|
|
@@ -215,6 +215,40 @@ async function main() {
|
|
|
215
215
|
)) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
|
|
216
216
|
"DeepSeek failed-test repair did not force its sole bounded mutation tool"
|
|
217
217
|
);
|
|
218
|
+
assert(
|
|
219
|
+
JSON.stringify(toolChoiceForProvider(
|
|
220
|
+
{
|
|
221
|
+
provider: "deepseek",
|
|
222
|
+
testFailureRepairActive: true,
|
|
223
|
+
testFailureRepairMutationRequired: true,
|
|
224
|
+
testFailureRepairOptionalRereadPaths: ["service.py"],
|
|
225
|
+
},
|
|
226
|
+
[{ role: "user", content: "Apply the coherent repair from retained evidence." }],
|
|
227
|
+
[
|
|
228
|
+
{ type: "function", function: { name: "read_file" } },
|
|
229
|
+
{ type: "function", function: { name: "apply_patch" } },
|
|
230
|
+
{ type: "function", function: { name: "finish" } },
|
|
231
|
+
]
|
|
232
|
+
)) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
|
|
233
|
+
"DeepSeek bounded reread fallback displaced the required repair mutation"
|
|
234
|
+
);
|
|
235
|
+
assert(
|
|
236
|
+
JSON.stringify(toolChoiceForProvider(
|
|
237
|
+
{
|
|
238
|
+
provider: "deepseek",
|
|
239
|
+
testFailureRepairActive: true,
|
|
240
|
+
testFailureRepairMutationRequired: true,
|
|
241
|
+
testFailureRepairNeedsPatchContext: true,
|
|
242
|
+
},
|
|
243
|
+
[{ role: "user", content: "Continue from the retained failing test evidence." }],
|
|
244
|
+
[
|
|
245
|
+
{ type: "function", function: { name: "read_file" } },
|
|
246
|
+
{ type: "function", function: { name: "apply_patch" } },
|
|
247
|
+
{ type: "function", function: { name: "finish" } },
|
|
248
|
+
]
|
|
249
|
+
)) === JSON.stringify({ type: "function", function: { name: "read_file" } }),
|
|
250
|
+
"DeepSeek failed-test repair did not force its bounded context refresh first"
|
|
251
|
+
);
|
|
218
252
|
assert(
|
|
219
253
|
toolChoiceForProvider(
|
|
220
254
|
{ provider: "deepseek" },
|
|
@@ -292,6 +326,61 @@ async function main() {
|
|
|
292
326
|
!Object.hasOwn(deepSeekActionPayload || {}, "reasoning_effort"),
|
|
293
327
|
"DeepSeek action-only recovery sent a conflicting reasoning effort"
|
|
294
328
|
);
|
|
329
|
+
let deepSeekRepairReadPayload = null;
|
|
330
|
+
await requestNextStep(
|
|
331
|
+
{
|
|
332
|
+
chat: {
|
|
333
|
+
completions: {
|
|
334
|
+
create: async (payload) => {
|
|
335
|
+
deepSeekRepairReadPayload = payload;
|
|
336
|
+
return {
|
|
337
|
+
choices: [{
|
|
338
|
+
message: {
|
|
339
|
+
role: "assistant",
|
|
340
|
+
content: "",
|
|
341
|
+
tool_calls: [{
|
|
342
|
+
id: "deepseek-repair-read",
|
|
343
|
+
type: "function",
|
|
344
|
+
function: {
|
|
345
|
+
name: "read_file",
|
|
346
|
+
arguments: JSON.stringify({ path: "service.py" }),
|
|
347
|
+
},
|
|
348
|
+
}],
|
|
349
|
+
},
|
|
350
|
+
}],
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
provider: "deepseek",
|
|
358
|
+
model: "deepseek-v4-pro",
|
|
359
|
+
reasoning: "xhigh",
|
|
360
|
+
goal: "Repair service.py from the exact failed test evidence.",
|
|
361
|
+
taskProfile: "code",
|
|
362
|
+
allowFileTools: true,
|
|
363
|
+
allowShellTool: false,
|
|
364
|
+
allowWebSearch: false,
|
|
365
|
+
allowMcpTools: false,
|
|
366
|
+
allowWrapperTools: false,
|
|
367
|
+
allowAuxiliaryTools: false,
|
|
368
|
+
testFailureRepairActive: true,
|
|
369
|
+
testFailureRepairMutationRequired: true,
|
|
370
|
+
testFailureRepairNeedsPatchContext: true,
|
|
371
|
+
testFailureRepairPatchTargets: ["service.py"],
|
|
372
|
+
testFailureRepairContextPaths: ["service.py"],
|
|
373
|
+
},
|
|
374
|
+
[{ role: "user", content: "Continue from the retained failing test evidence." }]
|
|
375
|
+
);
|
|
376
|
+
assert(
|
|
377
|
+
deepSeekRepairReadPayload?.tool_choice?.function?.name === "read_file",
|
|
378
|
+
"DeepSeek failed-test repair request did not force the bounded context read"
|
|
379
|
+
);
|
|
380
|
+
assert(
|
|
381
|
+
deepSeekRepairReadPayload?.thinking?.type === "disabled",
|
|
382
|
+
"DeepSeek failed-test context refresh spent another unbounded reasoning pass"
|
|
383
|
+
);
|
|
295
384
|
|
|
296
385
|
assert(!isPublicWebUrl("http://127.0.0.1/private"), "public URL guard accepted loopback");
|
|
297
386
|
assert(!isPublicWebUrl("http://10.0.0.1/private"), "public URL guard accepted RFC1918 address");
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
|
+
import net from "node:net";
|
|
5
6
|
import os from "node:os";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
@@ -59,6 +60,7 @@ import {
|
|
|
59
60
|
completionExternalBlockerCanClose,
|
|
60
61
|
pythonTopLevelDefinitionDuplicates,
|
|
61
62
|
recordCanonicalGeneratedOutputProgress,
|
|
63
|
+
recordAlreadyCommittedRepositoryRepair,
|
|
62
64
|
recordProjectVerificationOutcome,
|
|
63
65
|
recordExactOutputProgress,
|
|
64
66
|
recordStaticDiscoveryProgress,
|
|
@@ -264,7 +266,7 @@ try {
|
|
|
264
266
|
}],
|
|
265
267
|
},
|
|
266
268
|
failedTestDiagnostic: {
|
|
267
|
-
packetVersion:
|
|
269
|
+
packetVersion: 15,
|
|
268
270
|
mutationRevision: 0,
|
|
269
271
|
failureSignature: "python-entrypoint-order",
|
|
270
272
|
focuses: [{
|
|
@@ -645,6 +647,137 @@ try {
|
|
|
645
647
|
)) === null,
|
|
646
648
|
"the exact cwd-independent agent-created test harness repair was blocked"
|
|
647
649
|
);
|
|
650
|
+
const foreignListener = net.createServer((socket) => socket.end());
|
|
651
|
+
await new Promise((resolve, reject) => {
|
|
652
|
+
foreignListener.once("error", reject);
|
|
653
|
+
foreignListener.listen(0, "127.0.0.1", resolve);
|
|
654
|
+
});
|
|
655
|
+
try {
|
|
656
|
+
const collisionPort = Number(foreignListener.address()?.port || 0);
|
|
657
|
+
assert(collisionPort >= 1024, "failed to allocate the foreign-listener smoke port");
|
|
658
|
+
await fs.writeFile(
|
|
659
|
+
path.join(baselineWorkspace, "service_ctl.py"),
|
|
660
|
+
[
|
|
661
|
+
"from pathlib import Path",
|
|
662
|
+
"",
|
|
663
|
+
'GATEWAY = Path(__file__).resolve().parent / "gateway_service.py"',
|
|
664
|
+
"raise SystemExit(0)",
|
|
665
|
+
"",
|
|
666
|
+
].join("\n"),
|
|
667
|
+
"utf8"
|
|
668
|
+
);
|
|
669
|
+
await fs.writeFile(
|
|
670
|
+
path.join(baselineWorkspace, "gateway_service.py"),
|
|
671
|
+
"print('sensor gateway fixture')\n",
|
|
672
|
+
"utf8"
|
|
673
|
+
);
|
|
674
|
+
const portCollisionSource = [
|
|
675
|
+
"import subprocess",
|
|
676
|
+
"import sys",
|
|
677
|
+
"import unittest",
|
|
678
|
+
"from pathlib import Path",
|
|
679
|
+
"",
|
|
680
|
+
'SERVICE_CTL = (Path(__file__).resolve().parent / "../service_ctl.py").resolve()',
|
|
681
|
+
"",
|
|
682
|
+
"class TestLifecycle(unittest.TestCase):",
|
|
683
|
+
" def test_start(self):",
|
|
684
|
+
` first = subprocess.run([sys.executable, SERVICE_CTL, "start", "--port", "${collisionPort}"], capture_output=True)`,
|
|
685
|
+
` second = subprocess.run([sys.executable, SERVICE_CTL, "status", "--port", "${collisionPort}"], capture_output=True)`,
|
|
686
|
+
" self.assertEqual(first.returncode, 0)",
|
|
687
|
+
" self.assertEqual(second.returncode, 0)",
|
|
688
|
+
"",
|
|
689
|
+
].join("\n");
|
|
690
|
+
await fs.writeFile(harnessTestPath, portCollisionSource, "utf8");
|
|
691
|
+
const portCollisionState = {
|
|
692
|
+
meta: {
|
|
693
|
+
projectVerification: {
|
|
694
|
+
mutationRevision: 5,
|
|
695
|
+
discoveredTests: ["tests/test_service_lifecycle.py"],
|
|
696
|
+
testRuns: [{
|
|
697
|
+
command: "python3 -m unittest discover -s tests -v",
|
|
698
|
+
mutationRevision: 5,
|
|
699
|
+
passed: false,
|
|
700
|
+
failureEvidenceVersion: 2,
|
|
701
|
+
failureSignature: "agent-created-test-foreign-port-collision",
|
|
702
|
+
failureSummary:
|
|
703
|
+
"test_start AssertionError: 1 != 0 while starting the task service",
|
|
704
|
+
}],
|
|
705
|
+
},
|
|
706
|
+
},
|
|
707
|
+
};
|
|
708
|
+
const portCollisionPacket = await buildFailedTestRecoveryPacket(
|
|
709
|
+
{ commandCwd: baselineWorkspace },
|
|
710
|
+
portCollisionState
|
|
711
|
+
);
|
|
712
|
+
const portCollisionFocus = portCollisionState.meta.failedTestDiagnostic.focuses.find(
|
|
713
|
+
(focus) => focus.kind === "python-agent-test-foreign-port-collision"
|
|
714
|
+
);
|
|
715
|
+
assert(
|
|
716
|
+
portCollisionPacket.content.includes("Foreign listener collision") &&
|
|
717
|
+
portCollisionPacket.paths.includes("gateway_service.py") &&
|
|
718
|
+
portCollisionFocus?.path === "tests/test_service_lifecycle.py" &&
|
|
719
|
+
portCollisionFocus?.ports?.[0] === collisionPort &&
|
|
720
|
+
portCollisionFocus?.portOccurrences === 2 &&
|
|
721
|
+
portCollisionFocus?.listenerEvidence?.[0]?.ownership === "outside-task-workspace" &&
|
|
722
|
+
portCollisionFocus?.testNames?.join(",") === "test_start" &&
|
|
723
|
+
portCollisionFocus?.assertionCount === 2,
|
|
724
|
+
"a foreign hard-coded port or its exact executable dependency was not retained for repair"
|
|
725
|
+
);
|
|
726
|
+
const dynamicPortSource = [
|
|
727
|
+
"import socket",
|
|
728
|
+
"import subprocess",
|
|
729
|
+
"import sys",
|
|
730
|
+
"import unittest",
|
|
731
|
+
"from pathlib import Path",
|
|
732
|
+
"",
|
|
733
|
+
'SERVICE_CTL = (Path(__file__).resolve().parent / "../service_ctl.py").resolve()',
|
|
734
|
+
"",
|
|
735
|
+
"def free_port():",
|
|
736
|
+
" with socket.socket() as probe:",
|
|
737
|
+
' probe.bind(("127.0.0.1", 0))',
|
|
738
|
+
" return probe.getsockname()[1]",
|
|
739
|
+
"",
|
|
740
|
+
"class TestLifecycle(unittest.TestCase):",
|
|
741
|
+
" def test_start(self):",
|
|
742
|
+
" port = free_port()",
|
|
743
|
+
" first = subprocess.run([sys.executable, SERVICE_CTL, \"start\", \"--port\", str(port)], capture_output=True)",
|
|
744
|
+
" second = subprocess.run([sys.executable, SERVICE_CTL, \"status\", \"--port\", str(port)], capture_output=True)",
|
|
745
|
+
" self.assertEqual(first.returncode, 0)",
|
|
746
|
+
" self.assertEqual(second.returncode, 0)",
|
|
747
|
+
"",
|
|
748
|
+
].join("\n");
|
|
749
|
+
assert(
|
|
750
|
+
(await failedTestRepairPatchBlock(
|
|
751
|
+
portCollisionState,
|
|
752
|
+
"apply_patch",
|
|
753
|
+
{
|
|
754
|
+
path: "tests/test_service_lifecycle.py",
|
|
755
|
+
search: portCollisionSource,
|
|
756
|
+
replace: dynamicPortSource.replace(
|
|
757
|
+
" self.assertEqual(second.returncode, 0)",
|
|
758
|
+
" self.assertTrue(True)"
|
|
759
|
+
),
|
|
760
|
+
},
|
|
761
|
+
{ commandCwd: baselineWorkspace }
|
|
762
|
+
))?.category === "failed-test-regression",
|
|
763
|
+
"foreign-port isolation was allowed to change the assertion-method contract"
|
|
764
|
+
);
|
|
765
|
+
assert(
|
|
766
|
+
(await failedTestRepairPatchBlock(
|
|
767
|
+
portCollisionState,
|
|
768
|
+
"apply_patch",
|
|
769
|
+
{
|
|
770
|
+
path: "tests/test_service_lifecycle.py",
|
|
771
|
+
search: portCollisionSource,
|
|
772
|
+
replace: dynamicPortSource,
|
|
773
|
+
},
|
|
774
|
+
{ commandCwd: baselineWorkspace }
|
|
775
|
+
)) === null,
|
|
776
|
+
"a complete dynamic-port rewrite of the Git-new test was blocked"
|
|
777
|
+
);
|
|
778
|
+
} finally {
|
|
779
|
+
await new Promise((resolve) => foreignListener.close(resolve));
|
|
780
|
+
}
|
|
648
781
|
for (const args of [
|
|
649
782
|
["add", "service_ctl.py", "tests/test_service_lifecycle.py"],
|
|
650
783
|
["commit", "-m", "tracked harness boundary"],
|
|
@@ -667,9 +800,11 @@ try {
|
|
|
667
800
|
);
|
|
668
801
|
assert(
|
|
669
802
|
!trackedHarnessState.meta.failedTestDiagnostic.focuses.some(
|
|
670
|
-
(focus) =>
|
|
803
|
+
(focus) =>
|
|
804
|
+
focus.kind === "python-agent-test-harness-path" ||
|
|
805
|
+
focus.kind === "python-agent-test-foreign-port-collision"
|
|
671
806
|
),
|
|
672
|
-
"
|
|
807
|
+
"an agent-created test exception was incorrectly applied to a tracked authoritative test"
|
|
673
808
|
);
|
|
674
809
|
await fs.mkdir(path.join(workspace, "tests"), { recursive: true });
|
|
675
810
|
await fs.writeFile(
|
|
@@ -1961,6 +2096,36 @@ try {
|
|
|
1961
2096
|
}
|
|
1962
2097
|
);
|
|
1963
2098
|
assert(coveredTestQuality.ok === true, coveredTestQuality.reason);
|
|
2099
|
+
const coveredBeforeAcceptanceQuality = await validateMutatedPythonSourceQuality(
|
|
2100
|
+
{ commandCwd: pythonQualityWorkspace },
|
|
2101
|
+
{
|
|
2102
|
+
meta: {
|
|
2103
|
+
projectVerification: {
|
|
2104
|
+
mutationRevision: 3,
|
|
2105
|
+
privateMutationRevision: 0,
|
|
2106
|
+
mutationHistory: [{ revision: 3, paths: ["tests/test_service_launch.py"] }],
|
|
2107
|
+
testRuns: [
|
|
2108
|
+
{
|
|
2109
|
+
command: "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v",
|
|
2110
|
+
mutationRevision: 3,
|
|
2111
|
+
privateMutationRevision: 0,
|
|
2112
|
+
passed: true,
|
|
2113
|
+
},
|
|
2114
|
+
{
|
|
2115
|
+
command: "python3 /tmp/project_acceptance.py",
|
|
2116
|
+
mutationRevision: 3,
|
|
2117
|
+
privateMutationRevision: 0,
|
|
2118
|
+
passed: true,
|
|
2119
|
+
},
|
|
2120
|
+
],
|
|
2121
|
+
},
|
|
2122
|
+
},
|
|
2123
|
+
}
|
|
2124
|
+
);
|
|
2125
|
+
assert(
|
|
2126
|
+
coveredBeforeAcceptanceQuality.ok === true,
|
|
2127
|
+
"a later passing acceptance verifier erased current unit-suite coverage for a changed test"
|
|
2128
|
+
);
|
|
1964
2129
|
assert(normalizeDynamicStepsMode("off") === "off", "dynamic mode off did not normalize");
|
|
1965
2130
|
for (const command of [
|
|
1966
2131
|
"npm run build",
|
|
@@ -5078,6 +5243,69 @@ try {
|
|
|
5078
5243
|
leadingContinuationUpdate?.refreshExecutionContract,
|
|
5079
5244
|
"a leading bare continuation clause followed by concrete details became a new task"
|
|
5080
5245
|
);
|
|
5246
|
+
const activeTaskContinuationState = structuredClone(concreteContinuationState);
|
|
5247
|
+
const retainedActiveTaskVerification = activeTaskContinuationState.meta.projectVerification;
|
|
5248
|
+
const activeTaskContinuationUpdate = applyContinuationContractTransition(
|
|
5249
|
+
activeTaskContinuationState,
|
|
5250
|
+
`Continue the exact active DevOps task from the current workspace. Diagnose the retained failures from exact evidence, rerun validation, and commit the coherent repair. ${"Preserve the existing task lineage while applying this correction. ".repeat(12)}`,
|
|
5251
|
+
{ at: "2026-08-24T09:59:30.000Z" }
|
|
5252
|
+
);
|
|
5253
|
+
assert(
|
|
5254
|
+
activeTaskContinuationUpdate?.preserveTaskBoundary &&
|
|
5255
|
+
activeTaskContinuationUpdate?.refreshExecutionContract,
|
|
5256
|
+
"an explicit exact active-task continuation opened a new task boundary"
|
|
5257
|
+
);
|
|
5258
|
+
assert(
|
|
5259
|
+
activeTaskContinuationState.meta.projectVerification === retainedActiveTaskVerification,
|
|
5260
|
+
"an exact active-task continuation discarded durable verification evidence"
|
|
5261
|
+
);
|
|
5262
|
+
const postMutationVerifier = "python3 -m unittest discover -s tests -v";
|
|
5263
|
+
const postMutationVerificationState = {
|
|
5264
|
+
goal: "Repair and verify the current service controller.",
|
|
5265
|
+
meta: {
|
|
5266
|
+
goalContract: {
|
|
5267
|
+
revision: 12,
|
|
5268
|
+
currentRequest: "Repair and verify the current service controller.",
|
|
5269
|
+
},
|
|
5270
|
+
activeExecutionContract: {
|
|
5271
|
+
revision: 12,
|
|
5272
|
+
startedMutationRevision: 7,
|
|
5273
|
+
materialMutationRevision: 8,
|
|
5274
|
+
requiresFileMutation: true,
|
|
5275
|
+
requiresSourceGrounding: true,
|
|
5276
|
+
},
|
|
5277
|
+
projectVerification: {
|
|
5278
|
+
mutationRevision: 8,
|
|
5279
|
+
testRuns: [{
|
|
5280
|
+
command: postMutationVerifier,
|
|
5281
|
+
mutationRevision: 7,
|
|
5282
|
+
passed: false,
|
|
5283
|
+
failureEvidenceVersion: 2,
|
|
5284
|
+
failureSignature: "pre-repair-failure",
|
|
5285
|
+
}],
|
|
5286
|
+
},
|
|
5287
|
+
failedTestRecoveryPacket: {
|
|
5288
|
+
packetVersion: 15,
|
|
5289
|
+
mutationRevision: 7,
|
|
5290
|
+
failureSignature: "pre-repair-failure",
|
|
5291
|
+
content: "Bounded failed-test evidence packet v15.",
|
|
5292
|
+
},
|
|
5293
|
+
},
|
|
5294
|
+
};
|
|
5295
|
+
const postMutationVerificationRuntime = nextStepRuntimeConfig(
|
|
5296
|
+
{
|
|
5297
|
+
provider: "deepseek",
|
|
5298
|
+
taskProfile: "devops",
|
|
5299
|
+
commandCwd: workspace,
|
|
5300
|
+
goal: postMutationVerificationState.goal,
|
|
5301
|
+
},
|
|
5302
|
+
postMutationVerificationState
|
|
5303
|
+
);
|
|
5304
|
+
assert(
|
|
5305
|
+
postMutationVerificationRuntime.testVerificationPending === true &&
|
|
5306
|
+
postMutationVerificationRuntime.testVerificationCommand === postMutationVerifier,
|
|
5307
|
+
"a material failed-test repair did not advance directly to its exact retained verifier"
|
|
5308
|
+
);
|
|
5081
5309
|
const concreteGoalUpdate = applyContinuationContractTransition(
|
|
5082
5310
|
concreteContinuationState,
|
|
5083
5311
|
concreteContinuation,
|
|
@@ -5716,6 +5944,29 @@ try {
|
|
|
5716
5944
|
) === null,
|
|
5717
5945
|
"the repeated-read guard blocked an exact source refresh required after a stale patch"
|
|
5718
5946
|
);
|
|
5947
|
+
assert(
|
|
5948
|
+
repeatedStaticToolBlock(
|
|
5949
|
+
{
|
|
5950
|
+
meta: {
|
|
5951
|
+
toolLoop: {
|
|
5952
|
+
staticCounts: {
|
|
5953
|
+
[staticToolCallSignature("read_file", { path: "service_ctl.py" }, {
|
|
5954
|
+
commandCwd: workspace,
|
|
5955
|
+
})]: 1,
|
|
5956
|
+
},
|
|
5957
|
+
staticTotal: 1,
|
|
5958
|
+
},
|
|
5959
|
+
},
|
|
5960
|
+
},
|
|
5961
|
+
"read_file",
|
|
5962
|
+
{ path: "service_ctl.py" },
|
|
5963
|
+
{
|
|
5964
|
+
commandCwd: workspace,
|
|
5965
|
+
testFailureRepairContextPaths: ["service_ctl.py"],
|
|
5966
|
+
}
|
|
5967
|
+
) === null,
|
|
5968
|
+
"the repeated-read guard blocked an exact bounded failed-test context refresh"
|
|
5969
|
+
);
|
|
5719
5970
|
assert(
|
|
5720
5971
|
repeatedStaticToolBlock(
|
|
5721
5972
|
{ meta: { toolLoop: { staticCounts: { [exactReadSignature]: 1 }, staticTotal: 1 } } },
|
|
@@ -5916,6 +6167,124 @@ try {
|
|
|
5916
6167
|
) === null,
|
|
5917
6168
|
"a clean-worktree verification gate could not rerun after a Git-state repair"
|
|
5918
6169
|
);
|
|
6170
|
+
const successfulRepositoryRepairState = structuredClone(repositoryCleanGateFailure);
|
|
6171
|
+
successfulRepositoryRepairState.goal = "Repair and verify the service lifecycle.";
|
|
6172
|
+
successfulRepositoryRepairState.meta.goalContract = { revision: 4 };
|
|
6173
|
+
successfulRepositoryRepairState.meta.activeExecutionContract = {
|
|
6174
|
+
revision: 4,
|
|
6175
|
+
materialMutationRevision: 6,
|
|
6176
|
+
};
|
|
6177
|
+
const successfulRepositoryCommit = {
|
|
6178
|
+
toolName: "run_command",
|
|
6179
|
+
ok: true,
|
|
6180
|
+
exitCode: 0,
|
|
6181
|
+
args: {
|
|
6182
|
+
command:
|
|
6183
|
+
"git add -- 'gateway_service.py' && git commit -m 'Repair service lifecycle'",
|
|
6184
|
+
},
|
|
6185
|
+
stdout:
|
|
6186
|
+
"[main abcdef1] Repair service lifecycle\n 1 file changed, 1 insertion(+), 1 deletion(-)\n",
|
|
6187
|
+
stderr: "",
|
|
6188
|
+
};
|
|
6189
|
+
recordProjectVerificationOutcome(
|
|
6190
|
+
successfulRepositoryRepairState,
|
|
6191
|
+
successfulRepositoryCommit,
|
|
6192
|
+
{ commandCwd: workspace, taskProfile: "devops" }
|
|
6193
|
+
);
|
|
6194
|
+
const successfulRepositoryRepairMarker = recordAlreadyCommittedRepositoryRepair(
|
|
6195
|
+
successfulRepositoryRepairState,
|
|
6196
|
+
successfulRepositoryCommit
|
|
6197
|
+
);
|
|
6198
|
+
const postCommitRepositoryRuntime = nextStepRuntimeConfig(
|
|
6199
|
+
{ provider: "deepseek", taskProfile: "devops", commandCwd: workspace },
|
|
6200
|
+
successfulRepositoryRepairState
|
|
6201
|
+
);
|
|
6202
|
+
assert(
|
|
6203
|
+
successfulRepositoryRepairMarker?.source === "successful-commit" &&
|
|
6204
|
+
postCommitRepositoryRuntime.testFailureRepositoryStateRepair !== true &&
|
|
6205
|
+
postCommitRepositoryRuntime.testVerificationPending === true &&
|
|
6206
|
+
postCommitRepositoryRuntime.testVerificationCommand === failedValidationCommand,
|
|
6207
|
+
"a successful bounded repair commit did not advance directly to the exact failed verifier"
|
|
6208
|
+
);
|
|
6209
|
+
const cleanStatusRepositoryRepairState = structuredClone(repositoryCleanGateFailure);
|
|
6210
|
+
cleanStatusRepositoryRepairState.goal = "Resume the committed service repair.";
|
|
6211
|
+
cleanStatusRepositoryRepairState.meta.goalContract = { revision: 5 };
|
|
6212
|
+
cleanStatusRepositoryRepairState.meta.activeExecutionContract = {
|
|
6213
|
+
revision: 5,
|
|
6214
|
+
startedMutationRevision: 6,
|
|
6215
|
+
materialMutationRevision: 6,
|
|
6216
|
+
requiresFileMutation: true,
|
|
6217
|
+
requiresSourceGrounding: true,
|
|
6218
|
+
};
|
|
6219
|
+
cleanStatusRepositoryRepairState.meta.durableGitEvidence = [{
|
|
6220
|
+
action: "commit",
|
|
6221
|
+
goalRevision: 5,
|
|
6222
|
+
mutationRevision: 5,
|
|
6223
|
+
}];
|
|
6224
|
+
const cleanStatusAfterCommit = {
|
|
6225
|
+
toolName: "run_command",
|
|
6226
|
+
ok: true,
|
|
6227
|
+
exitCode: 0,
|
|
6228
|
+
args: { command: "git status --short" },
|
|
6229
|
+
stdout: "",
|
|
6230
|
+
stderr: "",
|
|
6231
|
+
};
|
|
6232
|
+
recordProjectVerificationOutcome(
|
|
6233
|
+
cleanStatusRepositoryRepairState,
|
|
6234
|
+
cleanStatusAfterCommit,
|
|
6235
|
+
{ commandCwd: workspace, taskProfile: "devops" }
|
|
6236
|
+
);
|
|
6237
|
+
const cleanStatusRepositoryRepairMarker = recordAlreadyCommittedRepositoryRepair(
|
|
6238
|
+
cleanStatusRepositoryRepairState,
|
|
6239
|
+
cleanStatusAfterCommit
|
|
6240
|
+
);
|
|
6241
|
+
const cleanStatusRepositoryRuntime = nextStepRuntimeConfig(
|
|
6242
|
+
{ provider: "deepseek", taskProfile: "devops", commandCwd: workspace },
|
|
6243
|
+
cleanStatusRepositoryRepairState
|
|
6244
|
+
);
|
|
6245
|
+
assert(
|
|
6246
|
+
cleanStatusRepositoryRepairMarker?.source === "clean-status-after-commit" &&
|
|
6247
|
+
cleanStatusRepositoryRuntime.completionFreshMutationRequired !== true &&
|
|
6248
|
+
cleanStatusRepositoryRuntime.testVerificationPending === true &&
|
|
6249
|
+
cleanStatusRepositoryRuntime.testVerificationCommand === failedValidationCommand &&
|
|
6250
|
+
buildKnownConstrainedPhasePlan(
|
|
6251
|
+
{ provider: "deepseek", taskProfile: "devops", commandCwd: workspace },
|
|
6252
|
+
cleanStatusRepositoryRepairState,
|
|
6253
|
+
cleanStatusRepositoryRuntime
|
|
6254
|
+
)?.mode === "exact-verification",
|
|
6255
|
+
"current commit plus an exact clean Git status did not recover an interrupted repository repair"
|
|
6256
|
+
);
|
|
6257
|
+
const repeatedDirtyRepositoryResult = {
|
|
6258
|
+
toolName: "run_command",
|
|
6259
|
+
ok: false,
|
|
6260
|
+
exitCode: 1,
|
|
6261
|
+
args: { command: failedValidationCommand },
|
|
6262
|
+
stdout: "",
|
|
6263
|
+
stderr:
|
|
6264
|
+
"AssertionError: repository worktree is not clean after a new unrelated mutation",
|
|
6265
|
+
};
|
|
6266
|
+
recordProjectVerificationOutcome(
|
|
6267
|
+
successfulRepositoryRepairState,
|
|
6268
|
+
repeatedDirtyRepositoryResult,
|
|
6269
|
+
{
|
|
6270
|
+
provider: "deepseek",
|
|
6271
|
+
taskProfile: "devops",
|
|
6272
|
+
commandCwd: workspace,
|
|
6273
|
+
testVerificationPending: true,
|
|
6274
|
+
testVerificationCommand: failedValidationCommand,
|
|
6275
|
+
}
|
|
6276
|
+
);
|
|
6277
|
+
const repeatedDirtyRepositoryRuntime = nextStepRuntimeConfig(
|
|
6278
|
+
{ provider: "deepseek", taskProfile: "devops", commandCwd: workspace },
|
|
6279
|
+
successfulRepositoryRepairState
|
|
6280
|
+
);
|
|
6281
|
+
assert(
|
|
6282
|
+
repeatedDirtyRepositoryResult.repositoryStateRepairConsumed === true &&
|
|
6283
|
+
!successfulRepositoryRepairState.meta.repositoryStateRepair &&
|
|
6284
|
+
repeatedDirtyRepositoryRuntime.testFailureRepositoryStateRepair === true &&
|
|
6285
|
+
repeatedDirtyRepositoryRuntime.testVerificationPending !== true,
|
|
6286
|
+
"a consumed repository-repair marker caused an unchanged clean-worktree verifier loop"
|
|
6287
|
+
);
|
|
5919
6288
|
const oversizedRepositoryState = {
|
|
5920
6289
|
...repositoryCleanGateFailure,
|
|
5921
6290
|
goal: "Complete the current repository task and preserve its established acceptance contract.",
|
|
@@ -6379,6 +6748,32 @@ try {
|
|
|
6379
6748
|
projectTestVerificationFinishBlock(repairedValidationState) === null,
|
|
6380
6749
|
"a passing rerun at the current real mutation revision did not reopen completion"
|
|
6381
6750
|
);
|
|
6751
|
+
const presentationWrappedValidationState = {
|
|
6752
|
+
meta: {
|
|
6753
|
+
projectVerification: {
|
|
6754
|
+
mutationRevision: 7,
|
|
6755
|
+
privateMutationRevision: 0,
|
|
6756
|
+
testRuns: [
|
|
6757
|
+
{
|
|
6758
|
+
command: "python3 -m unittest discover -s tests -v 2>&1",
|
|
6759
|
+
mutationRevision: 2,
|
|
6760
|
+
privateMutationRevision: 0,
|
|
6761
|
+
passed: false,
|
|
6762
|
+
},
|
|
6763
|
+
{
|
|
6764
|
+
command: "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v",
|
|
6765
|
+
mutationRevision: 7,
|
|
6766
|
+
privateMutationRevision: 0,
|
|
6767
|
+
passed: true,
|
|
6768
|
+
},
|
|
6769
|
+
],
|
|
6770
|
+
},
|
|
6771
|
+
},
|
|
6772
|
+
};
|
|
6773
|
+
assert(
|
|
6774
|
+
projectTestVerificationFinishBlock(presentationWrappedValidationState) === null,
|
|
6775
|
+
"presentation-only test wrappers left a superseded failure unresolved"
|
|
6776
|
+
);
|
|
6382
6777
|
const tracebackEvidence = compactFailedTestEvidence(
|
|
6383
6778
|
{
|
|
6384
6779
|
stderr: [
|
|
@@ -6472,8 +6867,8 @@ try {
|
|
|
6472
6867
|
"a same-task refresh could not rebuild a missing failed-test evidence packet"
|
|
6473
6868
|
);
|
|
6474
6869
|
missingRecoveryPacketState.meta.failedTestRecoveryPacket = {
|
|
6475
|
-
packetVersion:
|
|
6476
|
-
content: "Bounded failed-test evidence packet
|
|
6870
|
+
packetVersion: 15,
|
|
6871
|
+
content: "Bounded failed-test evidence packet v15.",
|
|
6477
6872
|
mutationRevision: 6,
|
|
6478
6873
|
failureSignature: "same-failure",
|
|
6479
6874
|
};
|
|
@@ -7331,7 +7726,7 @@ try {
|
|
|
7331
7726
|
],
|
|
7332
7727
|
},
|
|
7333
7728
|
failedTestDiagnostic: {
|
|
7334
|
-
packetVersion:
|
|
7729
|
+
packetVersion: 15,
|
|
7335
7730
|
mutationRevision: 0,
|
|
7336
7731
|
failureSignature: "partial-derived-order",
|
|
7337
7732
|
focuses: [
|
|
@@ -539,12 +539,12 @@ const focusedRecoveryState = {
|
|
|
539
539
|
}],
|
|
540
540
|
},
|
|
541
541
|
failedTestRecoveryPacket: {
|
|
542
|
-
packetVersion:
|
|
542
|
+
packetVersion: 15,
|
|
543
543
|
mutationRevision: 4,
|
|
544
544
|
failureSignature: "missing-service-seams",
|
|
545
545
|
paths: ["tests/test_service_ctl.py", "service_ctl.py"],
|
|
546
546
|
content: [
|
|
547
|
-
"Bounded failed-test evidence packet
|
|
547
|
+
"Bounded failed-test evidence packet v15.",
|
|
548
548
|
'with mock.patch.object(service_ctl, "launch_service") as launch:',
|
|
549
549
|
'with mock.patch.object(service_ctl, "wait_until_healthy", return_value=True):',
|
|
550
550
|
"### service_ctl.py",
|
|
@@ -588,7 +588,7 @@ assert.match(
|
|
|
588
588
|
focusedRecoveryText,
|
|
589
589
|
/Required acceptance seams: service_ctl\.launch_service, service_ctl\.wait_until_healthy/
|
|
590
590
|
);
|
|
591
|
-
assert.match(focusedRecoveryText, /Bounded failed-test evidence packet
|
|
591
|
+
assert.match(focusedRecoveryText, /Bounded failed-test evidence packet v15/);
|
|
592
592
|
assert.match(focusedRecoveryText, /requires one coherent source mutation before verification/i);
|
|
593
593
|
|
|
594
594
|
const durablePatchArgs = {
|