@boyingliu01/xp-gate 0.30.1 → 0.30.3
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/adapters/iac.sh +45 -4
- package/adapters/java.sh +82 -16
- package/adapters/powershell.sh +70 -9
- package/bin/xp-gate.js +8 -0
- package/gate-10.sh +32 -2
- package/gate-3.sh +47 -6
- package/gate-4.sh +12 -0
- package/gate-7.sh +4 -0
- package/hooks/gate-10.sh +32 -2
- package/hooks/gate-3.sh +47 -6
- package/hooks/gate-4.sh +12 -0
- package/hooks/gate-7.sh +4 -0
- package/hooks/hook-module-resolution.sh +14 -0
- package/hooks/lib/coverage-total.sh +1 -1
- package/hooks/pre-commit +138 -17
- package/hooks/pre-push +97 -6
- package/hooks/sprint-gate.sh +81 -2
- package/lib/__tests__/crap-cli.test.js +76 -0
- package/lib/__tests__/crap.test.js +137 -0
- package/lib/__tests__/hook-health.test.js +85 -0
- package/lib/__tests__/retro-gate-m.test.js +144 -0
- package/lib/coverage-total.sh +92 -0
- package/lib/crap-cli.js +191 -0
- package/lib/crap.js +196 -0
- package/lib/doctor.js +44 -0
- package/lib/hook-health.js +121 -0
- package/lib/mattpocock-license-verdict.json +1 -1
- package/lib/retro.js +139 -2
- 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/sprint-gate.sh +81 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook file health inspection (#546).
|
|
3
|
+
*
|
|
4
|
+
* `xp-gate doctor` used to answer one question about an installed hook: does the
|
|
5
|
+
* file exist and does it carry the xp-gate signature. A hook can satisfy both
|
|
6
|
+
* and still be unrunnable — #546 was a pre-commit that had been rewritten with
|
|
7
|
+
* CRLF line endings, which fails every commit while doctor reported ✓.
|
|
8
|
+
*
|
|
9
|
+
* Two independent failure modes are checked here:
|
|
10
|
+
* - CRLF line endings: git runs hooks through bash, and a stray \r makes the
|
|
11
|
+
* parser choke at a line number far from the real cause (the reported line
|
|
12
|
+
* is wherever the multi-line construct that swallowed the \r began).
|
|
13
|
+
* - Unparseable syntax: a truncated or mangled write leaves a hook that
|
|
14
|
+
* exists but cannot run.
|
|
15
|
+
*
|
|
16
|
+
* Both are reported per file rather than as a single boolean, because the
|
|
17
|
+
* operator needs to know which one happened: CRLF has a mechanical fix, a
|
|
18
|
+
* syntax error does not.
|
|
19
|
+
*/
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const path = require('path');
|
|
22
|
+
const { spawnSync } = require('child_process');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Locate a bash binary without assuming it is on PATH under that exact name.
|
|
26
|
+
* @returns {string|null} Path or bare command name, null when none found
|
|
27
|
+
*/
|
|
28
|
+
function findBash() {
|
|
29
|
+
const candidates = ['bash'];
|
|
30
|
+
if (process.platform === 'win32') {
|
|
31
|
+
// Git for Windows ships bash outside PATH far more often than inside it.
|
|
32
|
+
const pf = process.env.ProgramFiles || 'C:\\Program Files';
|
|
33
|
+
const pf86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)';
|
|
34
|
+
const local = process.env.LOCALAPPDATA;
|
|
35
|
+
if (local) candidates.push(path.join(local, 'Programs', 'Git', 'bin', 'bash.exe'));
|
|
36
|
+
candidates.push(path.join(pf, 'Git', 'bin', 'bash.exe'));
|
|
37
|
+
candidates.push(path.join(pf86, 'Git', 'bin', 'bash.exe'));
|
|
38
|
+
candidates.push(path.join(pf, 'Git', 'usr', 'bin', 'bash.exe'));
|
|
39
|
+
}
|
|
40
|
+
for (const c of candidates) {
|
|
41
|
+
if (path.isAbsolute(c)) {
|
|
42
|
+
if (fs.existsSync(c)) return c;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const probe = spawnSync(c, ['--version'], { encoding: 'utf8', timeout: 10000 });
|
|
46
|
+
if (!probe.error && probe.status === 0) return c;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Count lines that end with CRLF.
|
|
53
|
+
* @param {string} text - File content
|
|
54
|
+
* @returns {number} Number of CRLF-terminated lines
|
|
55
|
+
*/
|
|
56
|
+
function countCrlfLines(text) {
|
|
57
|
+
const matches = text.match(/\r\n/g);
|
|
58
|
+
return matches ? matches.length : 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Ask bash whether it can parse the file (`bash -n`).
|
|
63
|
+
* @param {string} filePath - Hook to check
|
|
64
|
+
* @param {string} bashBin - Resolved bash binary
|
|
65
|
+
* @returns {{checked: boolean, ok: boolean, detail: string}} Parse verdict
|
|
66
|
+
*/
|
|
67
|
+
function checkParseable(filePath, bashBin) {
|
|
68
|
+
if (!bashBin) return { checked: false, ok: true, detail: 'bash not found; parse check skipped' };
|
|
69
|
+
const res = spawnSync(bashBin, ['-n', filePath], { encoding: 'utf8', timeout: 30000 });
|
|
70
|
+
if (res.error) return { checked: false, ok: true, detail: `bash -n could not run: ${res.error.message}` };
|
|
71
|
+
if (res.status === 0) return { checked: true, ok: true, detail: 'parses' };
|
|
72
|
+
// bash reports the first syntax error it hits. Under CRLF that line number is
|
|
73
|
+
// unreliable, which is exactly why the CRLF count is reported alongside.
|
|
74
|
+
const firstLine = String(res.stderr || '').split('\n').find(l => l.trim()) || `exit ${res.status}`;
|
|
75
|
+
return { checked: true, ok: false, detail: firstLine.trim() };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Inspect one hook file for the conditions that make git unable to run it.
|
|
80
|
+
* @param {string} filePath - Hook path
|
|
81
|
+
* @param {{bashBin?: string|null, parseCheck?: boolean}} [options] - Overrides
|
|
82
|
+
* @returns {{ok: boolean, crlfLines: number, parseable: boolean, problems: string[]}}
|
|
83
|
+
*/
|
|
84
|
+
function inspectHookFile(filePath, options = {}) {
|
|
85
|
+
const problems = [];
|
|
86
|
+
|
|
87
|
+
if (!fs.existsSync(filePath)) {
|
|
88
|
+
return { ok: false, crlfLines: 0, parseable: false, problems: [`hook file is missing: ${filePath}`] };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let text = '';
|
|
92
|
+
try {
|
|
93
|
+
text = fs.readFileSync(filePath, 'latin1');
|
|
94
|
+
} catch (err) {
|
|
95
|
+
return { ok: false, crlfLines: 0, parseable: false, problems: [`hook file is unreadable: ${err.message}`] };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const crlfLines = countCrlfLines(text);
|
|
99
|
+
if (crlfLines > 0) {
|
|
100
|
+
problems.push(
|
|
101
|
+
`hook has CRLF line endings (${crlfLines} line(s)) — bash will fail to parse it; ` +
|
|
102
|
+
'run `tr -d "\\r" < hook > hook.fixed && mv hook.fixed hook`'
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// A CRLF hit already answers the question this probe exists to answer, and
|
|
107
|
+
// the probe is the expensive half. Callers can also opt out for stubs.
|
|
108
|
+
if (crlfLines > 0 || options.parseCheck === false) {
|
|
109
|
+
return { ok: problems.length === 0, crlfLines, parseable: crlfLines === 0, problems };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const bashBin = options.bashBin !== undefined ? options.bashBin : findBash();
|
|
113
|
+
const parsed = checkParseable(filePath, bashBin);
|
|
114
|
+
if (!parsed.ok) {
|
|
115
|
+
problems.push(`hook is not parseable by bash: ${parsed.detail}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { ok: problems.length === 0, crlfLines, parseable: parsed.ok, problems };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = { inspectHookFile, findBash, countCrlfLines };
|
package/lib/retro.js
CHANGED
|
@@ -116,13 +116,133 @@ function readSprintHistory(dir, sprintFilter) {
|
|
|
116
116
|
return results;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Read Gate M rows out of the pre-push journals (#404 P1-3).
|
|
121
|
+
*
|
|
122
|
+
* Gate M lives in `.xp-gate/reports/pre-push/*.json`, not in the audit log: the
|
|
123
|
+
* audit log only sees the 12 pre-commit gates. Reading it here is the only way
|
|
124
|
+
* a retrospective can say anything about mutation testing at all.
|
|
125
|
+
*
|
|
126
|
+
* @param {string} dir - Repository root
|
|
127
|
+
* @returns {object[]} One entry per journal that carried a Gate M row
|
|
128
|
+
*/
|
|
129
|
+
function readGateMRuns(dir) {
|
|
130
|
+
const journalDir = path.join(dir, '.xp-gate', 'reports', 'pre-push');
|
|
131
|
+
if (!fs.existsSync(journalDir)) return [];
|
|
132
|
+
|
|
133
|
+
const runs = [];
|
|
134
|
+
for (const f of fs.readdirSync(journalDir).filter(n => n.endsWith('.json'))) {
|
|
135
|
+
let journal;
|
|
136
|
+
try {
|
|
137
|
+
journal = JSON.parse(fs.readFileSync(path.join(journalDir, f), 'utf8'));
|
|
138
|
+
} catch {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const rows = Array.isArray(journal.gates) ? journal.gates : [];
|
|
142
|
+
// The TS gate is "M"; the per-language variants are M-Python/M-Go/... and
|
|
143
|
+
// are counted separately by the caller when it wants them.
|
|
144
|
+
const row = rows.find(r => r && r.id === 'M');
|
|
145
|
+
if (!row) continue;
|
|
146
|
+
const details = row.details && typeof row.details === 'object' ? row.details : {};
|
|
147
|
+
runs.push({
|
|
148
|
+
timestamp: journal.timestamp || '',
|
|
149
|
+
status: row.status || 'UNKNOWN',
|
|
150
|
+
skipReason: details.skip_reason || '',
|
|
151
|
+
durationMs: details.duration_ms != null && details.duration_ms !== '' ? Number(details.duration_ms) : null,
|
|
152
|
+
score: details.mutation_score != null && details.mutation_score !== '' ? Number(details.mutation_score) : null,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return runs;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Summarise Gate M runs for the report.
|
|
160
|
+
* @param {object[]} runs - Output of readGateMRuns
|
|
161
|
+
* @returns {object} Counts plus measured score/duration samples
|
|
162
|
+
*/
|
|
163
|
+
function summariseGateM(runs) {
|
|
164
|
+
const total = runs.length;
|
|
165
|
+
const skipped = runs.filter(r => r.status === 'SKIP').length;
|
|
166
|
+
const timedOut = runs.filter(r => r.status === 'TIMEOUT').length;
|
|
167
|
+
// The journals write "BLOCKED" (pre-push's literal), not "BLOCK". Matching
|
|
168
|
+
// only one spelling silently reported 5 real mutation blocks as zero, which
|
|
169
|
+
// is the exact failure mode this whole issue is about.
|
|
170
|
+
const blocked = runs.filter(r => r.status === 'BLOCK' || r.status === 'BLOCKED').length;
|
|
171
|
+
const passed = runs.filter(r => r.status === 'PASS').length;
|
|
172
|
+
// A journal row that predates the #404 fix has an empty details object; that
|
|
173
|
+
// is "this run told us nothing", not "this run scored zero".
|
|
174
|
+
const measured = runs.filter(r => Number.isFinite(r.score));
|
|
175
|
+
const durations = runs.filter(r => Number.isFinite(r.durationMs)).map(r => r.durationMs);
|
|
176
|
+
const reasons = {};
|
|
177
|
+
for (const r of runs) {
|
|
178
|
+
if (r.status !== 'SKIP' && r.status !== 'TIMEOUT') continue;
|
|
179
|
+
const key = r.skipReason || '(no reason recorded)';
|
|
180
|
+
reasons[key] = (reasons[key] || 0) + 1;
|
|
181
|
+
}
|
|
182
|
+
return { total, skipped, timedOut, blocked, passed, measured, durations, reasons };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Build the Gate M retrospective section.
|
|
187
|
+
* @param {object[]} runs - Output of readGateMRuns
|
|
188
|
+
* @returns {string[]} Markdown lines
|
|
189
|
+
*/
|
|
190
|
+
function buildGateMSection(runs) {
|
|
191
|
+
const L = [];
|
|
192
|
+
L.push('## Gate M (Mutation Testing) (#404)');
|
|
193
|
+
|
|
194
|
+
if (runs.length === 0) {
|
|
195
|
+
L.push('No pre-push journals found — Gate M has never been measured here.');
|
|
196
|
+
L.push('');
|
|
197
|
+
return L;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const s = summariseGateM(runs);
|
|
201
|
+
const pct = n => `${((n / s.total) * 100).toFixed(1)}%`;
|
|
202
|
+
|
|
203
|
+
L.push(`- Runs recorded: ${s.total} (PASS ${s.passed}, BLOCK ${s.blocked}, TIMEOUT ${s.timedOut}, SKIP ${s.skipped})`);
|
|
204
|
+
L.push(`- Skip rate: ${pct(s.skipped)}; timeout rate: ${pct(s.timedOut)}`);
|
|
205
|
+
|
|
206
|
+
if (s.measured.length > 0) {
|
|
207
|
+
const scores = s.measured.map(r => r.score).sort((a, b) => a - b);
|
|
208
|
+
const median = scores[Math.floor(scores.length / 2)];
|
|
209
|
+
const p10 = scores[Math.floor(scores.length * 0.1)];
|
|
210
|
+
const p90 = scores[Math.min(scores.length - 1, Math.floor(scores.length * 0.9))];
|
|
211
|
+
L.push(`- Mutation score over ${scores.length} measured run(s): median ${median.toFixed(1)}%, p10 ${p10.toFixed(1)}%, p90 ${p90.toFixed(1)}%`);
|
|
212
|
+
} else {
|
|
213
|
+
// Printing "median 0%" or omitting the line would both read as a healthy
|
|
214
|
+
// result. There is no sample, and the report must say exactly that.
|
|
215
|
+
L.push('- Mutation score: no measured runs — the score has never been recorded in this window.');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (s.durations.length > 0) {
|
|
219
|
+
const sorted = [...s.durations].sort((a, b) => a - b);
|
|
220
|
+
const p50 = sorted[Math.floor(sorted.length / 2)];
|
|
221
|
+
const max = sorted[sorted.length - 1];
|
|
222
|
+
L.push(`- Duration over ${sorted.length} measured run(s): p50 ${p50}ms, max ${max}ms`);
|
|
223
|
+
} else {
|
|
224
|
+
L.push('- Duration: no measured runs.');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const reasonKeys = Object.keys(s.reasons);
|
|
228
|
+
if (reasonKeys.length > 0) {
|
|
229
|
+
L.push('- Why it did not run:');
|
|
230
|
+
for (const key of reasonKeys.sort((a, b) => s.reasons[b] - s.reasons[a])) {
|
|
231
|
+
L.push(` - ${key}: ${s.reasons[key]}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
L.push('');
|
|
236
|
+
return L;
|
|
237
|
+
}
|
|
238
|
+
|
|
119
239
|
/**
|
|
120
240
|
* Build the Markdown retrospective report.
|
|
121
241
|
* @param {object} opts - Report data
|
|
122
242
|
* @returns {string} Markdown report
|
|
123
243
|
*/
|
|
124
244
|
function buildReport(opts) {
|
|
125
|
-
const { days, commits, audit, quality, sprints } = opts;
|
|
245
|
+
const { days, commits, audit, quality, sprints, gateMRuns = [] } = opts;
|
|
126
246
|
const now = new Date();
|
|
127
247
|
const start = new Date(now.getTime() - days * 86400000);
|
|
128
248
|
const L = [];
|
|
@@ -201,6 +321,9 @@ function buildReport(opts) {
|
|
|
201
321
|
}
|
|
202
322
|
L.push('');
|
|
203
323
|
|
|
324
|
+
// Gate M (Mutation Testing) — #404 P1-3
|
|
325
|
+
L.push(...buildGateMSection(gateMRuns));
|
|
326
|
+
|
|
204
327
|
// Quality Trend
|
|
205
328
|
L.push('## Quality Trend');
|
|
206
329
|
if (quality.length === 0) {
|
|
@@ -238,6 +361,7 @@ async function handleRetro(args = []) {
|
|
|
238
361
|
const audit = readAuditEntries(dir);
|
|
239
362
|
const quality = readQualityHistory(dir);
|
|
240
363
|
const sprints = readSprintHistory(dir, sprintFilter);
|
|
364
|
+
const gateMRuns = readGateMRuns(dir);
|
|
241
365
|
|
|
242
366
|
if (jsonFlag) {
|
|
243
367
|
const gateEntries = audit.filter(e => e.gate_id);
|
|
@@ -249,11 +373,24 @@ async function handleRetro(args = []) {
|
|
|
249
373
|
rework_rates: sprints.filter(s => s.metrics?.rework_rate != null).map(s => ({ id: s.id, rate: s.metrics.rework_rate })),
|
|
250
374
|
evidence_skipped: audit.filter(e => e.event === 'evidence_skipped'),
|
|
251
375
|
quality: quality.map(q => ({ timestamp: q.timestamp, score: q.score })),
|
|
376
|
+
gate_m: (() => {
|
|
377
|
+
const s = summariseGateM(gateMRuns);
|
|
378
|
+
return {
|
|
379
|
+
runs: s.total,
|
|
380
|
+
passed: s.passed,
|
|
381
|
+
blocked: s.blocked,
|
|
382
|
+
timed_out: s.timedOut,
|
|
383
|
+
skipped: s.skipped,
|
|
384
|
+
skip_reasons: s.reasons,
|
|
385
|
+
measured_scores: s.measured.map(r => r.score),
|
|
386
|
+
measured_durations_ms: s.durations,
|
|
387
|
+
};
|
|
388
|
+
})(),
|
|
252
389
|
}, null, 2));
|
|
253
390
|
return 0;
|
|
254
391
|
}
|
|
255
392
|
|
|
256
|
-
console.log(buildReport({ days, commits, audit, quality, sprints }));
|
|
393
|
+
console.log(buildReport({ days, commits, audit, quality, sprints, gateMRuns }));
|
|
257
394
|
return 0;
|
|
258
395
|
}
|
|
259
396
|
|
package/mock-policy/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MOCK-POLICY KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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.30.
|
|
3
|
+
"version": "0.30.3",
|
|
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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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.30.
|
|
3
|
+
"version": "0.30.3",
|
|
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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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.30.
|
|
3
|
+
"version": "0.30.3",
|
|
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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.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-20
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 03f6d10a
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.30.
|
|
6
|
+
**Version:** 0.30.3.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|