@boyingliu01/xp-gate 0.14.31 → 0.15.1
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/java.sh +33 -4
- package/gate-9.sh +22 -48
- package/hooks/gate-9.sh +22 -48
- package/hooks/pre-commit +102 -44
- package/hooks/pre-push +1 -33
- package/lib/__tests__/doctor.test.js +34 -31
- package/lib/detect-deps.js +12 -0
- package/mock-policy/AGENTS.md +3 -3
- package/mutation/AGENTS.md +3 -3
- package/package.json +1 -1
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/claude-code/skills/sprint-flow/SKILL.md +1 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-3-build.md +71 -0
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/opencode/package.json +1 -1
- package/plugins/opencode/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/opencode/skills/sprint-flow/SKILL.md +1 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-3-build.md +71 -0
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/qoder/plugin.json +1 -1
- package/plugins/qoder/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
- package/principles/AGENTS.md +3 -3
- package/principles/adapters/python.ts +39 -6
- package/scripts/__tests__/sync-package-content.test.js +36 -17
- package/scripts/sync-package-content.js +5 -4
- package/skills/delphi-review/AGENTS.md +3 -3
- package/skills/sprint-flow/AGENTS.md +3 -3
- package/skills/sprint-flow/SKILL.md +1 -0
- package/skills/sprint-flow/references/phase-3-build.md +71 -0
- package/skills/test-specification-alignment/AGENTS.md +3 -3
|
@@ -299,10 +299,7 @@ describe('doctor', () => {
|
|
|
299
299
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('All checks passed'));
|
|
300
300
|
});
|
|
301
301
|
|
|
302
|
-
|
|
303
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
304
|
-
// but the test mocks execSync. Need to update mock strategy to handle both.
|
|
305
|
-
it.skip('AC-05: doctor reports all checks passed for healthy global install', async () => {
|
|
302
|
+
it('AC-05: doctor reports all checks passed for healthy global install', async () => {
|
|
306
303
|
setupGlobalInstall();
|
|
307
304
|
ensureTuiRegistered();
|
|
308
305
|
seedVersionCache();
|
|
@@ -319,10 +316,7 @@ describe('doctor', () => {
|
|
|
319
316
|
|
|
320
317
|
// === AC-08: partial uninstall detection ===
|
|
321
318
|
|
|
322
|
-
|
|
323
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
324
|
-
// but the test mocks execSync. Need to update mock strategy to handle both.
|
|
325
|
-
it.skip('AC-08: doctor detects missing hooks in partial install', async () => {
|
|
319
|
+
it('AC-08: doctor detects missing hooks in partial install', async () => {
|
|
326
320
|
setupLocalInstall();
|
|
327
321
|
seedVersionCache();
|
|
328
322
|
// Remove hooks to simulate partial state
|
|
@@ -368,10 +362,7 @@ describe('doctor', () => {
|
|
|
368
362
|
);
|
|
369
363
|
});
|
|
370
364
|
|
|
371
|
-
|
|
372
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
373
|
-
// but the test mocks execSync. Need to update mock strategy to handle both.
|
|
374
|
-
it.skip('AC-08: doctor detects missing adapters', async () => {
|
|
365
|
+
it('AC-08: doctor detects missing adapters', async () => {
|
|
375
366
|
setupLocalInstall();
|
|
376
367
|
seedVersionCache();
|
|
377
368
|
// Remove adapters dir
|
|
@@ -390,12 +381,10 @@ describe('doctor', () => {
|
|
|
390
381
|
);
|
|
391
382
|
});
|
|
392
383
|
|
|
393
|
-
|
|
394
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
395
|
-
// but the test mocks execSync. Need to update mock strategy to handle both.
|
|
396
|
-
it.skip('AC-08: doctor detects wrong core.hooksPath in global mode', async () => {
|
|
384
|
+
it('AC-08: doctor detects wrong core.hooksPath in global mode', async () => {
|
|
397
385
|
setupGlobalInstall();
|
|
398
386
|
seedVersionCache();
|
|
387
|
+
// Custom mock: returns wrong hooksPath to trigger detection
|
|
399
388
|
cp.execSync = (cmd) => {
|
|
400
389
|
if (cmd.includes('git config --global core.hooksPath')) {
|
|
401
390
|
if (cmd.includes('--unset')) {
|
|
@@ -417,6 +406,32 @@ describe('doctor', () => {
|
|
|
417
406
|
}
|
|
418
407
|
return '';
|
|
419
408
|
};
|
|
409
|
+
// Async mock matching execSync above
|
|
410
|
+
const mockAsyncExec = (cmd, opts, callback) => {
|
|
411
|
+
if (typeof opts === 'function') { callback = opts; opts = {}; }
|
|
412
|
+
if (cmd.includes('git config --global core.hooksPath')) {
|
|
413
|
+
callback(null, cmd.includes('--unset') ? '' : '/wrong/path\n', '');
|
|
414
|
+
} else if (cmd === 'git rev-parse --git-dir') {
|
|
415
|
+
callback(null, path.join(tmpProject, '.git') + '\n', '');
|
|
416
|
+
} else if (cmd === 'node --version') {
|
|
417
|
+
callback(null, 'v20.0.0\n', '');
|
|
418
|
+
} else if (cmd === 'git --version') {
|
|
419
|
+
callback(null, 'git version 2.39.0\n', '');
|
|
420
|
+
} else if (cmd === 'bash --version') {
|
|
421
|
+
callback(null, 'GNU bash, version 5.1.16\n', '');
|
|
422
|
+
} else {
|
|
423
|
+
callback(null, '', '');
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
mockAsyncExec[util.promisify.custom] = (cmd, options) => {
|
|
427
|
+
return new Promise((resolve, reject) => {
|
|
428
|
+
mockAsyncExec(cmd, options, (err, stdout, stderr) => {
|
|
429
|
+
if (err) { err.stdout = stdout || ''; err.stderr = stderr || ''; reject(err); }
|
|
430
|
+
else { resolve({ stdout, stderr }); }
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
cp.exec = mockAsyncExec;
|
|
420
435
|
const { doctor } = require('../doctor');
|
|
421
436
|
const result = await doctor([]);
|
|
422
437
|
expect(result).toBe(1);
|
|
@@ -551,11 +566,7 @@ describe('doctor', () => {
|
|
|
551
566
|
expect(result).toBe(1);
|
|
552
567
|
});
|
|
553
568
|
|
|
554
|
-
|
|
555
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
556
|
-
// to detect missing environment dependencies, but the test mocks execSync.
|
|
557
|
-
// Need to update mock strategy to handle asynchronous environment checks.
|
|
558
|
-
it.skip('detects missing environment dependencies', async () => {
|
|
569
|
+
it('detects missing environment dependencies', async () => {
|
|
559
570
|
setupLocalInstall();
|
|
560
571
|
seedVersionCache();
|
|
561
572
|
mockExecFail();
|
|
@@ -772,11 +783,7 @@ describe('doctor', () => {
|
|
|
772
783
|
|
|
773
784
|
// === Issue #186: --fix syncs global hooks from package source ===
|
|
774
785
|
|
|
775
|
-
|
|
776
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
777
|
-
// for --fix operations, but the test mocks execSync. Need to update mock
|
|
778
|
-
// strategy to handle asynchronous fix operations.
|
|
779
|
-
it.skip('--fix syncs global hooks when they are outdated', async () => {
|
|
786
|
+
it('--fix syncs global hooks when they are outdated', async () => {
|
|
780
787
|
setupGlobalInstall();
|
|
781
788
|
seedVersionCache();
|
|
782
789
|
// Write an outdated pre-commit hook (different content)
|
|
@@ -961,11 +968,7 @@ describe('doctor', () => {
|
|
|
961
968
|
);
|
|
962
969
|
});
|
|
963
970
|
|
|
964
|
-
|
|
965
|
-
// This test fails because doctor.js now uses execAsync (util.promisify(exec))
|
|
966
|
-
// to check gate scripts, but the test mocks execSync. Need to update mock
|
|
967
|
-
// strategy to handle asynchronous gate script validation.
|
|
968
|
-
it.skip('gate scripts: FAIL when gate scripts are missing', async () => {
|
|
971
|
+
it('gate scripts: FAIL when gate scripts are missing', async () => {
|
|
969
972
|
setupLocalInstall();
|
|
970
973
|
seedVersionCache();
|
|
971
974
|
// Clear adapters dir and create with only language adapters, no gate scripts
|
package/lib/detect-deps.js
CHANGED
|
@@ -104,6 +104,18 @@ const GATE_CLI_TOOLS = [
|
|
|
104
104
|
},
|
|
105
105
|
docUrl: 'https://docs.npmjs.com/cli/v10/commands/npx',
|
|
106
106
|
},
|
|
107
|
+
{
|
|
108
|
+
tool: 'jq',
|
|
109
|
+
gates: ['Gate MW (Code Walkthrough)', 'Sprint Gate (sprint-gate.sh)'],
|
|
110
|
+
checkCmd: 'jq --version',
|
|
111
|
+
install: {
|
|
112
|
+
darwin: 'brew install jq',
|
|
113
|
+
linux: 'apt-get install jq (Debian/Ubuntu) || yum install jq (RHEL/CentOS)',
|
|
114
|
+
win32: 'choco install jq || winget install jq',
|
|
115
|
+
},
|
|
116
|
+
docUrl: 'https://stedolan.github.io/jq/',
|
|
117
|
+
fallback: 'Node.js JSON parser fallback in sprint-gate.sh when jq is unavailable',
|
|
118
|
+
},
|
|
107
119
|
];
|
|
108
120
|
|
|
109
121
|
/**
|
package/mock-policy/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MOCK-POLICY KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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.15.1",
|
|
4
4
|
"displayName": "XP-Gate",
|
|
5
5
|
"description": "Extreme Programming quality gates + AI workflow skills for Claude Code. Includes 10 quality gates (Gate 0-9), Sprint Flow (11 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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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.
|
|
@@ -269,6 +269,7 @@ next_phase_context: [key info for next phase]
|
|
|
269
269
|
| Clean up CLOSE without backing up sprint-state first | `.sprint-state/` is inside worktree; it's lost on worktree removal. CLOSE step 1 MUST back up to repo-tracked path first |
|
|
270
270
|
| Keep adding random changes after verification failures | Max 3 fix cycles; if still failing, BLOCK and request user decision |
|
|
271
271
|
| Enter next phase without generating Phase Summary | Every phase MUST write `.sprint-state/phase-outputs/phase-{N}-summary.md` and pass transition gate |
|
|
272
|
+
| Complete implementation change without running verification | After every file edit/refactor/feature, MUST run `npm test` + `npm run lint` + `npx tsc --noEmit` and record the structured verification event (see `phase-3-build.md` §In-Session Verification) |
|
|
272
273
|
|
|
273
274
|
---
|
|
274
275
|
|
|
@@ -144,6 +144,77 @@ This enforcement is instructional (LLM follows SKILL.md instructions), not progr
|
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
147
|
+
## In-Session Verification (MANDATORY — v0.14.31+)
|
|
148
|
+
|
|
149
|
+
**Purpose**: Ensure every implementation change is immediately verified and recorded, enabling Better Loop Harness (and other observability tools) to capture normalized change→validation event pairs.
|
|
150
|
+
|
|
151
|
+
**Problem it solves**: Without explicit in-session verification, Agents may edit files and move on without running tests or linters. This creates unverified changes that are invisible to post-hoc review tools, breaking the traceability chain between "what changed" and "was it validated".
|
|
152
|
+
|
|
153
|
+
### Mandatory Verification Protocol
|
|
154
|
+
|
|
155
|
+
After **every** implementation change (file edit, refactor, new feature, bug fix), the Agent MUST execute the following sequence BEFORE claiming the change is complete:
|
|
156
|
+
|
|
157
|
+
1. **Run tests**: `npm test` or `npx vitest run` (or project-specific test command)
|
|
158
|
+
2. **Run linter**: `npm run lint` or `npx eslint .` (or project-specific lint command)
|
|
159
|
+
3. **Type-check** (TypeScript projects): `npx tsc --noEmit`
|
|
160
|
+
4. **Record the result**: Append a structured verification event (see format below)
|
|
161
|
+
|
|
162
|
+
### Verification Event Format
|
|
163
|
+
|
|
164
|
+
Each verification event MUST be recorded as a structured JSON object. Agents should output this to stdout or append to `.sprint-state/phase-outputs/verification-events.jsonl`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"timestamp": "2026-07-22T10:30:00Z",
|
|
169
|
+
"change": {
|
|
170
|
+
"type": "edit|refactor|feature|bugfix",
|
|
171
|
+
"files": ["src/lib/auth.ts", "src/lib/auth.test.ts"],
|
|
172
|
+
"description": "Implement validateToken() for expired token handling"
|
|
173
|
+
},
|
|
174
|
+
"verification": {
|
|
175
|
+
"tests": { "command": "npx vitest run src/lib/auth.test.ts", "status": "pass|fail", "summary": "4 passed, 0 failed" },
|
|
176
|
+
"lint": { "command": "npm run lint", "status": "pass|fail|warn", "summary": "0 errors, 2 warnings" },
|
|
177
|
+
"typecheck": { "command": "npx tsc --noEmit", "status": "pass|fail|skip", "summary": "No type errors" }
|
|
178
|
+
},
|
|
179
|
+
"outcome": "verified|failed|partial",
|
|
180
|
+
"req": "REQ-003"
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Integration with ralph-loop
|
|
185
|
+
|
|
186
|
+
When using ralph-loop mode (default BUILD strategy), each REQ iteration MUST include verification as the final step before marking the REQ complete:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
ralph-loop iteration:
|
|
190
|
+
1. [TDD-RED] Write failing test
|
|
191
|
+
2. [TDD-GREEN] Implement minimal code to pass
|
|
192
|
+
3. [TDD-REFACTOR] Clean up while keeping tests green
|
|
193
|
+
4. [VERIFY] Run tests + lint + typecheck ← MANDATORY
|
|
194
|
+
5. [RECORD] Append verification event ← MANDATORY
|
|
195
|
+
6. Mark REQ complete and continue to next
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Anti-Patterns
|
|
199
|
+
|
|
200
|
+
| ❌ Error | ✅ Correct |
|
|
201
|
+
|----------|----------|
|
|
202
|
+
| Edit file → claim done → move to next task | Edit file → run tests + lint → record result → claim done |
|
|
203
|
+
| "Tests should pass" (assertion without evidence) | "Tests passed: 4 passed, 0 failed (npx vitest run)" |
|
|
204
|
+
| Run tests only at end of entire BUILD phase | Run tests after every individual change/REQ |
|
|
205
|
+
| Skip type-check because "I didn't touch types" | Always run `tsc --noEmit` on TypeScript projects |
|
|
206
|
+
|
|
207
|
+
### Harness Integration
|
|
208
|
+
|
|
209
|
+
Better Loop Harness captures change and verification events by inspecting session history. The structured verification events above serve as the canonical signal that:
|
|
210
|
+
- A change occurred (the `change` field)
|
|
211
|
+
- The change was validated (the `verification` field)
|
|
212
|
+
- The outcome is attributable (the `outcome` field ties result to specific change)
|
|
213
|
+
|
|
214
|
+
Without these events, the Harness can only infer changes from file diffs and has no verification signal, resulting in lower "改动验证" (Change Verification) dimension scores.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
147
218
|
## TDD 强制执行
|
|
148
219
|
|
|
149
220
|
### Gate 5a-BLOCK: 新增文件测试强制
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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.
|
|
@@ -269,6 +269,7 @@ next_phase_context: [key info for next phase]
|
|
|
269
269
|
| Clean up CLOSE without backing up sprint-state first | `.sprint-state/` is inside worktree; it's lost on worktree removal. CLOSE step 1 MUST back up to repo-tracked path first |
|
|
270
270
|
| Keep adding random changes after verification failures | Max 3 fix cycles; if still failing, BLOCK and request user decision |
|
|
271
271
|
| Enter next phase without generating Phase Summary | Every phase MUST write `.sprint-state/phase-outputs/phase-{N}-summary.md` and pass transition gate |
|
|
272
|
+
| Complete implementation change without running verification | After every file edit/refactor/feature, MUST run `npm test` + `npm run lint` + `npx tsc --noEmit` and record the structured verification event (see `phase-3-build.md` §In-Session Verification) |
|
|
272
273
|
|
|
273
274
|
---
|
|
274
275
|
|
|
@@ -144,6 +144,77 @@ This enforcement is instructional (LLM follows SKILL.md instructions), not progr
|
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
147
|
+
## In-Session Verification (MANDATORY — v0.14.31+)
|
|
148
|
+
|
|
149
|
+
**Purpose**: Ensure every implementation change is immediately verified and recorded, enabling Better Loop Harness (and other observability tools) to capture normalized change→validation event pairs.
|
|
150
|
+
|
|
151
|
+
**Problem it solves**: Without explicit in-session verification, Agents may edit files and move on without running tests or linters. This creates unverified changes that are invisible to post-hoc review tools, breaking the traceability chain between "what changed" and "was it validated".
|
|
152
|
+
|
|
153
|
+
### Mandatory Verification Protocol
|
|
154
|
+
|
|
155
|
+
After **every** implementation change (file edit, refactor, new feature, bug fix), the Agent MUST execute the following sequence BEFORE claiming the change is complete:
|
|
156
|
+
|
|
157
|
+
1. **Run tests**: `npm test` or `npx vitest run` (or project-specific test command)
|
|
158
|
+
2. **Run linter**: `npm run lint` or `npx eslint .` (or project-specific lint command)
|
|
159
|
+
3. **Type-check** (TypeScript projects): `npx tsc --noEmit`
|
|
160
|
+
4. **Record the result**: Append a structured verification event (see format below)
|
|
161
|
+
|
|
162
|
+
### Verification Event Format
|
|
163
|
+
|
|
164
|
+
Each verification event MUST be recorded as a structured JSON object. Agents should output this to stdout or append to `.sprint-state/phase-outputs/verification-events.jsonl`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"timestamp": "2026-07-22T10:30:00Z",
|
|
169
|
+
"change": {
|
|
170
|
+
"type": "edit|refactor|feature|bugfix",
|
|
171
|
+
"files": ["src/lib/auth.ts", "src/lib/auth.test.ts"],
|
|
172
|
+
"description": "Implement validateToken() for expired token handling"
|
|
173
|
+
},
|
|
174
|
+
"verification": {
|
|
175
|
+
"tests": { "command": "npx vitest run src/lib/auth.test.ts", "status": "pass|fail", "summary": "4 passed, 0 failed" },
|
|
176
|
+
"lint": { "command": "npm run lint", "status": "pass|fail|warn", "summary": "0 errors, 2 warnings" },
|
|
177
|
+
"typecheck": { "command": "npx tsc --noEmit", "status": "pass|fail|skip", "summary": "No type errors" }
|
|
178
|
+
},
|
|
179
|
+
"outcome": "verified|failed|partial",
|
|
180
|
+
"req": "REQ-003"
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Integration with ralph-loop
|
|
185
|
+
|
|
186
|
+
When using ralph-loop mode (default BUILD strategy), each REQ iteration MUST include verification as the final step before marking the REQ complete:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
ralph-loop iteration:
|
|
190
|
+
1. [TDD-RED] Write failing test
|
|
191
|
+
2. [TDD-GREEN] Implement minimal code to pass
|
|
192
|
+
3. [TDD-REFACTOR] Clean up while keeping tests green
|
|
193
|
+
4. [VERIFY] Run tests + lint + typecheck ← MANDATORY
|
|
194
|
+
5. [RECORD] Append verification event ← MANDATORY
|
|
195
|
+
6. Mark REQ complete and continue to next
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Anti-Patterns
|
|
199
|
+
|
|
200
|
+
| ❌ Error | ✅ Correct |
|
|
201
|
+
|----------|----------|
|
|
202
|
+
| Edit file → claim done → move to next task | Edit file → run tests + lint → record result → claim done |
|
|
203
|
+
| "Tests should pass" (assertion without evidence) | "Tests passed: 4 passed, 0 failed (npx vitest run)" |
|
|
204
|
+
| Run tests only at end of entire BUILD phase | Run tests after every individual change/REQ |
|
|
205
|
+
| Skip type-check because "I didn't touch types" | Always run `tsc --noEmit` on TypeScript projects |
|
|
206
|
+
|
|
207
|
+
### Harness Integration
|
|
208
|
+
|
|
209
|
+
Better Loop Harness captures change and verification events by inspecting session history. The structured verification events above serve as the canonical signal that:
|
|
210
|
+
- A change occurred (the `change` field)
|
|
211
|
+
- The change was validated (the `verification` field)
|
|
212
|
+
- The outcome is attributable (the `outcome` field ties result to specific change)
|
|
213
|
+
|
|
214
|
+
Without these events, the Harness can only infer changes from file diffs and has no verification signal, resulting in lower "改动验证" (Change Verification) dimension scores.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
147
218
|
## TDD 强制执行
|
|
148
219
|
|
|
149
220
|
### Gate 5a-BLOCK: 新增文件测试强制
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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.15.1",
|
|
4
4
|
"displayName": "XP-Gate",
|
|
5
5
|
"description": "Extreme Programming quality gates + AI workflow skills for Qoder. Includes 10 quality gates (Gate 0-9), Sprint Flow (11 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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-23
|
|
4
|
+
**Commit:** 8eadbb9
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.15.1.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.
|
|
@@ -20,15 +20,20 @@ export class PythonAdapter extends BaseAdapter implements Adapter {
|
|
|
20
20
|
|
|
21
21
|
extractFunctions(): unknown[] {
|
|
22
22
|
const functionMatches = [];
|
|
23
|
-
const fnRegex = /(async\s+)?def\s+(\w+)\s*\([^)]
|
|
23
|
+
const fnRegex = /(async\s+)?def\s+(\w+)\s*\(([^)]*)\)\s*:/g;
|
|
24
24
|
let match;
|
|
25
25
|
|
|
26
26
|
while ((match = fnRegex.exec(this.fileContent)) !== null) {
|
|
27
|
+
const code = this.getCodeBlock(match.index);
|
|
28
|
+
const line = this.getLineNumber(match.index);
|
|
27
29
|
functionMatches.push({
|
|
28
30
|
name: match[2],
|
|
29
31
|
type: match[1] ? 'async_function' : 'function',
|
|
30
|
-
line
|
|
31
|
-
|
|
32
|
+
line,
|
|
33
|
+
startLine: line,
|
|
34
|
+
length: code.split('\n').length,
|
|
35
|
+
params: match[3] ? match[3].split(',').filter(p => p.trim()).length : 0,
|
|
36
|
+
code
|
|
32
37
|
});
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -41,17 +46,45 @@ export class PythonAdapter extends BaseAdapter implements Adapter {
|
|
|
41
46
|
let match;
|
|
42
47
|
|
|
43
48
|
while ((match = classRegex.exec(this.fileContent)) !== null) {
|
|
49
|
+
const code = this.getCodeBlock(match.index);
|
|
50
|
+
const line = this.getLineNumber(match.index);
|
|
51
|
+
// Count methods in class body
|
|
52
|
+
const methodRegex = /(?:async\s+)?def\s+\w+/g;
|
|
53
|
+
const methods = code.match(methodRegex) || [];
|
|
44
54
|
classMatches.push({
|
|
45
55
|
name: match[1],
|
|
46
56
|
type: 'class',
|
|
47
|
-
line
|
|
48
|
-
|
|
57
|
+
line,
|
|
58
|
+
startLine: line,
|
|
59
|
+
length: code.split('\n').length,
|
|
60
|
+
methodCount: methods.length,
|
|
61
|
+
code
|
|
49
62
|
});
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
return classMatches;
|
|
53
66
|
}
|
|
54
67
|
|
|
68
|
+
extractExports(): unknown[] {
|
|
69
|
+
// Python: module-level functions and classes are considered "exports"
|
|
70
|
+
const exports: unknown[] = [];
|
|
71
|
+
const topLevelDefRegex = /^(?:async\s+)?def\s+(\w+)/gm;
|
|
72
|
+
const topLevelClassRegex = /^class\s+(\w+)/gm;
|
|
73
|
+
let match;
|
|
74
|
+
|
|
75
|
+
while ((match = topLevelDefRegex.exec(this.fileContent)) !== null) {
|
|
76
|
+
if (!match[1].startsWith('_')) {
|
|
77
|
+
exports.push({ name: match[1], type: 'function', line: this.getLineNumber(match.index) });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
while ((match = topLevelClassRegex.exec(this.fileContent)) !== null) {
|
|
81
|
+
if (!match[1].startsWith('_')) {
|
|
82
|
+
exports.push({ name: match[1], type: 'class', line: this.getLineNumber(match.index) });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return exports;
|
|
86
|
+
}
|
|
87
|
+
|
|
55
88
|
private getCodeBlock(startPos: number): string {
|
|
56
89
|
const lines = this.fileContent.split('\n');
|
|
57
90
|
const startLine = this.getLineNumber(startPos) - 1;
|
|
@@ -75,7 +108,7 @@ export class PythonAdapter extends BaseAdapter implements Adapter {
|
|
|
75
108
|
}
|
|
76
109
|
}
|
|
77
110
|
|
|
78
|
-
if (codeLines.length >
|
|
111
|
+
if (codeLines.length > 200) break;
|
|
79
112
|
}
|
|
80
113
|
|
|
81
114
|
return codeLines.join('\n');
|