@lazyingart/agintiflow 0.20.276 → 0.20.278

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.276",
3
+ "version": "0.20.278",
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",
@@ -88,6 +88,18 @@ const pathWrappedImmutableSourceContract = deriveScsTaskContract({
88
88
  taskProfile: "slides",
89
89
  });
90
90
 
91
+ const wrappedNegativeVerificationOnlyContract = deriveScsTaskContract({
92
+ goal: [
93
+ "Continue the exact active presentation task from its clean committed state.",
94
+ "The prior run completed the task-owned repository repair.",
95
+ "Do not start over and do",
96
+ "not modify source_brief.md, measurements.csv, prompt.txt, or TASK.md.",
97
+ "Do not rebuild, rewrite, recommit, or otherwise mutate the repository.",
98
+ "Read build_deck.py and TASK.md, run the exact validator, and finish from the retained evidence.",
99
+ ].join("\n"),
100
+ taskProfile: "slides",
101
+ });
102
+
91
103
  const recoveryInstructionContract = deriveScsTaskContract({
92
104
  goal: [
93
105
  "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.",
@@ -201,6 +213,26 @@ for (const contract of [
201
213
  "a negative action or its governed path list lost protection across a line wrap"
202
214
  );
203
215
  }
216
+ assert.deepEqual(
217
+ wrappedNegativeVerificationOnlyContract.excludedOutputPaths.sort(),
218
+ ["TASK.md", "measurements.csv", "prompt.txt", "source_brief.md"].sort(),
219
+ "a line-wrapped 'do not' prefix lost its immutable source exclusions"
220
+ );
221
+ assert.deepEqual(
222
+ wrappedNegativeVerificationOnlyContract.exactOutputPaths,
223
+ [],
224
+ "a verification-only continuation inferred exact outputs from a wrapped negative clause"
225
+ );
226
+ assert.equal(
227
+ wrappedNegativeVerificationOnlyContract.requiresWorkspaceMutation,
228
+ false,
229
+ "a verification-only continuation with a wrapped negative prefix required workspace mutation"
230
+ );
231
+ assert.equal(
232
+ wrappedNegativeVerificationOnlyContract.requiresFileMutation,
233
+ false,
234
+ "a verification-only continuation with a wrapped negative prefix required file mutation"
235
+ );
204
236
  assert(
205
237
  recoveryInstructionContract.excludedOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt") &&
206
238
  !recoveryInstructionContract.exactOutputPaths.includes("resume-after-git-baseline-recovery-dev-prompt.txt"),
@@ -871,6 +903,46 @@ try {
871
903
  "a session-generated helper circularly grounded a path claim"
872
904
  );
873
905
 
906
+ fs.writeFileSync(
907
+ reportPath,
908
+ "Verified generated helper: `notes/generated-evidence.md`.\n",
909
+ "utf8"
910
+ );
911
+ const generatedHelperPathIsDirectlyObserved = evaluateScsSemanticContract(contract, {
912
+ commandCwd: groundingRoot,
913
+ events: [
914
+ {
915
+ type: "tool.completed",
916
+ data: {
917
+ ok: true,
918
+ toolName: "write_file",
919
+ path: "notes/generated-evidence.md",
920
+ change: { path: "notes/generated-evidence.md" },
921
+ },
922
+ },
923
+ {
924
+ type: "file.changed",
925
+ data: { path: "notes/generated-evidence.md", commandCwd: groundingRoot },
926
+ },
927
+ {
928
+ type: "tool.completed",
929
+ data: {
930
+ ok: true,
931
+ toolName: "read_file",
932
+ path: "notes/generated-evidence.md",
933
+ content: helperContent,
934
+ commandEvidence: extractMarkdownCommandEvidence(helperContent, "notes/generated-evidence.md"),
935
+ pathEvidence: extractMarkdownPathEvidence(helperContent, "notes/generated-evidence.md"),
936
+ },
937
+ },
938
+ ],
939
+ });
940
+ assert.equal(
941
+ generatedHelperPathIsDirectlyObserved.ok,
942
+ true,
943
+ "a successful direct read did not ground the generated file's own path"
944
+ );
945
+
874
946
  const shellSourceContent = [
875
947
  "Verified interface:",
876
948
  "```bash",
@@ -412,6 +412,13 @@ function forbiddenTails(text = "") {
412
412
  return tails;
413
413
  }
414
414
 
415
+ function normalizeWrappedNegativePrefixes(goal = "") {
416
+ return String(goal || "").replace(
417
+ /\b(do|must|should)\s*\r?\n\s*not\b/giu,
418
+ "$1 not"
419
+ );
420
+ }
421
+
415
422
  function inferExactOutputPaths(goal = "") {
416
423
  const paths = [];
417
424
  const lines = String(goal || "").split(/\n/);
@@ -557,7 +564,7 @@ export function inferExplicitlyExcludedOutputPaths(goal = "") {
557
564
  `(?=\\S{1,260}\\.(?:${extensionPattern})\\b)`,
558
565
  "giu"
559
566
  );
560
- const source = String(goal || "")
567
+ const source = normalizeWrappedNegativePrefixes(goal)
561
568
  .replace(/([,,、])\s*\r?\n\s*/gu, "$1 ")
562
569
  .replace(wrappedNegativeAction, "$1 ")
563
570
  .replace(wrappedNegativePath, "$1 ");
@@ -1065,7 +1072,7 @@ function codeProfileRequiresCommand(goal = "") {
1065
1072
  }
1066
1073
 
1067
1074
  function goalRequestsWorkspaceMutation(goal = "", taskProfile = "") {
1068
- const text = normalizedText(stripForbiddenLanguage(goal));
1075
+ const text = normalizedText(stripCompletedWorkNarration(stripForbiddenLanguage(goal)));
1069
1076
  if (String(taskProfile || "").trim().toLowerCase() === "review") {
1070
1077
  return /\b(?:append|copy|create|delete|edit|fix|implement|modify|move|patch|refactor|remove|rename|repair|replace|rewrite|save|update|write)\b/.test(
1071
1078
  text
@@ -1080,7 +1087,7 @@ function goalRequestsWorkspaceMutation(goal = "", taskProfile = "") {
1080
1087
  }
1081
1088
 
1082
1089
  function goalRequestsFileMutation(goal = "", taskProfile = "") {
1083
- const text = normalizedText(stripForbiddenLanguage(goal));
1090
+ const text = normalizedText(stripCompletedWorkNarration(stripForbiddenLanguage(goal)));
1084
1091
  if (!goalRequestsWorkspaceMutation(text, taskProfile)) return false;
1085
1092
  return (
1086
1093
  /\b(?:code|codebase|document(?:ation)?|files?|notes?|path|readme|repo(?:sitory)?|script|source|workspace)\b/.test(
@@ -1301,13 +1308,35 @@ function inferRequiredToolCalls(goal = "") {
1301
1308
  }
1302
1309
 
1303
1310
  function stripForbiddenLanguage(goal = "") {
1304
- return String(goal || "")
1305
- .replace(/\b(do not|don't|dont|never|no need to)\s+([^.\n;]+)/gi, "")
1311
+ return normalizeWrappedNegativePrefixes(goal)
1312
+ .replace(/\b(do not|don't|dont|must not|should not|never|no need to)\s+([^.\n;]+)/gi, "")
1306
1313
  .replace(/\bwithout\s+([^.,\n;]+)/gi, "")
1307
1314
  .replace(/不要([^。\n;]+)/g, "")
1308
1315
  .replace(/禁止([^。\n;]+)/g, "");
1309
1316
  }
1310
1317
 
1318
+ function stripCompletedWorkNarration(goal = "") {
1319
+ const completedAction =
1320
+ "(?:completed?|finished|performed|applied|committed|repaired|fixed|rebuilt|rewrote|generated|created|updated|modified|patched|moved|relocated)";
1321
+ const priorActor =
1322
+ "(?:(?:the\\s+)?(?:prior|previous|earlier|last)\\s+(?:run|turn|attempt|session|agent|worker)|(?:it|this|that)\\s+(?:was|has\\s+been))";
1323
+ return String(goal || "")
1324
+ .replace(
1325
+ new RegExp(
1326
+ `\\b${priorActor}\\b[^.!?;;。!?\\n]{0,300}\\b${completedAction}\\b[^.!?;;。!?\\n]*`,
1327
+ "gi"
1328
+ ),
1329
+ ""
1330
+ )
1331
+ .replace(
1332
+ new RegExp(
1333
+ `\\b(?:already|previously|earlier)\\b[^.!?;;。!?\\n]{0,180}\\b${completedAction}\\b[^.!?;;。!?\\n]*`,
1334
+ "gi"
1335
+ ),
1336
+ ""
1337
+ );
1338
+ }
1339
+
1311
1340
  function parseAgintiEvidenceScopeMatch(goal = "") {
1312
1341
  const matches = [
1313
1342
  ...String(goal || "").matchAll(/^AGINTI_EVIDENCE_SCOPE_JSON:\s*(\{[^\n]+\})\s*$/gm),
@@ -2592,11 +2621,11 @@ function sourceEvidencePaths({ events = [], state = {}, contract = {}, commandCw
2592
2621
  commandCwd,
2593
2622
  });
2594
2623
  const paths = new Map();
2595
- const addPath = (value = "", source = "") => {
2624
+ const addPath = (value = "", source = "", { allowExcludedDirect = false } = {}) => {
2596
2625
  const cleaned = cleanPathToken(value);
2597
2626
  if (!cleaned) return;
2598
2627
  const keys = pathComparisonKeys(cleaned, commandCwd);
2599
- if (keys.some((key) => excluded.has(key))) return;
2628
+ if (!allowExcludedDirect && keys.some((key) => excluded.has(key))) return;
2600
2629
  const canonical = keys[keys.length - 1] || cleaned;
2601
2630
  if (!paths.has(canonical)) paths.set(canonical, { path: cleaned, source: String(source || "") });
2602
2631
  for (const key of keys) {
@@ -2641,8 +2670,12 @@ function sourceEvidencePaths({ events = [], state = {}, contract = {}, commandCw
2641
2670
  const payloadPath = payload.path || payload.args?.path || "";
2642
2671
  const payloadPathKeys = pathComparisonKeys(payloadPath, commandCwd);
2643
2672
  const sourceIsExcluded = payloadPathKeys.some((key) => excluded.has(key));
2644
- if (toolName === "read_file" && sourceIsExcluded) return;
2645
- if (["read_file", "list_files", "search_files", "inspect_project"].includes(toolName)) {
2673
+ if (toolName === "read_file") {
2674
+ // Reading a generated or previously mutated file proves that exact path
2675
+ // exists. Its contents still cannot ground additional claims.
2676
+ addPath(payloadPath, `${toolName} result`, { allowExcludedDirect: true });
2677
+ if (sourceIsExcluded) return;
2678
+ } else if (["list_files", "search_files", "inspect_project"].includes(toolName)) {
2646
2679
  addPath(payloadPath, `${toolName} result`);
2647
2680
  }
2648
2681
  if (toolName === "read_file") {