@boyingliu01/xp-gate 0.32.3 → 0.33.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/bin/xp-gate.js +2 -2
- package/lib/__tests__/check-changed-brief.test.js +63 -0
- package/lib/check.js +114 -2
- 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/sprint-flow/references/phase-3-build.md +26 -0
- 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/sprint-flow/references/phase-3-build.md +26 -0
- 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/sprint-flow/references/phase-3-build.md +26 -0
- 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/sprint-flow/references/phase-3-build.md +26 -0
- 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/sprint-flow/references/phase-3-build.md +26 -0
- package/skills/test-specification-alignment/AGENTS.md +2 -2
package/bin/xp-gate.js
CHANGED
|
@@ -295,9 +295,9 @@ const COMMANDS = {
|
|
|
295
295
|
usage: 'xp-gate baseline <create|show|reset|diff>'
|
|
296
296
|
},
|
|
297
297
|
'check': {
|
|
298
|
-
description: 'Run quality gates (--list, --all, --gates <ids>, or <gate-id>)',
|
|
298
|
+
description: 'Run quality gates (--list, --all, --gates <ids>, --changed --brief, or <gate-id>)',
|
|
299
299
|
run: subargs => check(subargs).then(code => process.exit(code)),
|
|
300
|
-
usage: 'xp-gate check <file_or_directory|gate_number> [--gates gates] [--all] [--list]'
|
|
300
|
+
usage: 'xp-gate check <file_or_directory|gate_number> [--gates gates] [--all] [--changed --brief] [--list]'
|
|
301
301
|
},
|
|
302
302
|
'principles': {
|
|
303
303
|
description: 'Run Clean Code + SOLID principles checker (Gate 4 standalone)',
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @test check-changed-brief
|
|
3
|
+
* @intent Prove `xp-gate check --changed --brief` scopes to the current diff, prints one honest verdict per gate, and never reports a gate as PASS when it did not run
|
|
4
|
+
* @covers AC-DSH-019
|
|
5
|
+
*/
|
|
6
|
+
const { fileExtension, printBriefSummary } = require('../check.js');
|
|
7
|
+
|
|
8
|
+
describe('check --changed --brief helpers', () => {
|
|
9
|
+
describe('fileExtension', () => {
|
|
10
|
+
it('returns the lowercased extension without the dot', () => {
|
|
11
|
+
expect(fileExtension('src/a/B.TS')).toBe('ts');
|
|
12
|
+
expect(fileExtension('x/y/z.mjs')).toBe('mjs');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns empty string for a path without an extension', () => {
|
|
16
|
+
expect(fileExtension('Makefile')).toBe('');
|
|
17
|
+
expect(fileExtension('docs/README')).toBe('');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('printBriefSummary', () => {
|
|
22
|
+
function capture(fn) {
|
|
23
|
+
const lines = [];
|
|
24
|
+
const spy = vi.spyOn(console, 'log').mockImplementation((...a) => lines.push(a.join(' ')));
|
|
25
|
+
const ret = fn();
|
|
26
|
+
spy.mockRestore();
|
|
27
|
+
return { out: lines.join('\n'), ret };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
it('reports one PASS line per passing gate and returns 0 failures', () => {
|
|
31
|
+
const { out, ret } = capture(() =>
|
|
32
|
+
printBriefSummary(['a.ts'], ['a.ts'], [{ id: '3', code: 0 }, { id: '4', code: 0 }], 12),
|
|
33
|
+
);
|
|
34
|
+
expect(out).toMatch(/Gate 3 Complexity\s+PASS/);
|
|
35
|
+
expect(out).toMatch(/Gate 4 Principles\s+PASS/);
|
|
36
|
+
expect(out).toMatch(/✅ clear/);
|
|
37
|
+
expect(ret).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('reports BLOCK and counts failures when a gate fails', () => {
|
|
41
|
+
const { out, ret } = capture(() =>
|
|
42
|
+
printBriefSummary(['a.ts'], ['a.ts'], [{ id: '3', code: 0 }, { id: '4', code: 1 }], 12),
|
|
43
|
+
);
|
|
44
|
+
expect(out).toMatch(/Gate 4 Principles\s+BLOCK/);
|
|
45
|
+
expect(out).toMatch(/❌ 1 blocking/);
|
|
46
|
+
expect(ret).toBe(1);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('never prints PASS for a gate that did not run (NOT_RUN -> SKIP)', () => {
|
|
50
|
+
const { out, ret } = capture(() =>
|
|
51
|
+
printBriefSummary(['a.ts'], ['a.ts'], [{ id: '3', code: 'NOT_RUN' }], 5),
|
|
52
|
+
);
|
|
53
|
+
expect(out).toMatch(/Gate 3 Complexity\s+SKIP/);
|
|
54
|
+
expect(out).not.toMatch(/Gate 3 Complexity\s+PASS/);
|
|
55
|
+
expect(ret).toBe(0);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('states docs/config-only diffs apply no blocking source gate', () => {
|
|
59
|
+
const { out } = capture(() => printBriefSummary(['README.md'], [], [], 3));
|
|
60
|
+
expect(out).toMatch(/No source files changed/);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
package/lib/check.js
CHANGED
|
@@ -13,13 +13,15 @@ function resolveGateToken(token) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function parseCheckArgs(args) {
|
|
16
|
-
const flags = { all: false, list: false, gateIds: null };
|
|
16
|
+
const flags = { all: false, list: false, gateIds: null, changed: false, brief: false };
|
|
17
17
|
const posArgs = [];
|
|
18
18
|
let i = 0;
|
|
19
19
|
while (i < args.length) {
|
|
20
20
|
const arg = args[i];
|
|
21
21
|
if (arg === '--all') { flags.all = true; i++; }
|
|
22
22
|
else if (arg === '--list') { flags.list = true; i++; }
|
|
23
|
+
else if (arg === '--changed') { flags.changed = true; i++; }
|
|
24
|
+
else if (arg === '--brief') { flags.brief = true; i++; }
|
|
23
25
|
else if (arg === '--gates' && i + 1 < args.length) {
|
|
24
26
|
flags.gateIds = args[i + 1].split(',').map(s => s.trim()).filter(Boolean);
|
|
25
27
|
i += 2;
|
|
@@ -45,6 +47,7 @@ async function check(args) {
|
|
|
45
47
|
const opts = parseCheckArgs(args);
|
|
46
48
|
|
|
47
49
|
if (opts.list) return listGates();
|
|
50
|
+
if (opts.changed) return runChangedBrief();
|
|
48
51
|
if (opts.gateNumber && !opts.all && !opts.gateIds) return runGate(opts.gateNumber, opts.pathArg);
|
|
49
52
|
if (opts.all) return checkAllGates(opts.pathArg);
|
|
50
53
|
if (opts.gateIds && opts.gateIds.length > 0) return runGatesByIds(opts.gateIds, opts.pathArg);
|
|
@@ -55,6 +58,7 @@ async function check(args) {
|
|
|
55
58
|
console.error('Options:');
|
|
56
59
|
console.error(' --gates <ids> Run specific gates (comma-separated IDs or aliases, e.g. "version,4,secrets")');
|
|
57
60
|
console.error(' --all Run all invokable gates');
|
|
61
|
+
console.error(' --changed --brief Fast: run only the gates the current diff can trip, one-screen summary');
|
|
58
62
|
console.error(' --list List all available gates');
|
|
59
63
|
console.error('');
|
|
60
64
|
console.error('Available Gates:');
|
|
@@ -68,6 +72,7 @@ async function check(args) {
|
|
|
68
72
|
console.error(' xp-gate check secrets # Run Gate 8 via alias');
|
|
69
73
|
console.error(' xp-gate check . --gates version,4,secrets # Run gates 0, 4, and 8');
|
|
70
74
|
console.error(' xp-gate check . --all # Run all invokable gates');
|
|
75
|
+
console.error(' xp-gate check . --changed --brief # Fast: only what this diff trips');
|
|
71
76
|
console.error(' xp-gate check --list # List available gates');
|
|
72
77
|
return 1;
|
|
73
78
|
}
|
|
@@ -212,6 +217,113 @@ async function runGatesByIds(gateIds, target) {
|
|
|
212
217
|
return failures === 0 ? 0 : 1;
|
|
213
218
|
}
|
|
214
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Fast "what will this commit trip?" view (P1-4, diagnosis 2026-10-30).
|
|
222
|
+
*
|
|
223
|
+
* `check . --all` runs the whole tree (minutes). During BUILD the developer only
|
|
224
|
+
* needs to know which blocking rules the CURRENT diff touches, in one screen and
|
|
225
|
+
* in seconds. This maps the diff to the gates that read changed files and runs
|
|
226
|
+
* only those, so the common case (docs / a couple of sources) returns fast.
|
|
227
|
+
*
|
|
228
|
+
* Honest by construction: prints only gate->verdict, never implying a gate ran
|
|
229
|
+
* when it was skipped. Gates not modelled here are listed as "commit-time".
|
|
230
|
+
*/
|
|
231
|
+
|
|
232
|
+
/** Extension of a path, lowercased, without the dot ('' when none). */
|
|
233
|
+
function fileExtension(file) {
|
|
234
|
+
const m = /\.([a-z0-9]+)$/i.exec(file);
|
|
235
|
+
return m ? m[1].toLowerCase() : '';
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Wall-clock budget for one `git diff` used by the --changed resolver. */
|
|
239
|
+
const GIT_DIFF_TIMEOUT_MS = 10000;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Run one git diff and split its stdout into file names. Returns null ONLY for a
|
|
243
|
+
* failed diff (not a git repo); any git error is caught and mapped to null so the
|
|
244
|
+
* caller can report "not a repository" instead of crashing on a null status.
|
|
245
|
+
*/
|
|
246
|
+
function gitChangedNames(spawnSync, args) {
|
|
247
|
+
try {
|
|
248
|
+
const res = spawnSync('git', args, { encoding: 'utf-8', timeout: GIT_DIFF_TIMEOUT_MS });
|
|
249
|
+
if (res.status !== 0 || typeof res.stdout !== 'string') return null;
|
|
250
|
+
return res.stdout.split('\n').map((f) => f.trim()).filter(Boolean);
|
|
251
|
+
} catch {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Diff scope mirrors pre-commit: staged first, then anything vs HEAD. */
|
|
257
|
+
function readChangedFiles() {
|
|
258
|
+
const { spawnSync } = require('child_process');
|
|
259
|
+
const staged = gitChangedNames(spawnSync, ['diff', '--cached', '--name-only', '--diff-filter=ACM']);
|
|
260
|
+
if (staged === null) return null;
|
|
261
|
+
if (staged.length > 0) return staged;
|
|
262
|
+
const vsHead = gitChangedNames(spawnSync, ['diff', 'HEAD', '--name-only', '--diff-filter=ACM']);
|
|
263
|
+
return vsHead === null ? staged : vsHead;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Run the gates a diff can trip that are both diff-scoped and fast. Gate 2
|
|
268
|
+
* (jscpd) is excluded on purpose: it scans the whole tree and duplicate
|
|
269
|
+
* detection is a codebase-wide question, not a per-diff one. Gate 4 is handed the
|
|
270
|
+
* actual files — calling it with '.' examined 0 files and printed a vacuous
|
|
271
|
+
* "No violations found", the exact anti-pattern this project forbids.
|
|
272
|
+
*/
|
|
273
|
+
async function runBriefGates(sourceFiles) {
|
|
274
|
+
const results = [];
|
|
275
|
+
if (sourceFiles.length === 0) return results;
|
|
276
|
+
results.push({ id: '3', code: await runGate('3', '.', {}) });
|
|
277
|
+
const { principles } = require('./principles.js');
|
|
278
|
+
results.push({ id: '4', code: await principles(sourceFiles) });
|
|
279
|
+
return results;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const BRIEF_GATE_NAMES = { '2': 'Duplicates', '3': 'Complexity', '4': 'Principles' };
|
|
283
|
+
const COMMIT_TIME_GATES = ['1 lint', '5 tests', '6 Boy Scout', '7 IaC', '8 secrets', '9 sast', '10 build', '11 sprint'];
|
|
284
|
+
|
|
285
|
+
/** Print the one-screen summary; returns the number of blocking gates. */
|
|
286
|
+
function printBriefSummary(changed, sourceFiles, results, ms) {
|
|
287
|
+
console.log('');
|
|
288
|
+
console.log(`━━━ xp-gate check --changed (${changed.length} file(s), ${sourceFiles.length} source) ━━━`);
|
|
289
|
+
if (sourceFiles.length === 0) {
|
|
290
|
+
console.log(' No source files changed — no blocking source gate applies (docs/config only).');
|
|
291
|
+
}
|
|
292
|
+
let failures = 0;
|
|
293
|
+
for (const r of results) {
|
|
294
|
+
let verdict;
|
|
295
|
+
if (r.code === 0) verdict = 'PASS';
|
|
296
|
+
else if (r.code === 'NOT_RUN') verdict = 'SKIP';
|
|
297
|
+
else { verdict = 'BLOCK'; failures += 1; }
|
|
298
|
+
console.log(` Gate ${r.id} ${(BRIEF_GATE_NAMES[r.id] || r.id).padEnd(12)} ${verdict}`);
|
|
299
|
+
}
|
|
300
|
+
const rest = sourceFiles.length > 0 ? COMMIT_TIME_GATES.filter((g) => !/^(1 |5 |6 )/.test(g)) : COMMIT_TIME_GATES;
|
|
301
|
+
console.log(` commit-time (not run here): ${rest.join(', ')}`);
|
|
302
|
+
console.log(` ${failures === 0 ? '✅ clear' : `❌ ${failures} blocking`} — ${ms} ms`);
|
|
303
|
+
return failures;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async function runChangedBrief() {
|
|
307
|
+
const { SOURCE_FILE_EXTENSIONS } = require('./gate-runner.js');
|
|
308
|
+
const t0 = Date.now();
|
|
309
|
+
|
|
310
|
+
const changed = readChangedFiles();
|
|
311
|
+
if (changed === null) {
|
|
312
|
+
console.error('[xp-gate check --changed] not a git repository');
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
if (changed.length === 0) {
|
|
316
|
+
console.log('[xp-gate check --changed] no staged/tracked changes — nothing to gate (0 files).');
|
|
317
|
+
return 0;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const srcExt = new Set(SOURCE_FILE_EXTENSIONS);
|
|
321
|
+
const sourceFiles = changed.filter((f) => srcExt.has(fileExtension(f)));
|
|
322
|
+
const results = await runBriefGates(sourceFiles);
|
|
323
|
+
const failures = printBriefSummary(changed, sourceFiles, results, Date.now() - t0);
|
|
324
|
+
return failures === 0 ? 0 : 1;
|
|
325
|
+
}
|
|
326
|
+
|
|
215
327
|
function listGates() {
|
|
216
328
|
const { getAllGates } = require('./gate-runner.js');
|
|
217
329
|
const allGates = getAllGates();
|
|
@@ -244,4 +356,4 @@ function listGates() {
|
|
|
244
356
|
return 0;
|
|
245
357
|
}
|
|
246
358
|
|
|
247
|
-
module.exports = { check, checkAllGates, formatGateTally };
|
|
359
|
+
module.exports = { check, checkAllGates, formatGateTally, runChangedBrief, fileExtension, printBriefSummary };
|
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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## 提交前自检清单(P1 红线前移 — 2026-10-30,直接解 #652)
|
|
26
|
+
|
|
27
|
+
> 背景:47.6% 的提交是 fix/revert(323/679)。多数返工是"提交时才被门禁打回"——
|
|
28
|
+
> 红线原本只活在 `githooks/` 里,AI 在 BUILD 期间看不到。这一页把会**阻断提交**的
|
|
29
|
+
> 阈值提前到编码时自检,目标是"第一次提交就过",而不是"提交→被打回→改→再提交"。
|
|
30
|
+
|
|
31
|
+
**每次准备 `git commit` 前,逐条自检(按被拦频率排序):**
|
|
32
|
+
|
|
33
|
+
| # | 门禁 | 红线(会被 BLOCK/WARN 的硬阈值) | 自查方法 |
|
|
34
|
+
|---|------|------------------------------|----------|
|
|
35
|
+
| 1 | **Gate 3 CCN** | 单函数圈复杂度 **>10 BLOCK**、**>5 WARN** | 拆函数 / 早返回 / 抽策略表;`xp-gate check 3 <file>` |
|
|
36
|
+
| 2 | **Gate 6 Boy Scout** | **新文件 0 warning**;修改文件 warning 数不得高于 `.warnings-baseline.json`;**单函数 ≤50 行**;**嵌套 ≤4 层** | 新文件当"零容忍"写;改动前 `xp-gate check 6` 看基线 |
|
|
37
|
+
| 3 | **Gate 2 重复代码** | jscpd 相似度 **>5% BLOCK** | 抽公共函数,别复制粘贴;`xp-gate check 2 <dir>` |
|
|
38
|
+
| 4 | **Gate 4 Principles** | 14 条 Clean Code/SOLID 规则,任一 error/warning 即拦(按 `.principlesrc`) | `xp-gate check 4 <file>`;避免超长参数表、空 catch、`as any` |
|
|
39
|
+
| 5 | **Gate 1 Lint** | 适配器 lint 任一 error | 提交前跑一次项目 lint;不要留未用变量/导入 |
|
|
40
|
+
| 6 | **Gate 5 测试** | 测试全绿 + 覆盖率 ≥80%(新 .ts/.tsx 无测试直接 BLOCK) | 新代码先写测试(TDD);`npx vitest run <file>` |
|
|
41
|
+
| 7 | **mirror/sync 纪律** | 改 `githooks/` 或 `skills/` 后必须 `node src/npm-package/scripts/sync-package-content.js --fix` 且 `bash scripts/check-hook-mirror.sh` 报 PASS | 忘了同步会在 pre-push 的 mirror 校验被打回 |
|
|
42
|
+
|
|
43
|
+
**一条命令抢先看**:`xp-gate check . --changed --brief` 只跑"本次 diff 会触发的门禁",
|
|
44
|
+
一屏出 PASS/SKIP/BLOCK,目标 <5 s。把它放在 ralph-loop 每个 REQ 的 step 0,先看红不红,
|
|
45
|
+
再决定是否继续写——而不是写到一半才被 `git commit` 拦下。
|
|
46
|
+
|
|
47
|
+
**根因提醒**:Gate 3/6 是"返工双雄"。写完一个函数先扫一眼长度和嵌套,比提交后返工快得多。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
25
51
|
## BUILD Entry Contract Check (MANDATORY — v0.18.0+, 程序化)
|
|
26
52
|
|
|
27
53
|
**Purpose**: Validate `slices-manifest.json` schema and slice↔REQ cross-artifact consistency before entering BUILD.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## 提交前自检清单(P1 红线前移 — 2026-10-30,直接解 #652)
|
|
26
|
+
|
|
27
|
+
> 背景:47.6% 的提交是 fix/revert(323/679)。多数返工是"提交时才被门禁打回"——
|
|
28
|
+
> 红线原本只活在 `githooks/` 里,AI 在 BUILD 期间看不到。这一页把会**阻断提交**的
|
|
29
|
+
> 阈值提前到编码时自检,目标是"第一次提交就过",而不是"提交→被打回→改→再提交"。
|
|
30
|
+
|
|
31
|
+
**每次准备 `git commit` 前,逐条自检(按被拦频率排序):**
|
|
32
|
+
|
|
33
|
+
| # | 门禁 | 红线(会被 BLOCK/WARN 的硬阈值) | 自查方法 |
|
|
34
|
+
|---|------|------------------------------|----------|
|
|
35
|
+
| 1 | **Gate 3 CCN** | 单函数圈复杂度 **>10 BLOCK**、**>5 WARN** | 拆函数 / 早返回 / 抽策略表;`xp-gate check 3 <file>` |
|
|
36
|
+
| 2 | **Gate 6 Boy Scout** | **新文件 0 warning**;修改文件 warning 数不得高于 `.warnings-baseline.json`;**单函数 ≤50 行**;**嵌套 ≤4 层** | 新文件当"零容忍"写;改动前 `xp-gate check 6` 看基线 |
|
|
37
|
+
| 3 | **Gate 2 重复代码** | jscpd 相似度 **>5% BLOCK** | 抽公共函数,别复制粘贴;`xp-gate check 2 <dir>` |
|
|
38
|
+
| 4 | **Gate 4 Principles** | 14 条 Clean Code/SOLID 规则,任一 error/warning 即拦(按 `.principlesrc`) | `xp-gate check 4 <file>`;避免超长参数表、空 catch、`as any` |
|
|
39
|
+
| 5 | **Gate 1 Lint** | 适配器 lint 任一 error | 提交前跑一次项目 lint;不要留未用变量/导入 |
|
|
40
|
+
| 6 | **Gate 5 测试** | 测试全绿 + 覆盖率 ≥80%(新 .ts/.tsx 无测试直接 BLOCK) | 新代码先写测试(TDD);`npx vitest run <file>` |
|
|
41
|
+
| 7 | **mirror/sync 纪律** | 改 `githooks/` 或 `skills/` 后必须 `node src/npm-package/scripts/sync-package-content.js --fix` 且 `bash scripts/check-hook-mirror.sh` 报 PASS | 忘了同步会在 pre-push 的 mirror 校验被打回 |
|
|
42
|
+
|
|
43
|
+
**一条命令抢先看**:`xp-gate check . --changed --brief` 只跑"本次 diff 会触发的门禁",
|
|
44
|
+
一屏出 PASS/SKIP/BLOCK,目标 <5 s。把它放在 ralph-loop 每个 REQ 的 step 0,先看红不红,
|
|
45
|
+
再决定是否继续写——而不是写到一半才被 `git commit` 拦下。
|
|
46
|
+
|
|
47
|
+
**根因提醒**:Gate 3/6 是"返工双雄"。写完一个函数先扫一眼长度和嵌套,比提交后返工快得多。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
25
51
|
## BUILD Entry Contract Check (MANDATORY — v0.18.0+, 程序化)
|
|
26
52
|
|
|
27
53
|
**Purpose**: Validate `slices-manifest.json` schema and slice↔REQ cross-artifact consistency before entering BUILD.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## 提交前自检清单(P1 红线前移 — 2026-10-30,直接解 #652)
|
|
26
|
+
|
|
27
|
+
> 背景:47.6% 的提交是 fix/revert(323/679)。多数返工是"提交时才被门禁打回"——
|
|
28
|
+
> 红线原本只活在 `githooks/` 里,AI 在 BUILD 期间看不到。这一页把会**阻断提交**的
|
|
29
|
+
> 阈值提前到编码时自检,目标是"第一次提交就过",而不是"提交→被打回→改→再提交"。
|
|
30
|
+
|
|
31
|
+
**每次准备 `git commit` 前,逐条自检(按被拦频率排序):**
|
|
32
|
+
|
|
33
|
+
| # | 门禁 | 红线(会被 BLOCK/WARN 的硬阈值) | 自查方法 |
|
|
34
|
+
|---|------|------------------------------|----------|
|
|
35
|
+
| 1 | **Gate 3 CCN** | 单函数圈复杂度 **>10 BLOCK**、**>5 WARN** | 拆函数 / 早返回 / 抽策略表;`xp-gate check 3 <file>` |
|
|
36
|
+
| 2 | **Gate 6 Boy Scout** | **新文件 0 warning**;修改文件 warning 数不得高于 `.warnings-baseline.json`;**单函数 ≤50 行**;**嵌套 ≤4 层** | 新文件当"零容忍"写;改动前 `xp-gate check 6` 看基线 |
|
|
37
|
+
| 3 | **Gate 2 重复代码** | jscpd 相似度 **>5% BLOCK** | 抽公共函数,别复制粘贴;`xp-gate check 2 <dir>` |
|
|
38
|
+
| 4 | **Gate 4 Principles** | 14 条 Clean Code/SOLID 规则,任一 error/warning 即拦(按 `.principlesrc`) | `xp-gate check 4 <file>`;避免超长参数表、空 catch、`as any` |
|
|
39
|
+
| 5 | **Gate 1 Lint** | 适配器 lint 任一 error | 提交前跑一次项目 lint;不要留未用变量/导入 |
|
|
40
|
+
| 6 | **Gate 5 测试** | 测试全绿 + 覆盖率 ≥80%(新 .ts/.tsx 无测试直接 BLOCK) | 新代码先写测试(TDD);`npx vitest run <file>` |
|
|
41
|
+
| 7 | **mirror/sync 纪律** | 改 `githooks/` 或 `skills/` 后必须 `node src/npm-package/scripts/sync-package-content.js --fix` 且 `bash scripts/check-hook-mirror.sh` 报 PASS | 忘了同步会在 pre-push 的 mirror 校验被打回 |
|
|
42
|
+
|
|
43
|
+
**一条命令抢先看**:`xp-gate check . --changed --brief` 只跑"本次 diff 会触发的门禁",
|
|
44
|
+
一屏出 PASS/SKIP/BLOCK,目标 <5 s。把它放在 ralph-loop 每个 REQ 的 step 0,先看红不红,
|
|
45
|
+
再决定是否继续写——而不是写到一半才被 `git commit` 拦下。
|
|
46
|
+
|
|
47
|
+
**根因提醒**:Gate 3/6 是"返工双雄"。写完一个函数先扫一眼长度和嵌套,比提交后返工快得多。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
25
51
|
## BUILD Entry Contract Check (MANDATORY — v0.18.0+, 程序化)
|
|
26
52
|
|
|
27
53
|
**Purpose**: Validate `slices-manifest.json` schema and slice↔REQ cross-artifact consistency before entering BUILD.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## 提交前自检清单(P1 红线前移 — 2026-10-30,直接解 #652)
|
|
26
|
+
|
|
27
|
+
> 背景:47.6% 的提交是 fix/revert(323/679)。多数返工是"提交时才被门禁打回"——
|
|
28
|
+
> 红线原本只活在 `githooks/` 里,AI 在 BUILD 期间看不到。这一页把会**阻断提交**的
|
|
29
|
+
> 阈值提前到编码时自检,目标是"第一次提交就过",而不是"提交→被打回→改→再提交"。
|
|
30
|
+
|
|
31
|
+
**每次准备 `git commit` 前,逐条自检(按被拦频率排序):**
|
|
32
|
+
|
|
33
|
+
| # | 门禁 | 红线(会被 BLOCK/WARN 的硬阈值) | 自查方法 |
|
|
34
|
+
|---|------|------------------------------|----------|
|
|
35
|
+
| 1 | **Gate 3 CCN** | 单函数圈复杂度 **>10 BLOCK**、**>5 WARN** | 拆函数 / 早返回 / 抽策略表;`xp-gate check 3 <file>` |
|
|
36
|
+
| 2 | **Gate 6 Boy Scout** | **新文件 0 warning**;修改文件 warning 数不得高于 `.warnings-baseline.json`;**单函数 ≤50 行**;**嵌套 ≤4 层** | 新文件当"零容忍"写;改动前 `xp-gate check 6` 看基线 |
|
|
37
|
+
| 3 | **Gate 2 重复代码** | jscpd 相似度 **>5% BLOCK** | 抽公共函数,别复制粘贴;`xp-gate check 2 <dir>` |
|
|
38
|
+
| 4 | **Gate 4 Principles** | 14 条 Clean Code/SOLID 规则,任一 error/warning 即拦(按 `.principlesrc`) | `xp-gate check 4 <file>`;避免超长参数表、空 catch、`as any` |
|
|
39
|
+
| 5 | **Gate 1 Lint** | 适配器 lint 任一 error | 提交前跑一次项目 lint;不要留未用变量/导入 |
|
|
40
|
+
| 6 | **Gate 5 测试** | 测试全绿 + 覆盖率 ≥80%(新 .ts/.tsx 无测试直接 BLOCK) | 新代码先写测试(TDD);`npx vitest run <file>` |
|
|
41
|
+
| 7 | **mirror/sync 纪律** | 改 `githooks/` 或 `skills/` 后必须 `node src/npm-package/scripts/sync-package-content.js --fix` 且 `bash scripts/check-hook-mirror.sh` 报 PASS | 忘了同步会在 pre-push 的 mirror 校验被打回 |
|
|
42
|
+
|
|
43
|
+
**一条命令抢先看**:`xp-gate check . --changed --brief` 只跑"本次 diff 会触发的门禁",
|
|
44
|
+
一屏出 PASS/SKIP/BLOCK,目标 <5 s。把它放在 ralph-loop 每个 REQ 的 step 0,先看红不红,
|
|
45
|
+
再决定是否继续写——而不是写到一半才被 `git commit` 拦下。
|
|
46
|
+
|
|
47
|
+
**根因提醒**:Gate 3/6 是"返工双雄"。写完一个函数先扫一眼长度和嵌套,比提交后返工快得多。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
25
51
|
## BUILD Entry Contract Check (MANDATORY — v0.18.0+, 程序化)
|
|
26
52
|
|
|
27
53
|
**Purpose**: Validate `slices-manifest.json` schema and slice↔REQ cross-artifact consistency before entering BUILD.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.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.
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## 提交前自检清单(P1 红线前移 — 2026-10-30,直接解 #652)
|
|
26
|
+
|
|
27
|
+
> 背景:47.6% 的提交是 fix/revert(323/679)。多数返工是"提交时才被门禁打回"——
|
|
28
|
+
> 红线原本只活在 `githooks/` 里,AI 在 BUILD 期间看不到。这一页把会**阻断提交**的
|
|
29
|
+
> 阈值提前到编码时自检,目标是"第一次提交就过",而不是"提交→被打回→改→再提交"。
|
|
30
|
+
|
|
31
|
+
**每次准备 `git commit` 前,逐条自检(按被拦频率排序):**
|
|
32
|
+
|
|
33
|
+
| # | 门禁 | 红线(会被 BLOCK/WARN 的硬阈值) | 自查方法 |
|
|
34
|
+
|---|------|------------------------------|----------|
|
|
35
|
+
| 1 | **Gate 3 CCN** | 单函数圈复杂度 **>10 BLOCK**、**>5 WARN** | 拆函数 / 早返回 / 抽策略表;`xp-gate check 3 <file>` |
|
|
36
|
+
| 2 | **Gate 6 Boy Scout** | **新文件 0 warning**;修改文件 warning 数不得高于 `.warnings-baseline.json`;**单函数 ≤50 行**;**嵌套 ≤4 层** | 新文件当"零容忍"写;改动前 `xp-gate check 6` 看基线 |
|
|
37
|
+
| 3 | **Gate 2 重复代码** | jscpd 相似度 **>5% BLOCK** | 抽公共函数,别复制粘贴;`xp-gate check 2 <dir>` |
|
|
38
|
+
| 4 | **Gate 4 Principles** | 14 条 Clean Code/SOLID 规则,任一 error/warning 即拦(按 `.principlesrc`) | `xp-gate check 4 <file>`;避免超长参数表、空 catch、`as any` |
|
|
39
|
+
| 5 | **Gate 1 Lint** | 适配器 lint 任一 error | 提交前跑一次项目 lint;不要留未用变量/导入 |
|
|
40
|
+
| 6 | **Gate 5 测试** | 测试全绿 + 覆盖率 ≥80%(新 .ts/.tsx 无测试直接 BLOCK) | 新代码先写测试(TDD);`npx vitest run <file>` |
|
|
41
|
+
| 7 | **mirror/sync 纪律** | 改 `githooks/` 或 `skills/` 后必须 `node src/npm-package/scripts/sync-package-content.js --fix` 且 `bash scripts/check-hook-mirror.sh` 报 PASS | 忘了同步会在 pre-push 的 mirror 校验被打回 |
|
|
42
|
+
|
|
43
|
+
**一条命令抢先看**:`xp-gate check . --changed --brief` 只跑"本次 diff 会触发的门禁",
|
|
44
|
+
一屏出 PASS/SKIP/BLOCK,目标 <5 s。把它放在 ralph-loop 每个 REQ 的 step 0,先看红不红,
|
|
45
|
+
再决定是否继续写——而不是写到一半才被 `git commit` 拦下。
|
|
46
|
+
|
|
47
|
+
**根因提醒**:Gate 3/6 是"返工双雄"。写完一个函数先扫一眼长度和嵌套,比提交后返工快得多。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
25
51
|
## BUILD Entry Contract Check (MANDATORY — v0.18.0+, 程序化)
|
|
26
52
|
|
|
27
53
|
**Purpose**: Validate `slices-manifest.json` schema and slice↔REQ cross-artifact consistency before entering BUILD.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
3
|
**Generated:** 2026-10-30
|
|
4
|
-
**Commit:**
|
|
4
|
+
**Commit:** 3c5e9aaf
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.33.0.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|