@boyingliu01/xp-gate 0.12.4 → 0.12.6

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.
@@ -47,7 +47,16 @@ run_tests() {
47
47
  echo "Running Python tests..."
48
48
  PYTEST_OUTPUT=$(pytest --exitfirst --tb=short 2>&1)
49
49
  PYTEST_EXIT=$?
50
- echo "$PYTEST_OUTPUT" | tail -30
50
+
51
+ # Show the short summary tail — this is where FAILED/assert diagnostics live.
52
+ # With --exitfirst we stop at the first failure, so the last ~10 lines are the
53
+ # most actionable: they contain the test name, assert expression, and expected
54
+ # vs actual values. Full output is saved to /tmp/ for post-mortem inspection.
55
+ echo "$PYTEST_OUTPUT" | grep -E "(FAILED|PASSED|passed|failed|error|ERROR|assert)" | tail -10
56
+ echo "$PYTEST_OUTPUT" | tail -5
57
+
58
+ # Save full output for post-mortem inspection
59
+ echo "$PYTEST_OUTPUT" > /tmp/xp-gate-pytest-output-$$.log
51
60
 
52
61
  # Check for collection errors (ModuleNotFoundError / ImportError)
53
62
  if echo "$PYTEST_OUTPUT" | grep -qi "ModuleNotFoundError\|ImportError"; then
@@ -78,7 +87,9 @@ run_coverage() {
78
87
  echo "Running Python coverage..."
79
88
  PYTEST_OUTPUT=$(pytest --exitfirst --tb=short --cov=. --cov-fail-under=80 2>&1)
80
89
  PYTEST_EXIT=$?
81
- echo "$PYTEST_OUTPUT" | tail -30
90
+ echo "$PYTEST_OUTPUT" | grep -E "(FAILED|PASSED|passed|failed|error|ERROR|TOTAL|assert)" | tail -10
91
+ echo "$PYTEST_OUTPUT" | tail -5
92
+ echo "$PYTEST_OUTPUT" > /tmp/xp-gate-pytest-cov-output-$$.log
82
93
 
83
94
  # Check for collection errors (ModuleNotFoundError / ImportError)
84
95
  if echo "$PYTEST_OUTPUT" | grep -qi "ModuleNotFoundError\|ImportError"; then
package/gate-9.sh CHANGED
@@ -1,14 +1,14 @@
1
1
  # ============================================================================
2
- # GATE 9: Semgrep SAST Security Scan
2
+ # GATE 10: Semgrep SAST Security Scan
3
3
  # Detects security vulnerabilities (SQL injection, XSS, etc.) in staged files
4
4
  # Tool: semgrep -- https://semgrep.dev
5
5
  # ============================================================================
6
6
 
7
7
  2>&1 echo ""
8
- 2>&1 echo "→ Gate 9: Semgrep SAST Security Scan..."
9
- GATE_9_START=$(gate_start_ms)
8
+ 2>&1 echo "→ Gate 10: Semgrep SAST Security Scan..."
9
+ GATE_10_START=$(gate_start_ms)
10
10
 
11
- GATE_9_STATUS=""
11
+ GATE_10_STATUS=""
12
12
 
13
13
  # Semgrep availability check
14
14
  SEMGREP_CMD=""
@@ -22,15 +22,15 @@ if [ -z "$SEMGREP_CMD" ]; then
22
22
  echo " ⚠️ WARN - semgrep not installed — SAST scanning unavailable"
23
23
  echo " Install: brew install semgrep (macOS) | pip install semgrep (Linux) | pip install semgrep (Windows)"
24
24
  echo " Pre-cache rules: semgrep --config=p/security-audit"
25
- echo " Gate 9: SAST Security (WARN, semgrep not installed)"
26
- GATE_9_STATUS="WARN"
25
+ echo " Gate 10: SAST Security (WARN, semgrep not installed)"
26
+ GATE_10_STATUS="WARN"
27
27
  else
28
28
  # Get staged files filtered to Semgrep-supported languages
29
29
  SEMGREP_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null | grep -E '\.(ts|tsx|js|jsx|py|go|java|c|cpp|cs|rb|php|scala|swift)$' || true)
30
30
 
31
31
  if [ -z "$SEMGREP_FILES" ]; then
32
32
  echo " ⏭️ SKIPPED - SAST (no supported language files changed)"
33
- GATE_9_STATUS="SKIP"
33
+ GATE_10_STATUS="SKIP"
34
34
  else
35
35
  # Run semgrep with JSON output
36
36
  # --config=p/security-audit: explicit security ruleset
@@ -41,7 +41,7 @@ else
41
41
 
42
42
  if [ "$SEMGREP_EXIT" -eq 0 ]; then
43
43
  echo " ✅ PASSED - No security vulnerabilities found."
44
- GATE_9_STATUS="PASS"
44
+ GATE_10_STATUS="PASS"
45
45
  elif [ "$SEMGREP_EXIT" -eq 1 ]; then
46
46
  # Findings detected - parse JSON to categorize
47
47
  CRITICAL_HIGH=$(echo "$SEMGREP_OUTPUT" | python3 -c "
@@ -99,7 +99,7 @@ except:
99
99
  if [ "$CRITICAL_HIGH" -gt 0 ]; then
100
100
  echo ""
101
101
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
102
- echo " GATE 9: Semgrep Security Gate"
102
+ echo " GATE 10: Semgrep Security Gate"
103
103
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
104
104
  echo " CRITICAL/HIGH: ${CRITICAL_HIGH} ❌ BLOCKED"
105
105
  echo " MEDIUM/LOW: ${MEDIUM_LOW} ⚠️ warning"
@@ -108,7 +108,7 @@ except:
108
108
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
109
109
  echo "$FINDING_DETAILS"
110
110
  echo " Run 'semgrep scan --config=p/security-audit' to review all findings."
111
- GATE_9_STATUS="FAIL"
111
+ GATE_10_STATUS="FAIL"
112
112
  exit 1
113
113
  else
114
114
  echo ""
@@ -117,14 +117,14 @@ except:
117
117
  echo " ⚠️ ${MEDIUM_LOW} medium/low findings (warnings only)"
118
118
  echo "$FINDING_DETAILS"
119
119
  fi
120
- GATE_9_STATUS="PASS"
120
+ GATE_10_STATUS="PASS"
121
121
  fi
122
122
  else
123
123
  # semgrep runtime error (timeout, config error, etc.)
124
124
  echo " ⚠️ semgrep exited with code ${SEMGREP_EXIT} — skipping gate"
125
125
  echo " ⏭️ SKIPPED - SAST (semgrep runtime error)"
126
- GATE_9_STATUS="SKIP"
126
+ GATE_10_STATUS="SKIP"
127
127
  fi
128
128
  fi
129
129
  fi
130
- record_gate_audit "gate-9" "sast-security" "$GATE_9_STATUS" "0" "$GATE_9_START"
130
+ record_gate_audit "gate-10" "sast-security" "$GATE_10_STATUS" "0" "$GATE_10_START"
@@ -0,0 +1,130 @@
1
+ # ============================================================================
2
+ # GATE 10: Semgrep SAST Security Scan
3
+ # Detects security vulnerabilities (SQL injection, XSS, etc.) in staged files
4
+ # Tool: semgrep -- https://semgrep.dev
5
+ # ============================================================================
6
+
7
+ 2>&1 echo ""
8
+ 2>&1 echo "→ Gate 10: Semgrep SAST Security Scan..."
9
+ GATE_10_START=$(gate_start_ms)
10
+
11
+ GATE_10_STATUS=""
12
+
13
+ # Semgrep availability check
14
+ SEMGREP_CMD=""
15
+ if command -v semgrep >/dev/null 2>&1; then
16
+ SEMGREP_CMD="semgrep"
17
+ elif [ -f "$HOME/.local/bin/semgrep" ]; then
18
+ SEMGREP_CMD="$HOME/.local/bin/semgrep"
19
+ fi
20
+
21
+ if [ -z "$SEMGREP_CMD" ]; then
22
+ echo " ⚠️ WARN - semgrep not installed — SAST scanning unavailable"
23
+ echo " Install: brew install semgrep (macOS) | pip install semgrep (Linux) | pip install semgrep (Windows)"
24
+ echo " Pre-cache rules: semgrep --config=p/security-audit"
25
+ echo " Gate 10: SAST Security (WARN, semgrep not installed)"
26
+ GATE_10_STATUS="WARN"
27
+ else
28
+ # Get staged files filtered to Semgrep-supported languages
29
+ SEMGREP_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null | grep -E '\.(ts|tsx|js|jsx|py|go|java|c|cpp|cs|rb|php|scala|swift)$' || true)
30
+
31
+ if [ -z "$SEMGREP_FILES" ]; then
32
+ echo " ⏭️ SKIPPED - SAST (no supported language files changed)"
33
+ GATE_10_STATUS="SKIP"
34
+ else
35
+ # Run semgrep with JSON output
36
+ # --config=p/security-audit: explicit security ruleset
37
+ # --json: machine-readable output
38
+ # --disable-version-check: skip network call
39
+ SEMGREP_OUTPUT=$($SEMGREP_CMD scan --config=p/security-audit --json --disable-version-check $SEMGREP_FILES 2>&1)
40
+ SEMGREP_EXIT=$?
41
+
42
+ if [ "$SEMGREP_EXIT" -eq 0 ]; then
43
+ echo " ✅ PASSED - No security vulnerabilities found."
44
+ GATE_10_STATUS="PASS"
45
+ elif [ "$SEMGREP_EXIT" -eq 1 ]; then
46
+ # Findings detected - parse JSON to categorize
47
+ CRITICAL_HIGH=$(echo "$SEMGREP_OUTPUT" | python3 -c "
48
+ import sys, json
49
+ try:
50
+ data = json.load(sys.stdin)
51
+ results = data.get('results', [])
52
+ count = 0
53
+ for r in results:
54
+ extra = r.get('extra', {})
55
+ severity = extra.get('severity', '').upper()
56
+ if severity in ('CRITICAL', 'HIGH'):
57
+ count += 1
58
+ print(count)
59
+ except:
60
+ print('0')
61
+ " 2>/dev/null || echo "0")
62
+
63
+ MEDIUM_LOW=$(echo "$SEMGREP_OUTPUT" | python3 -c "
64
+ import sys, json
65
+ try:
66
+ data = json.load(sys.stdin)
67
+ results = data.get('results', [])
68
+ count = 0
69
+ for r in results:
70
+ extra = r.get('extra', {})
71
+ severity = extra.get('severity', '').upper()
72
+ if severity in ('MEDIUM', 'LOW'):
73
+ count += 1
74
+ print(count)
75
+ except:
76
+ print('0')
77
+ " 2>/dev/null || echo "0")
78
+
79
+ # Extract top finding details
80
+ FINDING_DETAILS=$(echo "$SEMGREP_OUTPUT" | python3 -c "
81
+ import sys, json
82
+ try:
83
+ data = json.load(sys.stdin)
84
+ results = data.get('results', [])
85
+ for r in results[:5]: # Show top 5
86
+ extra = r.get('extra', {})
87
+ severity = extra.get('severity', 'UNKNOWN').upper()
88
+ rule_id = r.get('check_id', 'unknown')
89
+ path = r.get('path', 'unknown')
90
+ start_line = r.get('start', {}).get('line', '?')
91
+ message = extra.get('message', '')[:80]
92
+ print(f' [{severity}] {rule_id}')
93
+ print(f' {path}:{start_line} → {message}')
94
+ print()
95
+ except:
96
+ print(' (Failed to parse semgrep output)')
97
+ " 2>/dev/null || echo " (Failed to parse semgrep output)")
98
+
99
+ if [ "$CRITICAL_HIGH" -gt 0 ]; then
100
+ echo ""
101
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
102
+ echo " GATE 10: Semgrep Security Gate"
103
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
104
+ echo " CRITICAL/HIGH: ${CRITICAL_HIGH} ❌ BLOCKED"
105
+ echo " MEDIUM/LOW: ${MEDIUM_LOW} ⚠️ warning"
106
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
107
+ echo " ❌ BLOCKED — Critical/High vulnerability found"
108
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
109
+ echo "$FINDING_DETAILS"
110
+ echo " Run 'semgrep scan --config=p/security-audit' to review all findings."
111
+ GATE_10_STATUS="FAIL"
112
+ exit 1
113
+ else
114
+ echo ""
115
+ echo " ✅ PASSED - No critical/high vulnerabilities"
116
+ if [ "$MEDIUM_LOW" -gt 0 ]; then
117
+ echo " ⚠️ ${MEDIUM_LOW} medium/low findings (warnings only)"
118
+ echo "$FINDING_DETAILS"
119
+ fi
120
+ GATE_10_STATUS="PASS"
121
+ fi
122
+ else
123
+ # semgrep runtime error (timeout, config error, etc.)
124
+ echo " ⚠️ semgrep exited with code ${SEMGREP_EXIT} — skipping gate"
125
+ echo " ⏭️ SKIPPED - SAST (semgrep runtime error)"
126
+ GATE_10_STATUS="SKIP"
127
+ fi
128
+ fi
129
+ fi
130
+ record_gate_audit "gate-10" "sast-security" "$GATE_10_STATUS" "0" "$GATE_10_START"
package/hooks/pre-commit CHANGED
@@ -932,11 +932,9 @@ elif [ "$PROJECT_LANG" = "python" ]; then
932
932
  else
933
933
  echo "✅ PASSED - pylint found no duplicates."
934
934
  fi
935
- elif require_tool "ruff" "Gate 2" "pip install ruff"; then
936
- ruff check --select=DUP $(echo "$CHANGED_FILES" | grep "\.py$") 2>&1 | head -30
937
- echo "✅ PASSED - ruff duplicate code check completed."
938
935
  else
939
- exit 1
936
+ echo "ℹ️ pylint not found — skipping Python duplicate code check."
937
+ echo " Install pylint: pip install pylint"
940
938
  fi
941
939
 
942
940
  elif [ "$PROJECT_LANG" = "go" ]; then
@@ -1223,6 +1221,13 @@ else
1223
1221
  fi
1224
1222
  done
1225
1223
 
1224
+ if [ "$TEST_FOUND" = false ] && [ "$ext" = "py" ]; then
1225
+ module_name="${filename//-/_}"
1226
+ if grep -rq "import $module_name\|from $module_name import" tests/ 2>/dev/null; then
1227
+ TEST_FOUND=true
1228
+ fi
1229
+ fi
1230
+
1226
1231
  if [ "$TEST_FOUND" = false ]; then
1227
1232
  echo "⚠️ TEST PAIRING WARNING: Source file without corresponding test: $src_file"
1228
1233
  echo " Expected patterns for .${ext}: ${patterns[0]}, ${patterns[1]:-...}"
@@ -1294,22 +1299,52 @@ else
1294
1299
  done
1295
1300
  fi
1296
1301
 
1297
- # First, run tests using adapter system
1302
+ # Run tests + coverage in a single pass (optimization: avoids running vitest twice)
1303
+ # For TypeScript with test:coverage script, use coverage-enabled run directly.
1304
+ # For other languages, fall back to the adapter's run_tests + run_coverage pair.
1298
1305
  echo "Running tests..."
1299
1306
 
1300
1307
  # Route to appropriate test runner via adapter
1301
1308
  ADAPTER_FILE=$(resolve_adapter_path "$PROJECT_LANG")
1302
1309
  if [ "${PROJECT_LANG}" != "unknown" ] && [ -n "$ADAPTER_FILE" ]; then
1303
1310
  if source "$ADAPTER_FILE" 2>/dev/null; then
1304
- TESTS_OUTPUT=$(run_tests 2>&1)
1305
- TESTS_EXIT_CODE=$?
1306
- echo "$TESTS_OUTPUT" | head -50
1307
- if [ "$TESTS_EXIT_CODE" -ne 0 ]; then
1308
- echo ""
1309
- echo "❌ BLOCKED - Tests FAILED"
1310
- exit 1
1311
+ # TypeScript: single vitest run --coverage (combines tests + coverage)
1312
+ if [ "$PROJECT_LANG" = "typescript" ] && [ -f "package.json" ]; then
1313
+ if npx vitest --version >/dev/null 2>&1; then
1314
+ echo "Running TypeScript tests with coverage..."
1315
+ TESTS_OUTPUT=$(npx vitest run --coverage 2>&1)
1316
+ TESTS_EXIT_CODE=$?
1317
+ echo "$TESTS_OUTPUT" | head -60
1318
+ if [ "$TESTS_EXIT_CODE" -ne 0 ]; then
1319
+ echo ""
1320
+ echo "❌ BLOCKED - Tests FAILED"
1321
+ exit 1
1322
+ else
1323
+ echo "✅ PASSED - Unit tests passed (with coverage)."
1324
+ fi
1325
+ else
1326
+ # Fallback: run_tests without coverage
1327
+ TESTS_OUTPUT=$(run_tests 2>&1)
1328
+ TESTS_EXIT_CODE=$?
1329
+ echo "$TESTS_OUTPUT" | head -50
1330
+ if [ "$TESTS_EXIT_CODE" -ne 0 ]; then
1331
+ echo ""
1332
+ echo "❌ BLOCKED - Tests FAILED"
1333
+ exit 1
1334
+ fi
1335
+ fi
1311
1336
  else
1312
- echo "✅ PASSED - Unit tests passed."
1337
+ # Non-TypeScript: standard adapter test flow
1338
+ TESTS_OUTPUT=$(run_tests 2>&1)
1339
+ TESTS_EXIT_CODE=$?
1340
+ echo "$TESTS_OUTPUT" | head -50
1341
+ if [ "$TESTS_EXIT_CODE" -ne 0 ]; then
1342
+ echo ""
1343
+ echo "❌ BLOCKED - Tests FAILED"
1344
+ exit 1
1345
+ else
1346
+ echo "✅ PASSED - Unit tests passed."
1347
+ fi
1313
1348
  fi
1314
1349
  else
1315
1350
  echo "✅ PASSED - Could not source ${PROJECT_LANG} adapter for tests, assuming none to run."
@@ -1318,29 +1353,18 @@ else
1318
1353
  echo "✅ PASSED - No ${PROJECT_LANG} adapter found for tests, assuming none to run."
1319
1354
  fi
1320
1355
 
1321
- # Next, run coverage check
1356
+ # Next, run coverage check (skip for TypeScript — already done above)
1322
1357
  echo "Running coverage check..."
1323
1358
 
1324
1359
  if [ "${PROJECT_LANG}" != "unknown" ] && [ -n "$ADAPTER_FILE" ]; then
1325
1360
  if source "$ADAPTER_FILE" 2>/dev/null; then
1326
1361
  case "$PROJECT_LANG" in
1327
1362
  "typescript")
1328
- if [ -f "package.json" ] && grep -q '"test:coverage"' package.json 2>/dev/null; then
1329
- echo "Running TypeScript coverage with minimum 80% requirement..."
1330
- npx vitest run --coverage 2>&1
1331
- COV_EXIT=$?
1332
- if [ "$COV_EXIT" -ne 0 ]; then
1333
- echo ""
1334
- echo "❌ BLOCKED - Coverage check FAILED (exit code: $COV_EXIT)"
1335
- echo "Coverage must meet the thresholds defined in vitest.config.ts"
1336
- exit 1
1337
- fi
1338
- else
1339
- echo "No 'test:coverage' script in package.json, running coverage via adapter..."
1340
- run_coverage_output=$(run_coverage 2>&1)
1341
- COV_EXIT=$?
1342
- echo "$run_coverage_output" | head -30
1343
- fi
1363
+ # Coverage already collected in the test section above (optimized single vitest run --coverage).
1364
+ # The --coverage flag produces coverage/coverage-summary.json which the unconditional
1365
+ # stage-2 enforcement reads. No need to run vitest again here.
1366
+ echo "TypeScript coverage already collected during test run."
1367
+ COV_EXIT=0
1344
1368
  ;;
1345
1369
  "python")
1346
1370
  if command -v pytest &> /dev/null && command -v coverage &> /dev/null; then
@@ -1793,19 +1817,74 @@ if [ -n "$ORIGINAL_DIR" ]; then
1793
1817
  fi
1794
1818
 
1795
1819
  # ============================================================================
1796
- # GATE 9: Semgrep SAST Security Scan
1797
- # Extracted to gate-9.sh for maintainability
1820
+ # GATE 9: Build Integrity Check (TypeScript compilation + package + imports)
1821
+ # ============================================================================
1822
+ 2>&1 echo ""
1823
+ 2>&1 echo "→ Gate 9: Build integrity... "
1824
+ GATE_9_START=$(gate_start_ms)
1825
+ GATE_9_STATUS="SKIP"
1826
+
1827
+ if [ -f "package.json" ] && [ -f "tsconfig.json" ]; then
1828
+ GATE_9_SCRIPT=""
1829
+ if [ -f "$PROJECT_ROOT/src/build-integrity/gate-10.ts" ]; then
1830
+ GATE_9_SCRIPT="$PROJECT_ROOT/src/build-integrity/gate-10.ts"
1831
+ elif [ -f ".xp-gate/modules/build-integrity/gate-10.ts" ]; then
1832
+ GATE_9_SCRIPT=".xp-gate/modules/build-integrity/gate-10.ts"
1833
+ elif [ -f "$HOME/.config/xp-gate/modules/build-integrity/gate-10.ts" ]; then
1834
+ GATE_9_SCRIPT="$HOME/.config/xp-gate/modules/build-integrity/gate-10.ts"
1835
+ fi
1836
+
1837
+ if [ -n "$GATE_9_SCRIPT" ]; then
1838
+ CHANGED_FILES_CSV=$(echo "$CHANGED_FILES" | tr ' ' ',')
1839
+ GATE_9_OUTPUT=$(mktemp)
1840
+ if timeout 120s npx tsx "$GATE_9_SCRIPT" --changed-files "$CHANGED_FILES_CSV" --project-root "$PROJECT_ROOT" --timeout 115000 > "$GATE_9_OUTPUT" 2>&1; then
1841
+ GATE_9_STATUS="PASS"
1842
+ echo " ✅ Build integrity check passed."
1843
+ else
1844
+ GATE_9_EXIT=$?
1845
+ if [ $GATE_9_EXIT -eq 124 ]; then
1846
+ GATE_9_STATUS="SKIP"
1847
+ echo " ⏱️ Build integrity check timed out (120s). SKIPPED."
1848
+ else
1849
+ GATE_9_STATUS="BLOCK"
1850
+ cat "$GATE_9_OUTPUT"
1851
+ echo ""
1852
+ echo "❌ BLOCKED - Gate 9: Build integrity check failed"
1853
+ echo "Fix type errors, broken imports, or package manifest issues before committing."
1854
+ rm -f "$GATE_9_OUTPUT"
1855
+ exit 1
1856
+ fi
1857
+ fi
1858
+ rm -f "$GATE_9_OUTPUT"
1859
+ else
1860
+ echo " ℹ️ Build integrity script not found - skipping"
1861
+ echo " ⏭️ SKIPPED - Build integrity (gate-10.ts not available)"
1862
+ fi
1863
+ else
1864
+ echo " ℹ️ Not a TypeScript project - skipping build integrity check"
1865
+ echo " ⏭️ SKIPPED - Build integrity (not a TypeScript project)"
1866
+ fi
1867
+
1868
+ GATE_9_END=$(date +%s)
1869
+ GATE_9_DURATION=$((GATE_9_END - GATE_9_START))
1870
+ echo "✅ Gate 9 completed in ${GATE_9_DURATION}s"
1871
+ echo ""
1872
+ # ============================================================================
1873
+
1874
+ # ============================================================================
1875
+ # GATE 10: Semgrep SAST Security Scan
1876
+ # Extracted to gate-10.sh for maintainability
1798
1877
  # ============================================================================
1799
1878
  source "$GATE_DIR/gate-9.sh"
1800
1879
  # ============================================================================
1801
1880
 
1802
1881
  # ============================================================================
1803
- # GATE 10: Sprint Flow Enforcement
1882
+ # GATE 11: Sprint Flow Enforcement
1804
1883
  # Validates sprint state consistency (delphi-review APPROVED before BUILD)
1805
1884
  # Uses sprint-gate.sh for standalone validation logic
1806
1885
  # ============================================================================
1807
- GATE_10_START=$(date +%s)
1808
- GATE_10_STATUS="PASS"
1886
+ GATE_11_START=$(date +%s)
1887
+ GATE_11_STATUS="PASS"
1809
1888
 
1810
1889
  SPRINT_GATE_SCRIPT=""
1811
1890
  if [ -f "$GATE_DIR/sprint-gate.sh" ]; then
@@ -1816,19 +1895,19 @@ fi
1816
1895
 
1817
1896
  if [ -n "$SPRINT_GATE_SCRIPT" ]; then
1818
1897
  if ! bash "$SPRINT_GATE_SCRIPT" --pre-commit; then
1819
- GATE_10_STATUS="BLOCK"
1820
- echo "❌ BLOCKED - Gate 10: Sprint Flow Enforcement"
1898
+ GATE_11_STATUS="BLOCK"
1899
+ echo "❌ BLOCKED - Gate 11: Sprint Flow Enforcement"
1821
1900
  # Sprint gate failure is a hard block — exit immediately
1822
1901
  exit 1
1823
1902
  fi
1824
1903
  else
1825
- echo "⏭️ SKIPPED - Gate 10: Sprint Flow (sprint-gate.sh not found)"
1826
- GATE_10_STATUS="SKIP"
1904
+ echo "⏭️ SKIPPED - Gate 11: Sprint Flow (sprint-gate.sh not found)"
1905
+ GATE_11_STATUS="SKIP"
1827
1906
  fi
1828
1907
 
1829
- GATE_10_END=$(date +%s)
1830
- GATE_10_DURATION=$((GATE_10_END - GATE_10_START))
1831
- echo "✅ Gate 10 completed in ${GATE_10_DURATION}s"
1908
+ GATE_11_END=$(date +%s)
1909
+ GATE_11_DURATION=$((GATE_11_END - GATE_11_START))
1910
+ echo "✅ Gate 11 completed in ${GATE_11_DURATION}s"
1832
1911
  echo ""
1833
1912
  # ============================================================================
1834
1913
 
@@ -1838,13 +1917,13 @@ generate_quality_report() {
1838
1917
  local TIMESTAMP
1839
1918
  local BRANCH
1840
1919
  local PASSED_COUNT=0
1841
- local TOTAL_GATES=10
1920
+ local TOTAL_GATES=11
1842
1921
 
1843
1922
  COMMIT_HASH=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
1844
1923
  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
1845
1924
  TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
1846
1925
 
1847
- for gate in 1 2 3 4 5 6 7 8 9 10; do
1926
+ for gate in 1 2 3 4 5 6 7 8 9 10 11; do
1848
1927
  local status_var="GATE_${gate}_STATUS"
1849
1928
  if [ "${!status_var}" = "PASS" ]; then
1850
1929
  PASSED_COUNT=$((PASSED_COUNT + 1))
@@ -1886,7 +1965,7 @@ generate_quality_report() {
1886
1965
 
1887
1966
  cat > "$REPORT_FILE" << ENDJSON
1888
1967
  {
1889
- "reportVersion": "1.1",
1968
+ "reportVersion": "2.0",
1890
1969
  "generatedAt": "$TIMESTAMP",
1891
1970
  "branch": "$BRANCH",
1892
1971
  "commit": "$COMMIT_HASH",
@@ -1943,14 +2022,19 @@ generate_quality_report() {
1943
2022
  "status": "${GATE_8_STATUS:-PASS}",
1944
2023
  "tool": "gitleaks"
1945
2024
  },
1946
- "gate9_sast": {
1947
- "name": "SAST Security Scan",
2025
+ "gate9_build_integrity": {
2026
+ "name": "Build Integrity",
1948
2027
  "status": "${GATE_9_STATUS:-PASS}",
2028
+ "tool": "tsc + npm pack + import check"
2029
+ },
2030
+ "gate10_sast": {
2031
+ "name": "SAST Security Scan",
2032
+ "status": "${GATE_10_STATUS:-PASS}",
1949
2033
  "tool": "semgrep"
1950
2034
  },
1951
- "gate10_sprint_flow": {
2035
+ "gate11_sprint_flow": {
1952
2036
  "name": "Sprint Flow Enforcement",
1953
- "status": "${GATE_10_STATUS:-PASS}",
2037
+ "status": "${GATE_11_STATUS:-PASS}",
1954
2038
  "tool": "sprint-gate.sh"
1955
2039
  }
1956
2040
  }
@@ -1992,8 +2076,9 @@ PY
1992
2076
  GATES_JSON="${GATES_JSON}\"gate6\":{\"status\":\"${GATE_6_STATUS:-PASS}\",\"name\":\"Architecture+BoyScout\",\"bsBlocked\":${BS_BLOCKED}},"
1993
2077
  GATES_JSON="${GATES_JSON}\"gate7\":{\"status\":\"${GATE_7_STATUS:-PASS}\",\"name\":\"IaC Security\"},"
1994
2078
  GATES_JSON="${GATES_JSON}\"gate8\":{\"status\":\"${GATE_8_STATUS:-PASS}\",\"name\":\"Secret Scanning\"},"
1995
- GATES_JSON="${GATES_JSON}\"gate9\":{\"status\":\"${GATE_9_STATUS:-PASS}\",\"name\":\"SAST Security\"},"
1996
- GATES_JSON="${GATES_JSON}\"gate10\":{\"status\":\"${GATE_10_STATUS:-PASS}\",\"name\":\"Sprint Flow\"}}"
2079
+ GATES_JSON="${GATES_JSON}\"gate9\":{\"status\":\"${GATE_9_STATUS:-PASS}\",\"name\":\"Build Integrity\"},"
2080
+ GATES_JSON="${GATES_JSON}\"gate10\":{\"status\":\"${GATE_10_STATUS:-PASS}\",\"name\":\"SAST Security\"},"
2081
+ GATES_JSON="${GATES_JSON}\"gate11\":{\"status\":\"${GATE_11_STATUS:-PASS}\",\"name\":\"Sprint Flow\"}}"
1997
2082
  GATES_JSON="${GATES_JSON}}"
1998
2083
 
1999
2084
  echo "{\"timestamp\":\"$TIMESTAMP\",\"commit\":\"$COMMIT_HASH\",\"branch\":\"$BRANCH\",\"score\":$SCORE,\"passed\":$PASSED_COUNT,\"total\":$TOTAL_GATES,\"gates\":$GATES_JSON,\"coverage\":\"$COV_PCT\",\"complexityWarnings\":${CC_WARNINGS:-0},\"principleWarnings\":${WARNING_COUNT:-0},\"boyScoutBlocked\":${BS_BLOCKED}}" >> "$HISTORY_FILE"
@@ -2012,8 +2097,9 @@ PY
2012
2097
  printf " %-45s %s\n" "Gate 6: Architecture + Boy Scout" "${GATE_6_STATUS:-PASS}"
2013
2098
  printf " %-45s %s\n" "Gate 7: IaC Security" "${GATE_7_STATUS:-PASS}"
2014
2099
  printf " %-45s %s\n" "Gate 8: Secret Scanning" "${GATE_8_STATUS:-PASS}"
2015
- printf " %-45s %s\n" "Gate 9: SAST Security" "${GATE_9_STATUS:-PASS}"
2016
- printf " %-45s %s\n" "Gate 10: Sprint Flow" "${GATE_10_STATUS:-PASS}"
2100
+ printf " %-45s %s\n" "Gate 9: Build Integrity" "${GATE_9_STATUS:-PASS}"
2101
+ printf " %-45s %s\n" "Gate 10: SAST Security" "${GATE_10_STATUS:-PASS}"
2102
+ printf " %-45s %s\n" "Gate 11: Sprint Flow" "${GATE_11_STATUS:-PASS}"
2017
2103
  echo ""
2018
2104
  echo " Overall Score: $SCORE/10 | $PASSED_COUNT/$TOTAL_GATES gates passed"
2019
2105
  echo " Branch status: $REPORT_FILE"
package/lib/arch.js CHANGED
@@ -4,7 +4,11 @@ const { spawnSync } = require('child_process');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
 
7
- // Looks for architecture.yaml in CWD, then walks up to git root.
7
+ function isPythonProject(dir) {
8
+ const markers = ['setup.py', 'setup.cfg', 'pyproject.toml', 'requirements.txt'];
9
+ return markers.some((m) => fs.existsSync(path.join(dir, m)));
10
+ }
11
+
8
12
  function findArchConfig(startDir) {
9
13
  let dir = path.resolve(startDir);
10
14
  const root = path.parse(dir).root;
@@ -17,6 +21,39 @@ function findArchConfig(startDir) {
17
21
  return null;
18
22
  }
19
23
 
24
+ function runArchlinter(config) {
25
+ const result = spawnSync(
26
+ 'npx',
27
+ ['-y', '@archlinter/cli', 'scan', '.', '--config', config],
28
+ { stdio: 'inherit', shell: process.platform === 'win32' },
29
+ );
30
+ if (result.error && result.error.code === 'ENOENT') {
31
+ console.error('[xp-gate arch] ERROR: npx not found in PATH. Install Node.js >=18.');
32
+ return 1;
33
+ }
34
+ return result.status === null ? 1 : result.status;
35
+ }
36
+
37
+ function runArchy(config) {
38
+ const result = spawnSync('archy', ['check', '.', '--config', config], {
39
+ stdio: 'inherit',
40
+ shell: process.platform === 'win32',
41
+ });
42
+ if (result.error && result.error.code === 'ENOENT') {
43
+ console.warn('[xp-gate arch] archy not found on PATH; trying npx fallback.');
44
+ const npxResult = spawnSync('npx', ['-y', 'archy', 'check', '.', '--config', config], {
45
+ stdio: 'inherit',
46
+ shell: process.platform === 'win32',
47
+ });
48
+ if (npxResult.error && npxResult.error.code === 'ENOENT') {
49
+ console.error('[xp-gate arch] ERROR: neither archy nor npx found in PATH.');
50
+ return 1;
51
+ }
52
+ return npxResult.status === null ? 1 : npxResult.status;
53
+ }
54
+ return result.status === null ? 1 : result.status;
55
+ }
56
+
20
57
  function arch(args) {
21
58
  const configIdx = args.indexOf('--config');
22
59
  const explicitConfig = configIdx >= 0 ? args[configIdx + 1] : null;
@@ -33,17 +70,12 @@ function arch(args) {
33
70
  return Promise.resolve(1);
34
71
  }
35
72
 
36
- const result = spawnSync('npx', ['-y', '@archlinter/cli', 'scan', '.', '--config', config], {
37
- stdio: 'inherit',
38
- shell: process.platform === 'win32',
39
- });
40
-
41
- if (result.error && result.error.code === 'ENOENT') {
42
- console.error('[xp-gate arch] ERROR: npx not found in PATH. Install Node.js >=18.');
43
- return Promise.resolve(1);
73
+ if (isPythonProject(process.cwd())) {
74
+ console.log('[xp-gate arch] Detected Python project — using archy');
75
+ return Promise.resolve(runArchy(config));
44
76
  }
45
77
 
46
- return Promise.resolve(result.status === null ? 1 : result.status);
78
+ return Promise.resolve(runArchlinter(config));
47
79
  }
48
80
 
49
81
  module.exports = { arch };
@@ -1,9 +1,9 @@
1
1
  # SRC/MOCK-POLICY KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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
- **Generated:** 2026-07-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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.12.4",
3
+ "version": "0.12.6",
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.12.4",
3
+ "version": "0.12.6",
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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → SHIP → LAND → USER ACCEPTANCE → FEEDBACK → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: 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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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.12.4",
3
+ "version": "0.12.6",
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",
@@ -80,21 +80,6 @@ function main() {
80
80
  }
81
81
 
82
82
  console.error(`[prepack] done: ${copied} skills bundled for @boyingliu01/opencode-plugin`);
83
-
84
- // Validate tui-plugin.ts structural integrity (Issue #248: stale cache detection)
85
- const tuiFile = path.join(PLUGIN_ROOT, 'tui-plugin.ts');
86
- const tuiContent = fs.readFileSync(tuiFile, 'utf8');
87
- const ok1 = tuiContent.includes('discoverActiveSprints') && tuiContent.includes('.worktrees');
88
- const ok2 = !tuiContent.match(/from\s+["'][^"']*\.\.\/\.\.\/src[^"']*["']/);
89
- if (!ok1) {
90
- console.error('[prepack] ERROR: tui-plugin.ts is missing discoverActiveSprints — old version detected');
91
- process.exit(1);
92
- }
93
- if (!ok2) {
94
- console.error('[prepack] ERROR: tui-plugin.ts contains broken import paths to ../../src/...');
95
- process.exit(1);
96
- }
97
- console.error('[prepack] OK: tui-plugin.ts structural checks passed');
98
83
  }
99
84
 
100
85
  main();
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → SHIP → LAND → USER ACCEPTANCE → FEEDBACK → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: 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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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.12.4",
3
+ "version": "0.12.6",
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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → USER ACCEPTANCE → FEEDBACK → SHIP → LAND → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: 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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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
- **Generated:** 2026-07-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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.
@@ -72,8 +72,21 @@ export async function main(args: string[]): Promise<number> {
72
72
  return result.summary.totalViolations > 0 ? 1 : 0;
73
73
  }
74
74
 
75
+ // Support both CJS (require.main === module) and ESM (import.meta.url) runtimes.
76
+ // npx tsx loads files via import() making require.main unreliable.
77
+ function isDirectExecution(): boolean {
78
+ if (typeof require !== 'undefined' && require.main === module) {
79
+ return true;
80
+ }
81
+ if (typeof import.meta !== 'undefined' && import.meta.url && process.argv[1]) {
82
+ const fileUrl = `file://${process.argv[1]}`;
83
+ return import.meta.url === fileUrl || import.meta.url.endsWith(`/${process.argv[1]}`);
84
+ }
85
+ return false;
86
+ }
87
+
75
88
  const args = process.argv.slice(2);
76
- if (typeof require !== 'undefined' && require.main === module) {
89
+ if (isDirectExecution()) {
77
90
  main(args)
78
91
  .then(exitCode => {
79
92
  if (exitCode !== 0) {
@@ -84,4 +97,4 @@ if (typeof require !== 'undefined' && require.main === module) {
84
97
  console.error('Analysis failed:', err.message);
85
98
  process.exit(1);
86
99
  });
87
- }
100
+ }
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → SHIP → LAND → USER ACCEPTANCE → FEEDBACK → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: 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-03
4
- **Commit:** c3ed581
3
+ **Generated:** 2026-07-05
4
+ **Commit:** e639b50
5
5
  **Branch:** main
6
- **Version:** 0.12.4.0
6
+ **Version:** 0.12.6.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.