@boyingliu01/xp-gate 0.34.1 → 0.35.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.
Files changed (38) hide show
  1. package/bin/xp-gate.js +8 -0
  2. package/gate-3.sh +46 -2
  3. package/gate-4.sh +20 -3
  4. package/hooks/gate-3.sh +46 -2
  5. package/hooks/gate-4.sh +20 -3
  6. package/hooks/lib/ccn-ratchet.sh +109 -0
  7. package/hooks/pre-commit +92 -0
  8. package/lib/__tests__/doctor-timeout-partial.test.js +79 -0
  9. package/lib/__tests__/rework.test.js +127 -0
  10. package/lib/doctor.js +60 -3
  11. package/lib/gate-audit.ts +8 -0
  12. package/lib/mattpocock-license-verdict.json +1 -1
  13. package/lib/rework.js +262 -0
  14. package/mock-policy/AGENTS.md +2 -2
  15. package/mutation/AGENTS.md +2 -2
  16. package/package.json +1 -1
  17. package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
  18. package/plugins/claude-code/skills/delphi-review/AGENTS.md +2 -2
  19. package/plugins/claude-code/skills/sprint-flow/AGENTS.md +2 -2
  20. package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +2 -2
  21. package/plugins/dsh/package.json +1 -1
  22. package/plugins/dsh/skills/delphi-review/AGENTS.md +2 -2
  23. package/plugins/dsh/skills/sprint-flow/AGENTS.md +2 -2
  24. package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +2 -2
  25. package/plugins/opencode/package.json +1 -1
  26. package/plugins/opencode/skills/delphi-review/AGENTS.md +2 -2
  27. package/plugins/opencode/skills/sprint-flow/AGENTS.md +2 -2
  28. package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +2 -2
  29. package/plugins/qoder/plugin.json +1 -1
  30. package/plugins/qoder/skills/delphi-review/AGENTS.md +2 -2
  31. package/plugins/qoder/skills/sprint-flow/AGENTS.md +2 -2
  32. package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +2 -2
  33. package/principles/AGENTS.md +2 -2
  34. package/scripts/__tests__/sync-package-content-isolation.test.js +73 -0
  35. package/scripts/__tests__/sync-package-content.test.js +109 -2
  36. package/skills/delphi-review/AGENTS.md +2 -2
  37. package/skills/sprint-flow/AGENTS.md +2 -2
  38. package/skills/test-specification-alignment/AGENTS.md +2 -2
package/lib/doctor.js CHANGED
@@ -80,6 +80,38 @@ const EXEC_TIMEOUT_MS = 1500;
80
80
  */
81
81
  const GLOBAL_DIAGNOSIS_TIMEOUT_MS = 10000;
82
82
 
83
+ /**
84
+ * Merge a timed-out partial diagnosis into one honest verdict (#629).
85
+ *
86
+ * `doctor`'s global timeout (#348) exists so the command never hangs, but the
87
+ * original handler threw away the entire `diagnoseAsync()` result and substituted
88
+ * a single placeholder check. Against an identical healthy install that made the
89
+ * SAME command print "All checks passed" or "Timed out after 10s" depending on
90
+ * machine load, and a timed-out run reported 0 installed skills — doctor giving
91
+ * LESS information the LONGER it runs is the opposite of a diagnostic.
92
+ *
93
+ * Keeps every completed check, adds ONE Diagnosis notice naming what did not
94
+ * report, and never lets a partial run read as clean (#495).
95
+ *
96
+ * @param {{checks?: Array, issues?: number}} partial checks finished before the deadline
97
+ * @param {string[]} pending names of surfaces that did not report in time
98
+ */
99
+ function mergeTimedOutDiagnosis(partial, pending) {
100
+ const completed = (partial && Array.isArray(partial.checks)) ? partial.checks : [];
101
+ const inherited = (partial && Number.isFinite(partial.issues)) ? partial.issues : 0;
102
+ const pendingNames = Array.isArray(pending) ? pending.filter(Boolean) : [];
103
+ const detail = pendingNames.length > 0
104
+ ? `Timed out after ${GLOBAL_DIAGNOSIS_TIMEOUT_MS / 1000}s — did not report in time: ${pendingNames.join(', ')}`
105
+ : `Timed out after ${GLOBAL_DIAGNOSIS_TIMEOUT_MS / 1000}s — some checks incomplete`;
106
+ return {
107
+ checks: [...completed, { name: 'Diagnosis', status: 'WARN', detail }],
108
+ // A partial run is never clean, and a real issue count is never reset.
109
+ issues: Math.max(inherited, 1),
110
+ timedOut: true,
111
+ completedCheckCount: completed.length,
112
+ };
113
+ }
114
+
83
115
  /**
84
116
  * Fixed attribution text for the WorkBuddy-desktop sandbox restriction (#525).
85
117
  *
@@ -1605,9 +1637,17 @@ async function checkAdapters(checks, mode, gitDirPromise) {
1605
1637
  * D) Env + CLI tools — fully independent, run IN PARALLEL
1606
1638
  * E) TUI + Skills — independent, run IN PARALLEL
1607
1639
  */
