Skip to content

plugin: the generated plugins page tells a gate from a guard - #162

Merged
jothimani-rajendran merged 1 commit into
mainfrom
claude/plugins-page-gates
Sep 23, 2026
Merged

jothimani-rajendran merged 1 commit into
mainfrom
claude/plugins-page-gates

Conversation

@jothimani-rajendran

Copy link
Copy Markdown
Collaborator

What

chock marketplace build wrote one fixed paragraph per tree into PLUGINS.md, describing every enforcing package as "a PreToolUse hook, a guard script and a stdlib-only adapter" that "can deny a shell command before the client runs it". Since 0.11.0 a package can carry a policy's gate instead, which judges what a turn writes rather than what it runs. So the page published in every distribution repo misdescribed five of its fourteen enforcing packages, and named PreToolUse even in the Cursor tree, whose guards hook beforeShellExecution.

The paragraph is now derived from the hooks each package actually publishes:

  • a hook command carrying --guard makes a guard package; one carrying --gate makes a gate package;
  • each kind is described with the events its own hooks file wires, in that client's spelling;
  • where the gate's events include no pre-tool event, the page says the gate runs at the turn's end only and the write itself is not judged.

Rendered against the four real published trees:

Tree Guards hooked at Gates hooked at
claude PreToolUse PreToolUse and Stop, judging the write then re-reading the turn
cursor beforeShellExecution preToolUse and stop
codex PreToolUse Stop only, write not judged
devin PreToolUse Stop only, plus its existing best-effort caveat

Devin's best-effort row and summary words are unchanged; its "not a guarantee" sentence now closes the derived paragraph rather than replacing it.

The renderer moves to its own module, chock.plugin.catalog_page. marketplace_core.py had grown past the repo's 300-line review budget, and the page is its own activity; marketplace.py imports it from there and every public name keeps its import path through chock.plugin.marketplace.

Definition of done

  • chock check → 0 errors, 0 warnings, 0 infos (the ## Unreleased changelog heading is skipped by check_release_consistency's digit-anchored pattern by design)
  • chock check --only matrix passes; the enforcement matrix is unaffected
  • chock sync --repo . --check clean
  • chock check --only verify clean
  • Registry rescanned; no stale entries
  • pytest -q green (1462 passed, 2 skipped)
  • pytest acceptance/ — not applicable, packaging, init, add and hook installation unchanged; only the generated page's prose changes
  • Existing artifacts migrated — the distribution repos pick this up on their next Publish
  • Touched manifests — none
  • ruff check . and ruff format --check . clean

Three new tests in tests/test_catalog_page.py build a tree holding a guard, a gate and an advisory policy through the real plugin CLI. All three fail against the old emitter and pass against this one: one pins that a gate is not called a shell-command guard, one that a stop-only client says the write is not judged, one that each client's own event spelling is used.

Claims

  • No surface is described as enforcing more than it installs. This narrows the page: it previously told a reader every enforcing package could deny a shell command, and five cannot.

After merge, the four distribution repos need a Publish run to carry the corrected page; nothing there should be hand-edited, since PLUGINS.md is generated.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CzNYfzP8ymU3r4JB9Sz8Ha


Generated by Claude Code

chock marketplace build wrote one fixed paragraph per tree describing every
enforcing package as a PreToolUse guard script that can deny a shell command.
Since 0.11.0 a package can carry a policy's gate instead, which judges what a
turn writes rather than what it runs. The published PLUGINS.md in every
distribution repo therefore misdescribed five of its fourteen enforcing
packages, and named PreToolUse even in the Cursor tree, whose guards hook
beforeShellExecution.

The paragraph is now derived from the hooks each package publishes. A --guard
command makes a guard package and a --gate command a gate package, and each
kind is described with the events its own hooks file wires, in that client's
spelling. Where a client records no write-tool vocabulary (Codex, Devin) the
page says the gate runs at the turn's end only and the write is not judged.
Devin keeps its best-effort framing as a closing caveat.

The renderer moves to chock.plugin.catalog_page: marketplace_core had grown
past the 300-line review budget, and the page is its own activity. Its three
new tests fail against the old emitter and pass against this one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
@jothimani-rajendran
jothimani-rajendran marked this pull request as ready for review September 23, 2026 23:20
@jothimani-rajendran
jothimani-rajendran merged commit d84235c into main Sep 23, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants