@lazyingart/agintiflow 0.20.225 → 0.20.227
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.
|
@@ -73,7 +73,7 @@ Current contract:
|
|
|
73
73
|
- `danger` is trusted host/full-access mode: host shell, destructive actions, host installs, password typing, and outside-workspace file paths are enabled. Use it only for tasks you trust; obvious secret/publish exfiltration guards remain hard stops.
|
|
74
74
|
- Workspace file tools may read and write inside the configured project folder when file tools are enabled.
|
|
75
75
|
- Narrow workspace-local shell actions such as safe probes, Gradle/TeX builds, and `chmod +x` on a project script may run when the command policy can classify them precisely.
|
|
76
|
-
- Finite literal read-only audits may bind a small literal path, inspect/hash it, count matches through a bounded read-only pipeline, and display numeric results with `echo` or `printf` without asking for destructive permission. Shell line continuations are accepted for finite literal item lists. Every producer, consumer, and surrounding command must still classify as bounded read-only work; network access, redirects, secret/dynamic expansion, shell-state `printf -v`, mutation, dynamic item lists, and computed values used as executable arguments remain blocked.
|
|
76
|
+
- Finite literal read-only audits may bind a small literal path, inspect/hash it, count matches through a bounded read-only pipeline, summarize stdin with `sort | uniq -c`, and display numeric results with `echo` or `printf` without asking for destructive permission. Shell line continuations are accepted for finite literal item lists. Every producer, consumer, and surrounding command must still classify as bounded read-only work; network access, redirects, output-file operands, secret/dynamic expansion, shell-state `printf -v`, mutation, dynamic item lists, and computed values used as executable arguments remain blocked.
|
|
77
77
|
- Completion checks distinguish a resolved historical state such as "previously paused" from work that is currently pending or incomplete. A resolved past blocker therefore does not force another verification loop, while any explicit current unfinished state still does.
|
|
78
78
|
- Android/JVM toolchain commands may include safe local env assignments such as `ANDROID_HOME`, `ANDROID_SDK_ROOT`, `JAVA_HOME`, or `GRADLE_USER_HOME`, plus small workspace-local status-log redirects. Secret-like env vars and redirects outside the workspace remain blocked.
|
|
79
79
|
- Workspace writes outside that folder, secret paths, `.git` internals, and dependency folders such as `node_modules` are blocked.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.227",
|
|
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",
|
|
@@ -714,6 +714,19 @@ try {
|
|
|
714
714
|
exactReadOnlyFormattedReportAuditPolicy.writesWorkspace === false,
|
|
715
715
|
"a literal-file formatted count audit incorrectly required destructive host permission"
|
|
716
716
|
);
|
|
717
|
+
const exactReadOnlyMultiPatternSummary =
|
|
718
|
+
"grep -oF -e 'handoff/report.md' -e 'Reviewed master' -e 'ffprobe' report.md | sort | uniq -c";
|
|
719
|
+
const exactReadOnlyMultiPatternSummaryPolicy = evaluateCommandPolicy(
|
|
720
|
+
exactReadOnlyMultiPatternSummary,
|
|
721
|
+
hostWorkspacePolicy
|
|
722
|
+
);
|
|
723
|
+
assert(
|
|
724
|
+
exactReadOnlyMultiPatternSummaryPolicy.allowed &&
|
|
725
|
+
exactReadOnlyMultiPatternSummaryPolicy.category === "read-only" &&
|
|
726
|
+
exactReadOnlyMultiPatternSummaryPolicy.needsNetwork === false &&
|
|
727
|
+
exactReadOnlyMultiPatternSummaryPolicy.writesWorkspace === false,
|
|
728
|
+
"a bounded grep/sort/uniq count summary incorrectly required destructive host permission"
|
|
729
|
+
);
|
|
717
730
|
const exactReadOnlyGitIdentityProbe =
|
|
718
731
|
'git status --short && echo "TOPLEVEL=$(git rev-parse --show-toplevel 2>&1)" && echo "BRANCH=$(git rev-parse --abbrev-ref HEAD 2>&1)"';
|
|
719
732
|
const exactReadOnlyGitIdentityProbePolicy = evaluateCommandPolicy(
|
|
@@ -797,6 +810,9 @@ try {
|
|
|
797
810
|
'f=$(cat README.md); printf "%s\\n" "$f"; for s in one; do echo "$s"; done',
|
|
798
811
|
'f=README.md; for s in one; do n=$(grep -oF -- "$s" "$f" | wc -l | tr -d " "); printf -v target "%s" "$n"; done',
|
|
799
812
|
'f=README.md; for s in one; do n=$(grep -oF -- "$s" "$f" | wc -l | tr -d " "); rm -rf "$n"; done',
|
|
813
|
+
"grep -oF -e 'term' report.md | sort | uniq -c output.txt",
|
|
814
|
+
"grep -oF -e 'term' report.md | sort | uniq -c > output.txt",
|
|
815
|
+
'grep -oF -e "$(cat .aginti/.env)" report.md | sort | uniq -c',
|
|
800
816
|
'for s in \'README.md; rm -rf report.md\'; do echo "$s"; done',
|
|
801
817
|
]) {
|
|
802
818
|
const unsafeLoopSubstitutionPolicy = evaluateCommandPolicy(
|
|
@@ -27,6 +27,13 @@ assert.equal(
|
|
|
27
27
|
false,
|
|
28
28
|
"resolved historical pause was mistaken for current unfinished work"
|
|
29
29
|
);
|
|
30
|
+
assert.equal(
|
|
31
|
+
finishResultClaimsIncompleteWork(
|
|
32
|
+
"The bounded verification (the previously-paused step) passed, and the audit is complete."
|
|
33
|
+
),
|
|
34
|
+
false,
|
|
35
|
+
"a hyphenated resolved historical pause was mistaken for current unfinished work"
|
|
36
|
+
);
|
|
30
37
|
assert.equal(
|
|
31
38
|
finishResultClaimsIncompleteWork(
|
|
32
39
|
"The earlier step was paused and the report is still incomplete."
|
package/src/command-policy.js
CHANGED
|
@@ -96,6 +96,18 @@ function isReadOnlyTrDeleteFilter(command = "") {
|
|
|
96
96
|
return tokens.length === 3 && tokens[0] === "tr" && tokens[1] === "-d";
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function isReadOnlyUniqFilter(command = "") {
|
|
100
|
+
const normalized = stripBenignRedirections(command);
|
|
101
|
+
if (hasActiveShellExpansion(normalized)) return false;
|
|
102
|
+
const tokens = tokenizeShellWords(normalized);
|
|
103
|
+
if (!tokens.length || tokens[0] !== "uniq") return false;
|
|
104
|
+
// Restrict uniq to stdin-only display/count options. Positional operands are
|
|
105
|
+
// intentionally rejected because a second operand is an output file.
|
|
106
|
+
return tokens.slice(1).every((token) =>
|
|
107
|
+
/^(?:-[cdui]+|--(?:count|repeated|unique|ignore-case))$/.test(token)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
99
111
|
function isReadOnlySha256Command(command = "") {
|
|
100
112
|
const normalized = stripBenignRedirections(command);
|
|
101
113
|
if (hasActiveShellExpansion(normalized)) return false;
|
|
@@ -1390,6 +1402,7 @@ function classifySimpleCommand(normalized) {
|
|
|
1390
1402
|
matchAny(READ_ONLY_PATTERNS, commandForPatternMatching) ||
|
|
1391
1403
|
isReadOnlyPrintfCommand(commandForPatternMatching) ||
|
|
1392
1404
|
isReadOnlyTrDeleteFilter(commandForPatternMatching) ||
|
|
1405
|
+
isReadOnlyUniqFilter(commandForPatternMatching) ||
|
|
1393
1406
|
isReadOnlySha256Command(commandForPatternMatching) ||
|
|
1394
1407
|
isReadOnlyFindCommand(normalized) ||
|
|
1395
1408
|
(!hasActiveShellExpansion(benignRedirectCommand) && isReadOnlyShellCondition(benignRedirectCommand))
|
package/src/scs-evidence.js
CHANGED
|
@@ -2957,7 +2957,7 @@ export function finishResultClaimsIncompleteWork(result = "") {
|
|
|
2957
2957
|
""
|
|
2958
2958
|
)
|
|
2959
2959
|
.replace(
|
|
2960
|
-
/\b(?:(?:was|were|had\s+been)\s+)?(?:previously|formerly|earlier|already)\s+(?:paused|pending|incomplete|unfinished)\b/gi,
|
|
2960
|
+
/\b(?:(?:was|were|had\s+been)\s+)?(?:previously|formerly|earlier|already)[\s-]+(?:paused|pending|incomplete|unfinished)(?:[\s-]+(?:step|attempt|run|verification|check|phase|command|process|audit))?\b/gi,
|
|
2961
2961
|
""
|
|
2962
2962
|
)
|
|
2963
2963
|
.replace(/\b(?:not|never)\s+(?:paused|pending|incomplete|unfinished)\b/gi, "")
|