@thebassclef/lite 0.1.2 → 1.0.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 (293) hide show
  1. package/dist/cli.cjs +238 -127
  2. package/dist/cli.js +240 -129
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/lite/.bassclef-source.json +10 -0
  7. package/dist/lite/.claude/settings.json +212 -0
  8. package/dist/lite/CLAUDE.md +41 -0
  9. package/dist/lite/gitignore +58 -0
  10. package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
  11. package/dist/lite/whereami.md +24 -0
  12. package/package.json +8 -2
  13. package/substrate/.bassclef/lite-manifest.json +0 -2701
  14. package/substrate/.claude/agents/architect.md +0 -70
  15. package/substrate/.claude/agents/builder.md +0 -114
  16. package/substrate/.claude/agents/designer.md +0 -156
  17. package/substrate/.claude/agents/reviewer.md +0 -88
  18. package/substrate/.claude/hooks/artifact-ingestion-gate.sh +0 -357
  19. package/substrate/.claude/hooks/assert-verify-steering.sh +0 -77
  20. package/substrate/.claude/hooks/bassclef-source-config-validate.sh +0 -215
  21. package/substrate/.claude/hooks/bassclef-sync.sh +0 -634
  22. package/substrate/.claude/hooks/compound-noun-scrub.sh +0 -292
  23. package/substrate/.claude/hooks/kiss-expansion-inject.sh +0 -69
  24. package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
  25. package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -492
  26. package/substrate/.claude/hooks/plain-english-steering.sh +0 -156
  27. package/substrate/.claude/hooks/post-skill-friction-check.sh +0 -177
  28. package/substrate/.claude/hooks/post-skill-telemetry.sh +0 -62
  29. package/substrate/.claude/hooks/pre-build-gate.sh +0 -511
  30. package/substrate/.claude/hooks/pre-commit-gate.sh +0 -451
  31. package/substrate/.claude/hooks/session-end.sh +0 -433
  32. package/substrate/.claude/hooks/session-reflection.sh +0 -303
  33. package/substrate/.claude/hooks/skill-body-grade-gate.sh +0 -219
  34. package/substrate/.claude/hooks/skill-body-intent-drift.sh +0 -107
  35. package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
  36. package/substrate/.claude/hooks/state-validate.sh +0 -271
  37. package/substrate/.claude/hooks/substrate-clarity-gate.sh +0 -1110
  38. package/substrate/.claude/hooks/temperance-gate.sh +0 -147
  39. package/substrate/.claude/hooks/testing-tier-enforce.sh +0 -233
  40. package/substrate/.claude/hooks/turn-prose-grade-measure.sh +0 -219
  41. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +0 -463
  42. package/substrate/.claude/hooks/vocabulary-migration-check.sh +0 -171
  43. package/substrate/.claude/hooks/whereami-utc-gate.sh +0 -142
  44. package/substrate/.claude/luminaries/alan-cooper.md +0 -170
  45. package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
  46. package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
  47. package/substrate/.claude/luminaries/ash-maurya.md +0 -121
  48. package/substrate/.claude/luminaries/bill-buxton.md +0 -210
  49. package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
  50. package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
  51. package/substrate/.claude/luminaries/don-norman.md +0 -173
  52. package/substrate/.claude/luminaries/edward-tufte.md +0 -179
  53. package/substrate/.claude/luminaries/eric-evans.md +0 -160
  54. package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
  55. package/substrate/.claude/luminaries/gang-of-four.md +0 -157
  56. package/substrate/.claude/luminaries/glenford-myers.md +0 -230
  57. package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
  58. package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
  59. package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
  60. package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
  61. package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
  62. package/substrate/.claude/luminaries/karl-popper.md +0 -132
  63. package/substrate/.claude/luminaries/kent-beck.md +0 -168
  64. package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
  65. package/substrate/.claude/luminaries/martin-fowler.md +0 -164
  66. package/substrate/.claude/luminaries/michael-feathers.md +0 -125
  67. package/substrate/.claude/luminaries/michael-nygard.md +0 -118
  68. package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
  69. package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
  70. package/substrate/.claude/luminaries/sophia-prater.md +0 -193
  71. package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
  72. package/substrate/.claude/luminaries/tony-hoare.md +0 -170
  73. package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
  74. package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
  75. package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
  76. package/substrate/.claude/rules/adr-discipline.md +0 -120
  77. package/substrate/.claude/rules/api-conventions.md +0 -125
  78. package/substrate/.claude/rules/artifact-ingestion.md +0 -179
  79. package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
  80. package/substrate/.claude/rules/blocked-items.md +0 -146
  81. package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
  82. package/substrate/.claude/rules/branching.md +0 -28
  83. package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
  84. package/substrate/.claude/rules/commit-conventions.md +0 -22
  85. package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
  86. package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
  87. package/substrate/.claude/rules/context-engineering.md +0 -202
  88. package/substrate/.claude/rules/context-management.md +0 -85
  89. package/substrate/.claude/rules/defensive-bash.md +0 -68
  90. package/substrate/.claude/rules/deferred-actions.md +0 -233
  91. package/substrate/.claude/rules/destructive-operations.md +0 -69
  92. package/substrate/.claude/rules/diagnosis.md +0 -38
  93. package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
  94. package/substrate/.claude/rules/guardrails.md +0 -73
  95. package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
  96. package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
  97. package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
  98. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
  99. package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
  100. package/substrate/.claude/rules/loop-discipline.md +0 -81
  101. package/substrate/.claude/rules/manual-prod-approval.md +0 -100
  102. package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
  103. package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
  104. package/substrate/.claude/rules/new-dependency-check.md +0 -51
  105. package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
  106. package/substrate/.claude/rules/operator-facing-prose.md +0 -196
  107. package/substrate/.claude/rules/option-label-discipline.md +0 -108
  108. package/substrate/.claude/rules/pattern-annotation.md +0 -100
  109. package/substrate/.claude/rules/plain-english-discipline.md +0 -156
  110. package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
  111. package/substrate/.claude/rules/pr-body-shape.md +0 -317
  112. package/substrate/.claude/rules/pr-strategy.md +0 -167
  113. package/substrate/.claude/rules/pr-title-shape.md +0 -161
  114. package/substrate/.claude/rules/prototype-workflow.md +0 -65
  115. package/substrate/.claude/rules/reserved-skill-names.md +0 -123
  116. package/substrate/.claude/rules/schema-management.md +0 -49
  117. package/substrate/.claude/rules/sdlc-gates.md +0 -149
  118. package/substrate/.claude/rules/security.md +0 -37
  119. package/substrate/.claude/rules/session-artifacts.md +0 -236
  120. package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
  121. package/substrate/.claude/rules/skill-description-clarity.md +0 -247
  122. package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
  123. package/substrate/.claude/rules/state-schema-validation.md +0 -162
  124. package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
  125. package/substrate/.claude/rules/substrate-config-schema.md +0 -98
  126. package/substrate/.claude/rules/test-list-discipline.md +0 -175
  127. package/substrate/.claude/rules/test-sufficiency.md +0 -210
  128. package/substrate/.claude/rules/testing-tier-config.md +0 -145
  129. package/substrate/.claude/rules/testing.md +0 -38
  130. package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
  131. package/substrate/.claude/rules/visual-hierarchy.md +0 -437
  132. package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
  133. package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
  134. package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
  135. package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
  136. package/substrate/.claude/skills/build/SKILL.md +0 -640
  137. package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
  138. package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
  139. package/substrate/.claude/skills/decompose/SKILL.md +0 -280
  140. package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
  141. package/substrate/.claude/skills/feynman/SKILL.md +0 -90
  142. package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
  143. package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
  144. package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
  145. package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
  146. package/substrate/.claude/skills/journal/SKILL.md +0 -209
  147. package/substrate/.claude/skills/kiss/SKILL.md +0 -449
  148. package/substrate/.claude/skills/launch/SKILL.md +0 -915
  149. package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
  150. package/substrate/.claude/skills/longrun/SKILL.md +0 -463
  151. package/substrate/.claude/skills/luminary/SKILL.md +0 -481
  152. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
  153. package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
  154. package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
  155. package/substrate/.claude/skills/personas/SKILL.md +0 -207
  156. package/substrate/.claude/skills/promote/SKILL.md +0 -283
  157. package/substrate/.claude/skills/requirement/SKILL.md +0 -98
  158. package/substrate/.claude/skills/retro/SKILL.md +0 -117
  159. package/substrate/.claude/skills/riff/SKILL.md +0 -114
  160. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
  161. package/substrate/.claude/skills/session-end/SKILL.md +0 -309
  162. package/substrate/.claude/skills/session-log/SKILL.md +0 -299
  163. package/substrate/.claude/skills/skills/SKILL.md +0 -228
  164. package/substrate/.claude/skills/spec/SKILL.md +0 -105
  165. package/substrate/.claude/skills/sprint/SKILL.md +0 -392
  166. package/substrate/.claude/skills/stage/SKILL.md +0 -384
  167. package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
  168. package/substrate/.claude/skills/temperance/SKILL.md +0 -108
  169. package/substrate/.claude/skills/use-case/SKILL.md +0 -417
  170. package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
  171. package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
  172. package/substrate/.claude/skills/verify/SKILL.md +0 -160
  173. package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
  174. package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
  175. package/substrate/.claude/skills/whereami/SKILL.md +0 -307
  176. package/substrate/AGENTS.md +0 -79
  177. package/substrate/CLAUDE-lite.md +0 -85
  178. package/substrate/CODE_OF_CONDUCT.md +0 -28
  179. package/substrate/CONTRIBUTING.md +0 -177
  180. package/substrate/README.md +0 -173
  181. package/substrate/SECURITY.md +0 -19
  182. package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
  183. package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
  184. package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
  185. package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
  186. package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
  187. package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
  188. package/substrate/lib/clean-artifacts-sweep.sh +0 -112
  189. package/substrate/lib/code-comment-discipline.sh +0 -144
  190. package/substrate/lib/composer-preflight.sh +0 -459
  191. package/substrate/lib/hook-inject.sh +0 -255
  192. package/substrate/lib/luminary-pick.sh +0 -96
  193. package/substrate/lib/output-discipline.sh +0 -143
  194. package/substrate/lib/prose-scan-boundary.sh +0 -171
  195. package/substrate/lib/rewrite-check.sh +0 -214
  196. package/substrate/lib/state.sh +0 -1372
  197. package/substrate/lib/telemetry.sh +0 -205
  198. package/substrate/lib/tier-check.sh +0 -187
  199. package/substrate/lib/tier-dependency-audit.sh +0 -1088
  200. package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
  201. package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
  202. package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
  203. package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
  204. package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
  205. package/substrate/scripts/aggregate-telemetry.sh +0 -217
  206. package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
  207. package/substrate/scripts/generate-lite-manifest.sh +0 -505
  208. package/substrate/scripts/generate-tier-manifest.sh +0 -28
  209. package/substrate/scripts/intent-drift-check.sh +0 -456
  210. package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
  211. package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
  212. package/substrate/standards/adr-template.md +0 -86
  213. package/substrate/standards/api-conventions/nextjs.md +0 -84
  214. package/substrate/standards/artifact-composition.md +0 -209
  215. package/substrate/standards/bash-hook-safety.md +0 -246
  216. package/substrate/standards/bassclef-configs-schema.md +0 -232
  217. package/substrate/standards/bassclef-evolution.md +0 -143
  218. package/substrate/standards/bassclef-internal-jargon.md +0 -244
  219. package/substrate/standards/bassclef-managed-sentinel.md +0 -96
  220. package/substrate/standards/bassclef-source-config.md +0 -228
  221. package/substrate/standards/branch-stacking.md +0 -408
  222. package/substrate/standards/code-safety-principles.md +0 -176
  223. package/substrate/standards/composer-prerequisites.md +0 -155
  224. package/substrate/standards/deferred-actions-schema.md +0 -204
  225. package/substrate/standards/dependency-discipline/cargo.md +0 -39
  226. package/substrate/standards/dependency-discipline/gem.md +0 -43
  227. package/substrate/standards/dependency-discipline/go-mod.md +0 -41
  228. package/substrate/standards/dependency-discipline/npm.md +0 -42
  229. package/substrate/standards/dependency-discipline/pip.md +0 -42
  230. package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
  231. package/substrate/standards/deployment-topology.md +0 -69
  232. package/substrate/standards/docs-sync-allowlist.md +0 -76
  233. package/substrate/standards/domain-and-dns.md +0 -145
  234. package/substrate/standards/frontend-stack.md +0 -67
  235. package/substrate/standards/frontmatter-schema.md +0 -154
  236. package/substrate/standards/graceful-exit.md +0 -227
  237. package/substrate/standards/hook-idempotency.md +0 -102
  238. package/substrate/standards/hook-injection-discipline.md +0 -202
  239. package/substrate/standards/hook-install-class.md +0 -215
  240. package/substrate/standards/input-handler-interface.md +0 -152
  241. package/substrate/standards/lite-manifest-schema-changes.md +0 -135
  242. package/substrate/standards/luminary-matching.md +0 -105
  243. package/substrate/standards/luminary-problem-patterns.md +0 -481
  244. package/substrate/standards/migration-discipline/active-record.md +0 -50
  245. package/substrate/standards/migration-discipline/alembic.md +0 -43
  246. package/substrate/standards/migration-discipline/gorm.md +0 -50
  247. package/substrate/standards/migration-discipline/prisma.md +0 -53
  248. package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
  249. package/substrate/standards/mobile-ephemeral-session.md +0 -167
  250. package/substrate/standards/model-routing-discipline.md +0 -160
  251. package/substrate/standards/ogilvy-writing-rules.md +0 -225
  252. package/substrate/standards/opener-discipline.md +0 -96
  253. package/substrate/standards/operator-facing-prose-discipline.md +0 -201
  254. package/substrate/standards/persona-schema.md +0 -229
  255. package/substrate/standards/pluggable-luminaries.md +0 -323
  256. package/substrate/standards/pr-body-discipline.md +0 -115
  257. package/substrate/standards/preview-state-schema.md +0 -189
  258. package/substrate/standards/project-directory-layout.md +0 -276
  259. package/substrate/standards/release-tagging.md +0 -137
  260. package/substrate/standards/reserved-skill-names.md +0 -120
  261. package/substrate/standards/scannable-multi-option-output.md +0 -261
  262. package/substrate/standards/sdlc-compliance.md +0 -286
  263. package/substrate/standards/sdlc-gates/typescript.md +0 -57
  264. package/substrate/standards/secrets-lifecycle.md +0 -210
  265. package/substrate/standards/security-scanner-adapter.md +0 -145
  266. package/substrate/standards/session-board.md +0 -256
  267. package/substrate/standards/skill-output-discipline.md +0 -90
  268. package/substrate/standards/state-spine-contract.md +0 -255
  269. package/substrate/standards/state-spine.md +0 -511
  270. package/substrate/standards/steering-hints/kiss-words.md +0 -11
  271. package/substrate/standards/substrate-config-schema.md +0 -267
  272. package/substrate/standards/tech-stack-config.md +0 -109
  273. package/substrate/standards/tier-dependency-analysis.md +0 -167
  274. package/substrate/standards/tier-runtime-deps/lite.md +0 -57
  275. package/substrate/standards/tier-tag-schema.md +0 -155
  276. package/substrate/standards/two-layer-config.md +0 -99
  277. package/substrate/standards/use-case-format.md +0 -292
  278. package/substrate/standards/user-story-invest.md +0 -268
  279. package/substrate/standards/velocity-and-appetite.md +0 -229
  280. package/substrate/standards/voice-input-pattern.md +0 -119
  281. package/substrate/standards/whereami-schema.md +0 -301
  282. package/substrate/standards/worktree-management.md +0 -211
  283. package/substrate/standards/writing-guide.md +0 -213
  284. package/substrate/templates/chronicle-template.md +0 -75
  285. package/substrate/templates/deferred-action-template.md +0 -45
  286. package/substrate/templates/memory-proposal-template.md +0 -77
  287. package/substrate/templates/persona-template.md +0 -200
  288. package/substrate/templates/pr-faq.md +0 -45
  289. package/substrate/templates/secret-rotation-template.md +0 -162
  290. package/substrate/templates/spec-template.md +0 -131
  291. package/substrate/templates/use-case-template.md +0 -194
  292. package/substrate/templates/user-story-template.md +0 -107
  293. package/substrate/templates/whereami-template.md +0 -101
