@thebassclef/lite 1.9.15 → 1.9.18

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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/lite/.claude/agents/builder.md +7 -4
  6. package/dist/lite/.claude/bassclef-orientation.md +22 -0
  7. package/dist/lite/.claude/hooks/artifact-ingestion-gate.sh +11 -3
  8. package/dist/lite/.claude/hooks/assert-verify-steering.sh +1 -19
  9. package/dist/lite/.claude/hooks/plain-english-steering.sh +86 -41
  10. package/dist/lite/.claude/hooks/pre-commit-gate.sh +10 -2
  11. package/dist/lite/.claude/hooks/pre-push-shellcheck.sh +144 -0
  12. package/dist/lite/.claude/hooks/reviewer-dispatch-check.sh +153 -0
  13. package/dist/lite/.claude/hooks/session-reflection.d/83-install-written-paths-rebuild.sh +15 -32
  14. package/dist/lite/.claude/hooks/turn-prose-density-measure.sh +109 -0
  15. package/dist/lite/.claude/hooks/turn-prose-kiss-check.sh +28 -0
  16. package/dist/lite/.claude/rules/branching.md +2 -0
  17. package/dist/lite/.claude/rules/identifier-leak-prevention.md +2 -1
  18. package/dist/lite/.claude/rules/lite-manifest-schema-change-discipline.md +23 -0
  19. package/dist/lite/.claude/rules/reviewer-dispatch.md +95 -0
  20. package/dist/lite/.claude/settings.json +10 -0
  21. package/dist/lite/.claude/skills/build/SKILL.md +81 -6
  22. package/dist/lite/.claude/skills/eisenhower/SKILL.md +26 -0
  23. package/dist/lite/.claude/skills/launch/SKILL.md +45 -2
  24. package/dist/lite/.claude/skills/onboard-repo/SKILL.md +204 -40
  25. package/dist/lite/.claude/skills/onboard-repo/concise-prompt.sh +73 -0
  26. package/dist/lite/.claude/skills/onboard-repo/write-state-marker.sh +81 -0
  27. package/dist/lite/.claude/skills/pre-mortem/SKILL.md +56 -0
  28. package/dist/lite/.claude/skills/sprint/SKILL.md +24 -3
  29. package/dist/lite/.claude/skills/temperance/SKILL.md +15 -4
  30. package/dist/lite/README.md +2 -0
  31. package/dist/lite/bassclef-version.json +5 -5
  32. package/dist/lite/lib/install-written-paths.sh +250 -3
  33. package/dist/lite/lib/prose-marker.sh +203 -0
  34. package/dist/lite/lib/tier-dependency-audit.sh +52 -25
  35. package/dist/lite/presence/install/bassclef-sync.template.sh +86 -8
  36. package/dist/lite/scripts/generate-lite-manifest.sh +15 -0
  37. package/dist/lite/scripts/launch/local-serve.sh +149 -8
  38. package/dist/lite/standards/bassclef-wiring-manifest.json +12 -0
  39. package/dist/lite/standards/lite-manifest-schema-changes.md +49 -0
  40. package/dist/lite/standards/lite-manifest.json +90 -27
  41. package/dist/lite/standards/prose-marker-format.md +105 -0
  42. package/package.json +1 -1
@@ -356,7 +356,80 @@ this divider.
356
356
  Run each phase in order. Operator confirms before destructive or
357
357
  cross-repo actions. Each phase is independently re-runnable.
358
358
 
