← 2.1.9 Release

2.1.9 Test (2.1.9)

| # | Feature | Status | Key Finding |

Claude Code 2.1.9 is the "hooks 2.0" release, shipping ${CLAUDE_SESSION_ID} substitution, PreToolUse additionalContext injection, and a plansDirectory setting -- collectively the most significant capability expansion since the hooks/skills foundation in 2.1.0.

"hooks become middleware, not just gates."

Epistemic status: changelog-derived and partially runtime-verified (2026-01-16). Three features were runtime-tested; two were queued as manual-only; one received code-review status without full runtime confirmation.

What shipped

${CLAUDE_SESSION_ID} substitution replaces the literal token with the session UUID at skill load time. Any skill .md file can embed the variable; the harness resolves it before the model reads the prompt. This enables session-scoped file paths such as /tmp/state-${CLAUDE_SESSION_ID}.json -- a low-ceremony working memory: write on one skill invocation, read on the next, auto-scoped to the session lifetime.

PreToolUse additionalContext lets hook commands return a JSON object with an additionalContext key. The harness surfaces that string to the model as a system reminder before the tool executes. Before 2.1.9, hooks could only approve, deny, or modify tool inputs; they could not communicate back to the model. A security hook can now annotate a sensitive file access; a compliance hook can surface a policy reminder inline.

plansDirectory is a settings key (e.g., {"plansDirectory": "./plans"}) that relocates plan-mode artifacts to a configurable path. Placing plans inside the repo makes them versionable and reviewable artifacts rather than ephemeral scratch files.

What the test found

Runtime tests on 2026-01-16 confirmed two core features. ${CLAUDE_SESSION_ID} passed: the UUID appeared correctly in skill text and was preserved across fork boundaries. additionalContext passed: context returned by a PreToolUse hook appeared to the model as a system reminder. The plansDirectory setting received CODE REVIEW status -- the path mechanism was inspected in source but not fully exercised at runtime. Three remaining features (auto:N MCP threshold, Ctrl+G in AskUserQuestion, session URL in commits) required interactive or MCP infrastructure and were deferred to manual testing queues.

One noted gap: ${CLAUDE_SESSION_ID} is available only inside skill markdown, not inside hook command strings. A hook cannot directly reference a session-scoped file using the variable; the skill must write the session ID to a known location for the hook to retrieve it, which limits the combined session-aware injection pattern.

Why it matters

The combination ${CLAUDE_SESSION_ID} + additionalContext creates a working-memory loop: a skill writes session state, a hook reads it, and the hook injects it as model context before each tool call. This pattern -- skill writes state, hook reads state, hook injects state as context -- was not expressible before 2.1.9. The plansDirectory setting is understated relative to its team utility: architectural decisions become versioned, reviewable repo artifacts instead of ephemeral plan buffers.

3features tested
    Evidence & receipt
    • file2.1.9/SUMMARY.md
    ◇ ed25519 receipt
    idrelease_07e30fc41b634c7798fad2cb
    alged25519
    pubkey9b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd
    sig5aae3ac346eee7a2946cb2ce3db712f91d76ae47b204ab42d9d10fcf347a135b4d3475970d0e27fee34d7b13e391c8e57b0d6836dbce990c28b28923cd35c006

    Signed with an ed25519 key held off the repo. Anyone can verify against the published public key; nobody without the secret key can forge it. Click verify: it recomputes the signature in your browser. The signature proves integrity and authorship of this exact content — not a third-party timestamp or that the underlying claim is objectively true. signedAt is when the @f3/attest pipeline ran, not when the work happened; the evidence refs carry the source dates.

    Connected