@mmerterden/multi-agent-pipeline 12.7.0 → 12.8.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 (244) hide show
  1. package/CHANGELOG.md +126 -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/phases/operations.md +28 -0
  13. package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -0
  14. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
  15. package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
  16. package/pipeline/multi-agent-refs/phases/phase-4-review.md +49 -4
  17. package/pipeline/schemas/prefs.schema.json +6 -0
  18. package/pipeline/scripts/_smoke-root.sh +61 -0
  19. package/pipeline/scripts/audit-log.sh +25 -0
  20. package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
  21. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
  22. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
  23. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
  24. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
  25. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
  26. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
  27. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
  28. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
  29. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
  30. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
  31. package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
  32. package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
  33. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
  34. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
  35. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
  36. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
  37. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
  38. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
  39. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
  40. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
  41. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
  42. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
  43. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
  44. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
  45. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
  46. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
  47. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
  48. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
  49. package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
  50. package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
  51. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
  52. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
  53. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
  54. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
  55. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
  56. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
  57. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
  58. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
  59. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
  60. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
  61. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
  62. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
  63. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
  64. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
  65. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
  66. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
  67. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
  68. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
  69. package/pipeline/eval/golden-tasks/README.md +0 -65
  70. package/pipeline/eval/intent-cases.json +0 -40
  71. package/pipeline/eval/run-metrics-fixture.json +0 -93
  72. package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
  73. package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
  74. package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
  75. package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
  76. package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
  77. package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
  78. package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
  79. package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
  80. package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
  81. package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
  82. package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
  83. package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
  84. package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
  85. package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
  86. package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
  87. package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
  88. package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
  89. package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
  90. package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
  91. package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
  92. package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
  93. package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
  94. package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
  95. package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
  96. package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
  97. package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
  98. package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
  99. package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
  100. package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
  101. package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
  102. package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
  103. package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
  104. package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
  105. package/pipeline/eval/triage/README.md +0 -54
  106. package/pipeline/scripts/benchmark-phase-0.sh +0 -128
  107. package/pipeline/scripts/check-md-links.mjs +0 -88
  108. package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -302
  109. package/pipeline/scripts/eval-golden-tasks.mjs +0 -224
  110. package/pipeline/scripts/eval-intent.mjs +0 -107
  111. package/pipeline/scripts/eval-mine-corpus.mjs +0 -211
  112. package/pipeline/scripts/eval-triage.mjs +0 -171
  113. package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
  114. package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
  115. package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
  116. package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
  117. package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
  118. package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
  119. package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
  120. package/pipeline/scripts/lint-mcp-refs.mjs +0 -218
  121. package/pipeline/scripts/lint-skills.mjs +0 -154
  122. package/pipeline/scripts/run-smokes.mjs +0 -130
  123. package/pipeline/scripts/scorecard.mjs +0 -258
  124. package/pipeline/scripts/smoke-add-detail.sh +0 -137
  125. package/pipeline/scripts/smoke-agent-guard.sh +0 -74
  126. package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
  127. package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
  128. package/pipeline/scripts/smoke-ask-choice.sh +0 -42
  129. package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
  130. package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
  131. package/pipeline/scripts/smoke-changelog-version.sh +0 -47
  132. package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
  133. package/pipeline/scripts/smoke-channels-flow.sh +0 -130
  134. package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
  135. package/pipeline/scripts/smoke-clarify.sh +0 -148
  136. package/pipeline/scripts/smoke-command-inventory.sh +0 -81
  137. package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
  138. package/pipeline/scripts/smoke-community-gates.sh +0 -75
  139. package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
  140. package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
  141. package/pipeline/scripts/smoke-context-budget.sh +0 -72
  142. package/pipeline/scripts/smoke-cost-budget.sh +0 -70
  143. package/pipeline/scripts/smoke-cost-summary.sh +0 -139
  144. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
  145. package/pipeline/scripts/smoke-description-tr.sh +0 -82
  146. package/pipeline/scripts/smoke-dev-critic.sh +0 -144
  147. package/pipeline/scripts/smoke-diff-explain.sh +0 -147
  148. package/pipeline/scripts/smoke-diff-risk.sh +0 -190
  149. package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
  150. package/pipeline/scripts/smoke-eval-live.sh +0 -136
  151. package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
  152. package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
  153. package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
  154. package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
  155. package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
  156. package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
  157. package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
  158. package/pipeline/scripts/smoke-generate-issue.sh +0 -120
  159. package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
  160. package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
  161. package/pipeline/scripts/smoke-install-layout.sh +0 -248
  162. package/pipeline/scripts/smoke-intent-guard.sh +0 -86
  163. package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
  164. package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
  165. package/pipeline/scripts/smoke-keychain.sh +0 -158
  166. package/pipeline/scripts/smoke-language-axis.sh +0 -109
  167. package/pipeline/scripts/smoke-learning-curve.sh +0 -61
  168. package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
  169. package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
  170. package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
  171. package/pipeline/scripts/smoke-md-links.sh +0 -8
  172. package/pipeline/scripts/smoke-md2confluence.sh +0 -126
  173. package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
  174. package/pipeline/scripts/smoke-migrate-state.sh +0 -102
  175. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
  176. package/pipeline/scripts/smoke-model-fallback.sh +0 -89
  177. package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
  178. package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
  179. package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -194
  180. package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
  181. package/pipeline/scripts/smoke-own-punctuation.sh +0 -103
  182. package/pipeline/scripts/smoke-pack-contents.sh +0 -140
  183. package/pipeline/scripts/smoke-pat-audit.sh +0 -128
  184. package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
  185. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
  186. package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
  187. package/pipeline/scripts/smoke-phase-banner.sh +0 -101
  188. package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
  189. package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
  190. package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
  191. package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
  192. package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
  193. package/pipeline/scripts/smoke-plan-safety.sh +0 -139
  194. package/pipeline/scripts/smoke-plan-todos.sh +0 -196
  195. package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
  196. package/pipeline/scripts/smoke-pre-commit.sh +0 -170
  197. package/pipeline/scripts/smoke-pref-migration.sh +0 -226
  198. package/pipeline/scripts/smoke-prefs-language.sh +0 -134
  199. package/pipeline/scripts/smoke-progress-contract.sh +0 -127
  200. package/pipeline/scripts/smoke-prune-logs.sh +0 -137
  201. package/pipeline/scripts/smoke-purge.sh +0 -138
  202. package/pipeline/scripts/smoke-push-retry.sh +0 -75
  203. package/pipeline/scripts/smoke-repo-map.sh +0 -300
  204. package/pipeline/scripts/smoke-review-readiness.sh +0 -92
  205. package/pipeline/scripts/smoke-review-watch.sh +0 -146
  206. package/pipeline/scripts/smoke-routines.sh +0 -84
  207. package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
  208. package/pipeline/scripts/smoke-run-metrics.sh +0 -50
  209. package/pipeline/scripts/smoke-search.sh +0 -187
  210. package/pipeline/scripts/smoke-shadow-git.sh +0 -224
  211. package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
  212. package/pipeline/scripts/smoke-skill-language.sh +0 -83
  213. package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
  214. package/pipeline/scripts/smoke-skill-scan.sh +0 -198
  215. package/pipeline/scripts/smoke-source-parity.sh +0 -85
  216. package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
  217. package/pipeline/scripts/smoke-sync-parity.sh +0 -92
  218. package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
  219. package/pipeline/scripts/smoke-telemetry.sh +0 -147
  220. package/pipeline/scripts/smoke-test-gap.sh +0 -183
  221. package/pipeline/scripts/smoke-token-budget.sh +0 -67
  222. package/pipeline/scripts/smoke-token-preflight.sh +0 -82
  223. package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
  224. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
  225. package/pipeline/scripts/smoke-triage-memory.sh +0 -174
  226. package/pipeline/scripts/smoke-update-check.sh +0 -135
  227. package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
  228. package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
  229. package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
  230. package/pipeline/scripts/smoke-validator-gates.sh +0 -164
  231. package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
  232. package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
  233. package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
  234. package/pipeline/scripts/smoke-work-summary.sh +0 -163
  235. package/pipeline/scripts/smoke-workflow-audit.sh +0 -101
  236. package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
  237. package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
  238. package/pipeline/scripts/smoke-write-state.sh +0 -159
  239. package/pipeline/scripts/sync-parity-check.sh +0 -135
  240. package/pipeline/scripts/test-gap-rules/android.json +0 -25
  241. package/pipeline/scripts/test-gap-rules/ios.json +0 -34
  242. package/pipeline/scripts/test-gap-rules/node.json +0 -29
  243. package/pipeline/scripts/test-gap-rules/python.json +0 -25
  244. package/pipeline/scripts/validate-schemas.mjs +0 -88
