From 01d29c8eb03dc0b07b1599e1cc9f2aca5635491f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 04:20:03 +0000 Subject: [PATCH 1/2] chore: bootstrap Safe Chain in Claude Code web sessions Claude Code on the web does not run the devcontainer postCreateCommand or .cursor/environment.json, so web sessions started without Safe Chain shims or node_modules. Add a SessionStart hook that runs scripts/setup-cloud-environment.sh in remote sessions only and writes the shim PATH to CLAUDE_ENV_FILE, since Bash tool shells do not re-read ~/.bashrc. Track only .claude/settings.json and .claude/hooks/ (local Claude state stays ignored), add /.claude/ to CODEOWNERS, and note the bootstrap in SECURITY.md and DEFENSE_IN_DEPTH.md. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FDGkvwCeXMsedfFUjqSrn9 --- .claude/hooks/session-start.sh | 18 ++++++++++++++++++ .claude/settings.json | 15 +++++++++++++++ .github/CODEOWNERS | 1 + .gitignore | 6 ++++-- DEFENSE_IN_DEPTH.md | 1 + SECURITY.md | 2 +- 6 files changed, 40 insertions(+), 3 deletions(-) create mode 100755 .claude/hooks/session-start.sh create mode 100644 .claude/settings.json diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh new file mode 100755 index 0000000..b9a5e04 --- /dev/null +++ b/.claude/hooks/session-start.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# SessionStart hook for Claude Code on the web: bootstrap Aikido Safe Chain and +# install dependencies through its shims, as .devcontainer and .cursor do. +set -euo pipefail + +if [ "${CLAUDE_CODE_REMOTE:-}" != "true" ]; then + exit 0 +fi + +cd "$CLAUDE_PROJECT_DIR" + +# Hook stdout becomes session context; keep the install log on stderr. +bash ./scripts/setup-cloud-environment.sh >&2 + +# Bash tool shells do not re-read ~/.bashrc, so persist the shims for them. +if [ -n "${CLAUDE_ENV_FILE:-}" ] && ! grep -qsF ".safe-chain/shims" "$CLAUDE_ENV_FILE"; then + echo 'export PATH="$HOME/.safe-chain/shims:$HOME/.safe-chain/bin:$PATH"' >>"$CLAUDE_ENV_FILE" +fi diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..4098b04 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh", + "timeout": 600 + } + ] + } + ] + } +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8339057..4330fce 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,7 @@ # High-risk paths. Last matching pattern wins. # Root-anchored so nested copies (e.g. skills/**/scripts/) are not owned here. /.github/ @jaredwray +/.claude/ @jaredwray /.cursor/ @jaredwray /.devcontainer/ @jaredwray /scripts/ @jaredwray diff --git a/.gitignore b/.gitignore index 2fdb6df..188e3bb 100644 --- a/.gitignore +++ b/.gitignore @@ -79,8 +79,10 @@ bun.lockb site/dist site/README.md -# AI -.claude +# AI (keep the shared Claude Code settings and hooks; ignore local state) +.claude/* +!.claude/settings.json +!.claude/hooks/ test/fixtures/output.html diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 07fe8d8..a459533 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -11,6 +11,7 @@ Profile: npm library · public ## 2. CODEOWNERS and cloud bootstrap - [x] `.github/CODEOWNERS` covers `/.github/`, `/.cursor/`, `/.devcontainer/`, `/scripts/` with owners the maintainer names — PR #517 - [x] Codespaces and Cursor Cloud Agents bootstrap Aikido Safe Chain via scripts/setup-cloud-environment.sh (--ci shims, frozen lockfile) — PR #518 +- [x] Claude Code on the web runs the same bootstrap from a SessionStart hook (`.claude/hooks/session-start.sh`, web sessions only) and keeps the shims first on `PATH`; `/.claude/` is in CODEOWNERS ## 3. Dependencies (pnpm) - [x] `packageManager: pnpm@12.3.4` pinned in `package.json` — verified 2026-09-14 (`pnpm@12.3.4`) diff --git a/SECURITY.md b/SECURITY.md index 1757718..0002719 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -25,6 +25,6 @@ This repository follows the [defense-in-depth](https://github.com/jaredwray/agen - All changes land through pull requests. Direct pushes to `main` are blocked; merging requires the `tests (22)`, `tests (24)`, `tests (26)`, and `zizmor` checks. Tags can only be created by repository admins; published GitHub Releases are immutable. - CI runs with a read-only default workflow token; Actions cannot create or approve PRs. Workflow runs from outside collaborators require owner approval. Only GitHub-owned, verified, and allowlisted third-party actions can run. - Every action is pinned to a full commit SHA; Socket Firewall (`sfw`) wraps `pnpm install` / `npm install`; workflows are security-linted with zizmor on every PR. Secret scanning with push protection is enabled. -- Codespaces and Cursor Cloud Agents install through Aikido Safe Chain; package-manager shims must not be bypassed. +- Codespaces, Cursor Cloud Agents, and Claude Code on the web install through Aikido Safe Chain; package-manager shims must not be bypassed. - Dependencies install through pnpm with a 7-day cooldown on new versions, lifecycle scripts blocked by default, and `trustPolicy: no-downgrade`. CI installs with a frozen lockfile. Socket reviews every dependency change; Aikido scans every build. - npm releases are staged, never published directly: CI authenticates with **stage-only** OIDC trusted publishing (`pnpm stage publish` with provenance). Drydock reviews the staged artifact; a maintainer promotes with 2FA. The package requires 2FA and disallows tokens. From 3ee339ce38afd5180d42f5d9077b70df8366f480 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 04:20:32 +0000 Subject: [PATCH 2/2] docs: reference PR #553 in defense-in-depth tracking Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FDGkvwCeXMsedfFUjqSrn9 --- DEFENSE_IN_DEPTH.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index a459533..7af2892 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -11,7 +11,7 @@ Profile: npm library · public ## 2. CODEOWNERS and cloud bootstrap - [x] `.github/CODEOWNERS` covers `/.github/`, `/.cursor/`, `/.devcontainer/`, `/scripts/` with owners the maintainer names — PR #517 - [x] Codespaces and Cursor Cloud Agents bootstrap Aikido Safe Chain via scripts/setup-cloud-environment.sh (--ci shims, frozen lockfile) — PR #518 -- [x] Claude Code on the web runs the same bootstrap from a SessionStart hook (`.claude/hooks/session-start.sh`, web sessions only) and keeps the shims first on `PATH`; `/.claude/` is in CODEOWNERS +- [x] Claude Code on the web runs the same bootstrap from a SessionStart hook (`.claude/hooks/session-start.sh`, web sessions only) and keeps the shims first on `PATH`; `/.claude/` is in CODEOWNERS — PR #553 ## 3. Dependencies (pnpm) - [x] `packageManager: pnpm@12.3.4` pinned in `package.json` — verified 2026-09-14 (`pnpm@12.3.4`)