@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.
- package/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.claude/agents/builder.md +7 -4
- package/dist/lite/.claude/bassclef-orientation.md +22 -0
- package/dist/lite/.claude/hooks/artifact-ingestion-gate.sh +11 -3
- package/dist/lite/.claude/hooks/assert-verify-steering.sh +1 -19
- package/dist/lite/.claude/hooks/plain-english-steering.sh +86 -41
- package/dist/lite/.claude/hooks/pre-commit-gate.sh +10 -2
- package/dist/lite/.claude/hooks/pre-push-shellcheck.sh +144 -0
- package/dist/lite/.claude/hooks/reviewer-dispatch-check.sh +153 -0
- package/dist/lite/.claude/hooks/session-reflection.d/83-install-written-paths-rebuild.sh +15 -32
- package/dist/lite/.claude/hooks/turn-prose-density-measure.sh +109 -0
- package/dist/lite/.claude/hooks/turn-prose-kiss-check.sh +28 -0
- package/dist/lite/.claude/rules/branching.md +2 -0
- package/dist/lite/.claude/rules/identifier-leak-prevention.md +2 -1
- package/dist/lite/.claude/rules/lite-manifest-schema-change-discipline.md +23 -0
- package/dist/lite/.claude/rules/reviewer-dispatch.md +95 -0
- package/dist/lite/.claude/settings.json +10 -0
- package/dist/lite/.claude/skills/build/SKILL.md +81 -6
- package/dist/lite/.claude/skills/eisenhower/SKILL.md +26 -0
- package/dist/lite/.claude/skills/launch/SKILL.md +45 -2
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +204 -40
- package/dist/lite/.claude/skills/onboard-repo/concise-prompt.sh +73 -0
- package/dist/lite/.claude/skills/onboard-repo/write-state-marker.sh +81 -0
- package/dist/lite/.claude/skills/pre-mortem/SKILL.md +56 -0
- package/dist/lite/.claude/skills/sprint/SKILL.md +24 -3
- package/dist/lite/.claude/skills/temperance/SKILL.md +15 -4
- package/dist/lite/README.md +2 -0
- package/dist/lite/bassclef-version.json +5 -5
- package/dist/lite/lib/install-written-paths.sh +250 -3
- package/dist/lite/lib/prose-marker.sh +203 -0
- package/dist/lite/lib/tier-dependency-audit.sh +52 -25
- package/dist/lite/presence/install/bassclef-sync.template.sh +86 -8
- package/dist/lite/scripts/generate-lite-manifest.sh +15 -0
- package/dist/lite/scripts/launch/local-serve.sh +149 -8
- package/dist/lite/standards/bassclef-wiring-manifest.json +12 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +49 -0
- package/dist/lite/standards/lite-manifest.json +90 -27
- package/dist/lite/standards/prose-marker-format.md +105 -0
- 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 —
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
package/dist/lite/README.md
CHANGED
|
@@ -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.
|
|
3
|
-
"marker_tag": "release-2026-10-
|
|
4
|
-
"release_date": "2026-10-
|
|
5
|
-
"release_sha": "
|
|
6
|
-
"release_tag": "v1.
|
|
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
|
}
|