forgedock 1.16.0 → 1.16.2
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/bin/engine/phases.mjs +69 -15
- package/bin/engine/runlog.mjs +21 -3
- package/bin/engine.mjs +43 -7
- package/bin/runner.mjs +21 -2
- package/commands/forge-stats.md +2 -2
- package/commands/orchestrate/phase-1-resolve.md +6 -40
- package/commands/orchestrate/phase-4-execution.md +26 -162
- package/commands/quality-gate.md +12 -80
- package/commands/review-pr-staging.md +67 -301
- package/commands/review-pr.md +150 -752
- package/commands/work-on/build/validate.md +6 -40
- package/commands/work-on/build.md +82 -40
- package/commands/work-on/close.md +7 -22
- package/commands/work-on/decompose.md +8 -24
- package/commands/work-on/investigate.md +18 -29
- package/commands/work-on/remediate.md +38 -147
- package/commands/work-on/review.md +25 -42
- package/commands/work-on.md +13 -63
- package/docs/CONFIG.md +10 -7
- package/docs/RELEASE-NOTES.md +6 -0
- package/docs/WORK-ON-RUNTIME.md +1 -1
- package/docs/spec/forge-protocol-v1.md +1 -1
- package/package.json +1 -1
- package/scripts/check-spec-markers.sh +2 -0
- package/scripts/check-spec-size.sh +47 -27
- package/scripts/check-spec-size.test.sh +46 -3
- package/scripts/diff-size.sh +36 -3
- package/scripts/diff-size.test.sh +47 -0
- package/scripts/forge-root.test.sh +218 -91
- package/scripts/lib/fence-bootstrap.sh +16 -0
- package/scripts/lib/forge-resolve.sh +96 -0
- package/scripts/lib/review-delta-mode.sh +41 -0
- package/scripts/lint-dispatch-prompt.test.sh +3 -3
- package/scripts/remediate-liveness.sh +96 -0
- package/scripts/review-acceptance-gate.sh +132 -0
- package/scripts/review-acceptance-gate.test.sh +90 -0
- package/scripts/review-pr-delta-wiring.test.sh +24 -7
- package/scripts/review-pr-staging-scope.test.sh +14 -7
- package/scripts/spec-no-worktree-script.test.sh +1 -1
package/scripts/diff-size.sh
CHANGED
|
@@ -19,8 +19,14 @@
|
|
|
19
19
|
# lockfiles (package-lock.json yarn.lock pnpm-lock.yaml Cargo.lock poetry.lock uv.lock go.sum Gemfile.lock
|
|
20
20
|
# composer.lock), *.min.*, *.snap, root-anchored dist/ build/ generated/ fixtures/ vendor/, any-depth
|
|
21
21
|
# __generated__/ __snapshots__/
|
|
22
|
-
# Output (stdout, key=value lines): diff_lines=N excluded_lines=M threshold=T over=true|false, then
|
|
22
|
+
# Output (stdout, key=value lines): diff_lines=N excluded_lines=M threshold=T over=true|false, then the cohesion
|
|
23
|
+
# measure new_lines=N test_lines=N cohesive_lines=N cohesive=true|false, then up to 10
|
|
23
24
|
# "top=<lines> <path>" lines, largest first. threshold 0 disables the gate (over=false always).
|
|
25
|
+
# Cohesion (forge#3790) counts only non-excluded files. new_lines = lines in files ADDED by the diff;
|
|
26
|
+
# test_lines = lines in test files (a test/ tests/ __tests__/ directory segment, *.test.* *.spec.* test_* *_test.*
|
|
27
|
+
# by basename); cohesive_lines = the union (a new test file counts once). cohesive=true when diff_lines>0 and
|
|
28
|
+
# cohesive_lines*100 >= 70*diff_lines and diff_lines <= threshold*3/2 (integer math; threshold 0 -> false).
|
|
29
|
+
# Test lines are classified, never discounted from diff_lines.
|
|
24
30
|
# Exit: 0 measured (even when over); 2 usage or git failure with EMPTY stdout (fail closed: unknown is not zero).
|
|
25
31
|
|
|
26
32
|
set -euo pipefail
|
|
@@ -62,7 +68,21 @@ MB="$(git -C "$REPO_PATH" merge-base HEAD "origin/$BASE" 2>/dev/null)" && [ -n "
|
|
|
62
68
|
RAW="$(git -C "$REPO_PATH" diff --cached --numstat --no-renames -z "$MB" -- | tr '\0' '\001')" \
|
|
63
69
|
|| die "git diff against merge base $MB failed"
|
|
64
70
|
|
|
65
|
-
|
|
71
|
+
ADDED="$(git -C "$REPO_PATH" diff --cached --diff-filter=A --no-renames --name-only -z "$MB" -- | tr '\0' '\001')" \
|
|
72
|
+
|| die "git diff --diff-filter=A against merge base $MB failed"
|
|
73
|
+
is_added() { # path -> 0 when the diff adds the file
|
|
74
|
+
case "$ADDED_SET" in *$'\001'"$1"$'\001'*) return 0 ;; esac
|
|
75
|
+
return 1
|
|
76
|
+
}
|
|
77
|
+
is_test() { # path -> 0 when it is a test file (directory segments exact, name patterns on the basename)
|
|
78
|
+
local p="$1" b="${1##*/}"
|
|
79
|
+
case "/$p" in */test/*|*/tests/*|*/__tests__/*) return 0 ;; esac
|
|
80
|
+
case "$b" in *.test.*|*.spec.*|test_*|*_test.*) return 0 ;; esac
|
|
81
|
+
return 1
|
|
82
|
+
}
|
|
83
|
+
ADDED_SET=$'\001'"$ADDED"
|
|
84
|
+
|
|
85
|
+
TOTAL=0; EXCL=0; LIST=""; NEWL=0; TESTL=0; COHL=0
|
|
66
86
|
# -z numstat records are "added<TAB>deleted<TAB>path" separated by NUL (translated to \001 above).
|
|
67
87
|
while IFS= read -r -d $'\001' rec; do
|
|
68
88
|
[ -n "$rec" ] || continue
|
|
@@ -70,7 +90,13 @@ while IFS= read -r -d $'\001' rec; do
|
|
|
70
90
|
case "$a" in ''|*[!0-9]*) a=0 ;; esac
|
|
71
91
|
case "$d" in ''|*[!0-9]*) d=0 ;; esac
|
|
72
92
|
n=$((a + d))
|
|
73
|
-
if excluded "$path"; then EXCL=$((EXCL + n)); else
|
|
93
|
+
if excluded "$path"; then EXCL=$((EXCL + n)); else
|
|
94
|
+
TOTAL=$((TOTAL + n)); LIST="${LIST}${n} ${path}"$'\n'
|
|
95
|
+
isn=0; ist=0
|
|
96
|
+
if is_added "$path"; then isn=1; NEWL=$((NEWL + n)); fi
|
|
97
|
+
if is_test "$path"; then ist=1; TESTL=$((TESTL + n)); fi
|
|
98
|
+
if [ "$isn" = 1 ] || [ "$ist" = 1 ]; then COHL=$((COHL + n)); fi
|
|
99
|
+
fi
|
|
74
100
|
done <<< "$RAW"
|
|
75
101
|
|
|
76
102
|
OVER=false
|
|
@@ -79,6 +105,13 @@ echo "diff_lines=$TOTAL"
|
|
|
79
105
|
echo "excluded_lines=$EXCL"
|
|
80
106
|
echo "threshold=$THRESHOLD"
|
|
81
107
|
echo "over=$OVER"
|
|
108
|
+
COHESIVE=false
|
|
109
|
+
if [ "$THRESHOLD" -gt 0 ] && [ "$TOTAL" -gt 0 ] && [ $((COHL * 100)) -ge $((70 * TOTAL)) ] \
|
|
110
|
+
&& [ $((TOTAL * 2)) -le $((THRESHOLD * 3)) ]; then COHESIVE=true; fi
|
|
111
|
+
echo "new_lines=$NEWL"
|
|
112
|
+
echo "test_lines=$TESTL"
|
|
113
|
+
echo "cohesive_lines=$COHL"
|
|
114
|
+
echo "cohesive=$COHESIVE"
|
|
82
115
|
if [ -n "$LIST" ]; then
|
|
83
116
|
printf '%s' "$LIST" | sort -t' ' -k1,1nr | head -n 10 | sed 's/^/top=/' || true
|
|
84
117
|
fi
|
|
@@ -95,6 +95,53 @@ reset; gen 3 > s.txt; gen 9 > l.txt; git add -A
|
|
|
95
95
|
OUT="$(run)"; FIRST="$(printf '%s\n' "$OUT" | sed -n 's/^top=//p' | head -n1)"
|
|
96
96
|
[ "$FIRST" = "9 l.txt" ] && ok || bad "top ordering (got '$FIRST')"
|
|
97
97
|
|
|
98
|
+
# cohesion (forge#3790): new files + test files >= 70% of diff_lines and diff_lines <= threshold*3/2
|
|
99
|
+
shape() { # all-new fixture: $1=new module lines, $2=new test file lines
|
|
100
|
+
reset; mkdir -p src tests; gen "$1" > src/newmod.py; gen "$2" > tests/test_newmod.py; git add -A
|
|
101
|
+
}
|
|
102
|
+
shape 685 458; OUT="$(run --threshold 1000)"
|
|
103
|
+
check "34844 shape cohesive" "$OUT" cohesive true; check "34844 shape new (test file is also new)" "$OUT" new_lines 1143
|
|
104
|
+
check "34844 shape test" "$OUT" test_lines 458; check "34844 shape cohesive_lines" "$OUT" cohesive_lines 1143
|
|
105
|
+
shape 471 593; OUT="$(run --threshold 1000)"; check "35124 shape cohesive" "$OUT" cohesive true
|
|
106
|
+
shape 516 697; OUT="$(run --threshold 1000)"; check "35143 shape cohesive" "$OUT" cohesive true
|
|
107
|
+
shape 1478 0; OUT="$(run --threshold 1000)"; check "35100 all-new at 1.5x cohesive" "$OUT" cohesive true
|
|
108
|
+
shape 1500 1; OUT="$(run --threshold 1000)"; check "over 1.5x not cohesive" "$OUT" cohesive false
|
|
109
|
+
shape 1000 0; OUT="$(run --threshold 0)"; check "threshold 0 not cohesive" "$OUT" cohesive false
|
|
110
|
+
|
|
111
|
+
# new test file counts once (union), under the threshold still reports cohesive
|
|
112
|
+
reset; mkdir -p tests; gen 50 > tests/test_x.py; git add -A
|
|
113
|
+
OUT="$(run --threshold 1000)"; check "new test file new" "$OUT" new_lines 50; check "new test file test" "$OUT" test_lines 50
|
|
114
|
+
check "new test file union once" "$OUT" cohesive_lines 50
|
|
115
|
+
|
|
116
|
+
# a modified (not added) test file counts as test, not new
|
|
117
|
+
reset; mkdir -p tests; gen 40 > tests/test_old.py
|
|
118
|
+
git add -A; git commit -qm t; git push -q origin feat:staging 2>/dev/null
|
|
119
|
+
gen 10 | sed 's/line/chg/' > tests/test_old.py; gen 30 > src_new.py; git add -A
|
|
120
|
+
OUT="$(run)"; check "modified test new_lines" "$OUT" new_lines 30; check "modified test test_lines" "$OUT" test_lines 50
|
|
121
|
+
check "modified test union" "$OUT" cohesive_lines 80
|
|
122
|
+
git reset -q --hard origin/staging
|
|
123
|
+
|
|
124
|
+
# sprawl: 1300 lines across 15 modified files is not cohesive
|
|
125
|
+
reset; for i in $(seq 1 15); do gen 50 > "m$i.txt"; done; git add -A; git commit -qm m; git push -q origin feat:staging 2>/dev/null
|
|
126
|
+
for i in $(seq 1 15); do gen 43 | sed 's/line/edit/' > "m$i.txt"; done; git add -A
|
|
127
|
+
OUT="$(run --threshold 1000)"
|
|
128
|
+
check "sprawl lines" "$OUT" diff_lines 1395; check "sprawl cohesive_lines" "$OUT" cohesive_lines 0; check "sprawl not cohesive" "$OUT" cohesive false
|
|
129
|
+
git reset -q --hard origin/staging
|
|
130
|
+
|
|
131
|
+
# modified (not added) test file is test-classified; modified non-test stays out; basename patterns, no substring match
|
|
132
|
+
reset; mkdir -p t; gen 10 > latest.sh; gen 10 > contest.txt; gen 10 > a.spec.ts; gen 10 > b_test.go; gen 10 > test_c.py; git add -A
|
|
133
|
+
OUT="$(run)"; check "latest.sh and contest.txt are new, all counted" "$OUT" new_lines 50
|
|
134
|
+
check "test name patterns" "$OUT" test_lines 30
|
|
135
|
+
|
|
136
|
+
# excluded files are not counted by cohesion
|
|
137
|
+
reset; gen 20 > keep.py; gen 900 > package-lock.json; git add -A
|
|
138
|
+
OUT="$(run --threshold 1000)"; check "excluded not in new_lines" "$OUT" new_lines 20
|
|
139
|
+
|
|
140
|
+
# existing key order is unchanged: cohesion keys sit between over= and top=
|
|
141
|
+
reset; gen 3 > s.txt; git add -A
|
|
142
|
+
KEYS="$(run | sed -n 's/^\([a-z_]*\)=.*/\1/p' | tr '\n' ' ')"
|
|
143
|
+
[ "$KEYS" = "diff_lines excluded_lines threshold over new_lines test_lines cohesive_lines cohesive top " ] && ok || bad "key order ($KEYS)"
|
|
144
|
+
|
|
98
145
|
# fail closed: bad repo path, bad base, bad threshold, unknown arg, missing base
|
|
99
146
|
OUT="$(bash "$S" --repo-path "$TMP/nope" --base staging 2>/dev/null)"; rc=$?
|
|
100
147
|
{ [ "$rc" = 2 ] && [ -z "$OUT" ]; } && ok || bad "bad repo path (rc=$rc out='$OUT')"
|