Skip to content

v1.9.9 — Kunal adopter cures bundled

Choose a tag to compare

@kingofrock kingofrock released this 03 Oct 13:35
· 144 commits to main since this release
32976ab

v1.9.9 — Kunal adopter cures bundled

Credit: Reported by Kunal V., adopter at @thebassclef/lite. Thank you for the 10-finding report that drove bassclef release 2026-10-03-89ceaa15 (upstream tag v1.7.0). cli v1.9.9 bundles 8 of those 10 cures into the shipped substrate.


Problem (≤500 chars): cli v1.9.8 bundled bassclef v1.6.5 substrate. Kunal V. filed 10 findings in bassclef-upstream#2036 after his first adopter session — 8 are hard blocks or active harm (auto-save pushing /Users/<name>/ paths to git, zsh wiping PATH on every state-reading skill, /build returning zero steps on template-authored specs). bassclef release-2026-10-03-89ceaa15 fixed 8 of 10. cli#295 pulls that release into dist/lite/ so npm adopters land on cured substrate.


Goal

Pull bassclef v1.7.0 into cli's shipped substrate. Preserve the per-finding RCA shape so downstream readers see one audit-visible chain per Kunal finding across every surface (upstream PR body + cli release notes + bassclef-web changelog).

What ships

  • Bump .github/workflows/publish.yml bassclef pin v1.6.5 → v1.7.0 across 3 refs (L136 + L151 tag-assert + L281; L152 error prose matches).
  • dist/lite/ rebuild via prepublishOnly picks up cured substrate at publish time.
  • Pre-mortem light ledger at docs/risk-ledgers/2026-10-03b-cli-295-bundle-sync.md (Linus + Nygard + Saltzer-Schroeder).

Cures inherited — per Kunal finding

Each cure is authored upstream; cli ships the bundle. See upstream PR body for full implementation detail — bassclef-upstream#1523.

#1 Trace-log privacy leak (upstream PR #2041)

  • Symptom (what Kunal saw): trace.log files committed to his adopter repo carried /Users/kunal/... paths; auto-save push surfaced these to git history.
  • Root cause (upstream): 3 compounding gaps — adopter template .gitignore lacked docs/sdlc-traces/; trace-helper.sh logged absolute paths; save-state.sh ran no leak check before commit.
  • Fix (bundled in v1.7.0): trace_log() now strips repo root via _trace_repo_root() helper; lib/identifier-leak-check.sh sources before git commit in save-state.sh; shipped .gitignore adds docs/sdlc-traces/.
  • cli verification: grep -c "sanitize\|/Users/" dist/lite/.claude/hooks/trace-helper.sh returns > 0 after bundle rebuild. ls dist/lite/lib/identifier-leak-check.sh resolves.

#2 /build Phase 1 awk range (upstream PR #2043)

  • Symptom: /build on any template-authored spec returned zero steps.
  • Root cause: awk range /^## Steps enumerated/,/^## / closed on its own start line because ^## matches ^## Steps enumerated.
  • Fix (bundled in v1.7.0): flag-based extractor accepts both Steps and Workunits heading forms during ADR-040 D1 grace window.
  • cli verification: grep -c "Steps\\|Workunits" dist/lite/.claude/skills/build/SKILL.md > 0 after bundle rebuild.

#3 Template heading mismatch (upstream PR #2043)

  • Symptom: Combined with #2 — template said ## Workunits enumerated while SKILL expected ## Steps enumerated.
  • Root cause: ADR-040 D1 renamed WU → step in prose but missed templates/spec-template.md.
  • Fix (bundled in v1.7.0): template heading renamed to ## Steps enumerated; SKILL regex accepts both forms during grace window.
  • cli verification: grep -c "## Steps enumerated" dist/lite/templates/spec-template.md > 0 after bundle rebuild.

#4 SKIP_* env-reach override recipes (upstream PR #2042)

  • Symptom: SKIP_FOO=1 git commit ... recipe from BLOCK banners did not bypass the hook.
  • Root cause: PreToolUse Bash hooks run in Claude Code's process env; inline SKIP_FOO=1 <cmd> sets the var in git's subshell, not the hook's env.
  • Fix (bundled in v1.7.0): lib/skip-env-inline-check.sh parses tool_input.command for inline prefix + falls back to process env. Applied across 6 PreToolUse Bash hooks.
  • cli verification: ls dist/lite/lib/skip-env-inline-check.sh resolves after bundle rebuild.