359
- #### Phase 0 — Refuse to run from main
359
+ #### Phase 0 — Preflight checks (OAuth, git identity, branch)
360
+
361
+ Phase 0 bundles three cheap preflight checks before any Phase 1 work runs. The checks fire together so adopter sees all gaps at once, not one at a time. Per bassclef-upstream#2242 preflight-first SKILL design + folds C1 + C4 from the 2026-10-14 pre-mortem.
362
+
363
+ ##### 0.1 Claude OAuth probe (per bassclef-upstream#2233)
364
+
365
+ Cold adopters have hit `/onboard-repo` with expired OAuth tokens. The skill wastes an orientation turn, then returns `Login expired · Please run /login`. The adopter re-fires the skill after login. Preflight the probe so the login prompt lands before any phase work.
366
+
367
+ Run the cheap-hello pattern (per memory `feedback_oauth_verify_via_cheap_hello`):
368
+
369
+ ```bash
370
+ if ! command -v claude >/dev/null 2>&1; then
371
+ cat >&2 <<'EOF'
372
+
373
+ 🛑 /onboard-repo preflight — Claude CLI not found on PATH.
374
+
375
+ Install Claude Code first. Then re-fire /onboard-repo.
376
+
377
+ EOF
378
+ exit 1
379
+ fi
380
+
381
+ if ! timeout 10 claude -p "say hello" >/dev/null 2>&1; then
382
+ cat >&2 <<'EOF'
383
+
384
+ 🛑 /onboard-repo preflight — Claude OAuth check failed.
385
+
386
+ Run `/login` first. Then re-fire `/onboard-repo`.
387
+
388
+ EOF
389
+ exit 1
390
+ fi
391
+ ```
392
+
393
+ Two checks: binary on PATH, then OAuth probe. Cost: ~2s on green path.
394
+
395
+ ##### 0.2 Git identity preflight (per bassclef-upstream#2232)
396
+
397
+ `/onboard-repo` runs commit paths in Phase 2. Git fails with `Author identity unknown` when `user.name` or `user.email` is unset. The adopter sees the gap mid-flow and has to answer a 3-option prompt. Preflight the check so the question lands here, not later.
398
+
399
+ ```bash
400
+ GIT_NAME=$(git config --get user.name 2>/dev/null || echo "")
401
+ GIT_EMAIL=$(git config --get user.email 2>/dev/null || echo "")
402
+
403
+ if [ -z "$GIT_NAME" ] || [ -z "$GIT_EMAIL" ]; then
404
+ cat >&2 <<'EOF'
405
+
406
+ 🛑 /onboard-repo preflight — git identity not set.
407
+
408
+ Pick one option (then re-fire /onboard-repo):
409
+
410
+ 1. GitHub no-reply address (private, derived from `gh api user`):
411
+ (requires `gh auth login` first — see Prerequisites)
412
+ GH_USER=$(gh api user --jq .login)
413
+ GH_ID=$(gh api user --jq .id)
414
+ git config --global user.name "$GH_USER"
415
+ git config --global user.email "${GH_ID}+${GH_USER}@users.noreply.github.com"
416
+
417
+ 2. Your own name + email:
418
+ git config --global user.name "Your Name"
419
+ git config --global user.email "you@example.com"
420
+
421
+ 3. Fixture smoke (keep repo-local identity for test runs):
422
+ git config user.name "fixture"
423
+ git config user.email "fixture@localhost"
424
+
425
+ EOF
426
+ exit 1
427
+ fi
428
+ ```
429
+
430
+ Three options cover the common paths. GitHub no-reply is private and matches the pattern bassclef uses for its own commits.
431
+
432
+ ##### 0.3 Refuse to run from main
360
433
 
361
434
  Substrate changes go through PRs, same as feature work. If `/onboard-repo`