1608
- async function diagnoseAsync(refreshEnv = false) {
1640
+ async function diagnoseAsync(refreshEnv = false, progress = null) {
1641
+ // #629: `progress` is a live view of the checks completed so far. The global
1642
+ // timeout used to discard everything diagnoseAsync had already produced; with a
1643
+ // shared sink, a deadline can report "these finished, those did not" instead of
1644
+ // replacing the whole diagnosis with a placeholder.
1609
1645
  const checks = [];
1610
1646
  let issues = 0;
1647
+ if (progress) {
1648
+ progress.checks = checks;
1649
+ progress.getIssues = () => issues;
1650
+ }
1611
1651
 
1612
1652
  // Spawn capability probe FIRST (sync, no config dependency) — #525: it must
1613
1653
  // report even when the config early-exits below, and its WARN (environmental,
@@ -2869,10 +2909,26 @@ async function doctor(args) {
2869
2909
 
2870
2910
  // Global timeout wrapper — ensures doctor completes within GLOBAL_DIAGNOSIS_TIMEOUT_MS
2871
2911
  // even if network/subprocess checks stack up (fix #348: 43s on Windows).
2872
- const diagnosisPromise = diagnoseAsync(refreshEnv);
2912
+ // #629: give diagnoseAsync a live sink so a deadline can keep what finished.
2913
+ // Without it, `Promise.race` discarded the entire diagnosis -- so the SAME
2914
+ // healthy install reported different results run to run, and a timed-out run
2915
+ // lost the skills section entirely (scrapers read 0/12 installed skills).
2916
+ const progress = { checks: [], getIssues: () => 0 };
2917
+ const diagnosisPromise = diagnoseAsync(refreshEnv, progress);
2873
2918
  let diagnosisTimer = null;
2874
2919
  const timeoutPromise = new Promise((resolve) => {
2875
- diagnosisTimer = setTimeout(() => resolve({ checks: [{ name: 'Diagnosis', status: 'WARN', detail: `Timed out after ${GLOBAL_DIAGNOSIS_TIMEOUT_MS / 1000}s — some checks incomplete` }], issues: 0, timedOut: true }), GLOBAL_DIAGNOSIS_TIMEOUT_MS);
2920
+ diagnosisTimer = setTimeout(() => {
2921
+ const completed = Array.isArray(progress.checks) ? progress.checks : [];
2922
+ const reported = new Set(completed.map((c) => c && c.name));
2923
+ // Name the surfaces that did NOT report, so the reader knows exactly which
2924
+ // conclusions are missing rather than just "something timed out".
2925
+ const pending = ['Hooks', 'Adapters', 'Skills', 'Gate env', 'OpenCode TUI']
2926
+ .filter((name) => !reported.has(name));
2927
+ resolve(mergeTimedOutDiagnosis(
2928
+ { checks: completed, issues: progress.getIssues() },
2929
+ pending,
2930
+ ));
2931
+ }, GLOBAL_DIAGNOSIS_TIMEOUT_MS);
2876
2932
  });
2877
2933
  const { checks, issues: diagnosedIssues, timedOut } = await Promise.race([
2878
2934
  diagnosisPromise.then(r => ({ ...r, timedOut: false })),
@@ -3349,6 +3405,7 @@ module.exports = {
3349
3405
  readTuiJson,
3350
3406
  formatDoctorJson,
3351
3407
  diagnoseHookDrift,
3408
+ mergeTimedOutDiagnosis,
3352
3409
  classifyHooksDir,
3353
3410
  syncGlobalHooksFromRepo,
3354
3411
  diagnoseModuleDrift,
package/lib/gate-audit.ts CHANGED
@@ -41,6 +41,12 @@ export interface GateAuditEntry {
41
41
  duration_anomaly?: boolean; // Issue #370: set when duration_ms > max_duration_ms
42
42
  duration_reason?: 'poisoned_start_ms' | 'clock_skew'; // REQ-B: why duration_ms is null
43
43
  detail?: string; // #507: optional gate-specific payload (e.g. effective CCN threshold)
44
+ /**
45
+ * #651: WHY the gate blocked. Without this the journal can only answer "how
46
+ * many failed", never "which rule fails most" — and the second question is the
47
+ * one that drives fixes. Only meaningful when passed=false.
48
+ */
49
+ failure_reason?: string;
44
50
  }
45
51
 
46
52
  // ── Public API ───────────────────────────────────────────────────────────────
@@ -415,6 +421,8 @@ function runCli(): void {
415
421
  ...(durationReason ? { duration_reason: durationReason as 'poisoned_start_ms' | 'clock_skew' } : {}),
416
422
  // #507: only set when provided (omit field otherwise)
417
423
  ...(opts['detail'] ? { detail: opts['detail'] } : {}),
424
+ // #651: only set when provided, so successful records stay byte-identical.
425
+ ...(opts['failure-reason'] ? { failure_reason: String(opts['failure-reason']).slice(0, 300) } : {}),
418
426
  };
419
427
  // Pre-commit (trigger=commit) is staging for a commit that does not exist
420
428
  // yet: park it in the pending sidecar so post-commit can stamp the real
@@ -2,6 +2,6 @@
2
2
  "verdict": "PASS",
3
3
  "license_type": "MIT",
4
4
  "sha256": "0e7ac423bf2c6e223b7c5b156f8cf72da49d748e56a1641402c31f22ad07dbb5",
5
- "checked_at": "2026-10-30T14:53:53.917Z",
5
+ "checked_at": "2026-10-30T15:51:17.008Z",
6
6
  "source": "network"
7
7
  }
package/lib/rework.js ADDED
@@ -0,0 +1,262 @@
1
+ /**
2
+ * `xp-gate rework` — what the gate journal says about rework (#651).
3
+ *
4
+ * `xp-gate retro` already answers "how much did we ship". This answers the
5
+ * narrower and more actionable question: how often does a round of work clear
6
+ * the gates on the first attempt, and which rule stops it most.
7
+ *
8
+ * The reason this needs a dedicated command rather than a `retro` line: before
9
+ * #651 the journal contained NO failure records at all, so a naive rework rate
10
+ * computed from it returned 100% every time. A metric that reads "perfect" when
11
+ * it is actually unmeasured is worse than no metric -- it manufactures
12
+ * confidence. So `measurable: false` is a first-class outcome here.
13
+ *
14
+ * No runtime dependencies: this ships inside the zero-install package.
15
+ */
16
+ 'use strict';
17
+
18
+ const fs = require('node:fs');
19
+ const path = require('node:path');
20
+
21
+ const AUDIT_DIR = '.xp-gate';
22
+ const AUDIT_FILE = 'audit.jsonl';
23
+ const PENDING_FILE = 'audit.pending.jsonl';
24
+
25
+ /** Bucket name for failures the journal cannot attribute to a rule. */
26
+ const UNATTRIBUTED = 'unattributed';
27
+
28
+ /**
29
+ * Read every journal record under `repoRoot`, oldest first.
30
+ *
31
+ * Malformed lines are skipped rather than thrown on: the journal is append-only
32
+ * and a single truncated write must not take the whole report down.
33
+ *
34
+ * @param {string} [repoRoot]
35
+ * @returns {Array<object>}
36
+ */
37
+ function readJournal(repoRoot = process.cwd()) {
38
+ const dir = path.join(repoRoot, AUDIT_DIR);
39
+ const entries = [];
40
+ for (const file of [AUDIT_FILE, PENDING_FILE]) {
41
+ const full = path.join(dir, file);
42
+ let raw;
43
+ try {
44
+ raw = fs.readFileSync(full, 'utf8');
45
+ } catch {
46
+ continue;
47
+ }
48
+ for (const line of raw.split('\n')) {
49
+ if (!line.trim()) continue;
50
+ try {
51
+ const parsed = JSON.parse(line);
52
+ if (parsed && typeof parsed === 'object') entries.push(parsed);
53
+ } catch {
54
+ /* truncated/garbled line -- skip, do not fail the report */
55
+ }
56
+ }
57
+ }
58
+ return entries;
59
+ }
60
+
61
+ /** Median of a numeric array (0 for an empty array). */
62
+ function median(values) {
63
+ if (values.length === 0) return 0;
64
+ const sorted = [...values].sort((a, b) => a - b);
65
+ const mid = Math.floor(sorted.length / 2);
66
+ return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
67
+ }
68
+
69
+ /** Mean of a numeric array (0 for an empty array). */
70
+ function mean(values) {
71
+ if (values.length === 0) return 0;
72
+ return values.reduce((a, b) => a + b, 0) / values.length;
73
+ }
74
+
75
+ /**
76
+ * Group a flat record list into rework rounds.
77
+ *
78
+ * The journal is a flat stream of gate executions with no round identifier, so a
79
+ * round is reconstructed the only way the data allows: a run of FAIL records
80
+ * terminated by the next PASS. That is exactly "how many attempts before this
81
+ * landed", which is the definition rework needs. A trailing run of failures with
82
+ * no resolving pass is a round that has not landed yet, and is counted as
83
+ * `unresolved` rather than being dropped.
84
+ *
85
+ * @param {Array<object>} entries
86
+ */
87
+ function groupRounds(entries) {
88
+ const rounds = [];
89
+ let current = 0;
90
+ for (const entry of entries) {
91
+ if (entry.passed) {
92
+ if (current > 0) rounds.push(current);
93
+ current = 0;
94
+ continue;
95
+ }
96
+ current += 1;
97
+ }
98
+ return { resolved: rounds, unresolved: current };
99
+ }
100
+
101
+ /**
102
+ * Aggregate the journal into rework metrics.
103
+ *
104
+ * @param {Array<object>} entries journal records
105
+ * @returns {object} see AC-670-59..62
106
+ */
107
+ function computeReworkStats(entries) {
108
+ const list = Array.isArray(entries) ? entries : [];
109
+ const totals = list.length;
110
+ const failures = list.filter((e) => e.passed === false).length;
111
+ const passes = totals - failures;
112
+
113
+ // ── Failures by reason ────────────────────────────────────────────────────
114
+ // Unlabelled failures are bucketed, never dropped: dropping them would lower
115
+ // the failure count and push the first-pass rate UP, which is the optimistic
116
+ // direction and therefore the dangerous one.
117
+ const byReason = new Map();
118
+ for (const entry of list) {
119
+ if (entry.passed !== false) continue;
120
+ const raw = typeof entry.failure_reason === 'string' ? entry.failure_reason.trim() : '';
121
+ const key = raw === '' ? UNATTRIBUTED : raw;
122
+ byReason.set(key, (byReason.get(key) || 0) + 1);
123
+ }
124
+ const topFailures = [...byReason.entries()]
125
+ .map(([reason, count]) => ({ reason, count }))
126
+ .sort((a, b) => b.count - a.count || a.reason.localeCompare(b.reason));
127
+
128
+ // ── Durations ─────────────────────────────────────────────────────────────
129
+ // Two independent guards, because the flag alone is not enough:
130
+ //
131
+ // 1. honour `duration_anomaly` -- the writer's own verdict;
132
+ // 2. reject implausible magnitudes. Measured on the real journal: 391 records
133
+ // carry the flag, but 6 MORE epoch-sized values (up to 1.78e12) do not,
134
+ // so trusting the flag alone left the mean at 1.3e9 ms -- the very
135
+ // "average 430 million seconds" artifact this is supposed to kill.
136
+ //
137
+ // The ceiling is deliberately generous (1 hour): a real gate run that long is
138
+ // pathological but conceivable, while an epoch stamp is ~1.78e12 and cannot be
139
+ // mistaken for anything else.
140
+ const MAX_PLAUSIBLE_DURATION_MS = 60 * 60 * 1000;
141
+ const isPlausible = (e) => typeof e.duration_ms === 'number'
142
+ && Number.isFinite(e.duration_ms)
143
+ && e.duration_ms >= 0
144
+ && e.duration_ms <= MAX_PLAUSIBLE_DURATION_MS
145
+ && e.duration_anomaly !== true;
146
+ const sane = list.filter(isPlausible);
147
+ const duration = sane.length > 0
148
+ ? {
149
+ medianMs: median(sane.map((e) => e.duration_ms)),
150
+ meanMs: Math.round(mean(sane.map((e) => e.duration_ms))),
151
+ samples: sane.length,
152
+ // Every record that did NOT contribute -- flagged or implausible. Reporting
153
+ // only the flagged count would understate the exclusion and make the
154
+ // sample size look closer to the record count than it is.
155
+ excludedAnomalies: list.filter((e) => typeof e.duration_ms === 'number' && !isPlausible(e)).length,
156
+ }
157
+ : null;
158
+
159
+ // ── Rounds ────────────────────────────────────────────────────────────────
160
+ const rounds = groupRounds(list);
161
+ const reworkRounds = rounds.resolved;
162
+
163
+ // ── First-pass rate ───────────────────────────────────────────────────────
164
+ // Undefined without failures. A rate over an empty failure set is not 100%.
165
+ const measurable = failures > 0;
166
+ const firstPassRate = measurable ? Math.round((passes / totals) * 1000) / 10 : null;
167
+
168
+ return {
169
+ measurable,
170
+ reason: measurable ? null : 'no failure records in the journal -- first-pass rate is not measurable (pre-#651 journals only recorded passes)',
171
+ totalRecords: totals,
172
+ passes,
173
+ failures,
174
+ firstPassRate,
175
+ rounds: {
176
+ resolved: reworkRounds.length,
177
+ unresolved: rounds.unresolved > 0,
178
+ medianRework: median(reworkRounds),
179
+ meanRework: Math.round(mean(reworkRounds) * 100) / 100,
180
+ worstRework: reworkRounds.length > 0 ? Math.max(...reworkRounds) : 0,
181
+ },
182
+ topFailures,
183
+ duration,
184
+ };
185
+ }
186
+
187
+ /** Render a stats object for the terminal. */
188
+ function formatReworkReport(stats, { limit = 10 } = {}) {
189
+ const lines = [];
190
+ lines.push('');
191
+ lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
192
+ lines.push(' REWORK REPORT');
193
+ lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
194
+ lines.push('');
195
+ lines.push(` Journal records: ${stats.totalRecords} (${stats.passes} pass, ${stats.failures} fail)`);
196
+
197
+ if (!stats.measurable) {
198
+ // Say WHY, and say it loudly: a silent 100% would be a lie.
199
+ lines.push('');
200
+ lines.push(' ⚠️ First-pass rate: NOT MEASURABLE');
201
+ lines.push(` ${stats.reason}`);
202
+ } else {
203
+ lines.push(` First-pass rate: ${stats.firstPassRate}%`);
204
+ }
205
+
206
+ if (stats.rounds.resolved > 0) {
207
+ lines.push('');
208
+ lines.push(` Rework rounds (failures before a landing): ${stats.rounds.resolved}`);
209
+ lines.push(` median ${stats.rounds.medianRework} / mean ${stats.rounds.meanRework} / worst ${stats.rounds.worstRework}`);
210
+ if (stats.rounds.unresolved) {
211
+ lines.push(' (a trailing run of failures has not landed yet)');
212
+ }
213
+ }
214
+
215
+ if (stats.topFailures.length > 0) {
216
+ lines.push('');
217
+ lines.push(` Top ${limit} blocking reasons:`);
218
+ for (const { reason, count } of stats.topFailures.slice(0, limit)) {
219
+ lines.push(` ${String(count).padStart(5)} ${reason}`);
220
+ }
221
+ }
222
+
223
+ if (stats.duration) {
224
+ lines.push('');
225
+ lines.push(` Gate duration: median ${stats.duration.medianMs} ms / mean ${stats.duration.meanMs} ms (${stats.duration.samples} samples`);
226
+ lines.push(` ${stats.duration.excludedAnomalies} anomaly record(s) excluded)`);
227
+ }
228
+
229
+ lines.push('');
230
+ return lines.join('\n');
231
+ }
232
+
233
+ /**
234
+ * CLI entry.
235
+ * @param {string[]} argv args after `rework`
236
+ */
237
+ function main(argv = []) {
238
+ const repoRootIdx = argv.indexOf('--dir');
239
+ const repoRoot = repoRootIdx !== -1 && argv[repoRootIdx + 1] ? argv[repoRootIdx + 1] : process.cwd();
240
+ const limitIdx = argv.indexOf('--top');
241
+ const limit = limitIdx !== -1 && argv[limitIdx + 1] ? parseInt(argv[limitIdx + 1], 10) : 10;
242
+
243
+ const stats = computeReworkStats(readJournal(repoRoot));
244
+ if (argv.includes('--json')) {
245
+ process.stdout.write(`${JSON.stringify(stats, null, 2)}\n`);
246
+ return 0;
247
+ }
248
+ process.stdout.write(`${formatReworkReport(stats, { limit })}\n`);
249
+ return 0;
250
+ }
251
+
252
+ module.exports = {
253
+ readJournal,
254
+ computeReworkStats,
255
+ formatReworkReport,
256
+ main,
257
+ UNATTRIBUTED,
258
+ };
259
+
260
+ if (require.main === module) {
261
+ process.exitCode = main(process.argv.slice(2));
262
+ }
@@ -1,9 +1,9 @@
1
1
  # SRC/MOCK-POLICY KNOWLEDGE BASE
2
2
 
3
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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.
@@ -1,9 +1,9 @@
1
1
  # SRC/MUTATION KNOWLEDGE BASE
2
2
 
3
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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": "@boyingliu01/xp-gate",
3
- "version": "0.34.1",
3
+ "version": "0.35.1",
4
4
  "description": "AI-driven development workflow: 6 quality gates + Delphi review + Sprint Flow",
5
5
  "bin": {
6
6
  "xp-gate": "bin/xp-gate.js"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xp-gate",
3
- "version": "0.34.1",
3
+ "version": "0.35.1",
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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.1.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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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": "@boyingliu01/dsh-plugin-xp-gate",
3
- "version": "0.34.1",
3
+ "version": "0.35.1",
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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.1.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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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": "@boyingliu01/opencode-plugin",
3
- "version": "0.34.1",
3
+ "version": "0.35.1",
4
4
  "type": "module",
5
5
  "main": "index.ts",
6
6
  "description": "XP-Gate quality gates + AI workflow skills + Sprint Flow TUI sidebar for OpenCode",
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.1.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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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.34.1",
3
+ "version": "0.35.1",
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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.1.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:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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
  # PRINCIPLES CHECKER MODULE
2
2
 
3
3
  **Generated:** 2026-10-30
4
- **Commit:** e583bcfb
4
+ **Commit:** 2ce96f13
5
5
  **Branch:** main
6
- **Version:** 0.34.1.0
6
+ **Version:** 0.35.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.