@thebassclef/lite 0.1.3 → 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.
- package/dist/cli.cjs +216 -137
- package/dist/cli.js +218 -139
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.bassclef-source.json +10 -0
- package/dist/lite/.claude/settings.json +212 -0
- package/dist/lite/CLAUDE.md +41 -0
- package/dist/lite/gitignore +58 -0
- package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
- package/dist/lite/whereami.md +24 -0
- package/package.json +8 -2
- package/substrate/.bassclef/lite-manifest.json +0 -2701
- package/substrate/.claude/agents/architect.md +0 -70
- package/substrate/.claude/agents/builder.md +0 -114
- package/substrate/.claude/agents/designer.md +0 -156
- package/substrate/.claude/agents/reviewer.md +0 -88
- package/substrate/.claude/hooks/artifact-ingestion-gate.sh +0 -357
- package/substrate/.claude/hooks/assert-verify-steering.sh +0 -77
- package/substrate/.claude/hooks/bassclef-source-config-validate.sh +0 -215
- package/substrate/.claude/hooks/bassclef-sync.sh +0 -634
- package/substrate/.claude/hooks/compound-noun-scrub.sh +0 -292
- package/substrate/.claude/hooks/kiss-expansion-inject.sh +0 -69
- package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
- package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -492
- package/substrate/.claude/hooks/plain-english-steering.sh +0 -156
- package/substrate/.claude/hooks/post-skill-friction-check.sh +0 -177
- package/substrate/.claude/hooks/post-skill-telemetry.sh +0 -62
- package/substrate/.claude/hooks/pre-build-gate.sh +0 -511
- package/substrate/.claude/hooks/pre-commit-gate.sh +0 -451
- package/substrate/.claude/hooks/session-end.sh +0 -433
- package/substrate/.claude/hooks/session-reflection.sh +0 -303
- package/substrate/.claude/hooks/skill-body-grade-gate.sh +0 -219
- package/substrate/.claude/hooks/skill-body-intent-drift.sh +0 -107
- package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
- package/substrate/.claude/hooks/state-validate.sh +0 -271
- package/substrate/.claude/hooks/substrate-clarity-gate.sh +0 -1110
- package/substrate/.claude/hooks/temperance-gate.sh +0 -147
- package/substrate/.claude/hooks/testing-tier-enforce.sh +0 -233
- package/substrate/.claude/hooks/turn-prose-grade-measure.sh +0 -219
- package/substrate/.claude/hooks/turn-prose-kiss-check.sh +0 -463
- package/substrate/.claude/hooks/vocabulary-migration-check.sh +0 -171
- package/substrate/.claude/hooks/whereami-utc-gate.sh +0 -142
- package/substrate/.claude/luminaries/alan-cooper.md +0 -170
- package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
- package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
- package/substrate/.claude/luminaries/ash-maurya.md +0 -121
- package/substrate/.claude/luminaries/bill-buxton.md +0 -210
- package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
- package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
- package/substrate/.claude/luminaries/don-norman.md +0 -173
- package/substrate/.claude/luminaries/edward-tufte.md +0 -179
- package/substrate/.claude/luminaries/eric-evans.md +0 -160
- package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
- package/substrate/.claude/luminaries/gang-of-four.md +0 -157
- package/substrate/.claude/luminaries/glenford-myers.md +0 -230
- package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
- package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
- package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
- package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
- package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
- package/substrate/.claude/luminaries/karl-popper.md +0 -132
- package/substrate/.claude/luminaries/kent-beck.md +0 -168
- package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
- package/substrate/.claude/luminaries/martin-fowler.md +0 -164
- package/substrate/.claude/luminaries/michael-feathers.md +0 -125
- package/substrate/.claude/luminaries/michael-nygard.md +0 -118
- package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
- package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
- package/substrate/.claude/luminaries/sophia-prater.md +0 -193
- package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
- package/substrate/.claude/luminaries/tony-hoare.md +0 -170
- package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
- package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
- package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
- package/substrate/.claude/rules/adr-discipline.md +0 -120
- package/substrate/.claude/rules/api-conventions.md +0 -125
- package/substrate/.claude/rules/artifact-ingestion.md +0 -179
- package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
- package/substrate/.claude/rules/blocked-items.md +0 -146
- package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
- package/substrate/.claude/rules/branching.md +0 -28
- package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
- package/substrate/.claude/rules/commit-conventions.md +0 -22
- package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/context-engineering.md +0 -202
- package/substrate/.claude/rules/context-management.md +0 -85
- package/substrate/.claude/rules/defensive-bash.md +0 -68
- package/substrate/.claude/rules/deferred-actions.md +0 -233
- package/substrate/.claude/rules/destructive-operations.md +0 -69
- package/substrate/.claude/rules/diagnosis.md +0 -38
- package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
- package/substrate/.claude/rules/guardrails.md +0 -73
- package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
- package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
- package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
- package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
- package/substrate/.claude/rules/loop-discipline.md +0 -81
- package/substrate/.claude/rules/manual-prod-approval.md +0 -100
- package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
- package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
- package/substrate/.claude/rules/new-dependency-check.md +0 -51
- package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
- package/substrate/.claude/rules/operator-facing-prose.md +0 -196
- package/substrate/.claude/rules/option-label-discipline.md +0 -108
- package/substrate/.claude/rules/pattern-annotation.md +0 -100
- package/substrate/.claude/rules/plain-english-discipline.md +0 -156
- package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
- package/substrate/.claude/rules/pr-body-shape.md +0 -317
- package/substrate/.claude/rules/pr-strategy.md +0 -167
- package/substrate/.claude/rules/pr-title-shape.md +0 -161
- package/substrate/.claude/rules/prototype-workflow.md +0 -65
- package/substrate/.claude/rules/reserved-skill-names.md +0 -123
- package/substrate/.claude/rules/schema-management.md +0 -49
- package/substrate/.claude/rules/sdlc-gates.md +0 -149
- package/substrate/.claude/rules/security.md +0 -37
- package/substrate/.claude/rules/session-artifacts.md +0 -236
- package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
- package/substrate/.claude/rules/skill-description-clarity.md +0 -247
- package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
- package/substrate/.claude/rules/state-schema-validation.md +0 -162
- package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
- package/substrate/.claude/rules/substrate-config-schema.md +0 -98
- package/substrate/.claude/rules/test-list-discipline.md +0 -175
- package/substrate/.claude/rules/test-sufficiency.md +0 -210
- package/substrate/.claude/rules/testing-tier-config.md +0 -145
- package/substrate/.claude/rules/testing.md +0 -38
- package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
- package/substrate/.claude/rules/visual-hierarchy.md +0 -437
- package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
- package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
- package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
- package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
- package/substrate/.claude/skills/build/SKILL.md +0 -640
- package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
- package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
- package/substrate/.claude/skills/decompose/SKILL.md +0 -280
- package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
- package/substrate/.claude/skills/feynman/SKILL.md +0 -90
- package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
- package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
- package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
- package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
- package/substrate/.claude/skills/journal/SKILL.md +0 -209
- package/substrate/.claude/skills/kiss/SKILL.md +0 -449
- package/substrate/.claude/skills/launch/SKILL.md +0 -915
- package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
- package/substrate/.claude/skills/longrun/SKILL.md +0 -463
- package/substrate/.claude/skills/luminary/SKILL.md +0 -481
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
- package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
- package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
- package/substrate/.claude/skills/personas/SKILL.md +0 -207
- package/substrate/.claude/skills/promote/SKILL.md +0 -283
- package/substrate/.claude/skills/requirement/SKILL.md +0 -98
- package/substrate/.claude/skills/retro/SKILL.md +0 -117
- package/substrate/.claude/skills/riff/SKILL.md +0 -114
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
- package/substrate/.claude/skills/session-end/SKILL.md +0 -309
- package/substrate/.claude/skills/session-log/SKILL.md +0 -299
- package/substrate/.claude/skills/skills/SKILL.md +0 -228
- package/substrate/.claude/skills/spec/SKILL.md +0 -105
- package/substrate/.claude/skills/sprint/SKILL.md +0 -392
- package/substrate/.claude/skills/stage/SKILL.md +0 -384
- package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
- package/substrate/.claude/skills/temperance/SKILL.md +0 -108
- package/substrate/.claude/skills/use-case/SKILL.md +0 -417
- package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
- package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
- package/substrate/.claude/skills/verify/SKILL.md +0 -160
- package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
- package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
- package/substrate/.claude/skills/whereami/SKILL.md +0 -307
- package/substrate/AGENTS.md +0 -79
- package/substrate/CLAUDE-lite.md +0 -85
- package/substrate/CODE_OF_CONDUCT.md +0 -28
- package/substrate/CONTRIBUTING.md +0 -177
- package/substrate/README.md +0 -173
- package/substrate/SECURITY.md +0 -19
- package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
- package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
- package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
- package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
- package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
- package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
- package/substrate/lib/clean-artifacts-sweep.sh +0 -112
- package/substrate/lib/code-comment-discipline.sh +0 -144
- package/substrate/lib/composer-preflight.sh +0 -459
- package/substrate/lib/hook-inject.sh +0 -255
- package/substrate/lib/luminary-pick.sh +0 -96
- package/substrate/lib/output-discipline.sh +0 -143
- package/substrate/lib/prose-scan-boundary.sh +0 -171
- package/substrate/lib/rewrite-check.sh +0 -214
- package/substrate/lib/state.sh +0 -1372
- package/substrate/lib/telemetry.sh +0 -205
- package/substrate/lib/tier-check.sh +0 -187
- package/substrate/lib/tier-dependency-audit.sh +0 -1088
- package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
- package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
- package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
- package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
- package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
- package/substrate/scripts/aggregate-telemetry.sh +0 -217
- package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
- package/substrate/scripts/generate-lite-manifest.sh +0 -505
- package/substrate/scripts/generate-tier-manifest.sh +0 -28
- package/substrate/scripts/intent-drift-check.sh +0 -456
- package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
- package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
- package/substrate/standards/adr-template.md +0 -86
- package/substrate/standards/api-conventions/nextjs.md +0 -84
- package/substrate/standards/artifact-composition.md +0 -209
- package/substrate/standards/bash-hook-safety.md +0 -246
- package/substrate/standards/bassclef-configs-schema.md +0 -232
- package/substrate/standards/bassclef-evolution.md +0 -143
- package/substrate/standards/bassclef-internal-jargon.md +0 -244
- package/substrate/standards/bassclef-managed-sentinel.md +0 -96
- package/substrate/standards/bassclef-source-config.md +0 -228
- package/substrate/standards/branch-stacking.md +0 -408
- package/substrate/standards/code-safety-principles.md +0 -176
- package/substrate/standards/composer-prerequisites.md +0 -155
- package/substrate/standards/deferred-actions-schema.md +0 -204
- package/substrate/standards/dependency-discipline/cargo.md +0 -39
- package/substrate/standards/dependency-discipline/gem.md +0 -43
- package/substrate/standards/dependency-discipline/go-mod.md +0 -41
- package/substrate/standards/dependency-discipline/npm.md +0 -42
- package/substrate/standards/dependency-discipline/pip.md +0 -42
- package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
- package/substrate/standards/deployment-topology.md +0 -69
- package/substrate/standards/docs-sync-allowlist.md +0 -76
- package/substrate/standards/domain-and-dns.md +0 -145
- package/substrate/standards/frontend-stack.md +0 -67
- package/substrate/standards/frontmatter-schema.md +0 -154
- package/substrate/standards/graceful-exit.md +0 -227
- package/substrate/standards/hook-idempotency.md +0 -102
- package/substrate/standards/hook-injection-discipline.md +0 -202
- package/substrate/standards/hook-install-class.md +0 -215
- package/substrate/standards/input-handler-interface.md +0 -152
- package/substrate/standards/lite-manifest-schema-changes.md +0 -135
- package/substrate/standards/luminary-matching.md +0 -105
- package/substrate/standards/luminary-problem-patterns.md +0 -481
- package/substrate/standards/migration-discipline/active-record.md +0 -50
- package/substrate/standards/migration-discipline/alembic.md +0 -43
- package/substrate/standards/migration-discipline/gorm.md +0 -50
- package/substrate/standards/migration-discipline/prisma.md +0 -53
- package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
- package/substrate/standards/mobile-ephemeral-session.md +0 -167
- package/substrate/standards/model-routing-discipline.md +0 -160
- package/substrate/standards/ogilvy-writing-rules.md +0 -225
- package/substrate/standards/opener-discipline.md +0 -96
- package/substrate/standards/operator-facing-prose-discipline.md +0 -201
- package/substrate/standards/persona-schema.md +0 -229
- package/substrate/standards/pluggable-luminaries.md +0 -323
- package/substrate/standards/pr-body-discipline.md +0 -115
- package/substrate/standards/preview-state-schema.md +0 -189
- package/substrate/standards/project-directory-layout.md +0 -276
- package/substrate/standards/release-tagging.md +0 -137
- package/substrate/standards/reserved-skill-names.md +0 -120
- package/substrate/standards/scannable-multi-option-output.md +0 -261
- package/substrate/standards/sdlc-compliance.md +0 -286
- package/substrate/standards/sdlc-gates/typescript.md +0 -57
- package/substrate/standards/secrets-lifecycle.md +0 -210
- package/substrate/standards/security-scanner-adapter.md +0 -145
- package/substrate/standards/session-board.md +0 -256
- package/substrate/standards/skill-output-discipline.md +0 -90
- package/substrate/standards/state-spine-contract.md +0 -255
- package/substrate/standards/state-spine.md +0 -511
- package/substrate/standards/steering-hints/kiss-words.md +0 -11
- package/substrate/standards/substrate-config-schema.md +0 -267
- package/substrate/standards/tech-stack-config.md +0 -109
- package/substrate/standards/tier-dependency-analysis.md +0 -167
- package/substrate/standards/tier-runtime-deps/lite.md +0 -57
- package/substrate/standards/tier-tag-schema.md +0 -155
- package/substrate/standards/two-layer-config.md +0 -99
- package/substrate/standards/use-case-format.md +0 -292
- package/substrate/standards/user-story-invest.md +0 -268
- package/substrate/standards/velocity-and-appetite.md +0 -229
- package/substrate/standards/voice-input-pattern.md +0 -119
- package/substrate/standards/whereami-schema.md +0 -301
- package/substrate/standards/worktree-management.md +0 -211
- package/substrate/standards/writing-guide.md +0 -213
- package/substrate/templates/chronicle-template.md +0 -75
- package/substrate/templates/deferred-action-template.md +0 -45
- package/substrate/templates/memory-proposal-template.md +0 -77
- package/substrate/templates/persona-template.md +0 -200
- package/substrate/templates/pr-faq.md +0 -45
- package/substrate/templates/secret-rotation-template.md +0 -162
- package/substrate/templates/spec-template.md +0 -131
- package/substrate/templates/use-case-template.md +0 -194
- package/substrate/templates/user-story-template.md +0 -107
- 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
|