@mmerterden/multi-agent-pipeline 12.7.0 → 12.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/install/_common.mjs +48 -0
  3. package/install/_dev-only-files.mjs +125 -5
  4. package/install/claude.mjs +14 -8
  5. package/install/copilot.mjs +5 -8
  6. package/package.json +17 -2
  7. package/pipeline/commands/multi-agent/analysis/SKILL.md +1 -1
  8. package/pipeline/lib/credential-store.sh +20 -0
  9. package/pipeline/multi-agent-refs/_account-picker.md +1 -1
  10. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  11. package/pipeline/multi-agent-refs/_repo-picker.md +1 -1
  12. package/pipeline/multi-agent-refs/features/review-multi-repo.md +65 -0
  13. package/pipeline/multi-agent-refs/features/url-enrichment.md +93 -0
  14. package/pipeline/multi-agent-refs/phases/operations.md +28 -0
  15. package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -83
  16. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
  17. package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
  18. package/pipeline/multi-agent-refs/phases/phase-4-review.md +50 -62
  19. package/pipeline/schemas/prefs.schema.json +6 -0
  20. package/pipeline/scripts/_smoke-root.sh +61 -0
  21. package/pipeline/scripts/agent-guard.py +57 -3
  22. package/pipeline/scripts/audit-log.sh +25 -0
  23. package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
  24. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
  25. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
  26. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
  27. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
  28. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
  29. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
  30. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
  31. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
  32. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
  33. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
  34. package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
  35. package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
  36. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
  37. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
  38. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
  39. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
  40. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
  41. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
  42. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
  43. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
  44. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
  45. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
  46. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
  47. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
  48. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
  49. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
  50. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
  51. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
  52. package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
  53. package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
  54. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
  55. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
  56. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
  57. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
  58. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
  59. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
  60. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
  61. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
  62. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
  63. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
  64. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
  65. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
  66. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
  67. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
  68. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
  69. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
  70. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
  71. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
  72. package/pipeline/eval/golden-tasks/README.md +0 -65
  73. package/pipeline/eval/intent-cases.json +0 -40
  74. package/pipeline/eval/run-metrics-fixture.json +0 -93
  75. package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
  76. package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
  77. package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
  78. package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
  79. package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
  80. package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
  81. package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
  82. package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
  83. package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
  84. package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
  85. package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
  86. package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
  87. package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
  88. package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
  89. package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
  90. package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
  91. package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
  92. package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
  93. package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
  94. package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
  95. package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
  96. package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
  97. package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
  98. package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
  99. package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
  100. package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
  101. package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
  102. package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
  103. package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
  104. package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
  105. package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
  106. package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
  107. package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
  108. package/pipeline/eval/triage/README.md +0 -54
  109. package/pipeline/scripts/benchmark-phase-0.sh +0 -128
  110. package/pipeline/scripts/check-md-links.mjs +0 -88
  111. package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -302
  112. package/pipeline/scripts/eval-golden-tasks.mjs +0 -224
  113. package/pipeline/scripts/eval-intent.mjs +0 -107
  114. package/pipeline/scripts/eval-mine-corpus.mjs +0 -211
  115. package/pipeline/scripts/eval-triage.mjs +0 -171
  116. package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
  117. package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
  118. package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
  119. package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
  120. package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
  121. package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
  122. package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
  123. package/pipeline/scripts/lint-mcp-refs.mjs +0 -218
  124. package/pipeline/scripts/lint-skills.mjs +0 -154
  125. package/pipeline/scripts/run-smokes.mjs +0 -130
  126. package/pipeline/scripts/scorecard.mjs +0 -258
  127. package/pipeline/scripts/smoke-add-detail.sh +0 -137
  128. package/pipeline/scripts/smoke-agent-guard.sh +0 -74
  129. package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
  130. package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
  131. package/pipeline/scripts/smoke-ask-choice.sh +0 -42
  132. package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
  133. package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
  134. package/pipeline/scripts/smoke-changelog-version.sh +0 -47
  135. package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
  136. package/pipeline/scripts/smoke-channels-flow.sh +0 -130
  137. package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
  138. package/pipeline/scripts/smoke-clarify.sh +0 -148
  139. package/pipeline/scripts/smoke-command-inventory.sh +0 -81
  140. package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
  141. package/pipeline/scripts/smoke-community-gates.sh +0 -75
  142. package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
  143. package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
  144. package/pipeline/scripts/smoke-context-budget.sh +0 -72
  145. package/pipeline/scripts/smoke-cost-budget.sh +0 -70
  146. package/pipeline/scripts/smoke-cost-summary.sh +0 -139
  147. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
  148. package/pipeline/scripts/smoke-description-tr.sh +0 -82
  149. package/pipeline/scripts/smoke-dev-critic.sh +0 -144
  150. package/pipeline/scripts/smoke-diff-explain.sh +0 -147
  151. package/pipeline/scripts/smoke-diff-risk.sh +0 -190
  152. package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
  153. package/pipeline/scripts/smoke-eval-live.sh +0 -136
  154. package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
  155. package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
  156. package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
  157. package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
  158. package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
  159. package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
  160. package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
  161. package/pipeline/scripts/smoke-generate-issue.sh +0 -120
  162. package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
  163. package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
  164. package/pipeline/scripts/smoke-install-layout.sh +0 -248
  165. package/pipeline/scripts/smoke-intent-guard.sh +0 -86
  166. package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
  167. package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
  168. package/pipeline/scripts/smoke-keychain.sh +0 -158
  169. package/pipeline/scripts/smoke-language-axis.sh +0 -109
  170. package/pipeline/scripts/smoke-learning-curve.sh +0 -61
  171. package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
  172. package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
  173. package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
  174. package/pipeline/scripts/smoke-md-links.sh +0 -8
  175. package/pipeline/scripts/smoke-md2confluence.sh +0 -126
  176. package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
  177. package/pipeline/scripts/smoke-migrate-state.sh +0 -102
  178. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
  179. package/pipeline/scripts/smoke-model-fallback.sh +0 -89
  180. package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
  181. package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
  182. package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -194
  183. package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
  184. package/pipeline/scripts/smoke-own-punctuation.sh +0 -103
  185. package/pipeline/scripts/smoke-pack-contents.sh +0 -140
  186. package/pipeline/scripts/smoke-pat-audit.sh +0 -128
  187. package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
  188. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
  189. package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
  190. package/pipeline/scripts/smoke-phase-banner.sh +0 -101
  191. package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
  192. package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
  193. package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
  194. package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
  195. package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
  196. package/pipeline/scripts/smoke-plan-safety.sh +0 -139
  197. package/pipeline/scripts/smoke-plan-todos.sh +0 -196
  198. package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
  199. package/pipeline/scripts/smoke-pre-commit.sh +0 -170
  200. package/pipeline/scripts/smoke-pref-migration.sh +0 -226
  201. package/pipeline/scripts/smoke-prefs-language.sh +0 -134
  202. package/pipeline/scripts/smoke-progress-contract.sh +0 -127
  203. package/pipeline/scripts/smoke-prune-logs.sh +0 -137
  204. package/pipeline/scripts/smoke-purge.sh +0 -138
  205. package/pipeline/scripts/smoke-push-retry.sh +0 -75
  206. package/pipeline/scripts/smoke-repo-map.sh +0 -300
  207. package/pipeline/scripts/smoke-review-readiness.sh +0 -92
  208. package/pipeline/scripts/smoke-review-watch.sh +0 -146
  209. package/pipeline/scripts/smoke-routines.sh +0 -84
  210. package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
  211. package/pipeline/scripts/smoke-run-metrics.sh +0 -50
  212. package/pipeline/scripts/smoke-search.sh +0 -187
  213. package/pipeline/scripts/smoke-shadow-git.sh +0 -224
  214. package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
  215. package/pipeline/scripts/smoke-skill-language.sh +0 -83
  216. package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
  217. package/pipeline/scripts/smoke-skill-scan.sh +0 -198
  218. package/pipeline/scripts/smoke-source-parity.sh +0 -85
  219. package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
  220. package/pipeline/scripts/smoke-sync-parity.sh +0 -92
  221. package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
  222. package/pipeline/scripts/smoke-telemetry.sh +0 -147
  223. package/pipeline/scripts/smoke-test-gap.sh +0 -183
  224. package/pipeline/scripts/smoke-token-budget.sh +0 -67
  225. package/pipeline/scripts/smoke-token-preflight.sh +0 -82
  226. package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
  227. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
  228. package/pipeline/scripts/smoke-triage-memory.sh +0 -174
  229. package/pipeline/scripts/smoke-update-check.sh +0 -135
  230. package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
  231. package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
  232. package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
  233. package/pipeline/scripts/smoke-validator-gates.sh +0 -164
  234. package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
  235. package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
  236. package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
  237. package/pipeline/scripts/smoke-work-summary.sh +0 -163
  238. package/pipeline/scripts/smoke-workflow-audit.sh +0 -101
  239. package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
  240. package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
  241. package/pipeline/scripts/smoke-write-state.sh +0 -159
  242. package/pipeline/scripts/sync-parity-check.sh +0 -135
  243. package/pipeline/scripts/test-gap-rules/android.json +0 -25
  244. package/pipeline/scripts/test-gap-rules/ios.json +0 -34
  245. package/pipeline/scripts/test-gap-rules/node.json +0 -29
  246. package/pipeline/scripts/test-gap-rules/python.json +0 -25
  247. package/pipeline/scripts/validate-schemas.mjs +0 -88