@@ -1,130 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-gc-tmp.sh - gc-tmp.sh sweeps only known scratch prefixes, is dry-run
3
- # by default, never touches unrelated files, refuses unsafe scratch roots,
4
- # never deletes the root itself, and spares fresh scratch by default.
5
- #
6
- # Exit 0 = all pass, 1 = any failure.
7
-
8
- set -uo pipefail
9
-
10
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
11
- GC="$ROOT/pipeline/scripts/gc-tmp.sh"
12
- PASS=0
13
- FAIL=0
14
- pass() {
15
- PASS=$((PASS + 1))
16
- echo " ✓ $1"
17
- }
18
- fail() {
19
- FAIL=$((FAIL + 1))
20
- echo " ✗ $1"
21
- }
22
- [ -f "$GC" ] || {
23
- echo "FAIL: gc-tmp.sh missing" >&2
24
- exit 1
25
- }
26
-
27
- SB="$(mktemp -d)"
28
- trap 'rm -rf "$SB"' EXIT
29
-
30
- seed() {
31
- rm -rf "${SB:?}"/*
32
- mkdir -p "$SB/multi-agent-review-PROJ-1-x" "$SB/analysis-foo-123"
33
- touch "$SB/multi-agent-picker-PROJ-1.json" \
34
- "$SB/issue-progress-PROJ-1-ab.md" \
35
- "$SB/channels-PROJ-1-pr.md" \
36
- "$SB/context-links-PROJ-1.json" \
37
- "$SB/context-by-type-PROJ-1.json" \
38
- "$SB/unrelated-file.txt"
39
- }
40
-
41
- echo "→ 1. dry-run lists matches and deletes nothing"
42
- seed
43
- before=$(find "$SB" -mindepth 1 | wc -l | tr -d ' ')
44
- out=$(GC_TMP_ROOT="$SB" GC_TMP_GRACE_MIN=0 bash "$GC" 2>&1)
45
- after=$(find "$SB" -mindepth 1 | wc -l | tr -d ' ')
46
- echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
47
- [ "$before" = "$after" ] && pass "dry-run deleted nothing ($after entries intact)" || fail "dry-run changed the tree ($before -> $after)"
48
- echo "$out" | grep -q "unrelated-file.txt" && fail "dry-run matched an unrelated file" || pass "unrelated file not matched"
49
-
50
- echo ""
51
- echo "→ 2. --yes removes only matched scratch"
52
- seed
53
- GC_TMP_ROOT="$SB" GC_TMP_GRACE_MIN=0 bash "$GC" --yes >/dev/null 2>&1
54
- [ -f "$SB/unrelated-file.txt" ] && pass "unrelated file preserved" || fail "unrelated file was deleted"
55
- [ ! -e "$SB/multi-agent-picker-PROJ-1.json" ] && pass "multi-agent-* file removed" || fail "multi-agent-* file survived"
56
- [ ! -e "$SB/multi-agent-review-PROJ-1-x" ] && pass "scratch dir removed" || fail "scratch dir survived"
57
- [ ! -e "$SB/analysis-foo-123" ] && pass "analysis draft dir removed" || fail "analysis draft survived"
58
- [ ! -e "$SB/channels-PROJ-1-pr.md" ] && pass "channels payload removed" || fail "channels payload survived"
59
- remaining=$(find "$SB" -mindepth 1 | wc -l | tr -d ' ')
60
- [ "$remaining" = "1" ] && pass "exactly the 1 unrelated entry remains" || fail "expected 1 survivor, got $remaining"
61
-
62
- echo ""
63
- echo "→ 3. --older-than excludes fresh scratch"
64
- seed
65
- out=$(GC_TMP_ROOT="$SB" GC_TMP_GRACE_MIN=0 bash "$GC" --older-than=1 2>&1)
66
- echo "$out" | grep -q "nothing to do" && pass "freshly-created scratch excluded by --older-than=1" || fail "--older-than did not exclude fresh files"
67
-
68
- echo ""
69
- echo "→ 4. usage errors exit 2"
70
- GC_TMP_ROOT="$SB" bash "$GC" --bogus >/dev/null 2>&1
71
- [ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
72
- GC_TMP_ROOT="$SB" bash "$GC" --older-than=abc >/dev/null 2>&1
73
- [ "$?" = "2" ] && pass "non-numeric --older-than exits 2" || fail "bad --older-than did not exit 2"
74
-
75
- echo ""
76
- echo "→ 5. empty root is a clean no-op"
77
- EMPTY="$(mktemp -d)"
78
- out=$(GC_TMP_ROOT="$EMPTY" bash "$GC" 2>&1)
79
- rc=$?
80
- rm -rf "$EMPTY"
81
- { [ "$rc" = "0" ] && echo "$out" | grep -q "nothing to do"; } && pass "empty root exits 0 with no-op message" || fail "empty root not a clean no-op"
82
-
83
- echo ""
84
- echo "→ 6. unsafe scratch roots are refused (exit 2)"
85
- GC_TMP_ROOT="$HOME" bash "$GC" >/dev/null 2>&1
86
- [ "$?" = "2" ] && pass "\$HOME as scratch root refused" || fail "\$HOME as scratch root not refused"
87
- GC_TMP_ROOT="/" bash "$GC" >/dev/null 2>&1
88
- [ "$?" = "2" ] && pass "/ as scratch root refused" || fail "/ as scratch root not refused"
89
- GITROOT="$(mktemp -d)"
90
- mkdir -p "$GITROOT/.git"
91
- touch "$GITROOT/multi-agent-bait.json"
92
- GC_TMP_ROOT="$GITROOT" bash "$GC" --yes >/dev/null 2>&1
93
- rc=$?
94
- [ "$rc" = "2" ] && pass "git work tree as scratch root refused" || fail "git work tree as scratch root not refused"
95
- [ -f "$GITROOT/multi-agent-bait.json" ] && pass "bait file inside refused root untouched" || fail "refused root was still swept"
96
- rm -rf "$GITROOT"
97
-
98
- echo ""
99
- echo "→ 7. a root itself named like scratch is never deleted"
100
- SR="$(mktemp -d)"
101
- mkdir -p "$SR/multi-agent-root"
102
- touch "$SR/multi-agent-root/multi-agent-inner.json"
103
- GC_TMP_ROOT="$SR/multi-agent-root" GC_TMP_GRACE_MIN=0 bash "$GC" --yes >/dev/null 2>&1
104
- [ -d "$SR/multi-agent-root" ] && pass "matching-named root survives --yes" || fail "root dir itself was deleted"
105
- [ ! -e "$SR/multi-agent-root/multi-agent-inner.json" ] && pass "inner scratch still removed" || fail "inner scratch survived"
106
- rm -rf "$SR"
107
-
108
- echo ""
109
- echo "→ 8. symlinked scratch is unlinked without following it"
110
- seed
111
- VICTIM="$(mktemp -d)"
112
- echo keep >"$VICTIM/keep.txt"
113
- ln -s "$VICTIM" "$SB/multi-agent-linked"
114
- GC_TMP_ROOT="$SB" GC_TMP_GRACE_MIN=0 bash "$GC" --yes >/dev/null 2>&1
115
- [ ! -e "$SB/multi-agent-linked" ] && pass "symlink itself removed" || fail "symlink survived"
116
- [ -f "$VICTIM/keep.txt" ] && pass "symlink target untouched" || fail "symlink target was deleted"
117
- rm -rf "$VICTIM"
118
-
119
- echo ""
120
- echo "→ 9. default grace spares fresh scratch"
121
- seed
122
- out=$(GC_TMP_ROOT="$SB" bash "$GC" --yes 2>&1)
123
- rc=$?
124
- [ "$rc" = "0" ] && pass "grace run exits 0" || fail "grace run exited $rc"
125
- [ -f "$SB/multi-agent-picker-PROJ-1.json" ] && pass "fresh scratch spared by default grace" || fail "default grace deleted fresh scratch"
126
- echo "$out" | grep -qi "spared" && pass "output mentions spared fresh items" || fail "no spared note in output"
127
-
128
- echo ""
129
- echo "══ gc-tmp smoke: $PASS passed, $FAIL failed ══"
130
- [ "$FAIL" -eq 0 ]
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-gc-worktrees.sh - contract of the worktree residue sweeper.
3
- #
4
- # Verifies gc-worktrees.sh: dry-run-by-default, orphan-dir removal only with
5
- # --yes, registered worktrees untouched, gitlink residue unstaged, exclude
6
- # guard added idempotently, --older-than sparing, non-repo no-op, and flag
7
- # validation.
8
-
9
- set -uo pipefail
10
-
11
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12
- SCRIPT="$SCRIPT_DIR/gc-worktrees.sh"
13
-
14
- PASS=0
15
- FAIL=0
16
- record_pass() { PASS=$((PASS + 1)); printf ' \342\234\223 %s\n' "$1"; }
17
- record_fail() { FAIL=$((FAIL + 1)); printf ' \342\234\227 %s\n' "$1"; }
18
-
19
- printf '\342\206\222 smoke-gc-worktrees: worktree residue sweep contract\n'
20
-
21
- tmpdir=$(mktemp -d)
22
- trap 'rm -rf "$tmpdir"' EXIT
23
-
24
- # Fixture repo: one registered worktree, one orphan dir, one gitlink residue.
25
- REPO="$tmpdir/repo"
26
- mkdir -p "$REPO"
27
- git -C "$REPO" init -q -b main
28
- git -C "$REPO" config user.email smoke@test
29
- git -C "$REPO" config user.name smoke
30
- echo hi > "$REPO/f.txt"
31
- git -C "$REPO" add f.txt
32
- git -C "$REPO" commit -qm init
33
- git -C "$REPO" worktree add -q "$REPO/.worktrees/REG" -b reg-branch
34
- mkdir -p "$REPO/.worktrees/ORPHAN"
35
- echo x > "$REPO/.worktrees/ORPHAN/file"
36
- git -C "$REPO" update-index --add --cacheinfo "160000,$(git -C "$REPO" rev-parse HEAD),.worktrees/GONE"
37
-
38
- # 1. Script parses
39
- if bash -n "$SCRIPT" 2>/dev/null; then
40
- record_pass "gc-worktrees.sh parses (bash -n)"
41
- else
42
- record_fail "gc-worktrees.sh has syntax errors"
43
- fi
44
-
45
- # 2. Dry-run lists all three findings and deletes nothing
46
- out=$(bash "$SCRIPT" --repo "$REPO" 2>&1); rc=$?
47
- if [ "$rc" -eq 0 ] \
48
- && printf '%s' "$out" | grep -q "would remove orphan worktree dir: .worktrees/ORPHAN" \
49
- && printf '%s' "$out" | grep -q "would unstage gitlink residue from the index: .worktrees/GONE" \
50
- && printf '%s' "$out" | grep -q "would add .worktrees/ to .git/info/exclude"; then
51
- record_pass "dry-run lists orphan dir + gitlink + missing guard"
52
- else
53
- record_fail "dry-run should list all three findings (rc=$rc): $out"
54
- fi
55
- if [ -d "$REPO/.worktrees/ORPHAN" ] && git -C "$REPO" ls-files -s -- .worktrees | grep -q 160000; then
56
- record_pass "dry-run changed nothing"
57
- else
58
- record_fail "dry-run must not delete or unstage anything"
59
- fi
60
-
61
- # 3. --older-than spares the freshly-touched orphan
62
- out=$(bash "$SCRIPT" --repo "$REPO" --older-than=60 2>&1)
63
- if printf '%s' "$out" | grep -q "would remove orphan"; then
64
- record_fail "--older-than=60 should spare the fresh orphan dir"
65
- else
66
- record_pass "--older-than spares recently-touched orphan dirs"
67
- fi
68
-
69
- # 4. --yes applies all three
70
- out=$(bash "$SCRIPT" --repo "$REPO" --yes 2>&1); rc=$?
71
- if [ "$rc" -eq 0 ] && [ ! -d "$REPO/.worktrees/ORPHAN" ]; then
72
- record_pass "--yes removes the orphan dir"
73
- else
74
- record_fail "--yes should remove the orphan dir (rc=$rc): $out"
75
- fi
76
- if git -C "$REPO" ls-files -s -- .worktrees | grep -q 160000; then
77
- record_fail "--yes should unstage the gitlink residue"
78
- else
79
- record_pass "--yes unstages the gitlink residue"
80
- fi
81
- if [ "$(grep -cxF '.worktrees/' "$REPO/.git/info/exclude" 2>/dev/null)" = "1" ]; then
82
- record_pass "--yes adds the exclude guard exactly once"
83
- else
84
- record_fail "exclude guard missing or duplicated"
85
- fi
86
-
87
- # 5. Registered worktree untouched
88
- if [ -d "$REPO/.worktrees/REG" ] && git -C "$REPO" worktree list | grep -q "REG"; then
89
- record_pass "registered worktree left untouched"
90
- else
91
- record_fail "registered worktree must never be touched"
92
- fi
93
-
94
- # 6. Re-run -> nothing to do, guard not duplicated
95
- out=$(bash "$SCRIPT" --repo "$REPO" 2>&1); rc=$?
96
- if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -q "nothing to do"; then
97
- record_pass "clean repo -> nothing to do (exit 0)"
98
- else
99
- record_fail "clean repo should be a no-op (rc=$rc): $out"
100
- fi
101
- bash "$SCRIPT" --repo "$REPO" --yes >/dev/null 2>&1
102
- if [ "$(grep -cxF '.worktrees/' "$REPO/.git/info/exclude")" = "1" ]; then
103
- record_pass "exclude guard is idempotent across --yes reruns"
104
- else
105
- record_fail "exclude guard duplicated on rerun"
106
- fi
107
-
108
- # 7. Non-repo -> silent no-op exit 0
109
- out=$(bash "$SCRIPT" --repo "$tmpdir" 2>&1); rc=$?
110
- if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -q "not a git work tree"; then
111
- record_pass "non-repo -> exit 0 no-op"
112
- else
113
- record_fail "non-repo should exit 0 with a no-op message (rc=$rc)"
114
- fi
115
-
116
- # 8. Unknown flag -> usage error exit 2
117
- bash "$SCRIPT" --definitely-not-a-flag >/dev/null 2>&1; rc=$?
118
- if [ "$rc" -eq 2 ]; then
119
- record_pass "unknown flag -> exit 2"
120
- else
121
- record_fail "unknown flag should exit 2 (got $rc)"
122
- fi
123
-
124
- printf '\n\342\225\220\342\225\220 smoke-gc-worktrees: %d passed, %d failed \342\225\220\342\225\220\n' "$PASS" "$FAIL"
125
- [ "$FAIL" -eq 0 ]
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-generate-issue.sh - contract for /multi-agent:create-jira.
3
- #
4
- # Verifies:
5
- # 1. All 3 files exist (1 command, shared ref, 1 Copilot/plugin SKILL.md).
6
- # 2. Frontmatter keys present on both surfaces.
7
- # 3. Command delegates to refs/generate-issue.md and asks the issue type.
8
- # 4. Approval gate documented and marked unskippable in the ref.
9
- # 5. Convention mining + createmeta + Agile sprint endpoints present.
10
- # 6. UTF-8 verbatim POST path (--rawfile + --data-binary) present.
11
- # 7. Standard template vocab: Task/Story (Scope/Acceptance/Test Scenarios), Bug (Steps/Expected/Actual/Environment), Swagger.
12
- # 8. Registration: dispatcher rows, inventory lists, count derived from the command tree.
13
- # 9. Forbidden strings absent (em-dash, section sign, the M-word, unicode_escape).
14
-
15
- set -euo pipefail
16
-
17
- HERE="$(cd "$(dirname "$0")" && pwd)"
18
- ROOT="$(cd "$HERE/../.." && pwd)"
19
- CMD="$ROOT/pipeline/commands/multi-agent/create-jira/SKILL.md"
20
- REF="$ROOT/pipeline/multi-agent-refs/generate-issue.md"
21
- SKILL="$ROOT/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md"
22
- DISPATCHER="$ROOT/pipeline/commands/multi-agent/SKILL.md"
23
- CONTRACT="$ROOT/pipeline/multi-agent-refs/cross-cli-contract.md"
24
- CMD_COUNT=$(find "$ROOT/pipeline/commands/multi-agent" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')
25
- SYNC="$ROOT/pipeline/commands/multi-agent/sync/SKILL.md"
26
- HELP="$ROOT/pipeline/commands/multi-agent/help/SKILL.md"
27
-
28
- PASS=0
29
- FAIL=0
30
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
31
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
32
-
33
- echo "→ 1. files exist"
34
- for f in "$CMD" "$REF" "$SKILL"; do
35
- if [ -f "$f" ]; then pass "exists: ${f#$ROOT/}"; else fail "missing: ${f#$ROOT/}"; fi
36
- done
37
- # old split commands must be gone
38
- for f in "$ROOT/pipeline/commands/multi-agent/generate-task/SKILL.md" "$ROOT/pipeline/commands/multi-agent/generate-bug/SKILL.md"; do
39
- if [ -f "$f" ]; then fail "stale file present: ${f#$ROOT/}"; else pass "removed: ${f##*/}"; fi
40
- done
41
- [ "$FAIL" -eq 0 ] || { echo "══ generate-issue smoke: $PASS passed, $FAIL failed ══"; exit 1; }
42
-
43
- echo ""
44
- echo "→ 2. frontmatter keys"
45
- head -5 "$CMD" | grep -q '^description:' && pass "description: ${CMD##*/}" || fail "description missing: ${CMD##*/}"
46
- head -5 "$CMD" | grep -q '^argument-hint:' && pass "argument-hint: ${CMD##*/}" || fail "argument-hint missing: ${CMD##*/}"
47
- head -8 "$SKILL" | grep -q '^name: multi-agent-create-jira$' && pass "name: multi-agent-create-jira" || fail "name wrong: $SKILL"
48
- head -8 "$SKILL" | grep -q '^language: en' && pass "language en" || fail "language missing: $SKILL"
49
- head -8 "$SKILL" | grep -q '^user-invocable: true' && pass "user-invocable" || fail "user-invocable missing: $SKILL"
50
-
51
- echo ""
52
- echo "→ 3. command delegates to the shared ref and asks the type"
53
- grep -Fq "refs/generate-issue.md" "$CMD" && pass "ref link present" || fail "ref link missing"
54
- for t in "Task" "Bug" "Story"; do
55
- grep -Fq "$t" "$CMD" && pass "type offered: $t" || fail "type missing: $t"
56
- done
57
- grep -Fqi "Pick issue type" "$REF" && pass "type-selection step present" || fail "type-selection step missing"
58
-
59
- echo ""
60
- echo "→ 4. approval gate documented and unskippable"
61
- grep -Fq "Full preview + approval gate (never skipped)" "$REF" && pass "gate section present" || fail "gate section missing"
62
- for marker in "Approve" "Edit" "Cancel" "no bypass" "Nothing was created"; do
63
- grep -Fqi "$marker" "$REF" && pass "gate marker: $marker" || fail "gate marker missing: $marker"
64
- done
65
- grep -Fq "no autopilot variant" "$REF" && pass "no-autopilot rule" || fail "no-autopilot rule missing"
66
-
67
- echo ""
68
- echo "→ 5. mining + createmeta + agile endpoints"
69
- for marker in "rest/api/2/search" "rest/api/2/issue/createmeta" "rest/agile/1.0/board" "sprint?state=active" 'sprint/${SPRINT_ID}/issue' "remotelink" "attachments"; do
70
- grep -Fq "$marker" "$REF" && pass "endpoint marker: $marker" || fail "endpoint marker missing: $marker"
71
- done
72
- grep -Fq "gh-sprint" "$REF" && pass "generic sprint-field detection" || fail "generic sprint-field detection missing"
73
-
74
- echo ""
75
- echo "→ 6. UTF-8 verbatim POST path"
76
- grep -Fq -- "--rawfile" "$REF" && pass "--rawfile present" || fail "--rawfile missing"
77
- grep -Fq -- "--data-binary" "$REF" && pass "--data-binary present" || fail "--data-binary missing"
78
- grep -Fqi "humanizer" "$REF" && pass "humanizer pass referenced" || fail "humanizer missing"
79
-
80
- echo ""
81
- echo "→ 7. standard template vocabulary + auto-sizing + swagger"
82
- for s in "Scope" "Acceptance Criteria" "Test Scenarios"; do
83
- grep -Fq "$s" "$REF" && pass "task/story section: $s" || fail "task/story section missing: $s"
84
- done
85
- for s in "Steps to Reproduce" "Expected Result" "Actual Result" "Environment"; do
86
- grep -Fq "$s" "$REF" && pass "bug section: $s" || fail "bug section missing: $s"
87
- done
88
- grep -Fqi "auto-sizing" "$REF" && pass "auto-sizing rule present" || fail "auto-sizing rule missing"
89
- grep -Fqi "swagger" "$REF" && pass "swagger context present" || fail "swagger context missing"
90
-
91
- echo ""
92
- echo "→ 8. registration + count consistency (derived)"
93
- grep -Fq '| `create-jira ' "$DISPATCHER" && pass "dispatcher routing: create-jira" || fail "dispatcher routing missing: generate"
94
- grep -Fq "create-jira/SKILL.md" "$DISPATCHER" && pass "dispatcher loading row" || fail "dispatcher loading row missing"
95
- grep -Fq "## 1. Command Inventory ($CMD_COUNT commands)" "$CONTRACT" && pass "contract count = $CMD_COUNT (derived)" || fail "contract count wrong"
96
- grep -Eq '(^|[ ,])create-jira([ ,]|$)' "$CONTRACT" && pass "contract list has create-jira" || fail "contract list missing generate"
97
- grep -Fq "**$CMD_COUNT commands are synced**" "$SYNC" && pass "sync count = $CMD_COUNT (derived)" || fail "sync count wrong"
98
- SYNC_SKILL="$ROOT/pipeline/skills/shared/core/multi-agent-sync/SKILL.md"
99
- grep -Fq "**$CMD_COUNT commands are synced**" "$SYNC_SKILL" && pass "sync SKILL count = $CMD_COUNT (derived)" || fail "sync SKILL count wrong (Copilot parity)"
100
- grep -Fq "create-jira" "$ROOT/pipeline/skills/shared/core/multi-agent-help/SKILL.md" && pass "help SKILL lists create-jira" || fail "help SKILL missing create-jira (Copilot parity)"
101
- grep -c "multi-agent:create-jira" "$HELP" | awk '{exit !($1>=2)}' && pass "help.md has EN + TR entries" || fail "help.md entries incomplete"
102
- # no stale split-command references anywhere in the synced surfaces
103
- if grep -rqE "generate-task|generate-bug" "$DISPATCHER" "$CONTRACT" "$SYNC" "$HELP" "$CMD" "$REF" "$SKILL"; then
104
- fail "stale generate-task/generate-bug reference found"
105
- else
106
- pass "no stale split-command references"
107
- fi
108
-
109
- echo ""
110
- echo "→ 9. forbidden strings absent"
111
- MWORD="MAN""DATORY"
112
- for f in "$CMD" "$REF" "$SKILL"; do
113
- if grep -q $'—\|§\|…' "$f"; then fail "forbidden unicode punctuation in ${f##*/}"; else pass "punctuation clean: ${f##*/}"; fi
114
- if grep -q "$MWORD" "$f"; then fail "forbidden word in ${f##*/}"; else pass "vocabulary clean: ${f##*/}"; fi
115
- if grep -q "unicode_escape" "$f" && ! grep -q "Never round-trip" "$f"; then fail "unicode_escape misuse in ${f##*/}"; else pass "encoding rule clean: ${f##*/}"; fi
116
- done
117
-
118
- echo ""
119
- echo "══ generate-issue smoke: $PASS passed, $FAIL failed ══"
120
- [ "$FAIL" -eq 0 ]
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-handoff-contract.sh
3
- #
4
- # Verifies the v10.8.0 structured-handoff contract (fresh-context re-entry):
5
- # 1. operations.md documents the Handoff block with all 5 required lines
6
- # 2. operations.md compaction trigger re-reads state AND the latest handoff
7
- # 3. log-format.md documents the Handoff section in the canonical log shape
8
- # 4. resume.md Step 3 reads the latest handoff FIRST with pre-v10.8 fallback
9
- #
10
- # Exit 0 = all pass, 1 = any failure.
11
-
12
- set -euo pipefail
13
-
14
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
15
- OPS="$ROOT/pipeline/multi-agent-refs/phases/operations.md"
16
- LOGFMT="$ROOT/pipeline/multi-agent-refs/phases/log-format.md"
17
- RESUME="$ROOT/pipeline/commands/multi-agent/resume/SKILL.md"
18
-
19
- pass=0
20
- fail=0
21
- failures=()
22
- record_pass() { pass=$((pass + 1)); printf ' \033[0;32mPASS\033[0m %s\n' "$1"; }
23
- record_fail() { fail=$((fail + 1)); failures+=("$1"); printf ' \033[0;31mFAIL\033[0m %s\n' "$1"; }
24
-
25
- printf '→ smoke-handoff-contract: structured handoff (fresh-context re-entry)\n'
26
-
27
- # 1. operations.md documents the Handoff block with the 5 required lines
28
- if [ ! -f "$OPS" ]; then
29
- record_fail "operations.md missing"
30
- else
31
- if grep -qF "Handoff block (v10.8.0)" "$OPS"; then
32
- record_pass "operations.md documents the Handoff block"
33
- else
34
- record_fail "operations.md missing 'Handoff block (v10.8.0)' spec"
35
- fi
36
- for line in "- Done:" "- Remaining:" "- Decisions:" "- Open findings:" "- Next:"; do
37
- if grep -qF -- "$line" "$OPS"; then
38
- record_pass "operations.md handoff spec has '$line'"
39
- else
40
- record_fail "operations.md handoff spec missing '$line'"
41
- fi
42
- done
43
- if grep -qF "no agent dispatch, no extra LLM call" "$OPS"; then
44
- record_pass "operations.md states handoff is orchestrator-written (no LLM call)"
45
- else
46
- record_fail "operations.md must state the handoff costs no LLM call"
47
- fi
48
- fi
49
-
50
- # 2. Compaction trigger re-reads state AND latest handoff
51
- if grep -qE 'agent-state\.json.*AND the latest.*Handoff' "$OPS"; then
52
- record_pass "compaction trigger re-reads state + latest handoff"
53
- else
54
- record_fail "operations.md compaction trigger must re-read agent-state.json AND the latest Handoff block"
55
- fi
56
-
57
- # 3. log-format.md documents the Handoff section
58
- if grep -qF "## Handoff - end of Phase" "$LOGFMT"; then
59
- record_pass "log-format.md documents the Handoff section"
60
- else
61
- record_fail "log-format.md missing the Handoff section"
62
- fi
63
- if grep -qF "LATEST block is authoritative" "$LOGFMT"; then
64
- record_pass "log-format.md states latest-block-wins semantics"
65
- else
66
- record_fail "log-format.md must state the latest handoff block is authoritative"
67
- fi
68
-
69
- # 4. resume.md reads handoff first, with fallback for older logs
70
- if grep -qE 'LATEST .?## Handoff.? block' "$RESUME"; then
71
- record_pass "resume.md Step 3 reads the latest Handoff block first"
72
- else
73
- record_fail "resume.md Step 3 must read the latest Handoff block first"
74
- fi
75
- if grep -qiF "fall back to per-phase findings" "$RESUME"; then
76
- record_pass "resume.md keeps the pre-v10.8 per-phase fallback"
77
- else
78
- record_fail "resume.md must keep the pre-v10.8 per-phase findings fallback"
79
- fi
80
- if grep -qF "trust state on mismatch" "$RESUME"; then
81
- record_pass "resume.md defines state-wins conflict rule"
82
- else
83
- record_fail "resume.md must define the handoff-vs-state conflict rule (state wins)"
84
- fi
85
-
86
- printf '\n══ handoff-contract smoke: %d passed, %d failed ══\n' "$pass" "$fail"
87
- if [ "$fail" -gt 0 ]; then
88
- printf '\nFailures:\n'
89
- for msg in "${failures[@]}"; do printf ' - %s\n' "$msg"; done
90
- exit 1
91
- fi
92
- exit 0
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-identity-isolation.sh - asserts identity isolation rules from section18.3
3
- # of REFACTOR_PLAN_v3.7.md are documented & wired:
4
- #
5
- # • Identity lookup happens via platformIdentityRouting only - NEVER fall
6
- # back to "try all PATs"
7
- # • If no routing match, prompt user - do not guess
8
- # • servicePatMap is checked per-identity - corp identity cannot accidentally
9
- # use personal identity's PAT even if the keychain name is discoverable
10
- #
11
- # Doc-shape smoke (no fake keychain entries; pure spec assertion).
12
-
13
- set -uo pipefail
14
-
15
- # Read from source (authoritative) - installed tree may lag behind on
16
- # machines that haven't re-run install.js after a pipeline update.
17
- HERE="$(cd "$(dirname "$0")" && pwd)"
18
- ROOT="$(cd "$HERE/../.." && pwd)"
19
- PHASE0="$ROOT/pipeline/multi-agent-refs/phases/phase-0-init.md"
20
- SETUP="$ROOT/pipeline/commands/multi-agent/setup/SKILL.md"
21
- PREFS_SCHEMA="$ROOT/pipeline/schemas/prefs.schema.json"
22
-
23
- PASS=0; FAIL=0
24
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
25
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
26
-
27
- echo "→ 1. servicePatMap is per-identity (schema)"
28
- grep -q "servicePatMap" "$PREFS_SCHEMA" \
29
- && pass "Schema declares identities[].servicePatMap" \
30
- || fail "Schema missing servicePatMap on identities"
31
- grep -q "Enables cross-identity isolation\|cross-identity isolation" "$PREFS_SCHEMA" \
32
- && pass "Schema description articulates cross-identity isolation invariant" \
33
- || fail "Schema description missing isolation invariant"
34
-
35
- echo ""
36
- echo "→ 2. Phase 0 routing - no silent fallback to 'try all PATs'"
37
- grep -q "platformIdentityRouting" "$PHASE0" \
38
- && pass "Phase 0 Step 6 references platformIdentityRouting" \
39
- || fail "Phase 0 missing platformIdentityRouting reference"
40
- # Post-10caff1 wording: the resolution order ends with an explicit "ask once"
41
- # clause for the multi-identity case - same invariant as the older
42
- # "multi-identity picker" text.
43
- grep -q "Multiple identities, no routing rule" "$PHASE0" \
44
- && pass "Phase 0 handles 'no routing match, multiple identities' branch" \
45
- || fail "Phase 0 missing no-match + multi-identity handling"
46
- grep -q "No identities" "$PHASE0" \
47
- && pass "Phase 0 handles 'no identities ever' branch (Token Save Flow)" \
48
- || fail "Phase 0 missing 'no identities' branch"
49
- grep -qE "save routing rule so it never asks again" "$PHASE0" \
50
- && pass "Phase 0 persists routing on first ask (no silent guess)" \
51
- || fail "Phase 0 missing routing-persistence guarantee"
52
-
53
- echo ""
54
- echo "→ 3. Setup Step 4 wires per-identity service ownership"
55
- grep -q "servicePatMap" "$SETUP" \
56
- && pass "Setup Step 4 documents servicePatMap" \
57
- || fail "Setup Step 4 missing servicePatMap"
58
- grep -qE "own tokens for|owns.*jira|per-identity" "$SETUP" \
59
- && pass "Setup Step 4 describes per-identity ownership" \
60
- || fail "Setup Step 4 missing per-identity ownership description"
61
-
62
- echo ""
63
- echo "→ 4. Multi-repo: identity routed per-repo (not shared)"
64
- grep -qE "per repo( independently)?|routed per-repo" "$PHASE0" \
65
- && pass "Multi-repo Step 6 routes identity per-repo" \
66
- || fail "Multi-repo per-repo identity routing missing"
67
-
68
- echo ""
69
- echo "══ identity-isolation smoke: $PASS passed, $FAIL failed ══"
70
- [ "$FAIL" -eq 0 ]