Skip to content

Commit 5ef98e5

Browse files
luiseimanclaude
andcommitted
release: v3.1.0 — domain knowledge sync + ask permissions
Watch-upstream pass against code.claude.com/docs (covers v2.1.70-2.1.109). Domain rules: - hook-architecture.md: 27 → 31 events, 3 lifecycle cadences, +InstructionsLoaded/Elicitation/PreCompact-blockable - hook-events.md: PreCompact blockability, MCP elicitation - permission-model.md: enterprise managed settings (managed-settings.d/, allowManagedHooksOnly, allowedChannelPlugins) + dynamic permissions API (addRules/replaceRules/setMode/addDirectories from hook output) - model-ids.md: default effort medium → high (v2.1.94) Template: - settings.json.tmpl: +ask: list (18 entries) for risky-but-legitimate commands (rm, chmod, npm/pip install, docker, k8s, gcloud/aws/terraform, git push/rebase) - block-destructive.sh: verified safe vs compound-bash bypass class fixed in v2.1.98 (uses grep -qiE over full command — catches `ls && rm -rf /` by design). Documented known limits + sandbox.enabled defense-in-depth. Practices: 8 accepted (inbox → active), 3 rejected (auto-stubs). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dfd77a4 commit 5ef98e5

19 files changed

Lines changed: 379 additions & 95 deletions

.claude/rules/domain/hook-architecture.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@
22
globs: "**/*.sh,**/settings.json,**/settings.json.partial"
33
description: "Hook system design patterns and safety requirements"
44
domain: claude-code-engineering
5-
last_verified: 2026-04-07
5+
last_verified: 2026-04-15
66
---
77

88
# Hook Architecture
99

10-
## Events (27 total, verified v2.1.92)
11-
12-
Core: SessionStart, SessionEnd, Stop, StopFailure
13-
Tool lifecycle: PreToolUse, PostToolUse, PostToolUseFailure
14-
User: UserPromptSubmit
15-
Permissions: PermissionRequest, PermissionDenied
16-
Elicitation: Elicitation, ElicitationResult
17-
Agent: SubagentStart, SubagentStop, TeammateIdle, TaskCreated, TaskCompleted
18-
Context: PreCompact, PostCompact, CwdChanged, FileChanged, InstructionsLoaded
19-
System: ConfigChange, Notification
20-
Worktree: WorktreeCreate, WorktreeRemove
10+
## Events (31 total, verified v2.1.108 — code.claude.com/docs/en/hooks)
11+
12+
Three lifecycle cadences:
13+
14+
**Session-level** (once per session): SessionStart, SessionEnd, InstructionsLoaded
15+
**Turn-level** (once per user prompt): UserPromptSubmit, Stop, StopFailure
16+
**Tool-loop** (every tool call): PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied
17+
**Async/side**: Notification, SubagentStart, SubagentStop, TaskCreated, TaskCompleted, TeammateIdle, ConfigChange, CwdChanged, FileChanged, WorktreeCreate, WorktreeRemove, PreCompact, PostCompact, Elicitation, ElicitationResult
18+
19+
`InstructionsLoaded` fires when CLAUDE.md or `.claude/rules/*.md` loads. `load_reason` field: `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact`. Observability-only — no decision control.
20+
21+
`PreCompact` is **blockable** since v2.1.105 (exit 2 prevents compaction). Was non-blocking before.
22+
23+
`Elicitation`/`ElicitationResult` fire during MCP tool execution when an MCP server requests structured user input. Support `accept`/`decline`/`cancel` actions and field overrides.
2124

2225
## Exit codes, types, and decisions
2326

.claude/rules/domain/hook-events.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
globs: "**/*.sh,**/settings.json"
33
description: "Hook event payloads and per-event behavior details"
44
domain: claude-code-engineering
5-
last_verified: 2026-04-07
5+
last_verified: 2026-04-15
66
---
77

88
# Hook Event Details
@@ -11,10 +11,11 @@ last_verified: 2026-04-07
1111