@@ -1,127 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-progress-contract.sh - enforce the progress-line contract across phase docs.
3
- #
4
- # Verifies:
5
- # 1. Contract doc exists at refs/progress-contract.md with the required sections.
6
- # 2. Line shape example is present in the doc (so downstream consumers have a
7
- # canonical pattern to grep).
8
- # 3. progressVerbosity field exists in prefs.schema.json with enum {quiet, normal, verbose}.
9
- # 4. Adoption marker `<!-- progress-contract: applied -->` count across phase docs
10
- # is reported (advisory in v5.0.0 development; will flip to blocking at
11
- # v5.0.0 release once every phase has opted in).
12
- # 5. Phases that DO carry the marker actually emit at least one `→ <verb>` line
13
- # or reference the contract explicitly.
14
-
15
- set -euo pipefail
16
-
17
- HERE="$(cd "$(dirname "$0")" && pwd)"
18
- ROOT="$(cd "$HERE/../.." && pwd)"
19
- CONTRACT="$ROOT/pipeline/multi-agent-refs/progress-contract.md"
20
- PREFS="$ROOT/pipeline/schemas/prefs.schema.json"
21
- PHASE_DIR="$ROOT/pipeline/multi-agent-refs/phases"
22
-
23
- # Flip to "true" to make missing adoption markers blocking. Today: advisory.
24
- BLOCKING_ADOPTION="${PROGRESS_CONTRACT_BLOCKING:-false}"
25
-
26
- PASS=0
27
- FAIL=0
28
- WARN=0
29
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
30
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
31
- warn() { WARN=$((WARN+1)); echo " ⚠ $1"; }
32
-
33
- need() { command -v "$1" >/dev/null 2>&1 || { echo "error: $1 required" >&2; exit 127; }; }
34
- need jq
35
- need grep
36
-
37
- [ -f "$CONTRACT" ] || { echo "error: contract not found at $CONTRACT" >&2; exit 1; }
38
- [ -f "$PREFS" ] || { echo "error: prefs schema not found at $PREFS" >&2; exit 1; }
39
- [ -d "$PHASE_DIR" ] || { echo "error: phase docs dir not found at $PHASE_DIR" >&2; exit 1; }
40
-
41
- echo "→ 1. contract doc has required sections"
42
- for section in "## Line shape" "## When to emit" "## Verbosity" "## Telemetry" "## Phase adoption marker" "## Cross-CLI parity"; do
43
- if grep -Fq "$section" "$CONTRACT"; then
44
- pass "section present: $section"
45
- else
46
- fail "section missing: $section"
47
- fi
48
- done
49
-
50
- echo ""
51
- echo "→ 2. canonical line-shape template present"
52
- # The doc should show: ` → <verb> <object>[ <target>]`
53
- if grep -qE '→ <verb> <object>' "$CONTRACT"; then
54
- pass "canonical shape '→ <verb> <object>' present"
55
- else
56
- fail "canonical shape missing"
57
- fi
58
-
59
- echo ""
60
- echo "→ 3. prefs schema declares progressVerbosity with correct enum"
61
- VERBOSITY_ENUM=$(jq -c '.properties.global.properties.progressVerbosity.enum' "$PREFS")
62
- if [ "$VERBOSITY_ENUM" = '["quiet","normal","verbose"]' ]; then
63
- pass "progressVerbosity.enum = [quiet, normal, verbose]"
64
- else
65
- fail "progressVerbosity.enum wrong: $VERBOSITY_ENUM"
66
- fi
67
- DEFAULT=$(jq -r '.properties.global.properties.progressVerbosity.default' "$PREFS")
68
- [ "$DEFAULT" = "normal" ] && pass "default = normal" || fail "default should be normal, got '$DEFAULT'"
69
-
70
- echo ""
71
- echo "→ 4. phase adoption marker inventory"
72
- TOTAL_PHASES=0
73
- ADOPTED=0
74
- MISSING=()
75
- for doc in "$PHASE_DIR"/phase-*.md; do
76
- [ -f "$doc" ] || continue
77
- TOTAL_PHASES=$((TOTAL_PHASES+1))
78
- if grep -Fq "<!-- progress-contract: applied -->" "$doc"; then
79
- ADOPTED=$((ADOPTED+1))
80
- else
81
- MISSING+=("$(basename "$doc")")
82
- fi
83
- done
84
- echo " phases scanned: $TOTAL_PHASES"
85
- echo " adopted: $ADOPTED"
86
- if [ "${#MISSING[@]}" -eq 0 ]; then
87
- pass "all phases have the adoption marker"
88
- else
89
- if [ "$BLOCKING_ADOPTION" = "true" ]; then
90
- fail "missing adoption in ${#MISSING[@]} phases: ${MISSING[*]}"
91
- else
92
- warn "advisory - missing adoption in ${#MISSING[@]} phases: ${MISSING[*]}"
93
- fi
94
- fi
95
-
96
- echo ""
97
- echo "→ 5. phases that DO adopt the marker actually emit progress lines"
98
- BROKEN_ADOPTIONS=()
99
- for doc in "$PHASE_DIR"/phase-*.md; do
100
- [ -f "$doc" ] || continue
101
- if grep -Fq "<!-- progress-contract: applied -->" "$doc"; then
102
- # Must reference the contract OR show at least one sample `→ <verb>` line.
103
- if grep -qE '→ (fetching|reading|running|writing|posting|waiting|dispatching|retrying|building|committing|checking) ' "$doc" \
104
- || grep -Fq "refs/progress-contract.md" "$doc"; then
105
- pass "$(basename "$doc") carries marker + shows progress usage"
106
- else
107
- fail "$(basename "$doc") has marker but no sample progress line or contract link"
108
- BROKEN_ADOPTIONS+=("$(basename "$doc")")
109
- fi
110
- fi
111
- done
112
- if [ "$ADOPTED" -eq 0 ]; then
113
- warn "no phases have adopted yet - this is expected until WS-4/5/6 land"
114
- fi
115
-
116
- echo ""
117
- echo "→ Live mirror cross-link (tracker coupling)"
118
- if grep -q "Live mirror to the phase tracker" "$CONTRACT" \
119
- && grep -q "phase-tracker.sh now" "$CONTRACT"; then
120
- pass "contract cross-links the tracker mirror rule"
121
- else
122
- fail "contract missing the live-mirror cross-link to tracker-contract.md"
123
- fi
124
-
125
- echo ""
126
- echo "══ progress-contract smoke: $PASS passed, $WARN warnings, $FAIL failed ══"
127
- [ "$FAIL" -eq 0 ]
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-prune-logs.sh - prune-logs.sh removes per-task log dirs, honors the
3
- # project/task/age filters, is dry-run by default, NEVER deletes the audit
4
- # trail or metrics corpus (even under adversarial dir names), refuses unsafe
5
- # log roots, and spares active task dirs.
6
- #
7
- # Exit 0 = all pass, 1 = any failure.
8
-
9
- set -uo pipefail
10
-
11
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
12
- PL="$ROOT/pipeline/scripts/prune-logs.sh"
13
- PASS=0
14
- FAIL=0
15
- pass() {
16
- PASS=$((PASS + 1))
17
- echo " ✓ $1"
18
- }
19
- fail() {
20
- FAIL=$((FAIL + 1))
21
- echo " ✗ $1"
22
- }
23
- [ -f "$PL" ] || {
24
- echo "FAIL: prune-logs.sh missing" >&2
25
- exit 1
26
- }
27
-
28
- LR="$(mktemp -d)"
29
- trap 'rm -rf "$LR"' EXIT
30
-
31
- seed() {
32
- rm -rf "${LR:?}"/*
33
- mkdir -p "$LR/my-ios-app/PROJ-1" "$LR/my-ios-app/PROJ-2" "$LR/other/PROJ-9"
34
- echo '{}' >"$LR/my-ios-app/PROJ-1/agent-state.json"
35
- echo '{}' >"$LR/my-ios-app/PROJ-2/tracker-state.json"
36
- echo '{}' >"$LR/other/PROJ-9/agent-log.md"
37
- echo 'audit' >"$LR/audit.jsonl"
38
- echo 'metric' >"$LR/metrics.jsonl"
39
- echo '5' >"$LR/my-ios-app/.counter"
40
- }
41
-
42
- echo "→ 1. dry-run lists task dirs and deletes nothing"
43
- seed
44
- out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" 2>&1)
45
- echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
46
- [ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "dry-run kept task dirs" || fail "dry-run deleted a task dir"
47
- echo "$out" | grep -qi "preserved" && pass "dry-run states audit/metrics are preserved" || fail "no preservation note"
48
-
49
- echo ""
50
- echo "→ 2. --yes deletes task dirs but preserves audit + metrics + .counter"
51
- seed
52
- PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
53
- [ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
54
- [ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
55
- [ -f "$LR/my-ios-app/.counter" ] && pass ".counter preserved" || fail ".counter was deleted"
56
- [ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "task dir PROJ-1 removed" || fail "task dir PROJ-1 survived"
57
- [ ! -e "$LR/other/PROJ-9" ] && pass "task dir PROJ-9 removed" || fail "task dir PROJ-9 survived"
58
-
59
- echo ""
60
- echo "→ 3. --project scopes deletion to one project"
61
- seed
62
- PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --project=my-ios-app --yes >/dev/null 2>&1
63
- [ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "my-ios-app task removed" || fail "my-ios-app task survived"
64
- [ -f "$LR/other/PROJ-9/agent-log.md" ] && pass "other project untouched" || fail "other project was deleted"
65
-
66
- echo ""
67
- echo "→ 4. --task scopes deletion to one task dir"
68
- seed
69
- PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
70
- [ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "PROJ-1 removed" || fail "PROJ-1 survived"
71
- [ -f "$LR/my-ios-app/PROJ-2/tracker-state.json" ] && pass "PROJ-2 untouched" || fail "PROJ-2 was deleted"
72
-
73
- echo ""
74
- echo "→ 5. --older-than excludes fresh task dirs"
75
- seed
76
- out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --older-than=1 2>&1)
77
- echo "$out" | grep -q "nothing" && pass "freshly-created dirs excluded by --older-than=1" || fail "--older-than did not exclude fresh dirs"
78
-
79
- echo ""
80
- echo "→ 6. usage errors + empty root"
81
- PRUNE_LOG_ROOT="$LR" bash "$PL" --bogus >/dev/null 2>&1
82
- [ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
83
- PRUNE_LOG_ROOT="/nonexistent-$$-dir" bash "$PL" >/dev/null 2>&1
84
- [ "$?" = "0" ] && pass "missing log root exits 0 (no-op)" || fail "missing log root did not exit 0"
85
-
86
- echo ""
87
- echo "→ 7. adversarial dirs named like preserved files survive --yes"
88
- rm -rf "${LR:?}"/*
89
- mkdir -p "$LR/audit.jsonl" "$LR/proj/metrics.jsonl" "$LR/proj/metrics-summary.md" "$LR/proj/.counter" "$LR/proj/PROJ-5"
90
- echo '{}' >"$LR/audit.jsonl/agent-state.json"
91
- echo '{}' >"$LR/proj/metrics.jsonl/agent-log.md"
92
- echo '{}' >"$LR/proj/metrics-summary.md/tracker-state.json"
93
- echo '{}' >"$LR/proj/.counter/agent-state.json"
94
- echo '{}' >"$LR/proj/PROJ-5/agent-state.json"
95
- PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
96
- [ -d "$LR/audit.jsonl" ] && pass "dir named audit.jsonl spared" || fail "dir named audit.jsonl deleted"
97
- [ -d "$LR/proj/metrics.jsonl" ] && pass "dir named metrics.jsonl spared" || fail "dir named metrics.jsonl deleted"
98
- [ -d "$LR/proj/metrics-summary.md" ] && pass "dir named metrics-summary.md spared" || fail "dir named metrics-summary.md deleted"
99
- [ -d "$LR/proj/.counter" ] && pass "dir named .counter spared" || fail "dir named .counter deleted"
100
- [ ! -e "$LR/proj/PROJ-5" ] && pass "normal task dir beside them still removed" || fail "normal task dir survived"
101
-
102
- echo ""
103
- echo "→ 8. unsafe log roots are refused (exit 2, dry-run only)"
104
- PRUNE_LOG_ROOT="$HOME" bash "$PL" >/dev/null 2>&1
105
- [ "$?" = "2" ] && pass "\$HOME as log root refused" || fail "\$HOME as log root not refused"
106
- GITROOT="$(mktemp -d)"
107
- mkdir -p "$GITROOT/.git"
108
- PRUNE_LOG_ROOT="$GITROOT" bash "$PL" --yes >/dev/null 2>&1
109
- rc=$?
110
- rm -rf "$GITROOT"
111
- [ "$rc" = "2" ] && pass "git work tree as log root refused" || fail "git work tree as log root not refused"
112
-
113
- echo ""
114
- echo "→ 9. default grace spares freshly-touched (active) task dirs"
115
- seed
116
- out=$(PRUNE_LOG_ROOT="$LR" bash "$PL" --yes 2>&1)
117
- rc=$?
118
- [ "$rc" = "0" ] && pass "grace run exits 0" || fail "grace run exited $rc"
119
- [ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "active task dir spared by default grace" || fail "default grace deleted an active task dir"
120
- echo "$out" | grep -qi "spared" && pass "output mentions spared active dirs" || fail "no spared-active note in output"
121
- PRUNE_LOG_ROOT="$LR" bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
122
- [ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "explicit --task bypasses the grace" || fail "--task did not bypass the grace"
123
-
124
- echo ""
125
- echo "→ 10. traversal-shaped --task/--project values are rejected"
126
- PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=../evil" >/dev/null 2>&1
127
- [ "$?" = "2" ] && pass "--task=../evil exits 2" || fail "--task=../evil accepted"
128
- PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=.counter" >/dev/null 2>&1
129
- [ "$?" = "2" ] && pass "--task=.counter (leading dot) exits 2" || fail "--task=.counter accepted"
130
- PRUNE_LOG_ROOT="$LR" bash "$PL" "--project=a/b" >/dev/null 2>&1
131
- [ "$?" = "2" ] && pass "--project=a/b exits 2" || fail "--project=a/b accepted"
132
- PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=" >/dev/null 2>&1
133
- [ "$?" = "2" ] && pass "empty --task exits 2" || fail "empty --task accepted"
134
-
135
- echo ""
136
- echo "══ prune-logs smoke: $PASS passed, $FAIL failed ══"
137
- [ "$FAIL" -eq 0 ]
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-purge.sh - purge.sh wipes .worktrees/ worktrees (registered and
3
- # orphaned), their local branches, and the project task counter; is dry-run
4
- # by default; preserves the main worktree, protected branches, and the
5
- # audit/metrics corpus; and never follows symlinks out of .worktrees/.
6
- #
7
- # Exit 0 = all pass, 1 = any failure.
8
-
9
- set -uo pipefail
10
-
11
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
12
- PG="$ROOT/pipeline/scripts/purge.sh"
13
- PASS=0
14
- FAIL=0
15
- pass() {
16
- PASS=$((PASS + 1))
17
- echo " ✓ $1"
18
- }
19
- fail() {
20
- FAIL=$((FAIL + 1))
21
- echo " ✗ $1"
22
- }
23
- [ -f "$PG" ] || {
24
- echo "FAIL: purge.sh missing" >&2
25
- exit 1
26
- }
27
-
28
- SB="$(cd "$(mktemp -d)" && pwd -P)"
29
- trap 'rm -rf "$SB"' EXIT
30
-
31
- REPO="$SB/repo"
32
- LR="$SB/logs"
33
- VICTIM="$SB/victim"
34
-
35
- seed() {
36
- rm -rf "$REPO" "$LR" "$VICTIM"
37
- mkdir -p "$REPO" "$LR/repo" "$VICTIM"
38
- echo keep >"$VICTIM/keep.txt"
39
- git -C "$REPO" init -q -b main
40
- git -C "$REPO" -c user.email=t@t.t -c user.name=t commit -q --allow-empty -m init
41
- git -C "$REPO" worktree add -q -b feature/PROJ-1-x "$REPO/.worktrees/PROJ-1" >/dev/null 2>&1
42
- git -C "$REPO" worktree add -q -b bugfix/PROJ-2-y "$REPO/.worktrees/PROJ-2" >/dev/null 2>&1
43
- mkdir -p "$REPO/.worktrees/PROJ-9" # orphan: dir git no longer registers
44
- echo '{}' >"$REPO/.worktrees/PROJ-9/agent-state.json"
45
- ln -s "$VICTIM" "$REPO/.worktrees/evil-link" # symlink escape attempt
46
- echo '7' >"$LR/repo/.counter"
47
- echo audit >"$LR/audit.jsonl"
48
- echo metric >"$LR/metrics.jsonl"
49
- }
50
-
51
- has_branch() {
52
- git -C "$REPO" show-ref --verify -q "refs/heads/$1"
53
- }
54
-
55
- echo "→ 1. dry-run lists everything and deletes nothing"
56
- seed
57
- out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" 2>&1)
58
- rc=$?
59
- [ "$rc" = "0" ] && pass "dry-run exits 0" || fail "dry-run exited $rc"
60
- echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
61
- echo "$out" | grep -q "PROJ-1" && pass "worktree PROJ-1 listed" || fail "worktree PROJ-1 not listed"
62
- echo "$out" | grep -q "feature/PROJ-1-x" && pass "branch listed" || fail "branch not listed"
63
- echo "$out" | grep -q ".counter" && pass "counter listed" || fail "counter not listed"
64
- [ -d "$REPO/.worktrees/PROJ-1" ] && pass "dry-run kept worktrees" || fail "dry-run deleted a worktree"
65
- [ -f "$LR/repo/.counter" ] && pass "dry-run kept the counter" || fail "dry-run deleted the counter"
66
- has_branch feature/PROJ-1-x && pass "dry-run kept branches" || fail "dry-run deleted a branch"
67
-
68
- echo ""
69
- echo "→ 2. --yes wipes worktrees + branches + counter, preserves the rest"
70
- seed
71
- PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
72
- rc=$?
73
- [ "$rc" = "0" ] && pass "--yes exits 0" || fail "--yes exited $rc"
74
- [ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "registered worktree PROJ-1 removed" || fail "PROJ-1 survived"
75
- [ ! -e "$REPO/.worktrees/PROJ-2" ] && pass "registered worktree PROJ-2 removed" || fail "PROJ-2 survived"
76
- [ ! -e "$REPO/.worktrees/PROJ-9" ] && pass "orphan worktree dir removed" || fail "orphan PROJ-9 survived"
77
- ! has_branch feature/PROJ-1-x && pass "branch feature/PROJ-1-x deleted" || fail "feature/PROJ-1-x survived"
78
- ! has_branch bugfix/PROJ-2-y && pass "branch bugfix/PROJ-2-y deleted" || fail "bugfix/PROJ-2-y survived"
79
- has_branch main && pass "main branch preserved" || fail "main branch was deleted"
80
- git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main worktree still a git repo" || fail "main worktree destroyed"
81
- wt_count=$(git -C "$REPO" worktree list 2>/dev/null | wc -l | tr -d ' ')
82
- [ "$wt_count" = "1" ] && pass "only the main worktree remains registered" || fail "expected 1 registered worktree, got $wt_count"
83
- [ ! -e "$LR/repo/.counter" ] && pass "task counter removed" || fail "task counter survived"
84
- [ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
85
- [ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
86
- [ -f "$VICTIM/keep.txt" ] && pass "symlink target outside repo untouched" || fail "symlink target was deleted"
87
-
88
- echo ""
89
- echo "→ 3. protected branch carried by a worktree survives, worktree still removed"
90
- seed
91
- git -C "$REPO" worktree add -q -b develop "$REPO/.worktrees/DEV-1" >/dev/null 2>&1
92
- PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
93
- [ ! -e "$REPO/.worktrees/DEV-1" ] && pass "develop worktree removed" || fail "develop worktree survived"
94
- has_branch develop && pass "develop branch preserved" || fail "develop branch was deleted"
95
-
96
- echo ""
97
- echo "→ 4. clean repo and non-repo are no-ops (exit 0)"
98
- CLEAN="$SB/clean"
99
- mkdir -p "$CLEAN"
100
- git -C "$CLEAN" init -q -b main
101
- out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$CLEAN" 2>&1)
102
- rc=$?
103
- { [ "$rc" = "0" ] && echo "$out" | grep -q "nothing to do"; } && pass "clean repo is a no-op" || fail "clean repo not a clean no-op (rc=$rc)"
104
- PLAIN="$SB/plain"
105
- mkdir -p "$PLAIN"
106
- out=$(bash "$PG" --repo "$PLAIN" 2>&1)
107
- rc=$?
108
- { [ "$rc" = "0" ] && echo "$out" | grep -q "not a git work tree"; } && pass "non-repo dir is a no-op" || fail "non-repo dir not a clean no-op (rc=$rc)"
109
-
110
- echo ""
111
- echo "→ 5. usage errors exit 2"
112
- bash "$PG" --bogus >/dev/null 2>&1
113
- [ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
114
- bash "$PG" --repo >/dev/null 2>&1
115
- [ "$?" = "2" ] && pass "--repo without a path exits 2" || fail "--repo without a path did not exit 2"
116
-
117
- echo ""
118
- echo "→ 6. --delete-remote without a remote warns but does not fail"
119
- seed
120
- out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote 2>&1)
121
- echo "$out" | grep -q "remote branch origin/feature/PROJ-1-x" && pass "dry-run lists remote branch deletion" || fail "dry-run missing remote branch line"
122
- out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote --yes 2>&1)
123
- rc=$?
124
- [ "$rc" = "0" ] && pass "--delete-remote --yes exits 0 without a remote" || fail "--delete-remote --yes exited $rc"
125
- echo "$out" | grep -qi "warning" && pass "missing remote surfaces a warning" || fail "no warning for missing remote"
126
-
127
- echo ""
128
- echo "→ 7. purge from inside a linked worktree still anchors on the main repo"
129
- seed
130
- out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO/.worktrees/PROJ-1" --yes 2>&1)
131
- rc=$?
132
- [ "$rc" = "0" ] && pass "run from linked worktree exits 0" || fail "run from linked worktree exited $rc"
133
- [ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "worktrees removed when invoked from inside one" || fail "worktrees survived"
134
- git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main repo intact" || fail "main repo destroyed"
135
-
136
- echo ""
137
- echo "══ purge smoke: $PASS passed, $FAIL failed ══"
138
- [ "$FAIL" -eq 0 ]
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-push-retry.sh - asserts the push-must-succeed policy is documented
3
- # correctly in Phase 6 and gated by settings.pushMustSucceed.
4
-
5
- set -uo pipefail
6
-
7
- PHASE6="$HOME/.claude/multi-agent-refs/phases/phase-6-commit.md"
8
- PREFS_SCHEMA="$HOME/.claude/schemas/prefs.schema.json"
9
-
10
- PASS=0; FAIL=0
11
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
12
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
13
-
14
- if [ ! -f "$PHASE6" ]; then
15
- fail "phase-6-commit.md missing"; echo "══ aborted ══"; exit 2
16
- fi
17
-
18
- echo "→ 1. Push-must-succeed gate flag"
19
- grep -q "settings.pushMustSucceed" "$PHASE6" \
20
- && pass "Phase 6 references settings.pushMustSucceed gate" \
21
- || fail "settings.pushMustSucceed gate missing in Phase 6"
22
- [ -f "$PREFS_SCHEMA" ] && grep -q '"pushMustSucceed"' "$PREFS_SCHEMA" \
23
- && pass "Schema declares settings.pushMustSucceed" \
24
- || fail "Schema missing settings.pushMustSucceed"
25
-
26
- echo "→ 2. Retry budget"
27
- grep -q "settings.pushRetryMax" "$PHASE6" \
28
- && pass "Phase 6 references settings.pushRetryMax" \
29
- || fail "settings.pushRetryMax reference missing"
30
- [ -f "$PREFS_SCHEMA" ] && grep -q '"pushRetryMax"' "$PREFS_SCHEMA" \
31
- && pass "Schema declares settings.pushRetryMax" \
32
- || fail "Schema missing settings.pushRetryMax"
33
- grep -q "default 5\|default \`5\`" "$PHASE6" \
34
- && pass "Default retry budget 5 documented" \
35
- || fail "Default retry budget 5 missing"
36
-
37
- echo "→ 3. Rebase before push"
38
- grep -q "git -C \"\$WT_PATH\" fetch origin" "$PHASE6" \
39
- && pass "Re-fetch origin before push" \
40
- || fail "Re-fetch step missing"
41
- grep -q "git -C \"\$WT_PATH\" rebase" "$PHASE6" \
42
- && pass "Rebase on advancing base" \
43
- || fail "Rebase step missing"
44
- grep -q "rebase conflict: abort" "$PHASE6" \
45
- && pass "Rebase-conflict aborts cleanly" \
46
- || fail "Rebase-conflict abort missing"
47
-
48
- echo "→ 4. Back-off between attempts"
49
- grep -q "sleep" "$PHASE6" \
50
- && pass "Back-off sleep between push attempts" \
51
- || fail "Back-off sleep missing"
52
- grep -qE "back-off:\s*2,4,6,8" "$PHASE6" \
53
- && pass "Documented back-off cadence (2,4,6,8s)" \
54
- || fail "Back-off cadence not documented"
55
-
56
- echo "→ 5. Final-fail user prompt (4 options)"
57
- for opt in "Resolve conflict manually" "different base branch" "Skip this repo" "Pause Phase 6"; do
58
- grep -q "$opt" "$PHASE6" \
59
- && pass "Final-fail option present: $opt" \
60
- || fail "Final-fail option missing: $opt"
61
- done
62
-
63
- echo "→ 6. Push status persistence"
64
- grep -q "state.projects\[i\].pushStatus" "$PHASE6" \
65
- && pass "pushStatus persisted to state" \
66
- || fail "pushStatus persistence missing"
67
- for v in '"pushed"' '"rebase-pushed"' '"skipped"' '"paused"'; do
68
- grep -q "$v" "$PHASE6" \
69
- && pass "pushStatus enum value: $v" \
70
- || fail "pushStatus enum value missing: $v"
71
- done
72
-
73
- echo ""
74
- echo "══ push-retry smoke: $PASS passed, $FAIL failed ══"
75
- [ "$FAIL" -eq 0 ]