@boyingliu01/xp-gate 0.15.1 → 0.15.2
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/adapter-common.sh +0 -0
- package/adapters/cpp.sh +0 -0
- package/adapters/dart.sh +0 -0
- package/adapters/flutter.sh +0 -0
- package/adapters/go.sh +0 -0
- package/adapters/iac.sh +0 -0
- package/adapters/java.sh +0 -0
- package/adapters/kotlin.sh +0 -0
- package/adapters/objectivec.sh +0 -0
- package/adapters/plugins/book299-20132-python/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-20132-python/scripts/install-maven.sh +0 -0
- package/adapters/plugins/book299-4081-c/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-4081-c/scripts/install-maven.sh +0 -0
- package/adapters/plugins/book299-4083-javascriptes5/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-4083-javascriptes5/scripts/install-maven.sh +0 -0
- package/adapters/powershell.sh +0 -0
- package/adapters/python.sh +0 -0
- package/adapters/shell.sh +0 -0
- package/adapters/swift.sh +0 -0
- package/adapters/typescript.sh +0 -0
- package/bin/xp-gate.js +24 -0
- package/gate-3.sh +0 -0
- package/gate-4.sh +0 -0
- package/gate-7.sh +0 -0
- package/gate-8.sh +0 -0
- package/gate-9.sh +0 -0
- package/hooks/adapter-common.sh +0 -0
- package/hooks/gate-3.sh +0 -0
- package/hooks/gate-4.sh +0 -0
- package/hooks/gate-7.sh +0 -0
- package/hooks/gate-8.sh +0 -0
- package/hooks/gate-9.sh +0 -0
- package/hooks/pre-commit +24 -2
- package/hooks/pre-push +204 -14
- package/lib/__tests__/phase-transition.test.js +272 -272
- package/lib/__tests__/sprint-audit.test.js +207 -207
- package/lib/doctor.js +50 -0
- package/lib/init.js +91 -0
- package/lib/language-tools.js +833 -0
- package/lib/phase-transition.js +249 -249
- package/lib/sprint-audit.js +235 -235
- package/mock-policy/AGENTS.md +2 -2
- package/mutation/AGENTS.md +2 -2
- package/package.json +1 -1
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/bin/delphi-review-guard.sh +0 -0
- package/plugins/claude-code/bin/xp-gate-check +0 -0
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +2 -2
- package/plugins/opencode/package.json +1 -1
- package/plugins/opencode/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +2 -2
- package/plugins/qoder/agents/delphi-architecture.md +48 -48
- package/plugins/qoder/agents/delphi-feasibility.md +48 -48
- package/plugins/qoder/agents/delphi-technical.md +48 -48
- package/plugins/qoder/bin/sprint-flow-guard.sh +0 -0
- package/plugins/qoder/bin/xp-gate-check +0 -0
- package/plugins/qoder/plugin.json +1 -1
- package/plugins/qoder/skills/delphi-review/AGENTS.md +2 -2
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +2 -2
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +2 -2
- package/principles/AGENTS.md +2 -2
- package/scripts/delphi-external-review.cjs +432 -432
- package/skills/delphi-review/AGENTS.md +2 -2
- package/skills/sprint-flow/AGENTS.md +2 -2
- package/skills/test-specification-alignment/AGENTS.md +2 -2
package/adapter-common.sh
CHANGED
|
File without changes
|
package/adapters/cpp.sh
CHANGED
|
File without changes
|
package/adapters/dart.sh
CHANGED
|
File without changes
|
package/adapters/flutter.sh
CHANGED
|
File without changes
|
package/adapters/go.sh
CHANGED
|
File without changes
|
package/adapters/iac.sh
CHANGED
|
File without changes
|
package/adapters/java.sh
CHANGED
|
File without changes
|
package/adapters/kotlin.sh
CHANGED
|
File without changes
|
package/adapters/objectivec.sh
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/adapters/powershell.sh
CHANGED
|
File without changes
|
package/adapters/python.sh
CHANGED
|
File without changes
|
package/adapters/shell.sh
CHANGED
|
File without changes
|
package/adapters/swift.sh
CHANGED
|
File without changes
|
package/adapters/typescript.sh
CHANGED
|
File without changes
|
package/bin/xp-gate.js
CHANGED
|
@@ -211,6 +211,30 @@ const COMMANDS = {
|
|
|
211
211
|
handleSprintAudit(subargs).then(code => process.exit(code));
|
|
212
212
|
},
|
|
213
213
|
usage: 'xp-gate sprint-audit [--dir <path>] [--json]'
|
|
214
|
+
},
|
|
215
|
+
'detect-languages': {
|
|
216
|
+
description: 'Detect project languages and generate .xp-gate-config.json',
|
|
217
|
+
run: subargs => {
|
|
218
|
+
const { handleDetectLanguages } = require('../lib/language-tools.js');
|
|
219
|
+
handleDetectLanguages(subargs).then(code => process.exit(code));
|
|
220
|
+
},
|
|
221
|
+
usage: 'xp-gate detect-languages [--json] [--write]'
|
|
222
|
+
},
|
|
223
|
+
'check-tools': {
|
|
224
|
+
description: 'Check quality gate tool availability per language',
|
|
225
|
+
run: subargs => {
|
|
226
|
+
const { handleCheckTools } = require('../lib/language-tools.js');
|
|
227
|
+
handleCheckTools(subargs).then(code => process.exit(code));
|
|
228
|
+
},
|
|
229
|
+
usage: 'xp-gate check-tools [--languages <langs>] [--json]'
|
|
230
|
+
},
|
|
231
|
+
'install-tools': {
|
|
232
|
+
description: 'Install missing quality gate tools for detected languages',
|
|
233
|
+
run: subargs => {
|
|
234
|
+
const { handleInstallTools } = require('../lib/language-tools.js');
|
|
235
|
+
handleInstallTools(subargs).then(code => process.exit(code));
|
|
236
|
+
},
|
|
237
|
+
usage: 'xp-gate install-tools [--languages <langs>] [--dry-run] [--yes]'
|
|
214
238
|
}
|
|
215
239
|
};
|
|
216
240
|
|
package/gate-3.sh
CHANGED
|
File without changes
|
package/gate-4.sh
CHANGED
|
File without changes
|
package/gate-7.sh
CHANGED
|
File without changes
|
package/gate-8.sh
CHANGED
|
File without changes
|
package/gate-9.sh
CHANGED
|
File without changes
|
package/hooks/adapter-common.sh
CHANGED
|
File without changes
|
package/hooks/gate-3.sh
CHANGED
|
File without changes
|
package/hooks/gate-4.sh
CHANGED
|
File without changes
|
package/hooks/gate-7.sh
CHANGED
|
File without changes
|
package/hooks/gate-8.sh
CHANGED
|
File without changes
|
package/hooks/gate-9.sh
CHANGED
|
File without changes
|
package/hooks/pre-commit
CHANGED
|
@@ -375,7 +375,29 @@ if [ -n "$_RESOLVED_LANG_OVERRIDE" ]; then
|
|
|
375
375
|
echo " 🔧 LANGUAGE OVERRIDE: $PROJECT_LANG"
|
|
376
376
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
377
377
|
echo ""
|
|
378
|
-
|
|
378
|
+
elif [ -f ".xp-gate-config.json" ]; then
|
|
379
|
+
# ---- Read from project config file (v0.15.2+) ----
|
|
380
|
+
# .xp-gate-config.json is generated by `xp-gate init` or `xp-gate detect-languages`
|
|
381
|
+
# It contains detected languages and their tool status.
|
|
382
|
+
_CONFIG_LANGS=$(node -e "try{const c=JSON.parse(require('fs').readFileSync('.xp-gate-config.json','utf8'));console.log(Object.keys(c.languages||{}).join(' '));}catch(e){console.log('');}" 2>/dev/null || echo "")
|
|
383
|
+
if [ -n "$_CONFIG_LANGS" ]; then
|
|
384
|
+
PROJECT_LANGS="$_CONFIG_LANGS"
|
|
385
|
+
PROJECT_LANG=$(echo "$_CONFIG_LANGS" | awk '{print $1}')
|
|
386
|
+
echo ""
|
|
387
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
388
|
+
echo " 📋 LANGUAGES FROM .xp-gate-config.json"
|
|
389
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
390
|
+
echo ""
|
|
391
|
+
echo "Detected languages: $PROJECT_LANGS"
|
|
392
|
+
echo ""
|
|
393
|
+
else
|
|
394
|
+
# Config file exists but no languages detected — fall through to extension detection
|
|
395
|
+
_CONFIG_LANGS=""
|
|
396
|
+
fi
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
# If no languages from override or config, detect from changed files
|
|
400
|
+
if [ -z "$PROJECT_LANGS" ] && [ -z "$_CONFIG_LANGS" ]; then
|
|
379
401
|
# ---- Extension → language mapping ----
|
|
380
402
|
# Extracts unique languages from changed file extensions
|
|
381
403
|
PROJECT_LANGS=""
|
|
@@ -676,7 +698,7 @@ CHANGEDFILELIST
|
|
|
676
698
|
done
|
|
677
699
|
echo ""
|
|
678
700
|
fi
|
|
679
|
-
fi
|
|
701
|
+
fi # close language override if/else
|
|
680
702
|
|
|
681
703
|
# Helper: check if a language is in PROJECT_LANGS
|
|
682
704
|
has_project_lang() {
|
package/hooks/pre-push
CHANGED
|
@@ -865,16 +865,11 @@ if ! command -v jq &> /dev/null; then
|
|
|
865
865
|
fi
|
|
866
866
|
|
|
867
867
|
# Validate result file content
|
|
868
|
-
# SHA self-reference paradox fix
|
|
869
|
-
#
|
|
868
|
+
# SHA self-reference paradox fix (Issue #346):
|
|
869
|
+
# The walkthrough file may reference an earlier commit if it was generated before
|
|
870
|
+
# subsequent walkthrough-only commits. We check if the referenced commit is in
|
|
871
|
+
# the current branch's history and if no functional commits occurred after it.
|
|
870
872
|
CURRENT_COMMIT=$(git rev-parse HEAD)
|
|
871
|
-
if git diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null | grep -qx "$RESULT_FILE"; then
|
|
872
|
-
# Result file is part of the latest commit — compare against the reviewed commit
|
|
873
|
-
EXPECTED_COMMIT=$(git rev-parse HEAD^ 2>/dev/null || echo "unknown")
|
|
874
|
-
else
|
|
875
|
-
# Result file is working-tree only — compare against current HEAD
|
|
876
|
-
EXPECTED_COMMIT="$CURRENT_COMMIT"
|
|
877
|
-
fi
|
|
878
873
|
|
|
879
874
|
# Check JSON validity
|
|
880
875
|
if ! jq empty "$RESULT_FILE" 2>/dev/null; then
|
|
@@ -906,16 +901,42 @@ if [ "$RESULT_BRANCH" != "$CURRENT_BRANCH" ]; then
|
|
|
906
901
|
echo "Proceeding with commit verification..."
|
|
907
902
|
fi
|
|
908
903
|
|
|
909
|
-
# Commit match check
|
|
910
|
-
if
|
|
904
|
+
# Commit match check (Issue #346: flexible matching to avoid circular dependency)
|
|
905
|
+
# Check if RESULT_COMMIT is in the current branch's history
|
|
906
|
+
if ! git merge-base --is-ancestor "$RESULT_COMMIT" HEAD 2>/dev/null; then
|
|
907
|
+
echo ""
|
|
908
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
909
|
+
echo " ❌ RESULT FILE INVALID - PUSH BLOCKED"
|
|
910
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
911
|
+
echo ""
|
|
912
|
+
echo "Result file references a commit not in current branch:"
|
|
913
|
+
echo " Referenced: $RESULT_COMMIT"
|
|
914
|
+
echo " Current HEAD: $CURRENT_COMMIT"
|
|
915
|
+
echo ""
|
|
916
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
917
|
+
echo ""
|
|
918
|
+
exit 1
|
|
919
|
+
fi
|
|
920
|
+
|
|
921
|
+
# Check if there are any functional commits after RESULT_COMMIT
|
|
922
|
+
# Functional commits are those that are NOT walkthrough-only updates or Gate MW fixes
|
|
923
|
+
FUNCTIONAL_COMMITS_AFTER=$(git log --oneline "$RESULT_COMMIT"..HEAD -- . \
|
|
924
|
+
':!.code-walkthrough-result.json' \
|
|
925
|
+
':!.delphi/code-walkthrough.md' \
|
|
926
|
+
':!githooks/pre-push' \
|
|
927
|
+
':!src/npm-package/hooks/pre-push' 2>/dev/null | wc -l)
|
|
928
|
+
if [ "$FUNCTIONAL_COMMITS_AFTER" -gt 0 ]; then
|
|
911
929
|
echo ""
|
|
912
930
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
913
931
|
echo " ❌ RESULT FILE OUTDATED - PUSH BLOCKED"
|
|
914
932
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
915
933
|
echo ""
|
|
916
|
-
echo "
|
|
917
|
-
|
|
918
|
-
|
|
934
|
+
echo "Functional commits found after walkthrough:"
|
|
935
|
+
git log --oneline "$RESULT_COMMIT"..HEAD -- . \
|
|
936
|
+
':!.code-walkthrough-result.json' \
|
|
937
|
+
':!.delphi/code-walkthrough.md' \
|
|
938
|
+
':!githooks/pre-push' \
|
|
939
|
+
':!src/npm-package/hooks/pre-push' 2>/dev/null | head -5
|
|
919
940
|
echo ""
|
|
920
941
|
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
921
942
|
echo ""
|
|
@@ -961,9 +982,178 @@ if [[ "$CURRENT_TIME" > "$RESULT_EXPIRES" ]]; then
|
|
|
961
982
|
exit 1
|
|
962
983
|
fi
|
|
963
984
|
|
|
985
|
+
# ============================================================================
|
|
986
|
+
# PROVENANCE VALIDATION (Issue #339)
|
|
987
|
+
# Validate that the walkthrough was genuinely produced by Delphi review,
|
|
988
|
+
# not fabricated by an LLM.
|
|
989
|
+
# ============================================================================
|
|
990
|
+
|
|
991
|
+
# Check provenance fields exist
|
|
992
|
+
EXPERTS_COUNT=$(jq -r '.experts // [] | length' "$RESULT_FILE")
|
|
993
|
+
CONSENSUS=$(jq -r '.consensus // 0' "$RESULT_FILE")
|
|
994
|
+
WALKTHROUGH_HASH=$(jq -r '.walkthroughHash // empty' "$RESULT_FILE")
|
|
995
|
+
GENERATED_AT=$(jq -r '.generatedAt // empty' "$RESULT_FILE")
|
|
996
|
+
|
|
997
|
+
# Grace period: configurable via env var (default 30 days)
|
|
998
|
+
GRACE_DAYS="${XP_GATE_MW_GRACE_DAYS:-30}"
|
|
999
|
+
|
|
1000
|
+
# Check if this is a "new" walkthrough (has provenance fields)
|
|
1001
|
+
HAS_PROVENANCE="false"
|
|
1002
|
+
if [ -n "$WALKTHROUGH_HASH" ] && [ -n "$GENERATED_AT" ] && [ "$EXPERTS_COUNT" -ge 3 ]; then
|
|
1003
|
+
HAS_PROVENANCE="true"
|
|
1004
|
+
fi
|
|
1005
|
+
|
|
1006
|
+
if [ "$HAS_PROVENANCE" = "true" ]; then
|
|
1007
|
+
# Full provenance validation
|
|
1008
|
+
|
|
1009
|
+
# 1. Experts count check (minimum 3)
|
|
1010
|
+
if [ "$EXPERTS_COUNT" -lt 3 ]; then
|
|
1011
|
+
echo ""
|
|
1012
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1013
|
+
echo " ❌ INSUFFICIENT EXPERTS - PUSH BLOCKED"
|
|
1014
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1015
|
+
echo ""
|
|
1016
|
+
echo "Walkthrough requires minimum 3 experts:"
|
|
1017
|
+
echo " Found: $EXPERTS_COUNT experts"
|
|
1018
|
+
echo ""
|
|
1019
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
1020
|
+
echo ""
|
|
1021
|
+
exit 1
|
|
1022
|
+
fi
|
|
1023
|
+
|
|
1024
|
+
# 2. Consensus check (≥90%)
|
|
1025
|
+
# Use integer math: multiply by 10 to avoid bc dependency
|
|
1026
|
+
CONSENSUS_X10=$(echo "$CONSENSUS * 10" | bc -l | cut -d'.' -f1)
|
|
1027
|
+
if [ "$CONSENSUS_X10" -lt 900 ]; then
|
|
1028
|
+
echo ""
|
|
1029
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1030
|
+
echo " ❌ CONSENSUS TOO LOW - PUSH BLOCKED"
|
|
1031
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1032
|
+
echo ""
|
|
1033
|
+
echo "Walkthrough requires ≥90% consensus:"
|
|
1034
|
+
echo " Found: ${CONSENSUS}%"
|
|
1035
|
+
echo ""
|
|
1036
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
1037
|
+
echo ""
|
|
1038
|
+
exit 1
|
|
1039
|
+
fi
|
|
1040
|
+
|
|
1041
|
+
# 3. Walkthrough hash verification
|
|
1042
|
+
WALKTHROUGH_DOC=".delphi/code-walkthrough.md"
|
|
1043
|
+
if [ ! -f "$WALKTHROUGH_DOC" ]; then
|
|
1044
|
+
echo ""
|
|
1045
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1046
|
+
echo " ❌ WALKTHROUGH DOC MISSING - PUSH BLOCKED"
|
|
1047
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1048
|
+
echo ""
|
|
1049
|
+
echo "Walkthrough document not found:"
|
|
1050
|
+
echo " Expected: $WALKTHROUGH_DOC"
|
|
1051
|
+
echo ""
|
|
1052
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
1053
|
+
echo ""
|
|
1054
|
+
exit 1
|
|
1055
|
+
fi
|
|
1056
|
+
|
|
1057
|
+
# Cross-platform SHA-256 computation
|
|
1058
|
+
COMPUTED_HASH=""
|
|
1059
|
+
if command -v sha256sum &> /dev/null; then
|
|
1060
|
+
COMPUTED_HASH=$(sha256sum "$WALKTHROUGH_DOC" | cut -d' ' -f1)
|
|
1061
|
+
elif command -v shasum &> /dev/null; then
|
|
1062
|
+
COMPUTED_HASH=$(shasum -a 256 "$WALKTHROUGH_DOC" | cut -d' ' -f1)
|
|
1063
|
+
elif command -v openssl &> /dev/null; then
|
|
1064
|
+
COMPUTED_HASH=$(openssl sha256 -r "$WALKTHROUGH_DOC" | cut -d' ' -f1)
|
|
1065
|
+
fi
|
|
1066
|
+
|
|
1067
|
+
if [ -z "$COMPUTED_HASH" ]; then
|
|
1068
|
+
echo ""
|
|
1069
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1070
|
+
echo " ❌ NO SHA-256 TOOL - PUSH BLOCKED"
|
|
1071
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1072
|
+
echo ""
|
|
1073
|
+
echo "No SHA-256 tool available (install sha256sum, shasum, or openssl)"
|
|
1074
|
+
echo ""
|
|
1075
|
+
exit 1
|
|
1076
|
+
fi
|
|
1077
|
+
|
|
1078
|
+
if [ "$WALKTHROUGH_HASH" != "$COMPUTED_HASH" ]; then
|
|
1079
|
+
echo ""
|
|
1080
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1081
|
+
echo " ❌ WALKTHROUGH HASH MISMATCH - PUSH BLOCKED"
|
|
1082
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1083
|
+
echo ""
|
|
1084
|
+
echo "Walkthrough document has been modified after review:"
|
|
1085
|
+
echo " Expected: $WALKTHROUGH_HASH"
|
|
1086
|
+
echo " Found: $COMPUTED_HASH"
|
|
1087
|
+
echo ""
|
|
1088
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
1089
|
+
echo ""
|
|
1090
|
+
exit 1
|
|
1091
|
+
fi
|
|
1092
|
+
|
|
1093
|
+
# 4. generatedAt check (replay protection)
|
|
1094
|
+
if [ -z "$GENERATED_AT" ]; then
|
|
1095
|
+
echo ""
|
|
1096
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1097
|
+
echo " ❌ MISSING generatedAt - PUSH BLOCKED"
|
|
1098
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1099
|
+
echo ""
|
|
1100
|
+
echo "Walkthrough result missing generatedAt timestamp"
|
|
1101
|
+
echo ""
|
|
1102
|
+
echo "Re-run: /delphi-review --mode code-walkthrough"
|
|
1103
|
+
echo ""
|
|
1104
|
+
exit 1
|
|
1105
|
+
fi
|
|
1106
|
+
else
|
|
1107
|
+
# Grace period: old walkthroughs without provenance get WARNING
|
|
1108
|
+
echo ""
|
|
1109
|
+
echo "⚠️ WARNING: Legacy walkthrough format (no provenance fields)"
|
|
1110
|
+
echo " Provenance fields will be required after grace period (${GRACE_DAYS} days)"
|
|
1111
|
+
echo " Consider re-running: /delphi-review --mode code-walkthrough"
|
|
1112
|
+
echo ""
|
|
1113
|
+
fi
|
|
1114
|
+
|
|
964
1115
|
# ============================================================================
|
|
965
1116
|
# ALL CHECKS PASSED
|
|
966
1117
|
# ============================================================================
|
|
1118
|
+
echo ""
|
|
1119
|
+
|
|
1120
|
+
# ============================================================================
|
|
1121
|
+
# SPRINT-STATE BACKUP CHECK (WARNING ONLY — Issue #318)
|
|
1122
|
+
# Scan for worktree sprint-state directories that haven't been backed up
|
|
1123
|
+
# to .sprint-history/ before push. WARN only (doesn't block) — sprint-state
|
|
1124
|
+
# inside worktrees is deleted on `git worktree remove`, causing permanent
|
|
1125
|
+
# data loss if orchestrator forgets to back up during CLOSE phase.
|
|
1126
|
+
# ============================================================================
|
|
1127
|
+
if [ -d ".worktrees/sprint" ]; then
|
|
1128
|
+
for worktree_dir in .worktrees/sprint/sprint-*; do
|
|
1129
|
+
[ -d "$worktree_dir" ] || continue
|
|
1130
|
+
[ -d "$worktree_dir/.sprint-state" ] || continue
|
|
1131
|
+
sprint_id=$(basename "$worktree_dir")
|
|
1132
|
+
if [ -f "$worktree_dir/.sprint-state/sprint-state.json" ]; then
|
|
1133
|
+
if [ ! -d ".sprint-history/$sprint_id" ]; then
|
|
1134
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1135
|
+
echo " ⚠️ SPRINT-STATE NOT BACKED UP: $sprint_id"
|
|
1136
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1137
|
+
echo ""
|
|
1138
|
+
echo "Unarchived sprint state found in worktree:"
|
|
1139
|
+
echo " Path: $worktree_dir/.sprint-state/"
|
|
1140
|
+
echo " Backup: .sprint-history/$sprint_id/ (MISSING)"
|
|
1141
|
+
echo ""
|
|
1142
|
+
echo "RISK: If this worktree is removed before CLOSE backup,"
|
|
1143
|
+
echo " design docs, Delphi verdicts, and phase summaries"
|
|
1144
|
+
echo " are permanently lost."
|
|
1145
|
+
echo ""
|
|
1146
|
+
echo "Backup now:"
|
|
1147
|
+
echo " mkdir -p .sprint-history/$sprint_id"
|
|
1148
|
+
echo " cp -r $worktree_dir/.sprint-state/* .sprint-history/$sprint_id/"
|
|
1149
|
+
echo ""
|
|
1150
|
+
echo "See: https://github.com/boyingliu01/xp-gate/issues/318"
|
|
1151
|
+
echo ""
|
|
1152
|
+
fi
|
|
1153
|
+
fi
|
|
1154
|
+
done
|
|
1155
|
+
fi
|
|
1156
|
+
|
|
967
1157
|
echo ""
|
|
968
1158
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
969
1159
|
echo " ✅ GATE MW: CODE WALKTHROUGH VERIFIED"
|