362
435
  runs from `main`, every scaffold (`.claude/`, `CLAUDE.md`,
@@ -427,6 +500,59 @@ operator-decision items.
427
500
 
428
501
  Idempotent API calls against the target repo via `gh`.
429
502
 
503
+ ##### 1.0a Repo-name collision helper (per bassclef-upstream#2236)
504
+
505
+ When an agent or adopter runs `gh repo create` on behalf of `/onboard-repo` and the name is taken, iterate the suffix one-by-one is slow. A cold adopter on 2026-10-13 hit three round-trips before landing on `-4`. Enumerate the taken set in ONE call. Propose the lowest free name up front.
506
+
507
+ Use this helper whenever the flow creates a new repo:
508
+
509
+ ```bash
510
+ basename="bassclef-smoke-test" # or whatever the adopter picked
511
+ owner=$(gh api user --jq .login)
512
+
513
+ # Pull every repo under $owner starting with $basename in ONE call
514
+ taken=$(gh repo list "$owner" --json name --jq "[.[].name | select(startswith(\"$basename\"))] | sort" 2>/dev/null)
515
+
516
+ # Find lowest free suffix
517
+ suffix=""
518
+ for i in '' $(seq 2 100); do
519
+ candidate="${basename}$([ -n "$i" ] && echo "-$i")"
520
+ if ! jq -e --arg c "$candidate" '.[] | select(. == $c)' <<<"$taken" >/dev/null 2>&1; then
521
+ suffix="$i"
522
+ break
523
+ fi
524
+ done
525
+
526
+ proposed="${basename}$([ -n "$suffix" ] && echo "-$suffix")"
527
+ echo "Taken under $owner matching ${basename}*: $taken"
528
+ echo "Proposed free name: $proposed"
529
+ echo "Accept '$proposed'? Or type your own:"
530
+ ```
531
+
532
+ One `gh repo list` call enumerates every conflict. One prompt proposes the next free name. Adopter accepts or renames in one turn.
533
+
534
+ ##### 1.0 Write the temperance marker up-front (per bassclef-upstream#2237)
535
+
536
+ `/onboard-repo` is the scope decision. Running it means the operator picked this plan. The `pre-build-gate.sh` BLOCK on first Edit is a false positive. The scope landed at skill dispatch, not mid-skill.
537
+
538
+ Write the marker now, before any Edit tool call fires:
539
+
540
+ ```bash
541
+ mkdir -p state/markers/temperance
542
+ BRANCH=$(git branch --show-current)
543
+ cat > "state/markers/temperance/${BRANCH}.marker" <<EOF
544
+ # Temperance marker — /onboard-repo
545
+ - date: $(date -u +%Y-%m-%d)
546
+ - branch: ${BRANCH}
547
+ - scope-decision: scaffold bassclef setup via /onboard-repo
548
+ - right-thing: adopter needs .claude/ + .gitignore + .bassclef/ wiring
549
+ - right-way: idempotent API calls + file writes contained to adopter repo
550
+ - drift-trigger: operator asks for scope outside the standard bootstrap set
551
+ EOF
552
+ ```
553
+
554
+ The marker satisfies `pre-build-gate.sh` at the right scope boundary. Phase 2's first Edit (settings.json, bassclef-configs.jsonc, .gitignore) proceeds clean. No mid-flow BLOCK banner.
555
+
430
556
  ##### 1.1 Create the 11 standard labels
431
557
 
432
558
  ```bash
@@ -462,31 +588,33 @@ immediately without waiting for a sync cycle.
462
588
 
463
589
  ##### 1.2 Protect main from force-push and deletion
464
590
 
465
- **Heads up — GitHub free-tier adopters on PRIVATE repos:** the API call
466
- below returns HTTP 403 ("Upgrade to GitHub Pro or make this repository
467
- public") on free-tier accounts, because branch protection is a paid
468
- feature for private repos. Public repos get branch protection on every
469
- plan, free included. Pick a path below BEFORE running the call.
591
+ Branch protection on private repos is a paid GitHub feature. Free plan + private repo returns HTTP 403 on the API call. Public repos get branch protection on every plan.
470
592
 
471
- Three ways to clear this step:
472
-
473
- 1. **Make the repo public** — simplest; free plan includes branch
474
- protection on public repos. Good fit when the code is open source
475
- or ships to adopters anyway.
476
- 2. **Upgrade the GitHub plan** — Pro / Team / Enterprise includes
477
- branch protection on private repos.
478
- 3. **Skip the API call** — rely on local safety (no `git push --force`
479
- habits, PR review, pre-commit hooks). Mark the repo config so later
480
- phases know branch protection is operator-managed, not substrate-
481
- managed. See the fallback block below.
593
+ Preflight the plan + visibility pair. Skip the API call cleanly when free + private (per bassclef-upstream#2235). No adopter prompt, no 403 noise:
482
594
 
483
595
  ```bash
484
596
  DEFAULT_BRANCH=$(gh repo view "$REPO" --json defaultBranchRef -q '.defaultBranchRef.name')
597
+ PLAN=$(gh api /user --jq .plan.name 2>/dev/null || echo "unknown")
598
+ VISIBILITY=$(gh repo view "$REPO" --json visibility --jq .visibility 2>/dev/null || echo "UNKNOWN")
485
599
 
486
- # Pro / public-repo path — run the API call.
487
- gh api "repos/$REPO/branches/$DEFAULT_BRANCH/protection" \
488
- --method PUT \
489
- --input - <<EOF
600
+ if [ "$PLAN" = "free" ] && [ "$VISIBILITY" = "PRIVATE" ]; then
601
+ echo "Preflight: free plan + private repo. GitHub free does not offer branch protection on private repos. Skipping API call."
602
+ mkdir -p docs
603
+ cat >> docs/onboard-notes.md <<'NOTE'
604
+ ## Branch protection — operator-managed
605
+
606
+ GitHub free plan does not offer branch protection on private repos.
607
+ This repo relies on:
608
+ - Local discipline: no `git push --force` to main.
609
+ - PR review before merge.
610
+ - Pre-commit hooks shipped by bassclef.
611
+
612
+ Revisit if the repo moves to public, or the plan upgrades to Pro+.
613
+ NOTE
614
+ else
615
+ gh api "repos/$REPO/branches/$DEFAULT_BRANCH/protection" \
616
+ --method PUT \
617
+ --input - <<EOF
490
618
  {
491
619
  "required_status_checks": null,
492
620
  "enforce_admins": false,
@@ -496,6 +624,7 @@ gh api "repos/$REPO/branches/$DEFAULT_BRANCH/protection" \
496
624
  "allow_deletions": false
497
625
  }
498
626
  EOF
627
+ fi
499
628
  ```
500
629
 
501
630
  Minimum defense: no force-push or deletion of main. PR reviews NOT
@@ -503,25 +632,6 @@ required here — agent-created PRs (bassclef-sync) need to merge
503
632
  without human intervention for the mobile-sync story. Add stricter
504
633
  rules per-repo in `.github/branch-protection.yml` if the repo warrants.
505
634
 
506
- **Free-tier private-repo fallback (path 3 above).** If the API
507
- returned 403 and the operator picked "skip and manage locally":
508
-
509
- ```bash
510
- # Record the choice so later audits know main is not API-protected.
511
- mkdir -p .claude
512
- cat >> .claude/onboard-notes.md <<'NOTE'
513
- ## Branch protection — operator-managed
514
-
515
- GitHub free-tier does not include branch protection on private repos.
516
- This repo relies on:
517
- - Local discipline: no `git push --force` to main.
518
- - PR review before merge.
519
- - Pre-commit hooks shipped by bassclef.
520
-
521
- Revisit if the repo moves to public, or the plan upgrades to Pro+.
522
- NOTE
523
- ```
524
-
525
635
  The adopter can revisit this step after switching to public OR
526
636
  upgrading the plan.
527
637
 
@@ -550,6 +660,25 @@ production deploy target.
550
660
 
551
661
  **Working directory: target repo.** All file writes happen here.
552
662
 
663
+ ##### 2.0 Opt-in prompt pattern — lead with VALUE (per bassclef-upstream#2234)
664
+
665
+ Phase 2 fires four opt-in prompts: auto-update sync (2.1), auto-save cron (2.3.10), Concise output style (2.7), and deploy-host (3.5). The cold-adopter on 2026-10-13 wrote: "need to understand value of auto-save in the text". Current prompts render as 4-option tables with recommended labels but no VALUE row.
666
+
667
+ Every opt-in prompt the agent dispatches via `AskUserQuestion` MUST prepend one plain-English sentence on what the adopter gets. Keep the multi-option schema. Add value to the option body text.
668
+
669
+ **Pattern.** Each option description starts with the value sentence, then the mechanism:
670
+
671
+ - `description: "What this is for: <one-sentence benefit>. <one-sentence mechanism>."`
672
+
673
+ **Worked examples.** Agent composes these from the SKILL body text + the ticket semantics:
674
+
675
+ - **auto_sync** → "What this is for: your repo pulls bassclef skills + rules every session so you stay current. Mechanism: SessionStart hook fetches the latest tarball."
676
+ - **auto-save cron** → "What this is for: your work saves every 20 minutes so a crash or power loss costs minutes, not hours. Mechanism: launchd job (macOS) or Task Scheduler (Windows) commits uncommitted changes."
677
+ - **Concise output style** → "What this is for: Claude Code leads replies with the result, skips step-by-step narration, and skips the closing recap. Mechanism: adds `outputStyle: Concise` to your `~/.claude/settings.json`."
678
+ - **deploy-host** → "What this is for: your repo deploys to a live URL when main merges. Mechanism: AWS Amplify app + DNS + certificate via `/provision-deploy-host`."
679
+
680
+ The agent uses these as templates. One sentence of value. One sentence of mechanism. Then the standard options list.
681
+
553
682
  ##### 2.1 Install the auto-update script (off by default per bassclef#939)
554
683
 
555
684
  ```bash
@@ -1357,6 +1486,41 @@ EOF
1357
1486
  The sync hook will add its managed symlink block on next run; this
1358
1487
  seeds the file with everything else.
1359
1488
 
1489
+ ##### 2.7 Prompt to enable Concise output style (ADR-049 opt-in)
1490
+
1491
+ **Working directory: operator home.** Writes land in `~/.claude/`, not the target repo.
1492
+
1493
+ Anthropic ships four output styles. Concise leads with the result. It skips step-by-step narration. It skips closing recap. Three bassclef steering dimensions line up with Concise. Five bassclef dimensions stay in play at the project layer. They are grade target, jargon wordlist, appositive discipline, metric feedback, writing-craft discipline. Concise at operator scope cuts per-turn reminders. It covers three bassclef dimensions on its own.
1494
+
1495
+ Fire this phase only when `concise_prompt_should_fire` returns 0. That means no declined sentinel. It also means no outputStyle set to Concise yet.
1496
+
1497
+ ```bash
1498
+ HELPER="$CLAUDE_PROJECT_DIR/.claude/skills/onboard-repo/concise-prompt.sh"
1499
+ source "$HELPER"
1500
+ concise_prompt_should_fire || { echo "Concise prompt skipped (declined or already set)."; return 0 2>/dev/null || true; }
1501
+ ```
1502
+
1503
+ Prompt the operator:
1504
+
1505
+ > Enable Concise output style? (Y/n/skip)
1506
+ > - **Y** — write `"outputStyle": "Concise"` to `~/.claude/settings.json`. jq read-modify-write. Every pre-existing field survives.
1507
+ > - **n** — keep Default style. Do not prompt again.
1508
+ > - **skip** — do not change settings. Re-prompt on next `/onboard-repo` run.
1509
+
1510
+ Default is **Y**.
1511
+
1512
+ Apply the pick via the helper:
1513
+
1514
+ ```bash
1515
+ concise_prompt_apply "$CHOICE" # Y | n | skip
1516
+ ```
1517
+
1518
+ The helper writes atomically. On **Y** it uses `jq '. + {"outputStyle": "Concise"}'` plus `mktemp` plus `mv`. No partial write ever lands. On **n** it writes `~/.claude/state/concise-prompt-declined`. On **skip** it writes `~/.claude/state/concise-prompt-skipped` so the operator sees the prompt again next run.
1519
+
1520
+ Characterization test at `.claude/skills/onboard-repo/tests/concise-prompt.test.sh` pins all three paths plus field preservation (T1-T11; 11 tests).
1521
+
1522
+ Per ADR-049 opt-in default off. The prompt defaults to Y. The operator picks explicitly. The helper NEVER writes without an explicit choice.
1523
+
1360
1524
  #### Phase 3 — Create starter docs (CLAUDE.md, whereami)
1361
1525
 
1362
1526
  **Working directory: target repo.**
@@ -0,0 +1,73 @@
1
+ #!/bin/bash
2
+ # tier: lite
3
+ # install-class: project
4
+ # concise-prompt.sh — handle Y/n/skip for Anthropic Concise output style.
5
+ # Called by /onboard-repo SKILL Phase 2.7. Writes operator ~/.claude/settings.json
6
+ # atomically via jq read-modify-write so every pre-existing field survives.
7
+ #
8
+ # Per Longrun 2 Step 2g (bassclef-upstream#2197).
9
+ # ADR-049 opt-in default off — adopter picks Y explicitly.
10
+ #
11
+ # Env: HOME_OVERRIDE points at a fixture home for testing.
12
+ # Returns:
13
+ # 0 — path applied (Y wrote field, n wrote declined sentinel, skip wrote skip sentinel)
14
+ # 1 — jq missing OR write failed (fail-soft; operator sees warning)
15
+ # 2 — invalid choice
16
+
17
+ set +e
18
+
19
+ concise_prompt_apply() {
20
+ local choice="${1:-}"
21
+ local home="${HOME_OVERRIDE:-$HOME}"
22
+ local settings="$home/.claude/settings.json"
23
+ local state_dir="$home/.claude/state"
24
+ mkdir -p "$home/.claude" "$state_dir" 2>/dev/null
25
+
26
+ case "$choice" in
27
+ Y|y)
28
+ if ! command -v jq >/dev/null 2>&1; then
29
+ echo "concise-prompt: jq not installed; skipping outputStyle write" >&2
30
+ return 1
31
+ fi
32
+ [ -f "$settings" ] || echo '{}' > "$settings"
33
+ local tmp
34
+ tmp=$(mktemp 2>/dev/null) || return 1
35
+ if jq '. + {"outputStyle": "Concise"}' "$settings" > "$tmp" 2>/dev/null; then
36
+ mv "$tmp" "$settings"
37
+ else
38
+ rm -f "$tmp" 2>/dev/null
39
+ return 1
40
+ fi
41
+ rm -f "$state_dir/concise-prompt-skipped" "$state_dir/concise-prompt-declined" 2>/dev/null
42
+ return 0
43
+ ;;
44
+ n|N)
45
+ touch "$state_dir/concise-prompt-declined" 2>/dev/null || return 1
46
+ return 0
47
+ ;;
48
+ skip|SKIP|s|S)
49
+ touch "$state_dir/concise-prompt-skipped" 2>/dev/null || return 1
50
+ return 0
51
+ ;;
52
+ *)
53
+ return 2
54
+ ;;
55
+ esac
56
+ }
57
+
58
+ concise_prompt_should_fire() {
59
+ local home="${HOME_OVERRIDE:-$HOME}"
60
+ local state_dir="$home/.claude/state"
61
+ local settings="$home/.claude/settings.json"
62
+ [ -f "$state_dir/concise-prompt-declined" ] && return 1
63
+ if [ -f "$settings" ] && command -v jq >/dev/null 2>&1; then
64
+ if jq -e '.outputStyle == "Concise"' "$settings" >/dev/null 2>&1; then
65
+ return 1
66
+ fi
67
+ fi
68
+ return 0
69
+ }
70
+
71
+ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
72
+ concise_prompt_apply "${1:-}"
73
+ fi
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bash
2
+ # tier: lite
3
+ # write-state-marker.sh — Phase 2.3.9 helper for /onboard-repo (bassclef-upstream#664).
4
+ # Retagged standard→lite per bassclef-upstream#2140 (Cure 1) so lite adopters
5
+ # running /onboard-repo at Phase 2.3.9 capture the state marker cleanly.
6
+ # Script shape is small (≤80 lines, no bash gotchas); belongs in the lite bundle.
7
+ #
8
+ # Writes .claude/state/onboard-repo.state.json capturing which mode ran, when,
9
+ # and which files landed. Re-runs append to history[] instead of clobbering.
10
+ #
11
+ # Usage:
12
+ # bash .claude/skills/onboard-repo/write-state-marker.sh <mode>
13
+ #
14
+ # Env:
15
+ # ONBOARD_TARGET_DIR root of the adopter repo (defaults to $PWD)
16
+ #
17
+ # Composes with:
18
+ # - Configs UI first-run overlay (bassclef/configs/, bet 2026-07-08a WU-7)
19
+ # - @luminary john-ousterhout — deep module — one script, one job
20
+
21
+ set -eu
22
+
23
+ MODE="${1:-default}"
24
+ TARGET="${ONBOARD_TARGET_DIR:-$PWD}"
25
+
26
+ mkdir -p "$TARGET/.claude/state"
27
+ MARKER="$TARGET/.claude/state/onboard-repo.state.json"
28
+ NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
29
+
30
+ # Collect paths written to the adopter repo — check for existence.
31
+ PATHS_JSON='['
32
+ sep=""
33
+ for p in \
34
+ ".claude/bassclef-configs.jsonc" \
35
+ ".bassclef-source.json" \
36
+ ".claude/CLAUDE.md" \
37
+ "docs/whereami.md"; do
38
+ if [ -f "$TARGET/$p" ]; then
39
+ PATHS_JSON="$PATHS_JSON$sep\"$p\""
40
+ sep=","
41
+ fi
42
+ done
43
+ PATHS_JSON="$PATHS_JSON]"
44
+
45
+ if [ -f "$MARKER" ]; then
46
+ # Existing marker — append prior run to history[]; keep top-level as this run.
47
+ python3 - "$MARKER" "$MODE" "$NOW" "$PATHS_JSON" <<'PY'
48
+ import json, sys
49
+ marker_path = sys.argv[1]
50
+ mode = sys.argv[2]
51
+ now = sys.argv[3]
52
+ paths_written = json.loads(sys.argv[4])
53
+ with open(marker_path) as f:
54
+ data = json.load(f)
55
+ history = data.get("history", [])
56
+ history.append({
57
+ "mode": data.get("mode", "unknown"),
58
+ "timestamp_iso": data.get("timestamp_iso", "unknown"),
59
+ "paths_written": data.get("paths_written", []),
60
+ })
61
+ data["mode"] = mode
62
+ data["timestamp_iso"] = now
63
+ data["paths_written"] = paths_written
64
+ data["history"] = history
65
+ data["skill_version"] = data.get("skill_version", "1.0")
66
+ with open(marker_path, "w") as f:
67
+ json.dump(data, f, indent=2)
68
+ PY
69
+ else
70
+ cat > "$MARKER" <<JSON
71
+ {
72
+ "mode": "$MODE",
73
+ "timestamp_iso": "$NOW",
74
+ "paths_written": $PATHS_JSON,
75
+ "history": [],
76
+ "skill_version": "1.0"
77
+ }
78
+ JSON
79
+ fi
80
+
81
+ echo "wrote onboard-repo state marker at $MARKER (mode: $MODE)"
@@ -111,13 +111,69 @@ For non-always-fire scope, `/pre-mortem light` picks 3 lenses appropriate to the
111
111
  - Per lens: 5-8 imagined failures written by operator; Claude collates without ranking during the pass
