Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0063
ADR-0063: The Read tool is allowed on a module the session already read through the AST toolkit
| field | value |
|---|---|
| Status | Accepted — Accepted (ruling R9, Mohamed, 2026-09-23) |
| Date | 2026-09-23 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0063-read-allowed-after-ast-toolkit-source.md — permalink at 77a0013af (unchanged on master since that commit) |
| Wiki register entry | ADR-0063 (wiki status: Accepted) |
The record
Date: 2026-09-23 · Status: Accepted (ruling R9, Mohamed, 2026-09-23)
Context
The 2026-08-02 mandate ("ZERO hand-reading of Python source — the AST
toolkit serves everything") is enforced by .claude/hooks/force-ast-toolkit.sh,
which since 2026-08-08 DENIES the Read tool and every text tool on .py
files under src/, scripts/ and tests/ of this repo, and directs the
caller to scripts/serialize_codebase_ast.py source <qualified_name>.
The Edit and Write tools refuse to touch a file the session has not Read.
Measured 2026-09-23 on two swarm tasks (U-T3, U-T8a): both agents pulled the
exact bytes of the target symbols through source, drafted the patch, and
could not land it by any route a sibling guard permitted — Bash redirects
are denied by intercept_bash.py, rm/mv are denied, and the auto-mode
classifier refused cp over the target. The working method in use before
the ruling (build the file in the scratchpad, diff against
git show HEAD:<path>, copy over) is a route AROUND a guard, which is the
failure mode the guard's own header warns about: a guard whose only
satisfying action is impossible blocks work and teaches the operator to
route around it.
Decision
Ruling R9 (plan PLAN-2026-09-23-production-deployable-tools.md, Rulings
table): the Read tool is permitted on a Python file whose module the same
session has already read through serialize_codebase_ast.py source <name>.
Mechanism (RUL-014 — a ruling resolves to a mechanism), landed in
orchestrata-ultimate 1395825c4:
- the hook's Bash branch records every
serialize_codebase_ast.py source <name>argument into a per-session memo,${XDG_RUNTIME_DIR:-/tmp}/orchestrata-project-hooks/<session>.ast-read-allow, keyed by the payload'ssession_id(the same key_dispatch.shuses for its repo memo; an unsafe id records nothing); - the Read branch allows a
.pywhose stem is a dotted segment of a recorded name (source deploy.test_ship._orchestrata_repounlockstests/deploy/test_ship.py), and otherwise denies exactly as before; - text tools (
grep,sed,head,cat, …) stay denied unconditionally; the carve-out is for the Read tool only, per session, per module; - a payload without a session id records and unlocks nothing, so every
pre-existing test of the guard is unchanged (47 passed before, 55 after
with the 8 new cases in
tests/scripts/test_force_ast_toolkit_read_allowance.py).
Consequences
- Content still comes from the toolkit first; the allowance exists only
AFTER a
sourcecall, which is the mandate's own sanctioned read. - The scratchpad-and-copy method is retired for this repo; a builder that
needs to Edit an existing module runs
sourceon a symbol of it and then Reads and Edits it. - The plugin copy of the hook (
plugins/orchestrata/project-hooks/) goes live only with a ship, becauseinstall-claude-config.shrefuses unpushed commits; until that ship each worktree's own.claudecopy enforces the new rule while the plugin copy still denies. Recorded so the next such change is sequenced before, not during, a swarm wave.
Alternatives rejected
- Exempting
tests/from the guard. It would have restored hand-reading for the largest part of the tree and left thesrc//scripts/deadlock in place. - Keeping the scratchpad-and-copy method as the documented procedure. It routes around a guard, and a guard that is routinely routed around no longer enforces anything (RUL-014).
Homes
docs (this file) · wiki (rulings/RUL-033-read-after-ast-source, to be
synced) · graph (scripts/sync_architecture_to_graph.py --adrs).
Related ADRs
No other ADR is named in this record.
Rulings cited
- RUL-014: RUL-014 — A ruling that exists only in prose is incomplete work
- RUL-033: RUL-033 — The Read tool is allowed on a module the session already read through the AST toolkit
Specs cited
None (or no spec page exists for the ones named).