@boyingliu01/xp-gate 0.34.1 → 0.35.0
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/gate-3.sh +46 -2
- package/gate-4.sh +20 -3
- package/hooks/gate-3.sh +46 -2
- package/hooks/gate-4.sh +20 -3
- package/hooks/lib/ccn-ratchet.sh +109 -0
- package/lib/__tests__/doctor-timeout-partial.test.js +79 -0
- package/lib/doctor.js +60 -3
- package/lib/mattpocock-license-verdict.json +1 -1
- package/mock-policy/AGENTS.md +2 -2
- package/mutation/AGENTS.md +2 -2
- package/package.json +1 -1
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +2 -2
- package/plugins/dsh/package.json +1 -1
- package/plugins/dsh/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/dsh/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +2 -2
- package/plugins/opencode/package.json +1 -1
- package/plugins/opencode/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +2 -2
- package/plugins/qoder/plugin.json +1 -1
- package/plugins/qoder/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +2 -2
- package/principles/AGENTS.md +2 -2
- package/skills/delphi-review/AGENTS.md +2 -2
- package/skills/sprint-flow/AGENTS.md +2 -2
- package/skills/test-specification-alignment/AGENTS.md +2 -2
package/gate-3.sh
CHANGED
|
@@ -461,6 +461,52 @@ else
|
|
|
461
461
|
GATE_3_DETAIL="mode=ratchet verifier=MISSING"
|
|
462
462
|
exit 1
|
|
463
463
|
fi
|
|
464
|
+
RATCHET_LIB="$GATE_DIR/lib/ccn-ratchet.sh"
|
|
465
|
+
[ -f "$RATCHET_LIB" ] || RATCHET_LIB="$(git rev-parse --show-toplevel 2>/dev/null)/githooks/lib/ccn-ratchet.sh"
|
|
466
|
+
# #617: grade exactly the population the baseline was written from.
|
|
467
|
+
#
|
|
468
|
+
# The comment below has always said so, but only as a comment: a repo whose
|
|
469
|
+
# baseline came from a narrower scan (a Java-only ccn-report, say) had its
|
|
470
|
+
# vendored minified JS graded anyway, and --csv-verified then disagreed with
|
|
471
|
+
# lizard on single-line code and fail-closed with "could not be
|
|
472
|
+
# span-verified". That BLOCK has no repair: the file has no baseline entry
|
|
473
|
+
# to ratchet, so there is nothing the user could add to clear it.
|
|
474
|
+
#
|
|
475
|
+
# The population filter runs BEFORE verification on purpose. Domain
|
|
476
|
+
# restriction is decidable from the path alone, so asking the expensive
|
|
477
|
+
# span re-derivation about a file that will not be graded anyway only
|
|
478
|
+
# manufactures failures for code the ratchet never claims to cover.
|
|
479
|
+
if [ -f "$RATCHET_LIB" ]; then
|
|
480
|
+
# shellcheck source=/dev/null
|
|
481
|
+
. "$RATCHET_LIB" 2>/dev/null || true
|
|
482
|
+
if declare -F ccn_file_in_population >/dev/null 2>&1; then
|
|
483
|
+
_cc_pop_kept=""
|
|
484
|
+
_cc_pop_skipped=""
|
|
485
|
+
while IFS= read -r _cc_row; do
|
|
486
|
+
[ -n "$_cc_row" ] || continue
|
|
487
|
+
_cc_row_path=$(printf '%s' "$_cc_row" | awk -F, '{print $1}')
|
|
488
|
+
if ccn_file_in_population ".ccn-baseline.json" "$_cc_row_path"; then
|
|
489
|
+
_cc_pop_kept="${_cc_pop_kept}${_cc_row}
|
|
490
|
+
"
|
|
491
|
+
else
|
|
492
|
+
_cc_pop_skipped="${_cc_pop_skipped}${_cc_row_path}
|
|
493
|
+
"
|
|
494
|
+
fi
|
|
495
|
+
done <<CC_POP_EOF
|
|
496
|
+
$CC_CSV
|
|
497
|
+
CC_POP_EOF
|
|
498
|
+
CC_CSV=$(printf '%s' "$_cc_pop_kept")
|
|
499
|
+
if [ -n "$_cc_pop_skipped" ]; then
|
|
500
|
+
_cc_pop_skip_n=$(printf '%s' "$_cc_pop_skipped" | grep -c . || true)
|
|
501
|
+
echo "ℹ️ Gate 3: ${_cc_pop_skip_n:-0} file(s) outside the baseline population — not graded, not ratcheted:"
|
|
502
|
+
printf '%s' "$_cc_pop_skipped" | sed 's/^/ /' | sed -n '1,5p'
|
|
503
|
+
if [ "${_cc_pop_skip_n:-0}" -gt 5 ]; then
|
|
504
|
+
echo " ... and $((_cc_pop_skip_n - 5)) more"
|
|
505
|
+
fi
|
|
506
|
+
echo " (declare or widen the population in .ccn-baseline.json to grade them)"
|
|
507
|
+
fi
|
|
508
|
+
fi
|
|
509
|
+
fi
|
|
464
510
|
if [ -f "$CC_REPORT" ] && command -v node >/dev/null 2>&1; then
|
|
465
511
|
_cc_verify_failed=0
|
|
466
512
|
CC_CSV_VERIFIED=$(printf '%s\n' "$CC_CSV" | node "$CC_REPORT" --csv-verified batch --root "$(git rev-parse --show-toplevel 2>/dev/null)") || _cc_verify_failed=1
|
|
@@ -471,8 +517,6 @@ else
|
|
|
471
517
|
fi
|
|
472
518
|
CC_CSV="$CC_CSV_VERIFIED"
|
|
473
519
|
fi
|
|
474
|
-
RATCHET_LIB="$GATE_DIR/lib/ccn-ratchet.sh"
|
|
475
|
-
[ -f "$RATCHET_LIB" ] || RATCHET_LIB="$(git rev-parse --show-toplevel 2>/dev/null)/githooks/lib/ccn-ratchet.sh"
|
|
476
520
|
# Fail closed when the ratchet library is missing. Sourcing a nonexistent
|
|
477
521
|
# file only prints "No such file or directory" and leaves
|
|
478
522
|
# evaluate_ccn_ratchet undefined; the verdict then came back empty, every
|
package/gate-4.sh
CHANGED
|
@@ -172,9 +172,26 @@ else
|
|
|
172
172
|
rm -f "$PRINCIPLES_STDERR"
|
|
173
173
|
|
|
174
174
|
if [ "$PRINCIPLES_EXIT" -ge 2 ]; then
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
# #661: exit>=2 means the checker did not RUN (crash, module not found,
|
|
176
|
+
# bad invocation). This used to record SKIP, and pre-commit treats SKIP
|
|
177
|
+
# as non-blocking, so a tool failure was absorbed into the green light --
|
|
178
|
+
# the reproduction printed a module-not-found stack trace and then
|
|
179
|
+
# "✅ PASSED - Principles checker (no errors found)".
|
|
180
|
+
#
|
|
181
|
+
# The distinction the gate must keep:
|
|
182
|
+
# - tool NOT INSTALLED -> SKIP is honest; nothing is being claimed.
|
|
183
|
+
# - tool PRESENT, CRASH -> WARN. Not a pass (nothing was checked) and
|
|
184
|
+
# not a silent skip (the user must know their code went unaudited).
|
|
185
|
+
#
|
|
186
|
+
# WARN rather than FAIL on purpose: the commit itself is not necessarily
|
|
187
|
+
# bad, the TOOL is broken, and blocking every commit until node/tsx is
|
|
188
|
+
# repaired would blame the change for an environment fault. What must
|
|
189
|
+
# never happen is the green light.
|
|
190
|
+
echo "⚠️ Principles checker did not run (exit ${PRINCIPLES_EXIT}) — this code is NOT verified."
|
|
191
|
+
echo " Gate 4 cannot claim a pass for a check that never executed."
|
|
192
|
+
echo " Fix the checker invocation above (or run 'npx xp-gate check principles .')."
|
|
193
|
+
echo "⏭️ WARN - Principles check (checker execution error)"
|
|
194
|
+
GATE_4_STATUS="WARN"
|
|
178
195
|
# Consumed by the sourcing parent, not here (see #548).
|
|
179
196
|
# shellcheck disable=SC2034
|
|
180
197
|
GATE_4_REASON="checker_execution_error"
|
package/hooks/gate-3.sh
CHANGED
|
@@ -461,6 +461,52 @@ else
|
|
|
461
461
|
GATE_3_DETAIL="mode=ratchet verifier=MISSING"
|
|
462
462
|
exit 1
|
|
463
463
|
fi
|
|
464
|
+
RATCHET_LIB="$GATE_DIR/lib/ccn-ratchet.sh"
|
|
465
|
+
[ -f "$RATCHET_LIB" ] || RATCHET_LIB="$(git rev-parse --show-toplevel 2>/dev/null)/githooks/lib/ccn-ratchet.sh"
|
|
466
|
+
# #617: grade exactly the population the baseline was written from.
|
|
467
|
+
#
|
|
468
|
+
# The comment below has always said so, but only as a comment: a repo whose
|
|
469
|
+
# baseline came from a narrower scan (a Java-only ccn-report, say) had its
|
|
470
|
+
# vendored minified JS graded anyway, and --csv-verified then disagreed with
|
|
471
|
+
# lizard on single-line code and fail-closed with "could not be
|
|
472
|
+
# span-verified". That BLOCK has no repair: the file has no baseline entry
|
|
473
|
+
# to ratchet, so there is nothing the user could add to clear it.
|
|
474
|
+
#
|
|
475
|
+
# The population filter runs BEFORE verification on purpose. Domain
|
|
476
|
+
# restriction is decidable from the path alone, so asking the expensive
|
|
477
|
+
# span re-derivation about a file that will not be graded anyway only
|
|
478
|
+
# manufactures failures for code the ratchet never claims to cover.
|
|
479
|
+
if [ -f "$RATCHET_LIB" ]; then
|
|
480
|
+
# shellcheck source=/dev/null
|
|
481
|
+
. "$RATCHET_LIB" 2>/dev/null || true
|
|
482
|
+
if declare -F ccn_file_in_population >/dev/null 2>&1; then
|
|
483
|
+
_cc_pop_kept=""
|
|
484
|
+
_cc_pop_skipped=""
|
|
485
|
+
while IFS= read -r _cc_row; do
|
|
486
|
+
[ -n "$_cc_row" ] || continue
|
|
487
|
+
_cc_row_path=$(printf '%s' "$_cc_row" | awk -F, '{print $1}')
|
|
488
|
+
if ccn_file_in_population ".ccn-baseline.json" "$_cc_row_path"; then
|
|
489
|
+
_cc_pop_kept="${_cc_pop_kept}${_cc_row}
|
|
490
|
+
"
|
|
491
|
+
else
|
|
492
|
+
_cc_pop_skipped="${_cc_pop_skipped}${_cc_row_path}
|
|
493
|
+
"
|
|
494
|
+
fi
|
|
495
|
+
done <<CC_POP_EOF
|
|
496
|
+
$CC_CSV
|
|
497
|
+
CC_POP_EOF
|
|
498
|
+
CC_CSV=$(printf '%s' "$_cc_pop_kept")
|
|
499
|
+
if [ -n "$_cc_pop_skipped" ]; then
|
|
500
|
+
_cc_pop_skip_n=$(printf '%s' "$_cc_pop_skipped" | grep -c . || true)
|
|
501
|
+
echo "ℹ️ Gate 3: ${_cc_pop_skip_n:-0} file(s) outside the baseline population — not graded, not ratcheted:"
|
|
502
|
+
printf '%s' "$_cc_pop_skipped" | sed 's/^/ /' | sed -n '1,5p'
|
|
503
|
+
if [ "${_cc_pop_skip_n:-0}" -gt 5 ]; then
|
|
504
|
+
echo " ... and $((_cc_pop_skip_n - 5)) more"
|
|
505
|
+
fi
|
|
506
|
+
echo " (declare or widen the population in .ccn-baseline.json to grade them)"
|
|
507
|
+
fi
|
|
508
|
+
fi
|
|
509
|
+
fi
|
|
464
510
|
if [ -f "$CC_REPORT" ] && command -v node >/dev/null 2>&1; then
|
|
465
511
|
_cc_verify_failed=0
|
|
466
512
|
CC_CSV_VERIFIED=$(printf '%s\n' "$CC_CSV" | node "$CC_REPORT" --csv-verified batch --root "$(git rev-parse --show-toplevel 2>/dev/null)") || _cc_verify_failed=1
|
|
@@ -471,8 +517,6 @@ else
|
|
|
471
517
|
fi
|
|
472
518
|
CC_CSV="$CC_CSV_VERIFIED"
|
|
473
519
|
fi
|
|
474
|
-
RATCHET_LIB="$GATE_DIR/lib/ccn-ratchet.sh"
|
|
475
|
-
[ -f "$RATCHET_LIB" ] || RATCHET_LIB="$(git rev-parse --show-toplevel 2>/dev/null)/githooks/lib/ccn-ratchet.sh"
|
|
476
520
|
# Fail closed when the ratchet library is missing. Sourcing a nonexistent
|
|
477
521
|
# file only prints "No such file or directory" and leaves
|
|
478
522
|
# evaluate_ccn_ratchet undefined; the verdict then came back empty, every
|
package/hooks/gate-4.sh
CHANGED
|
@@ -172,9 +172,26 @@ else
|
|
|
172
172
|
rm -f "$PRINCIPLES_STDERR"
|
|
173
173
|
|
|
174
174
|
if [ "$PRINCIPLES_EXIT" -ge 2 ]; then
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
# #661: exit>=2 means the checker did not RUN (crash, module not found,
|
|
176
|
+
# bad invocation). This used to record SKIP, and pre-commit treats SKIP
|
|
177
|
+
# as non-blocking, so a tool failure was absorbed into the green light --
|
|
178
|
+
# the reproduction printed a module-not-found stack trace and then
|
|
179
|
+
# "✅ PASSED - Principles checker (no errors found)".
|
|
180
|
+
#
|
|
181
|
+
# The distinction the gate must keep:
|
|
182
|
+
# - tool NOT INSTALLED -> SKIP is honest; nothing is being claimed.
|
|
183
|
+
# - tool PRESENT, CRASH -> WARN. Not a pass (nothing was checked) and
|
|
184
|
+
# not a silent skip (the user must know their code went unaudited).
|
|
185
|
+
#
|
|
186
|
+
# WARN rather than FAIL on purpose: the commit itself is not necessarily
|
|
187
|
+
# bad, the TOOL is broken, and blocking every commit until node/tsx is
|
|
188
|
+
# repaired would blame the change for an environment fault. What must
|
|
189
|
+
# never happen is the green light.
|
|
190
|
+
echo "⚠️ Principles checker did not run (exit ${PRINCIPLES_EXIT}) — this code is NOT verified."
|
|
191
|
+
echo " Gate 4 cannot claim a pass for a check that never executed."
|
|
192
|
+
echo " Fix the checker invocation above (or run 'npx xp-gate check principles .')."
|
|
193
|
+
echo "⏭️ WARN - Principles check (checker execution error)"
|
|
194
|
+
GATE_4_STATUS="WARN"
|
|
178
195
|
# Consumed by the sourcing parent, not here (see #548).
|
|
179
196
|
# shellcheck disable=SC2034
|
|
180
197
|
GATE_4_REASON="checker_execution_error"
|
package/hooks/lib/ccn-ratchet.sh
CHANGED
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
# improves we say so and suggest refreshing the baseline, because a stale
|
|
12
12
|
# ceiling invites nobody to finish the job.
|
|
13
13
|
#
|
|
14
|
+
# ── Population (#617) ───────────────────────────────────────────────────────
|
|
15
|
+
# A ratchet is only meaningful over the population it was recorded from. Gate 3
|
|
16
|
+
# grades every extension it recognises; a repo whose baseline came from a
|
|
17
|
+
# narrower scan then reports pre-existing code as "new", which is a false BLOCK
|
|
18
|
+
# no repair can clear — the file has no baseline entry to fix.
|
|
19
|
+
#
|
|
20
|
+
# The baseline may therefore DECLARE its population:
|
|
21
|
+
#
|
|
22
|
+
# { "population": { "roots": ["src/main/java"], "extensions": [".java"] },
|
|
23
|
+
# "entries": { "src/main/java/A.java::f": 4 } }
|
|
24
|
+
#
|
|
25
|
+
# A baseline without that key is LEGACY and is treated as unrestricted, which is
|
|
26
|
+
# exactly the historical behaviour: every baseline already in the field has the
|
|
27
|
+
# flat `{ "path::fn": ccn }` shape, and refusing to load it would break every
|
|
28
|
+
# install on upgrade. Absent metadata must never be read as an empty population
|
|
29
|
+
# -- that would silently grade nothing at all, the opposite failure.
|
|
30
|
+
#
|
|
14
31
|
# Key = "<relative/path>::<functionName>". Rename or move = new key = treated
|
|
15
32
|
# as a new function. That is deliberate: fuzzy matching would hide debt moves.
|
|
16
33
|
# `node scripts/ccn-report.cjs --write-baseline` regenerates the file after a
|
|
@@ -41,6 +58,98 @@
|
|
|
41
58
|
# every row is read as a single field).
|
|
42
59
|
CSV_FS=$'\x1f'
|
|
43
60
|
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
# #617: baseline population.
|
|
63
|
+
#
|
|
64
|
+
# Prints the declared population as `<root>|<ext>|<ext>...` on one line, or
|
|
65
|
+
# NOTHING when the baseline carries no `population` key (legacy => unrestricted).
|
|
66
|
+
# Printing nothing is deliberate: "no declaration" and "empty population" are
|
|
67
|
+
# opposite meanings, and a caller that cannot tell them apart would either grade
|
|
68
|
+
# everything (wrong for a Java-only repo) or nothing (catastrophic -- the ratchet
|
|
69
|
+
# would report a clean run while comparing zero functions).
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
ccn_baseline_population() {
|
|
72
|
+
local _bl="${1:-.ccn-baseline.json}"
|
|
73
|
+
[ -f "$_bl" ] || return 0
|
|
74
|
+
command -v node >/dev/null 2>&1 || return 0
|
|
75
|
+
node -e '
|
|
76
|
+
const fs = require("fs");
|
|
77
|
+
let data;
|
|
78
|
+
try { data = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); }
|
|
79
|
+
catch { process.exit(0); }
|
|
80
|
+
// Legacy shape: a flat map of "path::fn" -> ccn. No declaration.
|
|
81
|
+
if (!data || typeof data !== "object" || !data.population) process.exit(0);
|
|
82
|
+
const pop = data.population || {};
|
|
83
|
+
const roots = Array.isArray(pop.roots) ? pop.roots : [];
|
|
84
|
+
const exts = Array.isArray(pop.extensions) ? pop.extensions : [];
|
|
85
|
+
// A declared-but-empty population is not a legitimate declaration: it would
|
|
86
|
+
// excuse every file. Treat it as no declaration so the gate keeps grading.
|
|
87
|
+
if (roots.length === 0 && exts.length === 0) process.exit(0);
|
|
88
|
+
// One line: "<roots csv>|<exts csv>". Callers split on the single pipe.
|
|
89
|
+
process.stdout.write(roots.join(",") + "|" + exts.join(","));
|
|
90
|
+
' "$_bl" 2>/dev/null
|
|
91
|
+
return 0
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# #617: is this file inside the baseline's declared population?
|
|
96
|
+
#
|
|
97
|
+
# Returns 0 when the file may be graded, 1 when it is outside the population.
|
|
98
|
+
# A legacy baseline (no declaration) permits everything, preserving the
|
|
99
|
+
# behaviour every existing install already relies on.
|
|
100
|
+
#
|
|
101
|
+
# Both axes are ANDed only when both are declared; a baseline declaring just
|
|
102
|
+
# roots (or just extensions) narrows on that axis alone.
|
|
103
|
+
# ---------------------------------------------------------------------------
|
|
104
|
+
ccn_file_in_population() {
|
|
105
|
+
local _bl="${1:-.ccn-baseline.json}"
|
|
106
|
+
local _file="${2:-}"
|
|
107
|
+
[ -n "$_file" ] || return 1
|
|
108
|
+
|
|
109
|
+
local _pop
|
|
110
|
+
_pop=$(ccn_baseline_population "$_bl")
|
|
111
|
+
# No declaration => unrestricted (legacy baseline).
|
|
112
|
+
[ -n "$_pop" ] || return 0
|
|
113
|
+
|
|
114
|
+
local _roots="${_pop%%|*}"
|
|
115
|
+
local _exts="${_pop#*|}"
|
|
116
|
+
# Normalise separators so a Windows path and a POSIX path compare the same way.
|
|
117
|
+
# sed, not `tr '\' '/'`: a lone backslash is a portability trap in tr's SET
|
|
118
|
+
# argument (GNU tr warns "unescaped backslash at end of string" and MSYS tr
|
|
119
|
+
# behaviour differs), while the sed regex below is unambiguous everywhere.
|
|
120
|
+
_norm=$(printf '%s' "$_file" | sed 's|\\|/|g')
|
|
121
|
+
|
|
122
|
+
if [ -n "$_roots" ]; then
|
|
123
|
+
local _hit=0 _r
|
|
124
|
+
local _oldifs="$IFS"
|
|
125
|
+
IFS=','
|
|
126
|
+
for _r in $_roots; do
|
|
127
|
+
IFS="$_oldifs"
|
|
128
|
+
case "$_norm" in
|
|
129
|
+
"$_r"|"$_r"/*) _hit=1; break ;;
|
|
130
|
+
esac
|
|
131
|
+
done
|
|
132
|
+
IFS="$_oldifs"
|
|
133
|
+
[ "$_hit" -eq 1 ] || return 1
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [ -n "$_exts" ]; then
|
|
137
|
+
local _match=0 _e
|
|
138
|
+
local _oldifs2="$IFS"
|
|
139
|
+
IFS=','
|
|
140
|
+
for _e in $_exts; do
|
|
141
|
+
IFS="$_oldifs2"
|
|
142
|
+
case "$_norm" in
|
|
143
|
+
*"$_e") _match=1; break ;;
|
|
144
|
+
esac
|
|
145
|
+
done
|
|
146
|
+
IFS="$_oldifs2"
|
|
147
|
+
[ "$_match" -eq 1 ] || return 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
return 0
|
|
151
|
+
}
|
|
152
|
+
|
|
44
153
|
csv_to_unit_separated() {
|
|
45
154
|
awk '
|
|
46
155
|
function emit(line, cur, i, ch, q, nf) {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @test REQ-629
|
|
3
|
+
* @intent `xp-gate doctor` is non-deterministic on Windows. Against an identical,
|
|
4
|
+
* freshly-installed, fully healthy installation it printed
|
|
5
|
+
* "All checks passed" on one run and "Timed out after 10s — some checks
|
|
6
|
+
* incomplete" on the next two. The timeout is a deliberate safety net
|
|
7
|
+
* (#348, "43s on Windows"); the defect is what happens when it fires.
|
|
8
|
+
*
|
|
9
|
+
* `Promise.race` discarded the entire `diagnoseAsync()` result and
|
|
10
|
+
* substituted a single placeholder check, so everything that had already
|
|
11
|
+
* finished was thrown away. Consequence: doctor can report LESS
|
|
12
|
+
* information the LONGER it runs — the opposite of what a diagnostic
|
|
13
|
+
* should do — and a WARN from the timeout made the skills section vanish
|
|
14
|
+
* entirely, so tooling that scrapes `Skill:.*Up to date` read 0/12.
|
|
15
|
+
*
|
|
16
|
+
* The fix: reach a verdict at the deadline (never hang — #348 stays fixed)
|
|
17
|
+
* but keep whatever finished. A diagnostic that says "these 9 checks
|
|
18
|
+
* passed, 2 did not report in time" is strictly more useful than one that
|
|
19
|
+
* says "timed out".
|
|
20
|
+
*
|
|
21
|
+
* The tests below pin the merge semantics directly rather than waiting on
|
|
22
|
+
* a real 10s timer: the behaviour that matters is "partial results are
|
|
23
|
+
* preserved and reported as partial", not the clock.
|
|
24
|
+
* @covers AC-670-43, AC-670-44, AC-670-45
|
|
25
|
+
*/
|
|
26
|
+
'use strict';
|
|
27
|
+
|
|
28
|
+
// describe/it/expect are vitest globals in this repo's config; requiring them from
|
|
29
|
+
// 'vitest' fails because this file is CommonJS. (Hooks are not needed here.)
|
|
30
|
+
|
|
31
|
+
/** A completed check, shaped like diagnoseAsync()'s output. */
|
|
32
|
+
function check(name, status) {
|
|
33
|
+
return { name, status, detail: `${name} detail` };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('doctor keeps completed checks when the global timeout fires (#629)', () => {
|
|
37
|
+
it('AC-670-43: completed checks are merged with the timeout notice, not replaced', () => {
|
|
38
|
+
const { mergeTimedOutDiagnosis } = require('../doctor');
|
|
39
|
+
expect(typeof mergeTimedOutDiagnosis).toBe('function');
|
|
40
|
+
|
|
41
|
+
const completed = {
|
|
42
|
+
checks: [check('Hooks', 'PASS'), check('Adapters', 'PASS'), check('Skills', 'WARN')],
|
|
43
|
+
issues: 1,
|
|
44
|
+
};
|
|
45
|
+
const merged = mergeTimedOutDiagnosis(completed, ['Gate env', 'OpenCode TUI']);
|
|
46
|
+
|
|
47
|
+
// Nothing that finished may be dropped -- that is the whole defect.
|
|
48
|
+
for (const name of ['Hooks', 'Adapters', 'Skills']) {
|
|
49
|
+
expect(merged.checks.map((c) => c.name)).toContain(name);
|
|
50
|
+
}
|
|
51
|
+
// The deadline itself is still reported, and still not a pass.
|
|
52
|
+
const notice = merged.checks.find((c) => c.name === 'Diagnosis');
|
|
53
|
+
expect(notice).toBeDefined();
|
|
54
|
+
expect(notice.status).toBe('WARN');
|
|
55
|
+
// Named individually, so the reader knows which surface is unknown.
|
|
56
|
+
expect(notice.detail).toContain('Gate env');
|
|
57
|
+
expect(notice.detail).toContain('OpenCode TUI');
|
|
58
|
+
expect(merged.timedOut).toBe(true);
|
|
59
|
+
// A partial run is never clean.
|
|
60
|
+
expect(merged.issues).toBeGreaterThanOrEqual(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('AC-670-44: an empty partial result still yields the honest timeout notice', () => {
|
|
64
|
+
const { mergeTimedOutDiagnosis } = require('../doctor');
|
|
65
|
+
const merged = mergeTimedOutDiagnosis({ checks: [], issues: 0 }, ['Gate env']);
|
|
66
|
+
expect(merged.checks).toHaveLength(1);
|
|
67
|
+
expect(merged.checks[0].name).toBe('Diagnosis');
|
|
68
|
+
expect(merged.timedOut).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('AC-670-45: nothing that already reported is ever lost, and a real issue count survives', () => {
|
|
72
|
+
const { mergeTimedOutDiagnosis } = require('../doctor');
|
|
73
|
+
const completed = { checks: [check('Hooks', 'FAIL'), check('Templates', 'PASS')], issues: 4 };
|
|
74
|
+
const merged = mergeTimedOutDiagnosis(completed, []);
|
|
75
|
+
// Pre-existing issues are not reset by the timeout.
|
|
76
|
+
expect(merged.issues).toBeGreaterThanOrEqual(4);
|
|
77
|
+
expect(merged.checks.map((c) => c.name)).toEqual(expect.arrayContaining(['Hooks', 'Templates']));
|
|
78
|
+
});
|
|
79
|
+
});
|
package/lib/doctor.js
CHANGED
|
@@ -80,6 +80,38 @@ const EXEC_TIMEOUT_MS = 1500;
|
|
|
80
80
|
*/
|
|
81
81
|
const GLOBAL_DIAGNOSIS_TIMEOUT_MS = 10000;
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Merge a timed-out partial diagnosis into one honest verdict (#629).
|
|
85
|
+
*
|
|
86
|
+
* `doctor`'s global timeout (#348) exists so the command never hangs, but the
|
|
87
|
+
* original handler threw away the entire `diagnoseAsync()` result and substituted
|
|
88
|
+
* a single placeholder check. Against an identical healthy install that made the
|
|
89
|
+
* SAME command print "All checks passed" or "Timed out after 10s" depending on
|
|
90
|
+
* machine load, and a timed-out run reported 0 installed skills — doctor giving
|
|
91
|
+
* LESS information the LONGER it runs is the opposite of a diagnostic.
|
|
92
|
+
*
|
|
93
|
+
* Keeps every completed check, adds ONE Diagnosis notice naming what did not
|
|
94
|
+
* report, and never lets a partial run read as clean (#495).
|
|
95
|
+
*
|
|
96
|
+
* @param {{checks?: Array, issues?: number}} partial checks finished before the deadline
|
|
97
|
+
* @param {string[]} pending names of surfaces that did not report in time
|
|
98
|
+
*/
|
|
99
|
+
function mergeTimedOutDiagnosis(partial, pending) {
|
|
100
|
+
const completed = (partial && Array.isArray(partial.checks)) ? partial.checks : [];
|
|
101
|
+
const inherited = (partial && Number.isFinite(partial.issues)) ? partial.issues : 0;
|
|
102
|
+
const pendingNames = Array.isArray(pending) ? pending.filter(Boolean) : [];
|
|
103
|
+
const detail = pendingNames.length > 0
|
|
104
|
+
? `Timed out after ${GLOBAL_DIAGNOSIS_TIMEOUT_MS / 1000}s — did not report in time: ${pendingNames.join(', ')}`
|
|
105
|
+
: `Timed out after ${GLOBAL_DIAGNOSIS_TIMEOUT_MS / 1000}s — some checks incomplete`;
|
|
106
|
+
return {
|
|
107
|
+
checks: [...completed, { name: 'Diagnosis', status: 'WARN', detail }],
|
|
108
|
+
// A partial run is never clean, and a real issue count is never reset.
|
|
109
|
+
issues: Math.max(inherited, 1),
|
|
110
|
+
timedOut: true,
|
|
111
|
+
completedCheckCount: completed.length,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
83
115
|
/**
|
|
84
116
|
* Fixed attribution text for the WorkBuddy-desktop sandbox restriction (#525).
|
|
85
117
|
*
|
|
@@ -1605,9 +1637,17 @@ async function checkAdapters(checks, mode, gitDirPromise) {
|
|
|
1605
1637
|
* D) Env + CLI tools — fully independent, run IN PARALLEL
|
|
1606
1638
|
* E) TUI + Skills — independent, run IN PARALLEL
|
|
1607
1639
|
*/
|
|
1608
|
-
async function diagnoseAsync(refreshEnv = false) {
|
|
1640
|
+
async function diagnoseAsync(refreshEnv = false, progress = null) {
|
|
1641
|
+
// #629: `progress` is a live view of the checks completed so far. The global
|
|
1642
|
+
// timeout used to discard everything diagnoseAsync had already produced; with a
|
|
1643
|
+
// shared sink, a deadline can report "these finished, those did not" instead of
|
|
1644
|
+
// replacing the whole diagnosis with a placeholder.
|
|
1609
1645
|
const checks = [];
|
|
1610
1646
|
let issues = 0;
|
|
1647
|
+
if (progress) {
|
|
1648
|
+
progress.checks = checks;
|
|
1649
|
+
progress.getIssues = () => issues;
|
|
1650
|
+
}
|
|
1611
1651
|
|
|
1612
1652
|
// Spawn capability probe FIRST (sync, no config dependency) — #525: it must
|
|
1613
1653
|
// report even when the config early-exits below, and its WARN (environmental,
|
|
@@ -2869,10 +2909,26 @@ async function doctor(args) {
|
|
|
2869
2909
|
|
|
2870
2910
|
// Global timeout wrapper — ensures doctor completes within GLOBAL_DIAGNOSIS_TIMEOUT_MS
|
|
2871
2911
|
// even if network/subprocess checks stack up (fix #348: 43s on Windows).
|
|
2872
|
-
|
|
2912
|
+
// #629: give diagnoseAsync a live sink so a deadline can keep what finished.
|
|
2913
|
+
// Without it, `Promise.race` discarded the entire diagnosis -- so the SAME
|
|
2914
|
+
// healthy install reported different results run to run, and a timed-out run
|
|
2915
|
+
// lost the skills section entirely (scrapers read 0/12 installed skills).
|
|
2916
|
+
const progress = { checks: [], getIssues: () => 0 };
|
|
2917
|
+
const diagnosisPromise = diagnoseAsync(refreshEnv, progress);
|
|
2873
2918
|
let diagnosisTimer = null;
|
|
2874
2919
|
const timeoutPromise = new Promise((resolve) => {
|
|
2875
|
-
diagnosisTimer = setTimeout(() =>
|
|
2920
|
+
diagnosisTimer = setTimeout(() => {
|
|
2921
|
+
const completed = Array.isArray(progress.checks) ? progress.checks : [];
|
|
2922
|
+
const reported = new Set(completed.map((c) => c && c.name));
|
|
2923
|
+
// Name the surfaces that did NOT report, so the reader knows exactly which
|
|
2924
|
+
// conclusions are missing rather than just "something timed out".
|
|
2925
|
+
const pending = ['Hooks', 'Adapters', 'Skills', 'Gate env', 'OpenCode TUI']
|
|
2926
|
+
.filter((name) => !reported.has(name));
|
|
2927
|
+
resolve(mergeTimedOutDiagnosis(
|
|
2928
|
+
{ checks: completed, issues: progress.getIssues() },
|
|
2929
|
+
pending,
|
|
2930
|
+
));
|
|
2931
|
+
}, GLOBAL_DIAGNOSIS_TIMEOUT_MS);
|
|
2876
2932
|
});
|
|
2877
2933
|
const { checks, issues: diagnosedIssues, timedOut } = await Promise.race([
|
|
2878
2934
|
diagnosisPromise.then(r => ({ ...r, timedOut: false })),
|
|
@@ -3349,6 +3405,7 @@ module.exports = {
|
|
|
3349
3405
|
readTuiJson,
|
|
3350
3406
|
formatDoctorJson,
|
|
3351
3407
|
diagnoseHookDrift,
|
|
3408
|
+
mergeTimedOutDiagnosis,
|
|
3352
3409
|
classifyHooksDir,
|
|
3353
3410
|
syncGlobalHooksFromRepo,
|
|
3354
3411
|
diagnoseModuleDrift,
|
package/mock-policy/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MOCK-POLICY KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Mock layering policy enforcement — Gate M3 of pre-push hook. Ensures integration tests use real implementations for internal dependencies, mock external dependencies, and annotate pending mocks with removal plans. Combines project scope scanning, mock decision engine, and per-file validation into a single pipeline.
|
package/mutation/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MUTATION KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**Gate M** (incremental mutation testing) + **Gate M2** helpers (test-layer detection used by `src/mock-policy/`). Pre-push quality gate. TypeScript-only; uses Stryker.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xp-gate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"displayName": "XP-Gate",
|
|
5
5
|
"description": "Extreme Programming quality gates + AI workflow skills for Claude Code. Includes 12 pre-commit gates (Gate 0-11), 8 pre-push gates, Sprint Flow (6 phases), and Delphi multi-expert review (>=90% consensus).",
|
|
6
6
|
"author": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|
package/plugins/dsh/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boyingliu01/dsh-plugin-xp-gate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "XP-Gate deterministic quality gates + AI workflow skills as a DeepSeek Harness (DSH) native plugin: gate-check / gate-principles / gate-arch tools + 12 SKILL.md skills",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xp-gate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"displayName": "XP-Gate",
|
|
5
5
|
"description": "Extreme Programming quality gates + AI workflow skills for Qoder. Includes 12 pre-commit gates (Gate 0-11), 8 pre-push gates, Sprint Flow (6 phases), and Delphi multi-expert review (>=90% consensus).",
|
|
6
6
|
"author": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|
package/principles/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# PRINCIPLES CHECKER MODULE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Clean Code & SOLID principles checker — **Gate 4** of pre-commit. 14 rules × 9 language adapters, SARIF 2.1.0 output. Houses the **Boy Scout Rule** enforcement engine (Gate 6) and warning-baseline storage.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** c8a73b2a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.35.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|