Skip to content

Wire cloud session guards via environment setup script#4

Merged
dougbreden merged 10 commits into
mainfrom
claude/cloud-brain-load-test-4dlzrv
Jul 10, 2026
Merged

Wire cloud session guards via environment setup script#4
dougbreden merged 10 commits into
mainfrom
claude/cloud-brain-load-test-4dlzrv

Conversation

@dougbreden

Copy link
Copy Markdown
Owner

Summary

Enables the safety guards (security-pretooluse.js and guard-main.js) to activate in fresh cloud/phone Claude Code sessions via an environment setup script, complementing the committed-vendor route (ADR-001) with a per-environment alternative (ADR-002). A fresh cloud session now achieves full parity with local bootstrap — payload, skills, commands, and both PreToolUse guards all present and active same-session.

Key Changes

  • hooks/merge-cloud-hooks.js (new) — derives all PreToolUse guards from the canonical tools/claude/settings.json, remaps each hook's command to the clone's absolute path, and merges them idempotently into ~/.claude/launcher-settings.json (the env's live hook surface). Fitness test asserts the wired hook set cannot drift from the source of truth.

  • hooks/merge-cloud-hooks.test.js (new) — comprehensive zero-dep Node test suite validating:

    • Fresh target gains both declared guards with correct matchers and remapped commands
    • Wired hook set equals the canonical set (no drift)
    • Guards actually deny: security-pretooluse blocks rm -rf ~/testdir; guard-main blocks main-branch force-push but allows feature-branch
    • Merge preserves infra hooks and is idempotent
  • hooks/secure-repo.js (refactored) — extracted mergePreToolUseHook(settingsPath, { matcher, command }) as a generic hook-merge function (used by both committed-vendor and env-setup routes), keeping the committed-vendor mergeSettings() as a thin wrapper. Dedup now works by hook basename, so any hook (security, guard-main, etc.) merges idempotently.

  • bootstrap.sh — added --no-plugins flag to skip external plugin provisioning (installs don't activate same-session in cloud and aren't agent-rules core). Enables the env setup script to run bootstrap.sh --no-plugins for payload without plugin overhead.

  • ADR-002 (new) — documents the environment setup script route, corrects ADR-001's alternative-(c) rejection (a malformed-probe confound; the real guard fires same-session), and establishes the two routes as complementary: per-environment (ADR-002) vs. per-repo (ADR-001).

  • docs/learnings/multi-repo-brain.md (new) — consolidated finding on which config surfaces cloud sessions read: global memory (account-synced AGENTS.md/CLAUDE.md) ✅, skills ✅, commands ✅, and a setup-script-merged PreToolUse guard ✅. Includes the production setup script and test evidence.

  • docs/ROADMAP.md — marked milestone 8 (cloud bootstrap parity) complete; updated milestone 9 (commit skill) to reflect autonomous commits within a slice.

  • docs/adr/cloud-brain-load.md (ADR-001) — updated status to accepted, refined context to reflect the empirical finding that cloud reads ~/.claude global memory (not operator's skills/hooks), and amended alternative-(c) to note the guard-via-setup-script correction.

  • docs/plans/slice-stacking-workflow.md (new) — backlog note on a minimal prompt pattern for milestone-first slice-stacking (plan the stack, get approval, run to completion). Captured from a working session; flagged for later evaluation.

  • docs/plans/cloud-pull-trigger.md and docs/plans/traveling-security.md — minor updates reflecting the 2026-07-06 empirical findings.

Implementation Details

  • Single source of truth: The set of PreToolUse hooks is derived from tools/claude/settings.json (the canonical local wiring). Add or remove a hook there once and it flows to both local (bootstrap) and cloud (merge-cloud-hooks) — the wiring cannot drift. A fitness test asserts the two hook sets stay equal.

  • **Idempot

https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN

claude added 10 commits July 6, 2026 04:59
Cloud reads ~/.claude global memory (account-synced AGENTS.md/CLAUDE.md)
and a setup-script-provisioned ~/.claude/skills/, but does not honor a
setup-script ~/.claude/settings.json PreToolUse hook. Committed project
.claude/ stays the universal same-session surface, so committed-vendor is
accepted for the skill + Security hook and setup-script is a skills-only
supplement.

Refine the falsified M5.0 "never ~/.claude" premise and drop the
brain/organs metaphor in the ADR; note the same correction in
traveling-security.md and cloud-pull-trigger.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
Add docs/learnings/multi-repo-brain.md (fixes the dangling ADR-001 ref):
consolidates which config surface each session reads and the 2026-07-06
cloud measurements -- memory + skills load from a setup-script ~/.claude/,
the safety hooks do not (settings.json ignored; launcher-settings.json is
the env surface). Records the recommended setup script and the two
operator tests that close the milestone.

Roadmap: add "cloud bootstrap parity" as an in-progress milestone with its
success bar; queue a post-milestone revisit of the commit-skill wrapper
(gates stay, wrapper is the open question); correct the stale "commits
only after approval" line to the autonomous-commit reality.
A fresh Claude Code cloud session honors ~/.claude/launcher-settings.json
for hooks, not a setup-script ~/.claude/settings.json. merge-cloud-hooks.js
wires the Security PreToolUse deny-list into that surface so an environment
setup script can guard a fresh session the way bootstrap.sh guards a local
machine.

Reuses secure-repo.js's idempotent, non-clobbering merge -- refactored to
export mergePreToolUseHook(settingsPath, {matcher, command}) so the
committed-vendor route and the cloud route share one merge. Preserves infra
SessionStart/Stop hooks; command points at this clone's guard.

Tooling for the cloud-bootstrap hooks decider test. Adds
merge-cloud-hooks.test.js; secure-repo.test.js stays green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
Record the milestone-first, stack-then-run prompt pattern (from a Copilot
CLI session) as a backlog note to evaluate later, plus a ROADMAP bullet.
Frames the delta vs AGENTS.md workflow and the question of whether a
minimal wording earns a place -- explicitly not a framework to build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
Cloud/headless runs should not trigger claude plugin install for external
marketplaces -- those installs do not activate same-session there and are
not agent-rules core. --no-plugins gates wire_claude_plugins so the cloud
setup script (clone + bootstrap --no-plugins + merge-cloud-hooks) runs clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
The 2026-07-06 decider settled it: a setup script that merges the real
security-pretooluse.js into ~/.claude/launcher-settings.json activates the
guard in a fresh cloud session (rm -rf ~/testdir BLOCKED; both surfaces
survived launch). The earlier "settings.json hook doesn't fire" was a
malformed-probe confound, not an unread surface.

ADR-002 records the per-environment guard route and amends ADR-001's alt (c)
rejection; ADR-001 keeps its committed-vendor decision as the per-repo route.
Corrects the learnings parity matrix, finalizes the production setup script,
and advances ROADMAP #8 (cloud bootstrap parity essentially met).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
merge-cloud-hooks.js now DERIVES every PreToolUse hook from the canonical
tools/claude/settings.json and remaps each command to the clone's path, so
both guards -- security-pretooluse and guard-main -- ride
~/.claude/launcher-settings.json in a fresh cloud session (previously only
security). Single source of truth: add a hook to settings.json once and it
reaches local and cloud; a fitness test asserts the two hook sets stay equal.

Generalizes secure-repo.js's merge to dedup by hook basename (was hardcoded
to security-pretooluse); secure-repo.test.js unchanged and green. Extends
merge-cloud-hooks.test.js with guard-main wiring, behavior, and the drift
fitness check. Updates learnings + ROADMAP #8.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
A fresh cloud session on the production setup script confirmed full parity:
AGENTS.md loaded (quoted its first Behavior bullet), agent-rules skills + the
/status command listed, and rm -rf ~/testdir blocked by the guard. Marks
ROADMAP #8 done and records the 2026-07-10 smoke in the learnings doc; the
subagents leg is n/a (agents/ is empty).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
main (PR #1) generalized secure-repo.js to vendor both guards via a GUARDS
array; this branch added the cloud route (merge-cloud-hooks.js). Reconciled
by extracting one shared mergeGuards(settingsPath, commandFor) driven by
GUARDS, used by BOTH routes: the committed-vendor route (repo .claude/
settings.json, $CLAUDE_PROJECT_DIR command) and the cloud route
(~/.claude/launcher-settings.json, absolute clone-path command).

GUARDS is now the single source of truth; the cloud test's fitness check
cross-verifies it against tools/claude/settings.json. Also folds in main's
new skills (teach, skill-scout, handoff) and pr-for-review update. All engine
tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
Post-merge, merge-cloud-hooks.js reuses secure-repo.js's shared GUARDS +
mergeGuards rather than parsing tools/claude/settings.json; the fitness test
cross-checks GUARDS against settings.json. Fix the two docs that still said
"derives from settings.json".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012NtohUoqyy2LWZYsYi2SWN
@dougbreden dougbreden merged commit a8bbd35 into main Jul 10, 2026
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.

2 participants