@@ -1,88 +0,0 @@
1
- #!/usr/bin/env bash
2
- # tier: lite
3
- # description: schedule-auto-save.cron.sh — install a cron entry that fires auto-save-idle.sh
4
- # schedule-auto-save.cron.sh — install a cron entry that fires auto-save-idle.sh
5
- # every 15 minutes on macOS + Linux + WSL.
6
- #
7
- # Per ADR-046 (cross-OS auto-save scheduling). Replaces the macOS-only
8
- # launchd path for adopters on Linux or WSL. Native Windows adopters
9
- # should read presence/install/schedule-auto-save.taskscheduler.md instead.
10
- #
11
- # Usage:
12
- # bash presence/install/schedule-auto-save.cron.sh [path-to-hook]
13
- #
14
- # Default hook path: $HOME/src/sunj-labs/bassclef/.claude/hooks/auto-save-idle.sh
15
- #
16
- # The installer is idempotent — running twice does not add duplicate entries.
17
- # The installer writes to the current user's crontab (crontab -l | grep -v ...).
18
- #
19
- # Override paths:
20
- # SKIP_CRON_INSTALL=1 — bypass the install (logged; no crontab change)
21
- # BASSCLEF_HOOK_PATH — override the default hook path
22
- #
23
- # Exit codes:
24
- # 0 = success (installed, updated, or already present)
25
- # 1 = cron not available or crontab command missing
26
- # 2 = hook file not found at target path
27
- # 3 = user cancelled or explicit skip
28
-
29
- set -euo pipefail
30
-
31
- BASSCLEF_HOOK_DEFAULT="$HOME/src/sunj-labs/bassclef/.claude/hooks/auto-save-idle.sh"
32
- HOOK_PATH="${1:-${BASSCLEF_HOOK_PATH:-$BASSCLEF_HOOK_DEFAULT}}"
33
- CRON_MARKER="# bassclef auto-save (ADR-046)"
34
- CRON_ENTRY="*/15 * * * * bash ${HOOK_PATH} >/dev/null 2>&1"
35
-
36
- echo "=== bassclef auto-save cron installer ==="
37
- echo "Hook path: ${HOOK_PATH}"
38
-
39
- # Override check
40
- if [ "${SKIP_CRON_INSTALL:-0}" = "1" ]; then
41
- echo "SKIP_CRON_INSTALL=1 — skipping install (logged)"
42
- exit 3
43
- fi
44
-
45
- # Check cron availability
46
- if ! command -v crontab >/dev/null 2>&1; then
47
- echo "ERROR: crontab command not found. This installer needs cron."
48
- echo " - macOS: cron ships by default; check /usr/bin/crontab"
49
- echo " - Linux: install via 'apt install cron' or 'yum install cronie'"
50
- echo " - Native Windows: use presence/install/schedule-auto-save.taskscheduler.md instead"
51
- exit 1
52
- fi
53
-
54
- # Check hook file exists
55
- if [ ! -f "$HOOK_PATH" ]; then
56
- echo "ERROR: hook file not found at ${HOOK_PATH}"
57
- echo " Pass the path as an argument OR set BASSCLEF_HOOK_PATH env var."
58
- echo " Example: bash $0 /path/to/bassclef/.claude/hooks/auto-save-idle.sh"
59
- exit 2
60
- fi
61
-
62
- # Read current crontab (empty if none)
63
- CURRENT_CRONTAB=$(crontab -l 2>/dev/null || echo "")
64
-
65
- # Idempotency check — skip if bassclef entry already present
66
- if echo "$CURRENT_CRONTAB" | grep -qF "$CRON_MARKER"; then
67
- echo "Bassclef auto-save entry already present in crontab — no change."
68
- echo ""
69
- echo "Current entry:"
70
- echo "$CURRENT_CRONTAB" | grep -A1 -F "$CRON_MARKER" | head -2
71
- exit 0
72
- fi
73
-
74
- # Install: append the marker + entry to the existing crontab
75
- NEW_CRONTAB=$(printf '%s\n%s\n%s\n' "$CURRENT_CRONTAB" "$CRON_MARKER" "$CRON_ENTRY")
76
-
77
- # Write via crontab -
78
- echo "$NEW_CRONTAB" | crontab -
79
-
80
- echo "Installed cron entry:"
81
- echo " ${CRON_MARKER}"
82
- echo " ${CRON_ENTRY}"
83
- echo ""
84
- echo "Verify with: crontab -l"
85
- echo "Remove with: crontab -l | grep -v 'bassclef auto-save' | crontab -"
86
- echo ""
87
- echo "Auto-save fires every 15 minutes. Feature branches are skipped by save-state.sh"
88
- echo "guards. SESSION_LOCK held by an active /longrun session suppresses fires."
@@ -1,122 +0,0 @@
1
- ---
2
- tier: lite
3
- title: Native Windows setup — auto-save via Task Scheduler
4
- adr_references: [ADR-046]
5
- audience: bassclef adopters on native Windows without WSL
6
- ---
7
-
8
- # Auto-save on native Windows via Task Scheduler
9
-
10
- Bassclef's auto-save fires every 15 minutes on macOS + Linux + WSL via cron. See `presence/install/schedule-auto-save.cron.sh` for that path.
11
-
12
- On native Windows without WSL, cron is not available. This doc gives the manual steps to register a scheduled task that runs the same hook via Git Bash (or MSYS bash).
13
-
14
- Per ADR-046.
15
-
16
- ## Prerequisites
17
-
18
- - Windows 10 or 11
19
- - Git for Windows installed (`git --version` works from PowerShell)
20
- - Bassclef checked out at `%USERPROFILE%\src\sunj-labs\bassclef` (or note your path)
21
- - Task Scheduler access (built into Windows; requires admin for some operations)
22
-
23
- ## Step 1 — Confirm the hook path
24
-
25
- Open PowerShell. Run:
26
-
27
- ```powershell
28
- Test-Path "$env:USERPROFILE\src\sunj-labs\bassclef\.claude\hooks\auto-save-idle.sh"
29
- ```
30
-
31
- Expected: `True`. If `False`, adjust the path to where you checked out bassclef.
32
-
33
- ## Step 2 — Find Git Bash
34
-
35
- Task Scheduler needs to invoke bash directly. Git for Windows ships `bash.exe` at:
36
-
37
- ```
38
- C:\Program Files\Git\bin\bash.exe
39
- ```
40
-
41
- Confirm with:
42
-
43
- ```powershell
44
- Test-Path "C:\Program Files\Git\bin\bash.exe"
45
- ```
46
-
47
- If the path differs (32-bit install, custom install), note the actual location for Step 3.
48
-
49
- ## Step 3 — Register the scheduled task
50
-
51
- Run in an elevated PowerShell (Run as Administrator):
52
-
53
- ```powershell
54
- $hookPath = "$env:USERPROFILE\src\sunj-labs\bassclef\.claude\hooks\auto-save-idle.sh"
55
- $bashExe = "C:\Program Files\Git\bin\bash.exe"
56
-
57
- $action = New-ScheduledTaskAction `
58
- -Execute $bashExe `
59
- -Argument "-lc `"bash '$hookPath'`""
60
-
61
- $trigger = New-ScheduledTaskTrigger `
62
- -Once -At (Get-Date) `
63
- -RepetitionInterval (New-TimeSpan -Minutes 15) `
64
- -RepetitionDuration (New-TimeSpan -Days 3650)
65
-
66
- $settings = New-ScheduledTaskSettingsSet `
67
- -AllowStartIfOnBatteries `
68
- -DontStopIfGoingOnBatteries `
69
- -StartWhenAvailable
70
-
71
- Register-ScheduledTask `
72
- -TaskName "BassclefAutoSave" `
73
- -Description "Bassclef auto-save fires every 15 minutes (ADR-046)" `
74
- -Action $action `
75
- -Trigger $trigger `
76
- -Settings $settings `
77
- -User $env:USERNAME
78
- ```
79
-
80
- The task fires every 15 minutes for 10 years. Idempotent — running the register command twice fails the second time with a name collision (safe to re-run after `Unregister-ScheduledTask`).
81
-
82
- ## Step 4 — Verify
83
-
84
- ```powershell
85
- Get-ScheduledTask -TaskName "BassclefAutoSave" | Get-ScheduledTaskInfo
86
- ```
87
-
88
- Shows `LastRunTime` after the first fire (~15 minutes after registration). Errors surface in `LastTaskResult` (0 = success).
89
-
90
- Manual fire for immediate check:
91
-
92
- ```powershell
93
- Start-ScheduledTask -TaskName "BassclefAutoSave"
94
- ```
95
-
96
- Then wait ~10 seconds and check the git log in your bassclef checkout for a `chore: auto-save checkpoint` commit.
97
-
98
- ## Step 5 — Remove (when needed)
99
-
100
- ```powershell
101
- Unregister-ScheduledTask -TaskName "BassclefAutoSave" -Confirm:$false
102
- ```
103
-
104
- ## Notes
105
-
106
- - The task runs as the current user, not SYSTEM. Files created by the task inherit the user's permissions.
107
- - Windows Task Scheduler wakes the machine only if the "Wake the computer to run this task" setting is enabled (not set by default here). Adopters who sleep their machine will miss fires during sleep.
108
- - When the machine reboots, the task resumes on schedule.
109
- - Session-end.sh Guard 0 (per bet 27b Step 2) still fires — the SESSION_LOCK precedence check works cross-OS because it reads the file, not the OS scheduler.
110
-
111
- ## Alternatives
112
-
113
- - **WSL2 available?** Skip this doc; use `presence/install/schedule-auto-save.cron.sh` inside WSL. Cron there watches your Windows filesystem via `/mnt/c/Users/...`.
114
- - **Prefer a .ps1 installer?** File a ticket. The current ship stays doc-only to avoid installer complexity for a population not yet observed. Path B (per-OS installers) upgrade is a follow-on.
115
-
116
- ## References
117
-
118
- - ADR-046 — Cross-OS auto-save scheduling
119
- - Bet 27b Step 4 — Native Windows path (this doc)
120
- - `presence/install/schedule-auto-save.cron.sh` — sister installer for macOS + Linux + WSL
121
- - `.claude/hooks/auto-save-idle.sh` — the hook this schedule invokes
122
- - `.claude/hooks/session-end.sh` — SESSION_LOCK precedence cure applies cross-OS
@@ -1,217 +0,0 @@
1
- #!/usr/bin/env bash
2
- # scripts/aggregate-telemetry.sh — read local telemetry store; emit uptake report
3
- # tier: lite
4
- # install-class: dual
5
- #
6
- # Reads state/telemetry/events-*.jsonl files, counts events by type + skill +
7
- # install source, writes docs/telemetry-reports/YYYY-MM-DD.md.
8
- #
9
- # CLI:
10
- # bash scripts/aggregate-telemetry.sh # full store, today's report
11
- # bash scripts/aggregate-telemetry.sh --from 2026-08-01 --to 2026-08-31
12
- # bash scripts/aggregate-telemetry.sh --output /tmp/rep.md
13
- #
14
- # Deep module per @luminary john-ousterhout — one CLI hides read + parse +
15
- # aggregate + write.
16
- # Local-first per ADR-049 — reads adopter machine only.
17
- #
18
- # Bash 3.2 compatible (macOS default) — uses temp files rather than
19
- # associative arrays.
20
-
21
- set -u
22
-
23
- REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
24
- EVENTS_DIR="${REPO_ROOT}/state/telemetry"
25
- TODAY="$(date -u +%Y-%m-%d)"
26
- OUTPUT_DIR="${REPO_ROOT}/docs/telemetry-reports"
27
- OUTPUT_FILE=""
28
- DATE_FROM=""
29
- DATE_TO=""
30
-
31
- # --- Arg parsing -----------------------------------------------------------
32
- while [ $# -gt 0 ]; do
33
- case "$1" in
34
- --from) DATE_FROM="$2"; shift 2 ;;
35
- --to) DATE_TO="$2"; shift 2 ;;
36
- --output) OUTPUT_FILE="$2"; shift 2 ;;
37
- --help|-h)
38
- grep '^# ' "$0" | head -20 | sed 's/^# //'
39
- exit 0
40
- ;;
41
- *) echo "unknown arg: $1" >&2; exit 2 ;;
42
- esac
43
- done
44
-
45
- [ -z "$OUTPUT_FILE" ] && OUTPUT_FILE="${OUTPUT_DIR}/${TODAY}.md"
46
-
47
- # --- Scratch counts dir (bash-3-compatible replacement for declare -A) ----
48
- COUNTS_DIR="$(mktemp -d -t telem-counts.XXXXXX)"
49
- trap 'rm -rf "$COUNTS_DIR"' EXIT
50
- mkdir -p "$COUNTS_DIR/skills" "$COUNTS_DIR/installs" "$COUNTS_DIR/sessions"
51
-
52
- _incr_dir() {
53
- local dir="$1"
54
- local key="$2"
55
- # Sanitize key for filesystem (allow /, alnum, dash, underscore)
56
- local safe_key
57
- safe_key=$(echo "$key" | tr '/' '_' | tr -c 'a-zA-Z0-9_-' '_')
58
- local file="$COUNTS_DIR/$dir/$safe_key"
59
- local n
60
- n=$(cat "$file" 2>/dev/null || echo 0)
61
- echo $((n + 1)) > "$file"
62
- # Also store original key for report output
63
- echo "$key" > "$COUNTS_DIR/$dir/$safe_key.name"
64
- }
65
-
66
- _mark_session() {
67
- local sid="$1"
68
- # Sanitize
69
- local safe_sid
70
- safe_sid=$(echo "$sid" | tr -c 'a-zA-Z0-9-' '_')
71
- touch "$COUNTS_DIR/sessions/$safe_sid"
72
- }
73
-
74
- # --- Enumerate matching event files ----------------------------------------
75
- EVENT_FILES=()
76
- if [ -d "$EVENTS_DIR" ]; then
77
- shopt -s nullglob
78
- for f in "$EVENTS_DIR"/events-*.jsonl; do
79
- base=$(basename "$f" .jsonl)
80
- date_stamp="${base#events-}"
81
- d="${date_stamp:0:4}-${date_stamp:4:2}-${date_stamp:6:2}"
82
- [ -n "$DATE_FROM" ] && [ "$d" \< "$DATE_FROM" ] && continue
83
- [ -n "$DATE_TO" ] && [ "$d" \> "$DATE_TO" ] && continue
84
- EVENT_FILES+=("$f")
85
- done
86
- shopt -u nullglob
87
- fi
88
-
89
- # --- Counters --------------------------------------------------------------
90
- total_events=0
91
- count_session_start=0
92
- count_session_end=0
93
- count_skill_invoke=0
94
- count_tier_boundary=0
95
- count_install_probe=0
96
-
97
- for f in ${EVENT_FILES[@]+"${EVENT_FILES[@]}"}; do
98
- while IFS= read -r line; do
99
- [ -z "$line" ] && continue
100
- total_events=$((total_events + 1))
101
-
102
- if command -v jq >/dev/null 2>&1; then
103
- et=$(echo "$line" | jq -r '.event_type // empty' 2>/dev/null)
104
- sid=$(echo "$line" | jq -r '.session_id // empty' 2>/dev/null)
105
- else
106
- et=$(echo "$line" | grep -oE '"event_type"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
107
- sid=$(echo "$line" | grep -oE '"session_id"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
108
- fi
109
-
110
- [ -n "$sid" ] && _mark_session "$sid"
111
-
112
- case "$et" in
113
- session_start)
114
- count_session_start=$((count_session_start + 1))
115
- ;;
116
- session_end)
117
- count_session_end=$((count_session_end + 1))
118
- ;;
119
- skill_invoke)
120
- count_skill_invoke=$((count_skill_invoke + 1))
121
- if command -v jq >/dev/null 2>&1; then
122
- skill=$(echo "$line" | jq -r '.payload.skill_name // empty' 2>/dev/null)
123
- else
124
- skill=$(echo "$line" | grep -oE '"skill_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
125
- fi
126
- [ -n "$skill" ] && _incr_dir skills "$skill"
127
- ;;
128
- tier_boundary_attempt)
129
- count_tier_boundary=$((count_tier_boundary + 1))
130
- ;;
131
- install_probe)
132
- count_install_probe=$((count_install_probe + 1))
133
- if command -v jq >/dev/null 2>&1; then
134
- src=$(echo "$line" | jq -r '.payload.install_source // empty' 2>/dev/null)
135
- else
136
- src=$(echo "$line" | grep -oE '"install_source"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
137
- fi
138
- [ -n "$src" ] && _incr_dir installs "$src"
139
- ;;
140
- esac
141
- done < "$f"
142
- done
143
-
144
- # Session count = number of session marker files
145
- session_count=$(ls -1 "$COUNTS_DIR/sessions" 2>/dev/null | wc -l | tr -d ' ')
146
-
147
- # --- Write report ----------------------------------------------------------
148
- mkdir -p "$(dirname "$OUTPUT_FILE")"
149
-
150
- {
151
- echo "---"
152
- echo "report_type: telemetry-uptake"
153
- echo "generated_at: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
154
- echo "date_range_from: ${DATE_FROM:-<all>}"
155
- echo "date_range_to: ${DATE_TO:-<all>}"
156
- echo "source: local"
157
- echo "---"
158
- echo ""
159
- echo "# Telemetry uptake report — $TODAY"
160
- echo ""
161
- echo "## Summary"
162
- echo ""
163
- echo "- **Total events:** $total_events"
164
- echo "- **Distinct sessions:** $session_count"
165
- echo "- **Files scanned:** ${#EVENT_FILES[@]}"
166
- echo ""
167
- echo "## Event counts by type"
168
- echo ""
169
- echo "| Type | Count |"
170
- echo "|---|---|"
171
- echo "| session_start | $count_session_start |"
172
- echo "| session_end | $count_session_end |"
173
- echo "| skill_invoke | $count_skill_invoke |"
174
- echo "| tier_boundary_attempt | $count_tier_boundary |"
175
- echo "| install_probe | $count_install_probe |"
176
- echo ""
177
- echo "## Skill invocations"
178
- echo ""
179
- skill_files=$(ls -1 "$COUNTS_DIR/skills"/*.name 2>/dev/null || true)
180
- if [ -z "$skill_files" ]; then
181
- echo "_No skill invocations recorded._"
182
- else
183
- echo "| Skill | Count |"
184
- echo "|---|---|"
185
- for name_file in "$COUNTS_DIR/skills"/*.name; do
186
- count_file="${name_file%.name}"
187
- skill=$(cat "$name_file")
188
- n=$(cat "$count_file")
189
- echo "| \`$skill\` | $n |"
190
- done | sort
191
- fi
192
- echo ""
193
- echo "## Install source distribution"
194
- echo ""
195
- install_files=$(ls -1 "$COUNTS_DIR/installs"/*.name 2>/dev/null || true)
196
- if [ -z "$install_files" ]; then
197
- echo "_No install probes recorded._"
198
- else
199
- echo "| Source | Count |"
200
- echo "|---|---|"
201
- for name_file in "$COUNTS_DIR/installs"/*.name; do
202
- count_file="${name_file%.name}"
203
- src=$(cat "$name_file")
204
- n=$(cat "$count_file")
205
- echo "| $src | $n |"
206
- done | sort
207
- fi
208
- echo ""
209
- echo "## Notes"
210
- echo ""
211
- echo "- Report is local-only per ADR-049 (opt-in default OFF; no remote endpoint)"
212
- echo "- Adopters share reports at their discretion; raw events stay on adopter machine"
213
- echo "- Iteration 3 pricing decision reads aggregated shared reports"
214
- } > "$OUTPUT_FILE"
215
-
216
- echo "telemetry report written: $OUTPUT_FILE"
217
- echo " total_events=$total_events sessions=$session_count files=${#EVENT_FILES[@]}"
@@ -1,239 +0,0 @@
1
- #!/usr/bin/env bash
2
- # tier: lite
3
- # analyze-tier-dependencies.sh — orchestrator for the tier-dependency-audit subsystem
4
- #
5
- # Per standards/tier-dependency-analysis.md — walks the dependency graph
6
- # for a given tier and classifies every file into one of 4 buckets.
7
- #
8
- # Per docs/decompositions/2026-08-17a-tier-dependency-audit.md — this script
9
- # is the orchestrator (main + dispatch). Actual work lives in
10
- # lib/tier-dependency-audit.sh (8 named functions per Larman GRASP).
11
- #
12
- # Usage:
13
- # scripts/analyze-tier-dependencies.sh <tier>
14
- # tier: one of lite | standard | standard-pro | ultra | upstream
15
- # OR 'all' (combined-tier — all 5 tiers)
16
- # OR 'tier,tier,..' (combined-tier — named list; e.g., lite,standard)
17
- #
18
- # Combined-tier mode (ADR-052 D5): INTENDED = union of every named tier's
19
- # INTENDED set. Buckets 1+3+4 report against the union. Bucket 3 becomes
20
- # TRUE accidental leaks (files no tier's graph claims), not
21
- # tagged-for-other-tier files that show up as false leaks in single-tier mode.
22
- #
23
- # Overrides (used by Tier 0 tests + advanced consumers):
24
- # OUTPUT_DIR — where to write manifest (default: docs/dependency-audits)
25
- # INTENDED_FIXTURE — file listing INTENDED set (skips Sources 1+2 walk)
26
- # ACTUAL_FIXTURE — file listing ACTUAL set (skips release-script call)
27
- # TAGS_FIXTURE — file listing "<path>\t<tier>" for tag data
28
- # RUNTIME_DEPS_FILE — override the tier-runtime-deps file location (single-tier only)
29
- # SKIP_TIER_DEPENDENCY_AUDIT=1 — bypass path (logged); exits 0 without writing
30
-
31
- set -uo pipefail
32
-
33
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
34
-
35
- # Source the lib with named functions (single-tier + combined-tier)
36
- # shellcheck disable=SC1091
37
- source "$REPO_ROOT/lib/tier-dependency-audit.sh"
38
-
39
- # Bypass path
40
- if [ "${SKIP_TIER_DEPENDENCY_AUDIT:-0}" = "1" ]; then
41
- echo "analyze-tier-dependencies: SKIP bypass (SKIP_TIER_DEPENDENCY_AUDIT=1 logged)" >&2
42
- exit 0
43
- fi
44
-
45
- # --- Combined-tier mode detection ------------------------------------------
46
- # If arg is 'all' or contains comma, dispatch to combined path and exit
47
- # before the single-tier code runs.
48
- ARG_RAW="${1:-}"
49
- if [ "$ARG_RAW" = "all" ] || [[ "$ARG_RAW" == *,* ]]; then
50
- TIER_LIST="$(parse_tier_list_arg "$ARG_RAW")" || exit $?
51
- OUTPUT_DIR="${OUTPUT_DIR:-$REPO_ROOT/docs/dependency-audits}"
52
- INTENDED_TMP="$(mktemp)"
53
- ACTUAL_TMP="$(mktemp)"
54
- TAGS_TMP="$(mktemp)"
55
- BUCKET_DIR="$(mktemp -d)"
56
- trap 'rm -rf "$INTENDED_TMP" "$ACTUAL_TMP" "$TAGS_TMP" "$BUCKET_DIR"' EXIT
57
-
58
- # Loop per tier: build INTENDED_i (Source 1 seeds + Source 2 BFS + Source 3 runtime deps)
59
- cd "$REPO_ROOT"
60
- while IFS= read -r t; do
61
- [ -z "$t" ] && continue
62
- echo "combined-tier: building INTENDED for $t" >&2
63
- seeds_tmp="$(mktemp)"
64
- read_intended_source_1 "$t" > "$seeds_tmp"
65
- walk_graph_bfs "$seeds_tmp" extract_references >> "$INTENDED_TMP"
66
- rm -f "$seeds_tmp"
67
- # Source 3 — runtime deps if present for this tier
68
- rt_file="$REPO_ROOT/standards/tier-runtime-deps/${t}.md"
69
- if [ -f "$rt_file" ]; then
70
- read_runtime_deps "$rt_file" >> "$INTENDED_TMP"
71
- else
72
- echo "combined-tier: no runtime-deps file for $t at $rt_file (skipping)" >&2
73
- fi
74
- done <<< "$TIER_LIST"
75
- sort -u -o "$INTENDED_TMP" "$INTENDED_TMP"
76
-
77
- # ACTUAL — release script include list (same regardless of tier; it is the full public release)
78
- if [ -n "${ACTUAL_FIXTURE:-}" ]; then
79
- cp "$ACTUAL_FIXTURE" "$ACTUAL_TMP"
80
- else
81
- # Pass 'lite' arg to keep read_actual_source signature; the release
82
- # script output is the full ACTUAL set regardless.
83
- read_actual_source "lite" > "$ACTUAL_TMP" || {
84
- echo "analyze-tier-dependencies: Source 4 (release script) failed" >&2
85
- exit 4
86
- }
87
- fi
88
- sort -u -o "$ACTUAL_TMP" "$ACTUAL_TMP"
89
-
90
- # TAGS — derive by grepping each file in INTENDED_TMP for its tier tag
91
- if [ -n "${TAGS_FIXTURE:-}" ]; then
92
- cp "$TAGS_FIXTURE" "$TAGS_TMP"
93
- else
94
- : > "$TAGS_TMP"
95
- while IFS= read -r path; do
96
- [ -z "$path" ] && continue
97
- tag=""
98
- if [ -f "$path" ]; then
99
- case "$path" in
100
- *.md)
101
- tag="$(awk '
102
- BEGIN{infm=0}
103
- NR==1 && /^---/ {infm=1; next}
104
- infm && /^---/ {exit}
105
- infm && /^tier:[[:space:]]/ {sub(/^tier:[[:space:]]*/,""); gsub(/[[:space:]]/,""); print; exit}
106
- ' "$path")"
107
- ;;
108
- *.sh)
109
- tag="$(head -5 "$path" | awk '/^# tier:[[:space:]]/ {sub(/^# tier:[[:space:]]*/,""); gsub(/[[:space:]]/,""); print; exit}')"
110
- ;;
111
- esac
112
- fi
113
- if [ -n "$tag" ]; then
114
- printf "%s\t%s\n" "$path" "$tag" >> "$TAGS_TMP"
115
- else
116
- printf "%s\n" "$path" >> "$TAGS_TMP"
117
- fi
118
- done < "$INTENDED_TMP"
119
- fi
120
-
121
- classify_files_combined "$INTENDED_TMP" "$ACTUAL_TMP" "$TAGS_TMP" "$BUCKET_DIR"
122
-
123
- TODAY="$(date -u +%Y-%m-%d)"
124
- # Slug the tier list for the filename (commas → dashes; keeps 'all' as-is)
125
- TIER_SLUG="$(echo "$ARG_RAW" | tr ',' '-')"
126
- OUTFILE="$OUTPUT_DIR/${TODAY}-combined-${TIER_SLUG}.md"
127
- write_manifest_combined "$BUCKET_DIR" "$TODAY" "$ARG_RAW" "$OUTFILE" || {
128
- echo "analyze-tier-dependencies: write_manifest_combined failed" >&2
129
- exit 5
130
- }
131
- echo "analyze-tier-dependencies: wrote $OUTFILE" >&2
132
- exit 0
133
- fi
134
- # --- End combined-tier mode ------------------------------------------------
135
-
136
- # Validate tier arg (parse_tier_arg from lib)
137
- TIER="$(parse_tier_arg "${1:-}")" || exit $?
138
-
139
- # Resolve inputs (fixture overrides for tests; real sources otherwise)
140
- OUTPUT_DIR="${OUTPUT_DIR:-$REPO_ROOT/docs/dependency-audits}"
141
- RUNTIME_DEPS_FILE="${RUNTIME_DEPS_FILE:-$REPO_ROOT/standards/tier-runtime-deps/${TIER}.md}"
142
-
143
- # Check runtime-deps file exists (unless fixture mode short-circuits later)
144
- if [ ! -f "$RUNTIME_DEPS_FILE" ]; then
145
- echo "analyze-tier-dependencies: runtime-deps file missing at $RUNTIME_DEPS_FILE" >&2
146
- echo " create per standards/tier-dependency-analysis.md Source 3" >&2
147
- exit 3
148
- fi
149
-
150
- INTENDED_FIXTURE="${INTENDED_FIXTURE:-}"
151
- ACTUAL_FIXTURE="${ACTUAL_FIXTURE:-}"
152
- TAGS_FIXTURE="${TAGS_FIXTURE:-}"
153
-
154
- # Check intended fixture exists when in fixture mode
155
- if [ -n "$INTENDED_FIXTURE" ] && [ ! -f "$INTENDED_FIXTURE" ]; then
156
- echo "analyze-tier-dependencies: intended fixture not found at $INTENDED_FIXTURE" >&2
157
- exit 3
158
- fi
159
-
160
- # Temp files for the pipeline
161
- INTENDED_TMP="$(mktemp)"
162
- ACTUAL_TMP="$(mktemp)"
163
- TAGS_TMP="$(mktemp)"
164
- BUCKET_DIR="$(mktemp -d)"
165
- trap 'rm -rf "$INTENDED_TMP" "$ACTUAL_TMP" "$TAGS_TMP" "$BUCKET_DIR"' EXIT
166
-
167
- # Build INTENDED set — Sources 1 + 2 (BFS from tagged root set) + Source 3 (runtime deps)
168
- if [ -n "$INTENDED_FIXTURE" ]; then
169
- cat "$INTENDED_FIXTURE" > "$INTENDED_TMP"
170
- else
171
- # Real mode — Source 1 seed + Source 2 BFS
172
- cd "$REPO_ROOT"
173
- seeds_tmp="$(mktemp)"
174
- read_intended_source_1 "$TIER" > "$seeds_tmp"
175
- walk_graph_bfs "$seeds_tmp" extract_references > "$INTENDED_TMP"
176
- rm -f "$seeds_tmp"
177
- fi
178
-
179
- # Source 3 — runtime deps
180
- read_runtime_deps "$RUNTIME_DEPS_FILE" >> "$INTENDED_TMP"
181
-
182
- sort -u -o "$INTENDED_TMP" "$INTENDED_TMP"
183
-
184
- # Build ACTUAL set — Source 4 (release script dry-run)
185
- if [ -n "$ACTUAL_FIXTURE" ]; then
186
- cp "$ACTUAL_FIXTURE" "$ACTUAL_TMP"
187
- else
188
- read_actual_source "$TIER" > "$ACTUAL_TMP" || {
189
- echo "analyze-tier-dependencies: Source 4 (release script) failed" >&2
190
- exit 4
191
- }
192
- fi
193
- sort -u -o "$ACTUAL_TMP" "$ACTUAL_TMP"
194
-
195
- # Build TAGS map
196
- if [ -n "$TAGS_FIXTURE" ]; then
197
- cp "$TAGS_FIXTURE" "$TAGS_TMP"
198
- else
199
- # Real mode — derive tags via grep against INTENDED set
200
- cd "$REPO_ROOT"
201
- : > "$TAGS_TMP"
202
- while IFS= read -r path; do
203
- [ -z "$path" ] && continue
204
- tag=""
205
- if [ -f "$path" ]; then
206
- case "$path" in
207
- *.md)
208
- tag="$(awk '
209
- BEGIN{infm=0}
210
- NR==1 && /^---/ {infm=1; next}
211
- infm && /^---/ {exit}
212
- infm && /^tier:[[:space:]]/ {sub(/^tier:[[:space:]]*/,""); gsub(/[[:space:]]/,""); print; exit}
213
- ' "$path")"
214
- ;;
215
- *.sh)
216
- tag="$(head -5 "$path" | awk '/^# tier:[[:space:]]/ {sub(/^# tier:[[:space:]]*/,""); gsub(/[[:space:]]/,""); print; exit}')"
217
- ;;
218
- esac
219
- fi
220
- if [ -n "$tag" ]; then
221
- printf "%s\t%s\n" "$path" "$tag" >> "$TAGS_TMP"
222
- else
223
- printf "%s\n" "$path" >> "$TAGS_TMP"
224
- fi
225
- done < "$INTENDED_TMP"
226
- fi
227
-
228
- # Classify + write manifest
229
- classify_files "$INTENDED_TMP" "$ACTUAL_TMP" "$TAGS_TMP" "$BUCKET_DIR" "$TIER"
230
-
231
- TODAY="$(date -u +%Y-%m-%d)"
232
- OUTFILE="$OUTPUT_DIR/${TODAY}-${TIER}.md"
233
- write_manifest "$BUCKET_DIR" "$TODAY" "$TIER" "$OUTFILE" || {
234
- echo "analyze-tier-dependencies: write_manifest failed" >&2
235
- exit 5
236
- }
237
-
238
- echo "analyze-tier-dependencies: wrote $OUTFILE" >&2
239
- exit 0