Skip to content

bundle-parity check is one-directional — orphans in _bundle ship in the pip wheel undetected #70

Description

@wesleysimplicio

bundle-parity check is one-directional — orphan files in simplicio_loop/_bundle/ ship in the pip wheel undetected

Problem

scripts/claims_audit.py check 4 (bundle-parity) walks source → bundle only: it verifies every source file exists and matches in simplicio_loop/_bundle/, but never does the reverse pass. A renamed or deleted source file leaves an orphan copy in _bundle/ that passes the gate and gets packaged into the pip wheel.

The plugin-parity check already does this correctly in both directions — the asymmetry is the bug.

Evidence

  • One-directional: scripts/claims_audit.py:158-171 iterates source files, checks presence+content in bundle. No bundle→source walk.
  • Correct reference implementation: scripts/sync_plugin.py:107-143 does both src→dst and dst→src (orphan detection) for plugin/.
  • Repro: git mv hooks/loop_capture.py hooks/loop_capture2.py && python3 scripts/sync_plugin.py && python3 scripts/check.py → bundle keeps the old loop_capture.py copy; check 4 still passes (every current source file matches); the wheel ships a stale hook. (Revert after repro.)

Impact

  • Stale/removed logic silently distributed to every pip install simplicio-loop user.
  • Worst case: a hook removed for being buggy keeps shipping and keeps being wired by stale docs.

Proposed fix

In claims_audit.py check 4, after the forward pass, walk simplicio_loop/_bundle/ (same subtrees: skills, hooks, runtime scripts, parity tests) and fail with a named list of orphans — mirroring sync_plugin.py's dst→src logic. Consider extracting the shared walk into one helper used by both (see the separate LEAN_SCRIPTS duplication issue — same theme: one source of truth for the mirror contract).

Add a gate test: create a temp orphan in _bundle/, assert check 4 fails closed, remove it.

Acceptance criteria

  • An orphan file planted in simplicio_loop/_bundle/hooks/ makes python3 scripts/check.py fail with the orphan path named.
  • Forward pass unchanged (existing behavior preserved).
  • Test in tests/ covering the orphan case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingqualityQuality gates / verification

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions