Skip to content

Commit d8f25e4

Browse files
chore(claude): add safer SessionStart hook (package-manager installs, no piped scripts) (#31)
Adds .claude/hooks/session-start.sh — best-effort, idempotent SessionStart hook provisioning reuse/shellcheck/asciidoctor via package managers only (no piped remote script; the curl-piped variant was safety-blocked). Wired into settings.json, .claude/hooks/ re-tracked in .gitignore, noted in CHANGELOG. shellcheck clean; valid JSON; reuse compliant; estate-rules green (validated locally). Refs ADR-0005.
1 parent e67daa7 commit d8f25e4

4 files changed

Lines changed: 45 additions & 6 deletions

File tree

.claude/hooks/session-start.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: MPL-2.0
3+
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
4+
#
5+
# SessionStart hook for Claude Code on the web. Best-effort and idempotent:
6+
# ensures the lint/compliance tools this repo's checks rely on are present so
7+
# a fresh session can run scripts/check-*.sh and `reuse lint` without manual
8+
# setup.
9+
#
10+
# Installs ONLY via standard package managers (pip / apt / gem) — there is
11+
# deliberately no piped remote script (no `curl ... | bash`). Never blocks a
12+
# session: each step is guarded by a `command -v` probe and trails `|| true`.
13+
set -u
14+
15+
note() { printf '[session-start] %s\n' "$*"; }
16+
17+
command -v reuse >/dev/null 2>&1 || { note "installing reuse (pip)"; pip install --quiet reuse >/dev/null 2>&1 || true; }
18+
command -v shellcheck >/dev/null 2>&1 || { note "installing shellcheck (apt)"; apt-get install -y shellcheck >/dev/null 2>&1 || true; }
19+
command -v asciidoctor >/dev/null 2>&1 || { note "installing asciidoctor (gem)"; gem install --silent asciidoctor >/dev/null 2>&1 || true; }
20+
21+
have() { command -v "$1" >/dev/null 2>&1 && echo y || echo n; }
22+
note "tooling present: reuse=$(have reuse) shellcheck=$(have shellcheck) asciidoctor=$(have asciidoctor)"
23+
note "(the 'just' task runner is not auto-installed here; add it manually if you want recipe shortcuts)"
24+
exit 0

.claude/settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,17 @@
1515
"Bash(just doctor:*)",
1616
"Bash(jq:*)"
1717
]
18+
},
19+
"hooks": {
20+
"SessionStart": [
21+
{
22+
"hooks": [
23+
{
24+
"type": "command",
25+
"command": "bash .claude/hooks/session-start.sh"
26+
}
27+
]
28+
}
29+
]
1830
}
1931
}

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ Thumbs.db
1414
# Agent & editor scaffolding (standards#68) — local-only, never committed
1515
# estate-wide. Owner decision 2026-05-16: gitignore per-repo agent/editor
1616
# config rather than commit it. Updated 2026-05-30: the *shared* Claude
17-
# config (.claude/settings.json) is now tracked so sessions share a safe
18-
# permission allowlist; personal local overrides (e.g.
19-
# .claude/settings.local.json) stay ignored.
17+
# config (.claude/settings.json + .claude/hooks/) is now tracked so sessions
18+
# share a permission allowlist and a best-effort tool-provisioning hook;
19+
# personal local overrides (e.g. .claude/settings.local.json) stay ignored.
2020
.editorconfig
2121
.claude/*
2222
!.claude/settings.json
23+
!.claude/hooks/
2324

2425
# Build
2526
/target/

CHANGELOG.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- `LICENSES/` directory (MPL-2.0, AGPL-3.0-or-later) and a root `REUSE.toml`
1515
declaring licensing for owner-authored files. The project is now fully
1616
compliant with version 3.3 of the REUSE Specification (`reuse lint` passes).
17-
- Claude Code project config (`.claude/settings.json`): a permission allowlist
18-
for the safe git / reuse / shellcheck / estate-rules commands used to
19-
validate this repo, reducing prompts in future sessions.
17+
- Claude Code project config under `.claude/`: a permission allowlist for the
18+
safe git / reuse / shellcheck / estate-rules commands used to validate this
19+
repo, plus a best-effort SessionStart hook that provisions the lint tooling
20+
(reuse, shellcheck, asciidoctor) via package managers — no piped remote
21+
scripts.
2022

2123
### Changed
2224
- Repaired the V-language ban check in the `estate-rules` workflow: a

0 commit comments

Comments
 (0)