Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion adoption/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ GitHub-hosted macOS runner; see
and `OTEL_LOG_TOOL_DETAILS` to `"1"`, a dated user exception whose Collector
filter exports only tool, MCP server, skill and agent names
([tool details](../docs/secret-storage.md#telemetry-and-pasted-values)).
`claude.settings.template.json` also changed after `v2026.09.26.2`: it adds a
`SubagentStart` group that runs `~/.claude/hooks/token-lanes-subagent-start.py`,
installed by the **guard hooks** step of `install_claude_profile.py` below, so
every non-blind subagent receives the token-lanes block
([decision](../docs/decisions/2026-09-27-token-lanes-subagent-start.md)); while that
file is absent the command exits 0 and adds nothing.
`codex.config.template.toml` changed after `v2026.09.26`: it turns the context-mode plugin's own MCP server off and registers context-mode at user scope with no `cwd`, running the pinned npm install's `start.mjs`, so each Codex session's server binds that session's own directory ([recipe](../recipes/README.md#retained-context-mode)), and its `headroom` entry adds `HF_HUB_OFFLINE` and `TRANSFORMERS_OFFLINE`; `project.codex.config.template.toml` changed after `v2026.09.26` in its comments only.
The recipe's project-scoped alternative changed after `v2026.09.26.2`: it adds `default_tools_approval_mode = "approve"` and a `CLAUDE_PROJECT_DIR` equal to its project directory, as upstream `start.mjs` sets, so a project entry keeps Codex tool approvals and the server-side project `Bash(...)` denies ([recipe](../recipes/README.md#retained-context-mode)).
The rendered `codex.config.toml` keeps the source host's `trusted_hash`
Expand Down Expand Up @@ -311,7 +317,14 @@ GitHub-hosted macOS runner; see
to `~/.claude/hooks/effort-default-guard.py` and the secret guard
[`scripts/hooks/secret_path_guard.py`](../scripts/hooks/secret_path_guard.py)
to `~/.claude/hooks/secret_path_guard.py` (the secret guard and its
settings entries were added after `v2026.09.24.1`), refusing to install either unless
settings entries were added after `v2026.09.24.1`). This step **changed after `v2026.09.26.2`**:
it also copies [`adoption/hooks/claude/token-lanes-subagent-start.py`](hooks/claude/token-lanes-subagent-start.py)
and its sibling [`adoption/hooks/claude/token-lanes-block.md`](hooks/claude/token-lanes-block.md)
into `~/.claude/hooks/` (both files added after `v2026.09.26.2`).
The hook supplies token-lane guidance before each non-blind subagent's first prompt
through the [SubagentStart context contract](https://code.claude.com/docs/en/hooks#subagentstart);
`blind-*` roles receive no context from this hook.
It refuses to install any file unless
every sha256 matches [`adoption/hooks/claude/SHA256SUMS`](hooks/claude/SHA256SUMS)
(paths relative to that file); skipped per file if the installed copy
already matches.
Expand Down
2 changes: 2 additions & 0 deletions adoption/hooks/claude/SHA256SUMS
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
df3248659c191d8800dfd64a8c7d415fc13652cebee08c9437bf579862c2e561 effort-default-guard.py
ed5556f0cb4942859cf9e8e2e6f709de4dbc5b96163fc6ef65fcd0dcab8da153 ../../../scripts/hooks/secret_path_guard.py
8b9a60fa425900930c610ba7e3e0f8a0fa1457048a39c79e3136fb5073e7269f token-lanes-block.md
7a9228e41235771336189287944d81d998795b025a9a038d022beb21a19ce870 token-lanes-subagent-start.py
11 changes: 11 additions & 0 deletions adoption/hooks/claude/token-lanes-block.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
TOKEN LANES (source: docs/token-session-handbook.md, "Token lanes carried into subagents").
- Load deferred token tools in ONE ToolSearch call before first use: "select:mcp__plugin_context-mode_context-mode__ctx_execute,mcp__plugin_context-mode_context-mode__ctx_batch_execute,mcp__plugin_context-mode_context-mode__ctx_search,mcp__serena__find_symbol,mcp__serena__find_referencing_symbols"; add jcodemunch/codebase-memory/socraticode/qmd/ai-memory/headroom names to that same call when this task needs them.
- For output over ~5 KB, use ctx_batch_execute / ctx_execute / ctx_search; print derived answers, keep failures and original-output recovery. The context-mode server is bound to the main checkout: explicitly cd to the actual working directory. Open authorized scratch files from Python inside ctx_execute; ctx_execute_file enforces project boundaries (#852). Never bypass permissions.
- Automatic RTK: a Bash call containing $(...), backticks, <(...), a redirect to a file or a heredoc is never rewritten. && chains and multi-line blocks are rewritten segment by segment. In a pipeline RTK rewrites a supported producer feeding cat, head or tail (git diff | head -n 5) or a final grep/rg stage, but not gh (gh pr view 1 | head -n 5 is not rewritten). Run heavy reads as their own call. Never directly prefix rtk before `git show REV:path`, `diff`, `git branch`, `git log`, `jq`, `cd`, or `find` on a possibly-missing path. Use native commands or `rtk proxy <cmd>` for exact bytes/exit status; process large results in ctx_execute.
- Use Serena find_symbol / find_referencing_symbols for exact symbols and references; jcodemunch route(task, repo?, execute?), menu(query?), order(action, args) on indexed repos; socraticode codebase_search(query, projectPath) with explicit projectPath for conceptual questions. Open original source before judging or editing.
- Use codebase-memory trace_path (include_evidence=true adds resolver class and confidence; this parameter is on trace_path, not search_graph) or search_graph for symbol/reference queries; treat edges below confidence 0.5 as unverified candidates, and verify exact caller lists with Serena find_referencing_symbols.
- For the indexed catalog, use qmd query (us-equities-foundation / us-equities-catalog), then get. Use ai-memory memory_query with workspace/project from .ai-memory.toml as historical evidence only, never authority.
- Use TOON for uniform arrays of flat records (same keys in every item); keep compact JSON for nested or non-uniform data, where TOON can be larger (upstream README).
- For large selected text, use headroom_compress, then headroom_retrieve for recovery; require fidelity and count the recovery cost.
- Use one lane per artifact; never stack compressors or claim token savings. At the end of your return, list the token tools used and why.
- Before claiming a task done, follow the installed verification-before-completion skill: real command output before any success claim. Research upstream first with the installed search-first skill before writing custom code. Source: already installed: skillOverrides in adoption/templates/claude.settings.template.json.
40 changes: 40 additions & 0 deletions adoption/hooks/claude/token-lanes-subagent-start.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""Inject sibling token-lanes text for non-blind subagents; fail open on errors.

SubagentStart supplies agent_type: https://code.claude.com/docs/en/hooks#subagentstart
Fail-open/output pattern: adoption/hooks/claude/effort-default-guard.py.
"""

import json
import os
import sys


def main():
try:
data = json.load(sys.stdin)
except Exception:
return
agent_type = data.get("agent_type")
if isinstance(agent_type, str) and agent_type.startswith("blind-"):
return
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "token-lanes-block.md")
with open(path, encoding="utf-8") as source:
block = source.read()
if not block:
return
output = {"hookSpecificOutput": {
"hookEventName": "SubagentStart", "additionalContext": block,
}}
# Unbuffered output leaves no failing flush to change the exit status at shutdown.
encoded = (json.dumps(output) + "\n").encode("utf-8")
while encoded:
encoded = encoded[os.write(1, encoded):]


if __name__ == "__main__":
try:
main()
except Exception:
pass
sys.exit(0)
10 changes: 10 additions & 0 deletions adoption/templates/claude.settings.template.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@
"command": "${ECO_ROOT}/tools/ai-memory-2.4.1/ai-memory --data-dir ${HOME}/.local/share/ai-memory hook --event subagent-start --agent claude-code --server-url http://${AI_MEMORY_URL}"
}
]
},
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python3 \"${HOME}/.claude/hooks/token-lanes-subagent-start.py\" 2>/dev/null || true",
"timeout": 5
}
]
}
]
},
Expand Down
Loading
Loading