112
112
  - Follow-up pass: pick top 5 risks total (across all lenses); name owner + mitigation per risk
113
113
  - Output at `docs/risk-ledgers/<slug>.md` — short-form ledger
114
+ - **Write marker at `state/markers/pre-mortem/<branch-slug>.marker`** — downstream skills (`/build` Phase 3, Reviewer) read it. See § Marker contract below.
114
115
 
115
116
  ### Full mode (90 min)
116
117
 
118
+ <!-- FKGL-EXEMPT: full-mode bullets inherit light-mode shape with denser per-risk fields (severity + trigger + mitigation); dense bullet reference list, not prose. -->
117
119
  - 5-8 rotating lenses per domain map
118
120
  - Per lens: 10-15 imagined failures; per-risk severity (high/medium/low); per-risk trigger signal (what would tell operator the risk materialized); per-risk mitigation
119
121
  - Follow-up pass: rank all risks by severity × probability; name owner + mitigation trigger + monitoring signal per top-10 risks
120
122
  - Output at `docs/risk-ledgers/<slug>.md` — research-grade ledger
123
+ - **Write marker at `state/markers/pre-mortem/<branch-slug>.marker`** — downstream skills read it. See § Marker contract below.
124
+ <!-- /FKGL-EXEMPT -->
125
+
126
+ <!-- FKGL-EXEMPT: § Marker contract — technical reference with bash fenced blocks and marker body template; not prose. Per bassclef-upstream#2175 Batch B — F4. -->
127
+
128
+ ## Marker contract (per bassclef-upstream#2175 Batch B — F4)
129
+
130
+ After the risk ledger lands, write a marker at `state/markers/pre-mortem/<branch-slug>.marker`. Downstream skills read it. `/build` Phase 3 surfaces the top risks. Reviewer reads it during review.
131
+
132
+ Marker body shape:
133
+
134
+ ```
135
+ # Pre-mortem marker — <scope>
136
+ - date: YYYY-MM-DD
137
+ - branch: <branch name>
138
+ - ledger: docs/risk-ledgers/<slug>.md
139
+ - mode: light | full
140
+ - lenses: lead-slug + supporting slugs (comma list)
141
+ - top-5 risks: one line per risk — <severity glyph> <one-sentence summary> (<lens slug>)
142
+ - disposition: fold | monitor | scope-cut per risk
143
+ ```
144
+
145
+ The ledger path is the canonical reference. The top-5 risks give a scan summary. Lenses pin the authoring luminaries.
146
+
147
+ ```bash
148
+ BRANCH=$(git branch --show-current)
149
+ BRANCH_SLUG=$(echo "$BRANCH" | tr '/' '-')
150
+ mkdir -p state/markers/pre-mortem
151
+ cat > "state/markers/pre-mortem/${BRANCH_SLUG}.marker" <<EOF
152
+ # Pre-mortem marker — <scope>
153
+ - date: $(date -u +%Y-%m-%d)
154
+ - branch: $BRANCH
155
+ - ledger: docs/risk-ledgers/<slug>.md
156
+ - mode: light
157
+ - lenses: <lead-slug>, <supporting-slug-1>, <supporting-slug-2>
158
+ - top-5 risks:
159
+ - 🔴 <risk one summary> (<lens-slug>)
160
+ - 🟡 <risk two summary> (<lens-slug>)
161
+ - 🟢 <risk three summary> (<lens-slug>)
162
+ - 🟡 <risk four summary> (<lens-slug>)
163
+ - 🔴 <risk five summary> (<lens-slug>)
164
+ - disposition: fold per risk (name mitigation inline)
165
+ EOF
166
+ ```
167
+
168
+ Guard the git-stage with a check-ignore test — adopter repos vary on whether `state/markers/` is tracked:
169
+
170
+ ```bash
171
+ if ! git check-ignore -q "state/markers/pre-mortem/${BRANCH_SLUG}.marker" 2>/dev/null; then
172
+ git add "state/markers/pre-mortem/${BRANCH_SLUG}.marker"
173
+ fi
174
+ ```
175
+
176
+ <!-- /FKGL-EXEMPT -->
121
177
 