1212
- PostCompact command: `trigger` ("auto"/"manual") + `compact_summary` (full text)
1313
- PostCompact SDK: `compactType` + `messageCountBefore` + `messageCountAfter`
14-
- PreCompact: `compactType` + `messageCount`NON-BLOCKING, exit code ignored
14+
- PreCompact: `compactType` + `messageCount`**BLOCKABLE since v2.1.105** (exit 2 prevents compaction)
1515
- SessionStart `source`: "startup", "resume", "compact", "clear"
1616
- CwdChanged: fires on directory change, supports CLAUDE_ENV_FILE
1717
- FileChanged: fires on external file modification — use for auto-reload
18+
- InstructionsLoaded: fires when CLAUDE.md or `.claude/rules/*.md` loads. `load_reason`: `session_start` | `nested_traversal` | `path_glob_match` | `include` | `compact`. Observability-only, no decision control.
1819

1920
## Tool events
2021

@@ -33,3 +34,9 @@ last_verified: 2026-04-07
3334

3435
- SubagentStart: inject additionalContext into spawned subagent via stdout
3536
- TeammateIdle: fires when a team member has no pending work
37+
38+
## MCP elicitation events (v2.1.76+)
39+
40+
- Elicitation: fires when an MCP server requests structured user input mid-tool-call. Hook can return `action: "accept" | "decline" | "cancel"` and override field values via `content: {field: "new_value"}`
41+
- ElicitationResult: fires after the user (or hook) responds. Observability + audit
42+
- Combined with `disableSkillShellExecution` and managed settings, lets enterprises pre-validate MCP form submissions before they reach the server

.claude/rules/domain/model-ids.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
globs: "**/agents/*.md,**/CLAUDE.md"
33
description: "Model IDs and agent defaults for Claude Code subagent instantiation"
44
domain: claude-code
5-
last_verified: 2026-04-05
5+
last_verified: 2026-04-15
66
---
77

88
# Model IDs (April 2026)
@@ -15,5 +15,14 @@ last_verified: 2026-04-05
1515

1616
Default agents: opus → architect, security-auditor. sonnet → implementer, code-reviewer, session-reviewer. haiku → researcher, test-runner.
1717

18+
## Default effort (changed v2.1.94, 2026-04-07)
19+
20+
Global default is now `effort: high` (was `medium`). Implication:
21+
22+
- Skills/agents WITHOUT explicit `effort:` consume more tokens and run slower
23+
- Pin `effort: low` in `agents/researcher.md` and `agents/test-runner.md` to keep them cheap
24+
- Benchmark baselines computed before 2026-04-07 are no longer comparable
25+
- For deterministic transformations (rename, reformat) explicit `effort: low` is recommended
26+
1827
> Claude 3 Haiku deprecated — retiring April 19, 2026. Use claude-haiku-4-5 only.
1928
> Update this table when Anthropic releases new model versions.

.claude/rules/domain/permission-model.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
globs: "**/settings.json,**/settings.local.json,**/settings.json.partial"
33
description: "Permission modes, evaluation cascade, deny list requirements"
44
domain: claude-code-engineering
5-
last_verified: 2026-04-05
5+
last_verified: 2026-04-15
66
---
77

88
# Permission Model
@@ -32,6 +32,38 @@ last_verified: 2026-04-05
3232

3333
Managed (enterprise) > Local (.claude/settings.local.json) > Project (.claude/settings.json) > Global (~/.claude/settings.json)
3434

