@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,73 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # smoke-tracker-tokens-invocation.sh
4
- #
5
- # Asserts every LLM-heavy phase doc invokes `phase-tracker.sh tokens <N> <in> <out>`
6
- # at least once, so the per-phase + cumulative token counter in the tracker's
7
- # render output stays accurate for every run. Without this gate, phase docs
8
- # tend to drop the token call as they get edited and the user loses cost
9
- # visibility - exactly Defect 5 from the GH1241 review.
10
- #
11
- # Phase 3 (Dev) and Phase 4 (Review) are the LLM-intensive ones. Phase 1+2
12
- # also do LLM work. Phase 0/5/6/7 are mostly orchestration.
13
-
14
- set -euo pipefail
15
-
16
- SELF_DIR=$(cd "$(dirname "$0")" && pwd)
17
- PIPELINE_ROOT=$(cd "$SELF_DIR/.." && pwd)
18
-
19
- cd "$PIPELINE_ROOT"
20
-
21
- FAIL=0
22
-
23
- # Every phase doc that runs LLM calls MUST mention `phase-tracker.sh tokens`
24
- # at least once (either in a code fence or inline).
25
- declare -a LLM_PHASES=(
26
- "multi-agent-refs/phases/phase-1-analysis.md:1"
27
- "multi-agent-refs/phases/phase-2-planning.md:2"
28
- "multi-agent-refs/phases/phase-3-dev.md:3"
29
- "multi-agent-refs/phases/phase-4-review.md:4"
30
- )
31
-
32
- for entry in "${LLM_PHASES[@]}"; do
33
- doc="${entry%:*}"
34
- phase_id="${entry##*:}"
35
- full="$doc"
36
- if [ ! -f "$full" ]; then
37
- echo "FAIL [smoke-tracker-tokens-invocation]: $doc missing"
38
- FAIL=$((FAIL + 1))
39
- continue
40
- fi
41
- if ! grep -qE "phase-tracker\.sh tokens" "$full"; then
42
- echo "FAIL [smoke-tracker-tokens-invocation]: $doc must invoke 'phase-tracker.sh tokens $phase_id <in> <out>' after every LLM call"
43
- FAIL=$((FAIL + 1))
44
- fi
45
- done
46
-
47
- # tracker-contract.md is the canonical location for the tokens API. Make sure
48
- # it documents the invocation pattern with both args.
49
- CONTRACT="multi-agent-refs/tracker-contract.md"
50
- if [ ! -f "$CONTRACT" ]; then
51
- echo "FAIL [smoke-tracker-tokens-invocation]: $CONTRACT missing"
52
- FAIL=$((FAIL + 1))
53
- elif ! grep -qE "phase-tracker\.sh tokens .*<in>.*<out>|phase-tracker\.sh tokens .*<input.*<output" "$CONTRACT"; then
54
- echo "FAIL [smoke-tracker-tokens-invocation]: $CONTRACT must document the tokens <N> <in> <out> signature"
55
- FAIL=$((FAIL + 1))
56
- fi
57
-
58
- # v9.10.2: the contract must also mandate the per-phase completion narration
59
- # line - the TaskList widget shows duration only, so without the chat line the
60
- # user never sees live per-phase tokens.
61
- if ! grep -q "per-phase token narration on completion" "$CONTRACT"; then
62
- echo "FAIL [smoke-tracker-tokens-invocation]: $CONTRACT must mandate the per-phase token narration line on completion"
63
- FAIL=$((FAIL + 1))
64
- fi
65
-
66
- if [ "$FAIL" -gt 0 ]; then
67
- echo ""
68
- echo "smoke-tracker-tokens-invocation: $FAIL violation(s)."
69
- echo "Defect 5: phase docs must invoke 'phase-tracker.sh tokens <N> <in> <out>' after every LLM call so the tracker render shows live cost."
70
- exit 1
71
- fi
72
-
73
- echo "smoke-tracker-tokens-invocation: ok"
@@ -1,174 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-triage-memory.sh - v8.3.0
3
- #
4
- # Verifies the triage-memory persistence layer:
5
- # 1. ingest writes JSONL rows for accepted/deferred/rejected and tags
6
- # task_id, classification, severity, file, issue, reason
7
- # 2. ingest is idempotent - re-running with the same input writes 0 rows
8
- # 3. stats reports correct row counts grouped by classification
9
- # 4. query ranks rows by token overlap, returns top-N hits
10
- # 5. query --file-glob filters by path
11
- # 6. path subcommand resolves to <slug>/triage-corpus.jsonl under HOME
12
- # 7. empty corpus query returns total=0 + exit 2
13
- # 8. validate-schemas accepts triage-corpus.schema.json
14
- # 9. phase-7-report.md ref doc declares the ingest call
15
- # 10. phase-4-review.md ref doc declares prior-art lookup
16
- # 11. prefs.schema.json exposes priorArtEnrichment toggle
17
- #
18
- # Uses HOME override so we never touch the user's real ~/.claude/memory.
19
- #
20
- # Exit 0 = all pass, 1 = any failure.
21
-
22
- set -uo pipefail
23
-
24
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
25
- TM="$ROOT/pipeline/scripts/triage-memory.mjs"
26
- PHASE7="$ROOT/pipeline/multi-agent-refs/phases/phase-7-report.md"
27
- PHASE4="$ROOT/pipeline/multi-agent-refs/phases/phase-4-review.md"
28
- PREFS="$ROOT/pipeline/schemas/prefs.schema.json"
29
- SCHEMA="$ROOT/pipeline/schemas/triage-corpus.schema.json"
30
-
31
- pass=0
32
- fail=0
33
- failures=()
34
- record_pass() { pass=$((pass + 1)); printf ' \033[0;32mPASS\033[0m %s\n' "$1"; }
35
- record_fail() { fail=$((fail + 1)); failures+=("$1"); printf ' \033[0;31mFAIL\033[0m %s\n' "$1"; }
36
-
37
- printf '→ smoke-triage-memory (v8.3.0): semantic memory contract\n'
38
-
39
- [ -f "$SCHEMA" ] || { record_fail "schema missing: $SCHEMA"; exit 1; }
40
-
41
- TMP_HOME=$(mktemp -d)
42
- trap 'rm -rf "$TMP_HOME"' EXIT
43
- export HOME="$TMP_HOME"
44
- export MULTI_AGENT_REPO_SLUG="smoke-corpus"
45
-
46
- # Build a fixture triage JSON
47
- TRIAGE_FIXTURE="$TMP_HOME/triage.json"
48
- cat > "$TRIAGE_FIXTURE" <<'JSON'
49
- {
50
- "accepted": [
51
- {"severity":"blocking","file":"Auth/KeychainStore.swift","line":42,"issue":"Force-unwrap on optional token","fix":"Use guard let","reviewer":"opus"},
52
- {"severity":"important","file":"Networking/ApiClient.swift","line":11,"issue":"Missing timeout configuration","fix":"Set request timeout","reviewer":"sonnet"}
53
- ],
54
- "deferred": [
55
- {"finding":{"severity":"suggestion","file":"Views/SettingsView.swift","line":50,"issue":"Could extract subview","fix":"refactor"},"reason":"out of scope"}
56
- ],
57
- "rejected": [
58
- {"finding":{"severity":"important","file":"Auth/KeychainStore.swift","line":99,"issue":"Use Sendable annotation","fix":"add Sendable"},"reason":"requires Swift 6 migration"}
59
- ],
60
- "approved": false
61
- }
62
- JSON
63
-
64
- # --- 1: first ingest writes rows ---
65
- out1=$(node "$TM" ingest --triage "$TRIAGE_FIXTURE" --task-id PROJ-100 --task-title "Auth refactor" --stack ios 2>/dev/null)
66
- ingested=$(echo "$out1" | jq -r '.ingested')
67
- if [ "$ingested" = "4" ]; then
68
- record_pass "ingest writes 4 rows (2 accepted + 1 deferred + 1 rejected)"
69
- else
70
- record_fail "ingest expected 4, got $ingested"
71
- fi
72
-
73
- # --- 2: idempotent re-ingest writes 0 rows ---
74
- out2=$(node "$TM" ingest --triage "$TRIAGE_FIXTURE" --task-id PROJ-100 --task-title "Auth refactor" --stack ios 2>/dev/null; echo "EC=$?")
75
- ingested2=$(echo "$out2" | grep -v EC= | jq -r '.ingested')
76
- ec2=$(echo "$out2" | grep "EC=" | sed 's/.*EC=//')
77
- if [ "$ingested2" = "0" ] && [ "$ec2" = "2" ]; then
78
- record_pass "re-ingest is idempotent (0 rows + exit 2)"
79
- else
80
- record_fail "re-ingest should write 0 rows + exit 2, got rows=$ingested2 ec=$ec2"
81
- fi
82
-
83
- # --- 3: stats counts ---
84
- stats=$(node "$TM" stats 2>/dev/null)
85
- acc=$(echo "$stats" | jq -r '.counts.accepted')
86
- def=$(echo "$stats" | jq -r '.counts.deferred')
87
- rej=$(echo "$stats" | jq -r '.counts.rejected')
88
- if [ "$acc" = "2" ] && [ "$def" = "1" ] && [ "$rej" = "1" ]; then
89
- record_pass "stats reports accepted=2 deferred=1 rejected=1"
90
- else
91
- record_fail "stats wrong: accepted=$acc deferred=$def rejected=$rej"
92
- fi
93
-
94
- # --- 4: query ranks by token overlap ---
95
- q1=$(node "$TM" query --issue "force unwrap optional" --top 2 2>/dev/null)
96
- top1=$(echo "$q1" | jq -r '.hits[0].file')
97
- top1_issue=$(echo "$q1" | jq -r '.hits[0].issue')
98
- if [[ "$top1" == *"KeychainStore.swift" ]] && [[ "$top1_issue" == *"Force-unwrap"* ]]; then
99
- record_pass "query: 'force unwrap optional' top hit = KeychainStore force-unwrap finding"
100
- else
101
- record_fail "query top hit wrong: $top1 / $top1_issue"
102
- fi
103
-
104
- # --- 5: file-glob filter ---
105
- q2=$(node "$TM" query --issue "timeout" --file-glob "Networking/*" 2>/dev/null)
106
- n2=$(echo "$q2" | jq -r '.hits | length')
107
- top2=$(echo "$q2" | jq -r '.hits[0].file' 2>/dev/null || echo "")
108
- if [ "$n2" = "1" ] && [[ "$top2" == "Networking/ApiClient.swift" ]]; then
109
- record_pass "query: --file-glob narrows to Networking/* path"
110
- else
111
- record_fail "file-glob narrow wrong: hits=$n2 top=$top2"
112
- fi
113
-
114
- # --- 6: path subcommand ---
115
- p=$(node "$TM" path 2>/dev/null)
116
- expected="$TMP_HOME/.claude/memory/multi-agent/smoke-corpus/triage-corpus.jsonl"
117
- if [ "$p" = "$expected" ]; then
118
- record_pass "path resolves to <HOME>/.claude/memory/multi-agent/<slug>/triage-corpus.jsonl"
119
- else
120
- record_fail "path wrong: $p (expected $expected)"
121
- fi
122
-
123
- # --- 7: empty-corpus query exits 2 with empty hits ---
124
- export MULTI_AGENT_REPO_SLUG="empty-corpus"
125
- set +e
126
- empty_out=$(node "$TM" query --issue "anything" 2>/dev/null)
127
- ec=$?
128
- set -e
129
- hits=$(echo "$empty_out" | jq -r '.hits | length')
130
- total=$(echo "$empty_out" | jq -r '.total')
131
- if [ "$ec" = "2" ] && [ "$hits" = "0" ] && [ "$total" = "0" ]; then
132
- record_pass "empty-corpus query: exit 2, hits=[], total=0"
133
- else
134
- record_fail "empty-corpus wrong: ec=$ec hits=$hits total=$total"
135
- fi
136
- export MULTI_AGENT_REPO_SLUG="smoke-corpus"
137
-
138
- # --- 8: schema present + valid JSON ---
139
- if jq -e '.title and .properties.classification' "$SCHEMA" >/dev/null 2>&1; then
140
- record_pass "triage-corpus schema present and well-formed"
141
- else
142
- record_fail "triage-corpus schema malformed"
143
- fi
144
-
145
- # --- 9: phase-7-report.md declares ingest ---
146
- if grep -q 'triage-memory.mjs' "$PHASE7"; then
147
- record_pass "phase-7-report.md references triage-memory.mjs"
148
- else
149
- record_fail "phase-7-report.md missing triage-memory.mjs reference"
150
- fi
151
-
152
- # --- 10: phase-4-review.md declares prior-art lookup ---
153
- if grep -qE 'prior.art|triage-memory' "$PHASE4"; then
154
- record_pass "phase-4-review.md declares prior-art lookup"
155
- else
156
- record_fail "phase-4-review.md missing prior-art lookup"
157
- fi
158
-
159
- # --- 11: prefs schema exposes priorArtEnrichment ---
160
- if jq -e '.properties.global.properties.priorArtEnrichment' "$PREFS" >/dev/null 2>&1; then
161
- record_pass "prefs schema exposes priorArtEnrichment toggle"
162
- else
163
- record_fail "prefs.schema.json missing global.priorArtEnrichment"
164
- fi
165
-
166
- # --- Summary ---
167
- total=$((pass + fail))
168
- printf '\n→ smoke-triage-memory: %d/%d passed\n' "$pass" "$total"
169
- if [ "$fail" -ne 0 ]; then
170
- printf '\nFailures:\n'
171
- for f in "${failures[@]}"; do printf ' - %s\n' "$f"; done
172
- exit 1
173
- fi
174
- exit 0
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-update-check.sh
3
- #
4
- # Verifies the Phase 0 Step 0.6 advisory update-check contract:
5
- # 1. update-check.sh exists, parses (bash -n), and honors the advisory contract
6
- # offline: exit 0 + empty stdout when the registry is unreachable
7
- # 2. Cached path: fresh cache short-circuits without a network call
8
- # 3. Newer latest -> "<local>|<latest>"; same or older latest -> silent
9
- # 4. prefs.schema.json exposes updateCheck.{enabled,ttlHours,autoUpdate}
10
- # with the documented defaults (enabled=true, autoUpdate=false)
11
- # 5. phase-0-init.md documents Step 0.6 with the autopilot log-only rule
12
- #
13
- # Exit 0 = all pass, 1 = any failure.
14
-
15
- set -euo pipefail
16
-
17
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
18
- SCRIPT="$ROOT/pipeline/scripts/update-check.sh"
19
- PREFS_SCHEMA="$ROOT/pipeline/schemas/prefs.schema.json"
20
- PHASE0_DOC="$ROOT/pipeline/multi-agent-refs/phases/phase-0-init.md"
21
-
22
- pass=0
23
- fail=0
24
- failures=()
25
- record_pass() { pass=$((pass + 1)); printf ' \033[0;32mPASS\033[0m %s\n' "$1"; }
26
- record_fail() { fail=$((fail + 1)); failures+=("$1"); printf ' \033[0;31mFAIL\033[0m %s\n' "$1"; }
27
-
28
- printf '→ smoke-update-check: Phase 0 Step 0.6 advisory contract\n'
29
-
30
- tmpdir=$(mktemp -d)
31
- trap 'rm -rf "$tmpdir"' EXIT
32
- CACHE="$tmpdir/update-check-cache"
33
-
34
- # 1. Script parses
35
- if bash -n "$SCRIPT" 2>/dev/null; then
36
- record_pass "update-check.sh parses (bash -n)"
37
- else
38
- record_fail "update-check.sh has syntax errors"
39
- fi
40
-
41
- now=$(date +%s)
42
-
43
- # 2. Fresh cache with newer latest -> reports, no network needed
44
- printf '%s|99.0.0\n' "$now" > "$CACHE"
45
- out=$(UPDATE_CHECK_CACHE="$CACHE" bash "$SCRIPT" --local 10.0.0 2>/dev/null); rc=$?
46
- if [ "$rc" -eq 0 ] && [ "$out" = "10.0.0|99.0.0" ]; then
47
- record_pass "newer cached latest -> '<local>|<latest>' (exit 0)"
48
- else
49
- record_fail "newer cached latest should print '10.0.0|99.0.0' (got '$out', rc=$rc)"
50
- fi
51
-
52
- # 3. Same version -> silent
53
- printf '%s|10.0.0\n' "$now" > "$CACHE"
54
- out=$(UPDATE_CHECK_CACHE="$CACHE" bash "$SCRIPT" --local 10.0.0 2>/dev/null); rc=$?
55
- if [ "$rc" -eq 0 ] && [ -z "$out" ]; then
56
- record_pass "same version -> silent"
57
- else
58
- record_fail "same version should be silent (got '$out', rc=$rc)"
59
- fi
60
-
61
- # 3b. Local ahead of registry (dev machine) -> silent
62
- printf '%s|10.0.0\n' "$now" > "$CACHE"
63
- out=$(UPDATE_CHECK_CACHE="$CACHE" bash "$SCRIPT" --local 10.1.0 2>/dev/null); rc=$?
64
- if [ "$rc" -eq 0 ] && [ -z "$out" ]; then
65
- record_pass "local ahead of registry -> silent (no downgrade prompt)"
66
- else
67
- record_fail "local-ahead should be silent (got '$out', rc=$rc)"
68
- fi
69
-
70
- # 3b2. No --local, no repo clone -> falls back to the install-time version
71
- # marker (npx-only installs have no clone to read a version from)
72
- marker_home="$tmpdir/marker-home"
73
- mkdir -p "$marker_home/.claude"
74
- printf '10.0.0\n' > "$marker_home/.claude/.pipeline-version"
75
- printf '%s|99.0.0\n' "$now" > "$CACHE"
76
- out=$(HOME="$marker_home" UPDATE_CHECK_CACHE="$CACHE" bash "$SCRIPT" 2>/dev/null); rc=$?
77
- if [ "$rc" -eq 0 ] && [ "$out" = "10.0.0|99.0.0" ]; then
78
- record_pass "no clone -> .pipeline-version marker fallback works"
79
- else
80
- record_fail "marker fallback should print '10.0.0|99.0.0' (got '$out', rc=$rc)"
81
- fi
82
-
83
- # 3c. Offline + stale cache -> silent exit 0 (advisory: never blocks)
84
- printf '0|10.0.0\n' > "$CACHE"
85
- out=$(UPDATE_CHECK_CACHE="$CACHE" http_proxy="http://127.0.0.1:1" https_proxy="http://127.0.0.1:1" \
86
- bash "$SCRIPT" --local 10.0.0 2>/dev/null); rc=$?
87
- if [ "$rc" -eq 0 ] && [ -z "$out" ]; then
88
- record_pass "offline + stale cache -> silent exit 0"
89
- else
90
- record_fail "offline should be a silent no-op (got '$out', rc=$rc)"
91
- fi
92
-
93
- # 4. Prefs schema knobs + defaults
94
- for prop in enabled ttlHours autoUpdate; do
95
- if jq -e ".properties.global.properties.updateCheck.properties.${prop}" "$PREFS_SCHEMA" >/dev/null 2>&1; then
96
- record_pass "prefs schema exposes updateCheck.${prop}"
97
- else
98
- record_fail "prefs schema missing updateCheck.${prop}"
99
- fi
100
- done
101
- if jq -e '.properties.global.properties.updateCheck.properties.enabled.default == true' "$PREFS_SCHEMA" >/dev/null 2>&1; then
102
- record_pass "updateCheck.enabled defaults to true (notify-only, bounded cost)"
103
- else
104
- record_fail "updateCheck.enabled must default to true"
105
- fi
106
- if jq -e '.properties.global.properties.updateCheck.properties.autoUpdate | has("default") and .default == false' "$PREFS_SCHEMA" >/dev/null 2>&1; then
107
- record_pass "updateCheck.autoUpdate defaults to false (no silent self-modify)"
108
- else
109
- record_fail "updateCheck.autoUpdate must default to false"
110
- fi
111
-
112
- # 5. Phase 0 doc wiring
113
- if grep -qF "Step 0.6 - Update check" "$PHASE0_DOC"; then
114
- record_pass "phase-0-init.md documents Step 0.6"
115
- else
116
- record_fail "phase-0-init.md missing Step 0.6"
117
- fi
118
- if grep -qF "update-check.sh" "$PHASE0_DOC"; then
119
- record_pass "phase-0-init.md invokes update-check.sh"
120
- else
121
- record_fail "phase-0-init.md must invoke update-check.sh"
122
- fi
123
- if grep -qF "log-only" "$PHASE0_DOC" && grep -qF "never ask (zero-interaction contract)" "$PHASE0_DOC"; then
124
- record_pass "phase-0-init.md states the autopilot log-only rule"
125
- else
126
- record_fail "phase-0-init.md must state autopilot never asks (log-only)"
127
- fi
128
-
129
- printf '\n══ update-check smoke: %d passed, %d failed ══\n' "$pass" "$fail"
130
- if [ "$fail" -gt 0 ]; then
131
- printf '\nFailures:\n'
132
- for msg in "${failures[@]}"; do printf ' - %s\n' "$msg"; done
133
- exit 1
134
- fi
135
- exit 0
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Smoke: Phase 0 Step 1b URL enrichment - Crashlytics + Fortify
3
- # Verifies that:
4
- # 1. phase-0-init.md documents Step 1b with both URL patterns
5
- # 2. state.crashContext and state.fortifyFinding shapes are specified
6
- # 3. prefs.schema.json has hosts.fortify
7
- # 4. setup.md Step 3.5 prompts for fortify host (and skips firebase)
8
- # 5. Token Save Flow routing includes fortify
9
-
10
- set -u
11
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
12
- PASS=0
13
- FAIL=0
14
-
15
- check() {
16
- local label="$1" cmd="$2"
17
- if eval "$cmd" > /dev/null 2>&1; then
18
- printf " ✓ %s\n" "$label"
19
- PASS=$((PASS+1))
20
- else
21
- printf " ✗ %s\n" "$label"
22
- FAIL=$((FAIL+1))
23
- fi
24
- }
25
-
26
- PHASE0="$ROOT/pipeline/multi-agent-refs/phases/phase-0-init.md"
27
- SETUP="$ROOT/pipeline/commands/multi-agent/setup/SKILL.md"
28
- SCHEMA="$ROOT/pipeline/schemas/prefs.schema.json"
29
-
30
- echo "→ 1. phase-0-init.md documents Step 1b URL Enrichment"
31
- check "Step 1b section present" "grep -Fq 'Step 1b - URL Enrichment' '$PHASE0'"
32
- check "Crashlytics pattern block present" "grep -Fq 'console.firebase.google.com' '$PHASE0'"
33
- check "Fortify pattern block present" "grep -Eq 'hosts\.fortify.*ssc/html|ssc/html.*version' '$PHASE0'"
34
-
35
- echo
36
- echo "→ 2. state enrichment shapes specified"
37
- check "state.crashContext documented" "grep -Fq 'state.crashContext' '$PHASE0'"
38
- check "state.fortifyFinding documented" "grep -Fq 'state.fortifyFinding' '$PHASE0'"
39
- check "Phase 1 prepend mention for crash" "grep -Fq 'Known Crash Context' '$PHASE0'"
40
- check "Phase 2 inject mention for fortify" "grep -Fq 'Known Security Finding' '$PHASE0'"
41
-
42
- echo
43
- echo "→ 3. Progress contract line documented"
44
- check "URL context log line shape" "grep -Fq 'URL deep fetch: crashlytics=' '$PHASE0'"
45
-
46
- echo
47
- echo "→ 4. prefs.schema.json has hosts.fortify"
48
- check "hosts.fortify field exists" "grep -Fq '\"fortify\":' '$SCHEMA' && grep -Fq 'Fortify SSC host' '$SCHEMA'"
49
- check "FORTIFY_HOST placeholder referenced" "grep -Fq '{FORTIFY_HOST}' '$SCHEMA'"
50
-
51
- echo
52
- echo "→ 5. Firebase description = 'Firebase JSON' (not 'SA JSON')"
53
- check "schema firebase (servicePatMap) renamed" "! grep -F 'Firebase Service Account JSON' '$SCHEMA'"
54
- check "schema firebase (keychainMapping) renamed" "grep -c '\"Firebase JSON' '$SCHEMA' | grep -q '[2-9]'"
55
-
56
- echo
57
- echo "→ 6. setup.md Step 3.5 routes fortify (not firebase)"
58
- check "Step 3.5 lists fortify" "grep -Eq 'jira.*confluence.*bitbucket.*fortify|fortify.*host' '$SETUP'"
59
- check "firebase skip note in Step 3.5" "grep -Fiq 'firebase is skipped' '$SETUP' || grep -Fiq 'Firebase tokens skip' '$SETUP'"
60
- check "Resulting shape has fortify host" "grep -Fq '\"fortify\":' '$SETUP'"
61
- check "FORTIFY_HOST placeholder listed" "grep -Fq '{FORTIFY_HOST}' '$SETUP'"
62
-
63
- echo
64
- echo "→ 7. Token Source Mapping shows 'Firebase JSON' label"
65
- check "setup.md Token Source Mapping renamed" "grep -Fq 'Firebase JSON (base64)' '$SETUP'"
66
- check "multi-agent-setup SKILL.md renamed" "grep -Fq 'Firebase JSON (base64)' '$ROOT/pipeline/skills/shared/core/multi-agent-setup/SKILL.md'"
67
-
68
- echo
69
- echo "══ url-enrichment smoke: $PASS passed, $FAIL failed ══"
70
- [ "$FAIL" -eq 0 ]
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-validate-analysis-doc.sh - contract for validate-analysis-doc.mjs,
3
- # the deterministic gate over an emitted /multi-agent:analysis document.
4
-
5
- set -uo pipefail
6
-
7
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- V="$SCRIPT_DIR/validate-analysis-doc.mjs"
9
-
10
- PASS=0
11
- FAIL=0
12
- record_pass() { PASS=$((PASS + 1)); printf ' \342\234\223 %s\n' "$1"; }
13
- record_fail() { FAIL=$((FAIL + 1)); printf ' \342\234\227 %s\n' "$1"; }
14
-
15
- printf '\342\206\222 smoke-validate-analysis-doc: emitted-doc gate\n'
16
-
17
- tmp=$(mktemp -d "${TMPDIR:-/tmp}/vdoc.XXXXXX")
18
- trap 'rm -rf "$tmp"' EXIT
19
-
20
- # A well-formed Full-mode doc (neutral UserProfile domain, BR referenced downstream).
21
- cat > "$tmp/good.md" <<'MD'
22
- ---
23
- feature: UserProfile
24
- platform: ios
25
- language: tr
26
- mode: full
27
- template_version: v3
28
- ---
29
- ## 1. Özet
30
- Profile screen.
31
- ## 2. Hedefler ve Karşı Hedefler
32
- goals.
33
- ## 4. Kullanıcı Hikayeleri
34
- ### 4.4 İş Kuralları
35
- | BR-profile-01 | rule | source | Given/When/Then |
36
- ## 9. API Kontratları
37
- api.
38
- ## 13. Mimari Plan
39
- arch.
40
- ## 14. Eklenecek Dosyalar
41
- files.
42
- ## 15. Test Planı
43
- BR-profile-01 happy path.
44
- ## 20. Riskler ve Açık Sorular
45
- risk.
46
- ## 21. Referanslar
47
- refs.
48
- MD
49
-
50
- if node "$V" "$tmp/good.md" >/dev/null 2>&1; then
51
- record_pass "well-formed Full doc passes (exit 0)"
52
- else
53
- record_fail "well-formed doc should pass"
54
- fi
55
-
56
- # Lite doc without Section 15 must still pass (Locked 31 mode-aware).
57
- cat > "$tmp/lite.md" <<'MD'
58
- ---
59
- feature: UserProfile
60
- platform: ios
61
- language: en
62
- mode: lite
63
- template_version: v3
64
- ---
65
- ## 1. Summary
66
- s
67
- ## 2. Goals and Non-Goals
68
- g
69
- ## 4. User Stories
70
- ### 4.4 Business Rules
71
- | BR-profile-01 | rule | source | Given/When/Then |
72
- ## 9. API Contracts
73
- a
74
- ## 13. Architecture
75
- x
76
- ## 14. Files to Add
77
- f
78
- ## 20. Risks and Open Questions
79
- r
80
- ## 21. References
81
- ref
82
- MD
83
- if node "$V" "$tmp/lite.md" >/dev/null 2>&1; then
84
- record_pass "Lite doc (no Section 15) passes - mode-aware Locked 31"
85
- else
86
- record_fail "Lite doc without Section 15 must pass"
87
- fi
88
-
89
- # Missing front-matter -> ERROR.
90
- printf '## 1. Summary\nno front matter\n' > "$tmp/nofm.md"
91
- node "$V" "$tmp/nofm.md" >/dev/null 2>&1
92
- [ "$?" -eq 1 ] && record_pass "missing front-matter fails (exit 1)" || record_fail "missing front-matter should fail"
93
-
94
- # Banned punctuation (em-dash) -> ERROR.
95
- cp "$tmp/good.md" "$tmp/emdash.md"
96
- printf 'A line with an em-dash \342\200\224 here.\n' >> "$tmp/emdash.md"
97
- # Capture first (pipefail + node's nonzero exit would poison a direct pipe).
98
- emdash_out=$(node "$V" "$tmp/emdash.md" 2>&1 || true)
99
- if printf '%s' "$emdash_out" | grep -q "em-dash"; then
100
- record_pass "em-dash flagged (Locked 7)"
101
- else
102
- record_fail "em-dash should be flagged"
103
- fi
104
-
105
- # Missing a never-omitted section (References) -> ERROR.
106
- grep -v "Referanslar\|References" "$tmp/good.md" > "$tmp/noref.md"
107
- node "$V" "$tmp/noref.md" >/dev/null 2>&1
108
- [ "$?" -eq 1 ] && record_pass "missing References section fails" || record_fail "missing References should fail"
109
-
110
- # Define-only BR under --strict -> fail (WARN promoted).
111
- cat > "$tmp/orphan.md" <<'MD'
112
- ---
113
- feature: UserProfile
114
- platform: ios
115
- language: en
116
- mode: full
117
- template_version: v3
118
- ---
119
- ## 1. Summary
120
- s
121
- ## 2. Goals
122
- g
123
- ## 4. User Stories
124
- ### 4.4 Business Rules
125
- | BR-profile-42 | rule | source | Given/When/Then |
126
- ## 9. API Contracts
127
- a
128
- ## 13. Architecture
129
- x
130
- ## 14. Files to Add
131
- f
132
- ## 15. Test Plan
133
- no BR reference here
134
- ## 20. Risks
135
- r
136
- ## 21. References
137
- ref
138
- MD
139
- node "$V" "$tmp/orphan.md" >/dev/null 2>&1
140
- [ "$?" -eq 0 ] && record_pass "define-only BR is WARN, not error (default)" || record_fail "orphan BR should not hard-fail by default"
141
- node "$V" "$tmp/orphan.md" --strict >/dev/null 2>&1
142
- [ "$?" -eq 1 ] && record_pass "define-only BR fails under --strict" || record_fail "orphan BR should fail under --strict"
143
-
144
- # ui_tests: true but no Section 15.6 -> ERROR.
145
- sed 's/^mode: full/mode: full\nui_tests: true\na11y_depth: basic/' "$tmp/good.md" > "$tmp/uimiss.md"
146
- node "$V" "$tmp/uimiss.md" >/dev/null 2>&1
147
- [ "$?" -eq 1 ] && record_pass "ui_tests:true without Section 15.6 fails" || record_fail "ui_tests:true must require 15.6"
148
-
149
- # ui_tests: true WITH a Section 15.6 heading -> passes.
150
- cp "$tmp/uimiss.md" "$tmp/uiok.md"
151
- printf '## 15.6 UI test senaryolari\nUI-profile-01 flow.\n' >> "$tmp/uiok.md"
152
- node "$V" "$tmp/uiok.md" >/dev/null 2>&1
153
- [ "$?" -eq 0 ] && record_pass "ui_tests:true with Section 15.6 passes" || record_fail "ui_tests:true + 15.6 should pass"
154
-
155
- # a11y_depth: full but no Section 16.2 walkthrough -> ERROR.
156
- sed 's/^mode: full/mode: full\nui_tests: false\na11y_depth: full/' "$tmp/good.md" > "$tmp/a11ymiss.md"
157
- node "$V" "$tmp/a11ymiss.md" >/dev/null 2>&1
158
- [ "$?" -eq 1 ] && record_pass "a11y_depth:full without Section 16.2 fails" || record_fail "a11y_depth:full must require 16.2"
159
-
160
- printf '\n\342\225\220\342\225\220 smoke-validate-analysis-doc: %d passed, %d failed \342\225\220\342\225\220\n' "$PASS" "$FAIL"
161
- [ "$FAIL" -eq 0 ]