122
178
  ## Output
123
179
 
@@ -100,6 +100,21 @@ Option labels are typeable letters per memory `feedback_keyboard_typeable_option
100
100
 
101
101
  **Step 0** — Lead with a `/value-prop tweet` claim (≤180 chars) plus a `/kiss words` grade-10 summary (2-3 sentences). This is what the operator reads first on mobile. Tables come after.
102
102
 
103
+ **Step 0.5 — First-run detection (per bassclef-upstream#2009; Sam-A).** Before any thread walk fires, check whether the repo is cold. Cold means:
104
+
105
+ - `docs/whereami.md` is missing OR has no `iteration_bet:` + no `next_bet:` field, AND
106
+ - `docs/canvases/` is empty or missing, AND
107
+ - `docs/roadmaps/` is empty or missing, AND
108
+ - `state/markers/temperance/` is empty or missing
109
+
110
+ When cold, jump straight to Step 7d. Skip Steps 1-6. The cold-repo output uses plain adopter vocabulary — no "parent-goal thread", no "orientation gates", no "roadmap reconcile", no "tier taxonomies". A cold adopter has no model for those words yet.
111
+
112
+ Routing hint for cold adopters points at the build path:
113
+
114
+ > New here? Try `/stage` for a clickable mock of your idea, `/launch` for a full variant gallery, or `/build` to ship against an existing spec. These let you see something real on your screen before learning the deeper surface area.
115
+
116
+ When warm (any of the four signals present), continue to Step 1.
117
+
103
118
  **Step 1** — Orientation gates. Check `state/markers/orientation-gate/<branch-slug>.marker`. Check `state/markers/roadmap-reconcile-gate/<branch-slug>.marker`. When either is missing on a feature branch, refuse Step 7. Point at the BLOCKED block. On main this step is silent.
104
119
 
105
120
  **Step 2** — Walk the parent chain before reading leaf state. Read the active goal's parent_drivers via `state_iteration_bet_active`. Walk up to parent_bet when present. Walk further until parent_goal is null. Read parent_roadmap when any goal in the chain has one. Fetch its `last_event` and `next_pending` via `state_roadmap_get`. Surface active goal plus parent goal plus parent roadmap plus combined parent_drivers.
@@ -177,11 +192,17 @@ Instead of refusing to render, `/sprint` reads three fallback sources:
177
192
 
178
193
  From these sources, propose 3 candidate options in the same card + scan-table shape (Step 7c). Cite the source per option — for example, "From your open issues #NNN + recent commits on `<area>`". The value-prop per option comes from what the source itself says, not from a strategic doc.
179
194
 
180
- End with a plain-English hint pointing the adopter at ways to sharpen future runs:
195
+ End with two plain-English hints. The first points the adopter at the build path — the fastest route from idea to something on screen:
196
+
197
+ > New here? Try `/stage` for a clickable mock, `/launch` for a full variant gallery, or `/build` to ship against an existing spec. These let you see something real on your screen before learning the deeper surface area.
198
+
199
+ The second hint points at ways to sharpen future runs:
200
+
201
+ > Want sharper option proposals from `/sprint` later? Author strategic docs first — `/lean-canvas` (business model), `/spec` (buildable spec), or `/user-stories` (backlog shape). These feed `/sprint` on future calls.
181
202
 
182
- > Want sharper option proposals next time? Author strategic docs first — `/lean-canvas` (business model), `/spec` (buildable spec), or `/user-stories` (INVEST backlog). These feed `/sprint` on future calls.
203
+ Both hints are opt-in. The adopter does NOT need to author strategic docs to get value from this call. This mirrors `/onboard-repo` Path B "greenfield-from-intent" — the skill produces useful output on its first fire, and hints at deeper flows without gating on them.
183
204
 
184
- The fallback is opt-in on the hint side. The adopter does NOT need to author strategic docs to get value from this call. This mirrors `/onboard-repo` Path B "greenfield-from-intent" — the skill produces useful output on its first fire, and hints at deeper flows without gating on them.
205
+ Note per Sam PDF cure (bassclef-upstream#2009): the first hint takes precedence over the second. Sam's bounce rule is that unfamiliar vocabulary at first mention causes exit. The build path uses adopter-vocab (`/stage`, `/launch`, `/build`); the strategic-docs path uses deeper vocab (`/lean-canvas`, `/user-stories`). First hint fires first.
185
206
 
186
207
  Note per risk ledger R2: production fixture harness for this fallback path uses a brownfield fixture (no canvas, no whereami) so the fallback runs under test. Adding that fixture ships as a follow-on when the fallback surface gets its first Tier 0 test.
187
208
 
@@ -82,7 +82,9 @@ State these five lines after the checklist:
82
82
  - **What you are NOT doing** — the temptations you resist.
83
83
  - **Verification plan** — how you will know it works.
84
84
 
85
- Then write the gate marker. BOTH the ephemeral flag AND the durable git-tracked marker. The pre-build-gate hook accepts either. The durable marker lets the 5-session compliance counter see mobile firings that would evaporate at sandbox teardown.
85
+ Then write the gate marker. BOTH the ephemeral flag AND the durable marker. The pre-build-gate hook accepts either. The durable marker lets the 5-session compliance counter see mobile firings that would evaporate at sandbox teardown.
86
+
87
+ <!-- FKGL-EXEMPT: bash command block; shell commands are not graded prose. F6 cure per bassclef-upstream#2175 Batch B wraps git add in check-ignore guard. -->
86
88
 
87
89
  ```bash