35+
## Enterprise managed settings (v2.1.83+)
36+
37+
- `managed-settings.d/` drop-in directory: every `*.json` inside merges with the main `managed-settings.json`. Lets ops ship modular policy files.
38+
- `allowManagedHooksOnly: true` — blocks ALL user/project/plugin hooks. Only managed-scope hooks (and hooks from plugins force-enabled by managed settings) run. Under this policy `.claude/hooks/` is inert at runtime — audit scoring should reflect runtime applicability, not file presence.
39+
- `allowedChannelPlugins` — restricts which plugins activate via `--channels`.
40+
- `forceRemoteSettingsRefresh` — fail-closed: blocks startup until remote settings fetched (v2.1.92).
41+
42+
## Dynamic permissions from hooks (v2.1.84+)
43+
44+
`PreToolUse` and `PermissionRequest` hooks can mutate runtime permission state via JSON output:
45+
46+
```json
47+
{
48+
"hookSpecificOutput": {
49+
"decision": {
50+
"behavior": "allow|deny",
51+
"updatedInput": { "...": "..." },
52+
"updatedPermissions": [
53+
{ "type": "addRules", "rules": ["Bash(make *)"] },
54+
{ "type": "replaceRules", "rules": ["..."] },
55+
{ "type": "removeRules", "rules": ["..."] },
56+
{ "type": "setMode", "mode": "auto|default|plan|acceptEdits" },
57+
{ "type": "addDirectories", "directories": ["/tmp/build"] },
58+
{ "type": "removeDirectories", "directories": ["..."] }
59+
]
60+
}
61+
}
62+
}
63+
```
64+
65+
Use cases: a behavior self-elevates its allowlist for a session, a safety hook downgrades to `plan` mode after detecting risk, or a build hook whitelists a temporary directory. Static deny rules still enforce — a hook cannot remove a managed deny.
66+
3567
## Bash prefix detection
3668

3769
- Separate LLM call (fast model) extracts command prefixes

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.4
1+
3.1.0

docs/changelog.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
>
55
> Historial de versiones. Las entradas usan español/inglés mixto según la evolución del proyecto. Los términos técnicos son universales.
66
7+
## v3.1.0 (2026-04-15)
8+
9+
### Domain knowledge sync — Claude Code v2.1.108
10+
11+
Watch-upstream pass against `code.claude.com/docs` (covers v2.1.70 → v2.1.109). Eight practices accepted, three rejected (auto-stubs).
12+
13+
#### Domain rule updates
14+
15+
- `domain/hook-architecture.md` — events count corrected 27 → **31**, restructured around three lifecycle cadences (session-level, turn-level, tool-loop, async/side). Added `InstructionsLoaded` (with `load_reason` field), `Elicitation`/`ElicitationResult`, and `PreCompact` blockability since v2.1.105.
16+
- `domain/hook-events.md``PreCompact` flagged as blockable, `InstructionsLoaded` payload documented, new MCP elicitation events section.
17+
- `domain/permission-model.md` — new sections: **Enterprise managed settings** (`managed-settings.d/`, `allowManagedHooksOnly`, `allowedChannelPlugins`, `forceRemoteSettingsRefresh`) and **Dynamic permissions from hooks** (`addRules`/`replaceRules`/`removeRules`/`setMode`/`addDirectories`/`removeDirectories` via `hookSpecificOutput.decision.updatedPermissions`).
18+
- `domain/model-ids.md` — documented v2.1.94 default effort change `medium → high`. Recommends pinning `effort: low` on `researcher`/`test-runner` agents.
19+
20+
#### Template
21+
22+
- `template/settings.json.tmpl` — added `ask:` permission list (18 entries) covering risky-but-legitimate commands: `rm *`, `chmod *`, `npm/pip install/uninstall`, `docker run`, `kubectl apply/delete`, `gcloud`/`aws`/`terraform apply/destroy`, `git push/rebase/cherry-pick`. Bridges the gap between unrestricted `allow:` and total `deny:`.
23+
- `template/hooks/block-destructive.sh` — added compound-bash safety verification block. Hook is **not vulnerable** to the v2.1.98 bypass class (the Claude Code core fix was about its own permission rule prefix matching; this hook uses `grep -qiE` over the full command string and catches `ls && rm -rf /`-style compound forms by design). Documented known limitations: indirect execution (`eval $(curl)`, `bash <(curl)`), encoded payloads, hostile env vars — defense-in-depth via `sandbox.enabled`.
24+
25+
#### Practices
26+
27+
- 8 practices moved `inbox/ → active/`, frontmatter `incorporated_in: [v3.1.0]`.
28+
- 3 auto-stub session-changes practices rejected (no actionable content).
29+
730
## v3.0.4 (2026-04-14)
831

