Skip to content

0.9.1 sync prunes an unwired vendor's runtime but leaves its hook config pointing at it #151

Description

@jothimani-rajendran

What happens

A repo that was synced on 0.9.0 (which wired every vendor chock knows) and then syncs on 0.9.1 with supported_agents narrower than that ends up with hook config files that point at runtimes sync just deleted.

Reproduced on chock-example main (5287c6c, synced on 0.9.0, supported_agents: [claude, copilot, gemini]) with a fresh pip install chock==0.9.1:

$ chock sync --repo .
$ git status --short
 D .chock/bin/antigravity.py
 M .chock/bin/claude_code.py
 D .chock/bin/codex_cli.py
 D .chock/bin/cursor.py
 D .chock/bin/devin.py
 M .chock/bin/gemini_cli.py
 D .chock/bin/grok.py
 D .chock/bin/tabnine.py
 M .chock/bin/vscode_copilot.py
 D .chock/bin/windsurf.py
$ git grep -n 'chock/bin/codex_cli.py' -- .codex
.codex/hooks.json:8:  "command": "\"/usr/local/bin/python3\" \".chock/bin/codex_cli.py\" --guard ..."

.agents/hooks.json, .codex/hooks.json, .cursor/hooks.json, .devin/hooks.v1.json, .grok/hooks/agentseam.json, .tabnine/agent/settings.json and .windsurf/hooks.json all still carry chock's entries, each naming a file that no longer exists. chock sync --repo . --check and chock check both report clean afterwards, so nothing tells the adopter. chock-mise main (a669d0f, same supported_agents) shows the same shape on --check.

For an adopter who opens that repo in Cursor, Codex or Windsurf, every tool call now runs a hook whose command fails before the gate is evaluated: a non-blocking error in every client, on a hook that was enforcing yesterday.

Why

0.9.1's sync wires in-agent hooks only for the vendors supported_agents names (recompile.wired_vendors(), #149) and prunes a vendored runtime whose vendor is no longer wired (#150). Neither step removes chock's entries from the unwired vendor's config file, which 0.9.0 wrote and which sync used to refresh on every run.

Fix

  • sync uninstalls chock's entries from every wired-capable vendor that is not in wired_vendors(agents) (the same removal path install_hooks takes when no compiled fragment exists; deleting the config file when only chock's entries were in it, as the generic installer already does), and only then prunes the runtime. A vendor the adopter never had is a no-op.
  • chock check gains a repo check that fails on any chock-written hook entry whose command names a path under .chock/bin/ that does not exist, so a dangling target is a finding rather than a silent client error. The pre-0.9.1 audit ran exactly this scan by hand across six repos; it belongs in validate.
  • Tests: a repo synced with every vendor wired, then re-synced with supported_agents: [claude], has no chock entry left in .cursor/hooks.json (or no file) and no .chock/bin/cursor.py; the new check fails on a hand-planted dangling entry and is silent on a clean tree.
  • Release as 0.9.2. chock-example and chock-mise resync on it; their 0.9.1 resync is held until then (chock-quickstart wires no vendor hooks and resynced cleanly).

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions