Skip to content

feat!: review follow-ups: main's Claude setup for branch sessions, Bun floor, one config read - #89

Merged
jflavan merged 1 commit into
mainfrom
fix/review-followups
Oct 27, 2026
Merged

jflavan merged 1 commit into
mainfrom
fix/review-followups

Conversation

@jflavan

@jflavan jflavan commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Follow-ups from the /code-review high 88 list (items 1–5), plus fixes from a second review of this work.

What changes

  1. No bare Bash rule anywhere. Bash or Bash(*) would let a session run any git, so it's refused on every step's agent tools and in claude.allowed_tools. Name the commands instead, like Bash(make *).
  2. The Bun minimum is enforced. loopstra start and loopstra upgrade refuse a Bun older than engines.bun and say to run bun upgrade (upgrade --check reports it and carries on). A canary counts as its release version.
  3. One Bun version. .bun-version holds it and every setup-bun step reads it (bun-version-file). A test keeps engines.bun and the README in step with it. @types/bun goes to 1.4.4.
  4. Sessions in a branch's files get main's Claude Code setup, never the branch's. These are build, reconcile, fix, verify, review, early review and revise. They run with --setting-sources user (or "" with sources: repo), so the branch's .claude/settings.json, .mcp.json, CLAUDE.md, rules, skills, agents and commands don't load. main's versions are read from main's commit, never from a checkout a session could write, into a temporary folder for each session:
    • settings are merged under Loopstra's --settings;
    • CLAUDE.md and rules come in as a read-only --add-dir;
    • skills, agents and commands come in as the plugin project;
    • MCP servers come in through --mcp-config, leaving out any that settings disable.
  5. The config is read once per session. Model keys use the config the prompt was rendered from. Duplicated helpers are merged: readText, splitFrontmatter, TEAM_NAME, ITEM_NAME, once, readBlobs and dropEmptyMaps. Removing a step's agent settings no longer leaves agents: {} behind.

Breaking change

A config with a bare Bash rule in claude.allowed_tools now fails to load.

Known limits (in the README)

  • A hook or MCP server in main's settings that runs a script from the project runs the branch's copy.
  • main's CLAUDE.md files in subfolders, and files a CLAUDE.md imports from elsewhere, don't load in these sessions.
  • main's own settings can still disable Loopstra's hook or allow a bare Bash rule, as before.

Testing

  • bun run check: 1851 pass, 0 fail; typecheck, lint and deadcode are clean.
  • Live run against real Claude Code 2.1.311 (haiku) on a committed probe repo:
    • main's CLAUDE.md, rules, skill (project:alpha), env and MCP server loaded;
    • a CLAUDE.md changed on disk after the commit was not read;
    • the branch's hook didn't run;
    • no temporary folders were left behind.

🤖 Generated with Claude Code

…n floor, one config read

- A session in a branch's files (build, fix, verify, review, revise) no longer
  loads the branch's own Claude Code setup. Its settings, CLAUDE.md, rules,
  skills, agents, commands and MCP servers come from main's commit, written
  into a per-session folder, so a build can't change what later sessions in
  its step are told or allowed.
- A bare Bash rule (Bash, Bash(*)) is refused on every step and in
  claude.allowed_tools, since it would let a session run any git.
- `start` and `upgrade` refuse a Bun older than engines.bun and say to run
  `bun upgrade`. A canary counts as its release version.
- The Bun version lives only in .bun-version, which setup-bun reads; a test
  keeps engines and the README in step. @types/bun goes to 1.4.4.
- A session reads the config once: model keys use the config its prompt was
  rendered from.
- Shared helpers are deduplicated (readText, splitFrontmatter, TEAM_NAME,
  ITEM_NAME, once, readBlobs, dropEmptyMaps). Removing a step's agent
  settings no longer leaves `agents: {}` behind.

BREAKING CHANGE: a config whose claude.allowed_tools contains a bare Bash
rule (Bash or Bash(*)) now fails to load. Name the commands instead, like
Bash(make *).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jflavan
jflavan merged commit 8e53f3c into main Oct 27, 2026
13 checks passed
@jflavan
jflavan deleted the fix/review-followups branch October 28, 2026 02:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant