Repository navigation
codex-claude-loop v0.4.0 — let git hash the tree
Second fail-open in two releases, found by the same method: a scout claimed it, and it reproduced on the first try.
_cl_tree_id hashed untracked files by looping over the names git ls-files --others prints. Git quotes any name that needs escaping, so "evil\nname.txt" arrived at git hash-object as a literal quoted string, hash-object could not find it, and that file contributed a constant to the digest no matter what was inside it. A tree tampered with after its review kept a byte-identical id, and cl_release approved it.
The fix deletes the class rather than the instance. A temporary index takes read-tree HEAD + add -A + write-tree, so git hashes every tracked and untracked file by content and returns one sha for all of it. Names bash cannot iterate safely never pass through the shell. The caller's real index is untouched, and there is an assertion for that.
Upgrading: digests changed, so a review approval recorded before this version is refused until you re-review. That is the intended direction.
60 → 62 assertions, including the reproduction itself.