88
90
  BRANCH=$(git branch --show-current)
@@ -93,13 +95,22 @@ SESSION_ID=${CLAUDE_SESSION_ID:-$$}
93
95
  # Ephemeral flag (existing pre-build-gate contract)
94
96
  touch "/tmp/claude-temperance-done-${SESSION_ID}-${BRANCH_HASH}"
95
97
 
96
- # Durable git-tracked marker
98
+ # Durable marker (gitignore-aware per F6 cure)
97
99
  mkdir -p state/markers/temperance
98
100
  date -u +%Y-%m-%dT%H:%M:%SZ > "state/markers/temperance/${BRANCH_SLUG}.marker"
99
- git add "state/markers/temperance/${BRANCH_SLUG}.marker"
101
+
102
+ # F6 cure (bassclef-upstream#2175 Batch B) — skip git add when the path is
103
+ # ignored. Adopter repos vary on whether state/markers/ is tracked. The marker
104
+ # write stays unconditional (local file always). The stage runs only when the
105
+ # path is tracked.
106
+ if ! git check-ignore -q "state/markers/temperance/${BRANCH_SLUG}.marker" 2>/dev/null; then
107
+ git add "state/markers/temperance/${BRANCH_SLUG}.marker"
108
+ fi
100
109
  ```
101
110
 
102
- The durable marker commits with the branch's normal flow. `state/markers/` is git-tracked per `.claude/rules/mobile-ephemeral-session.md` section 2.
111
+ <!-- /FKGL-EXEMPT -->
112
+
113
+ The durable marker always lands as a local file. The git stage runs only when the adopter repo tracks `state/markers/`. Per `.claude/rules/mobile-ephemeral-session.md` section 2 and `.claude/rules/session-artifacts.md` posture note.
103
114
 
104
115
  Then proceed with the work.
105
116
 
@@ -13,6 +13,8 @@ description: A shared substrate for working with AI coding agents.
13
13
 
14
14
  **A shared substrate for working with AI coding agents.** Install it once into your repo, and every Claude Code session starts loaded: skills you invoke, rules the agent reads, specialist agents you dispatch, practitioner profiles it designs against, hooks that catch mistakes, plus the standards and decision records that wire them together.
15
15
 
16
+ **What lands on disk.** Bassclef installs its working files under `.claude/`, plus one project-state document at `docs/whereami.md`, a config at `substrate.config.md`, and a `CLAUDE.md` that loads them. Most of these are bassclef's own files — you normally don't edit them. Your own code is untouched.
17
+
16
18
  Run `/skills` or `/luminary` in any session to see exactly what your install carries. The counts differ by tier, so this README does not print them.
17
19
 
18
20
  The agent reads your rules, knows the catalog, handles failure cleanly, and ships with discipline. You stop re-explaining your conventions every session — the difference between an assistant you brief and a band that already knows the set.
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "v1.8.0",
3
- "marker_tag": "release-2026-10-06-a874c748",
4
- "release_date": "2026-10-06T20:56:57Z",
5
- "release_sha": "a874c748",
6
- "release_tag": "v1.8.0"
2
+ "version": "v1.11.0",
3
+ "marker_tag": "release-2026-10-17-fcf192d8",
4
+ "release_date": "2026-10-17T23:16:18Z",
5
+ "release_sha": "fcf192d8",
6
+ "release_tag": "v1.11.0"
7
7
  }