Skip to content

v0.4.1: fix: pre-launch hardening — anchor containment, state-dir file shadowing

Latest

Choose a tag to compare

@OrenAshkenazy OrenAshkenazy released this 28 Aug 12:33

Three findings from an adversarial pass over the v0.2.34..v0.4.0 delta.

  1. Shape clustering read anchored files without the containment rule the
    sweep enforces. _anchored_tokens did root / path on a thread-supplied
    path, so a symlinked or ../ anchor leaked tokens from files the diff
    never touched into the merge decision — while the README extends the
    "never reads outside the changed files" claim to cluster_findings.py,
    and this same release shipped _contained_path for exactly this vector
    in sweep_siblings.py. It now routes through the same helper: a path
    that escapes yields no tokens, and the cluster falls back to prose.

  2. A stray file at ~/.config/gh-review-loop shadowed a legacy directory
    full of user data. state_dir() used exists(), which is true for files,
    so resolution picked a path that cannot hold state and the next write
    crashed with an uncaught FileExistsError (exist_ok does not cover
    non-directories) while preferences.json and runs.jsonl sat untouched
    in the legacy dir. is_dir() falls back to the legacy data instead.

  3. The relocated "Why this exists" README section was pasted without a
    blank line after the preceding paragraph.

Tests: symlink and ../ anchors produce no shape merge; a file at the new
state path resolves to the legacy directory. 1102 pass, replay byte-stable.

Summary by Sourcery

Harden pre-launch review processing against untrusted anchor paths and invalid state-directory shadowing.

Bug Fixes:

  • Prevent shape clustering from reading anchored files outside the changed repository through symlink or parent-directory escapes.
  • Resolve state storage to the legacy directory when the new state path is occupied by a file, preserving existing user data and avoiding write failures.

Documentation:

  • Restore the missing spacing before the README's “Why this exists” section.

Tests:

  • Add coverage for symlinked and parent-directory anchor escapes and file-shadowed state-directory resolution.