932
### Skills catalog — `skills/index.yaml` + CI validation

practices/inbox/2026-04-13-boris-cherny-tips-scout.md renamed to practices/active/2026-04-13-boris-cherny-tips-scout.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
id: boris-cherny-tips-scout
33
source: scout:shanraisshan/claude-code-best-practice/tips
4-
status: inbox
4+
status: active
55
captured: 2026-04-13
66
tags: [scout, boris-cherny, workflow, gaps]
77
tested_in: []
8-
incorporated_in: []
8+
incorporated_in: [v3.1.0]
99
---
1010

1111
# Boris Cherny tips — scout digest

practices/inbox/2026-04-13-granular-ask-permissions.md renamed to practices/active/2026-04-13-granular-ask-permissions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
id: granular-ask-permissions
33
source: scout:shanraisshan/claude-code-best-practice
4-
status: inbox
4+
status: active
55
captured: 2026-04-13
66
tags: [permissions, settings, safety, template]
77
tested_in: []
8-
incorporated_in: []
8+
incorporated_in: [v3.1.0]
99
---
1010

1111
# Granular `ask:` permission list for template settings

practices/inbox/2026-04-13-v3-clear-creates-session-boundary.md renamed to practices/active/2026-04-13-v3-clear-creates-session-boundary.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ title: "/clear creates a new session_id, abandoning all session-scoped behavior
44
source: "dotforge v3 Phase 1 live smoke test in ~/tmp-v3-live"
55
source_type: experience
66
discovered: 2026-04-13
7-
status: inbox
7+
status: active
88
tags: [v3, behavior-governance, session-lifecycle, runtime, audit-gap]
99
tested_in: tmp-v3-live
10-
incorporated_in: []
10+
incorporated_in: [v3.1.0]
1111
replaced_by: null
1212
---
1313

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
id: block-destructive-compound-bash
3+
source: watch:code.claude.com/docs/en/changelog
4+
status: active
5+
captured: 2026-04-15
6+
tags: [security, hooks, block-destructive, audit, high-priority]
7+
tested_in: []
8+
incorporated_in: [v3.1.0]
9+
---
10+
11+
# Audit block-destructive.sh against compound-bash bypass (CVE-class fix in v2.1.98)
12+
13+
## Observation
14+
15+
Changelog v2.1.98 (2026-04-09) explicitly mentions:
16+
> Fixed Bash tool permission bypass vulnerability
17+
> Fixed compound Bash commands bypassing permission prompts
18+
19+
This means before v2.1.98, commands like `ls && rm -rf /tmp/foo` or
20+
`echo ok; rm -rf *` could slip past pattern-based hooks that only matched the
21+
first token. The Claude Code core was patched, but **dotforge's
22+
`template/hooks/block-destructive.sh`** uses its own pattern matching and may
23+
have the same blind spot.
24+
25+
## Required verification
26+
27+
1. Read `template/hooks/block-destructive.sh`
28+
2. Confirm it matches destructive patterns ANYWHERE in the command string,
29+
not just at the start
30+
3. Test cases that MUST be blocked:
31+
- `ls && rm -rf /`
32+
- `echo ok; rm -rf *`
33+
- `cd /tmp && git push --force origin main`
34+
- `(cd / && DROP TABLE users)`
35+
- `true || rm -rf $HOME`
36+
4. If any pass, harden the regex / split on `&&`, `||`, `;`, `|`, `\``, `$()`
37+
38+
## Action
39+
40+
After verification:
41+
- If hook is already safe → document it in a comment block in the script
42+
- If gap found → patch + add tests under `tests/hooks/` + bump dotforge version
43+
44+
## Affected files
45+
- `template/hooks/block-destructive.sh` (and any stack-specific copies)
46+
- Possibly `tests/hooks/block-destructive.test.sh` (new)

0 commit comments

Comments
 (0)