#5 Shipped example path triggered own CCF-3 guard (upstream PR #2042)

  • Symptom: Operator-path guard fired on a verbatim /Users/kunal/... example in a shipped install guide.
  • Root cause: Example path in presence/install/schedule-auto-save.taskscheduler.md matched the CCF-3 regex. The guard fired correctly; the shipped content was the defect.
  • Fix (bundled in v1.7.0): rewrote the example as prose — removed the literal /Users/<name>/ pattern.
  • cli verification: grep -c "/Users/" dist/lite/presence/install/schedule-auto-save.taskscheduler.md returns 0 after bundle rebuild.

#6 zsh PATH kill (upstream PRs #2043 + #2045)

  • Symptom: Any state-reading skill failed silently (commands not found) when lib/state.sh sourced from zsh.
  • Root cause: zsh ties path and PATH as linked variables. local path="..." wiped PATH for function scope under zsh (invisible under bash).
  • Fix (bundled in v1.7.0, two upstream PRs):
    • PR #2043: renamed local path= → local p= across 7 functions in lib/state.sh
    • PR #2045: closed the full class across 10 more lib files (24 more occurrences)
  • cli verification: grep -rn "local path=" dist/lite/lib/*.sh returns 0 after bundle rebuild.

#9 Free-tier GitHub branch-protection docs (upstream PR #2044)

  • Symptom: /onboard-repo Phase 1.2 hit HTTP 403 on free-tier private repos with no fallback path documented.
  • Root cause: SKILL assumed gh api always succeeds (authored against Pro-tier accounts).
  • Fix (bundled in v1.7.0): three paths documented before the API call (make public, upgrade, skip local); fallback writes .claude/onboard-notes.md marker.
  • cli verification: grep -c "upgrade\\|public\\|local-only" dist/lite/.claude/skills/onboard-repo/SKILL.md > 0 after bundle rebuild.

/temperance + /luminary + /loop discipline

  • /temperance fired at feature/295-bundle-sync-v1.7.0 branch kickoff. Scope — bundle sync via semver pin (v1.6.5 → v1.7.0); not SHA. Drift trigger — any additional ref beyond L136/L151/L281, or build parity failure.
  • /luminary primary lens linus-torvalds — adopter contract preserved via semver pin (v1.7.0, not SHA fallback). Supporting lenses michael-nygard + saltzer-schroeder ran through pre-mortem light (3 lenses × 5 risks; ledger at docs/risk-ledgers/2026-10-03b-cli-295-bundle-sync.md).
  • /loop iteration count 1. Outcome — RED then GREEN. Pin shift (SHA → semver) folded mid-prep when peer bassclef-upstream-d3 surfaced v1.7.0 tag; 5 SHA-pin risks (L1-L5) dissolved; semver path preserved cleanly.

Test plan

  • npm run build passes.
  • npm run prepublish-bundle-substrate.mjs (or prepublishOnly lifecycle) rebuilds dist/lite/ against upstream v1.7.0.
  • Verify dist/lite/ carries cures — grep sanitize code in trace-helper, grep identifier-leak-check.sh exists, grep skip-env-inline-check.sh exists.
  • npm test passes (vitest suite GREEN).
  • npm run typecheck passes.
  • CI docker-smoke on v1.9.9 npm package exit 0 or exit 3 (expected-detection class per prior pattern).
  • Publish workflow armed; Touch ID at npm-publish env gate.
  • npm view @thebassclef/lite dist-tags.latest reports 1.9.9 within ~3 minutes of publish.

Out of scope

  • Driver authoring for cli#294 (5 adopter-regression smoke drivers against post-cure substrate) — deferred to next session per plan doc Step 2-6.
  • Kunal findings #7 + #8 + #10 — upstream Slot 5-6 in docs/next-session-plan-2026-10-04-kunal-slots-5-6.md.
  • bassclef-web docs-gen shape alignment — upstream ticket candidate per peer message.

Refs

  • Umbrella: bassclef-upstream#2036 (10 findings, 8 shipped in v1.7.0, 3 open)
  • Upstream release: bassclef-upstream PR #1523 (squash-merged 2026-10-03T11Z at commit 6bc46199; tagged v1.7.0)
  • cli ticket: cli#295 (closed by this PR)
  • Parent: cli#294 (driver authoring; resumes next session)
  • RCA-tracking spec: bassclef-upstream#2039