Skip to content

Skip unapproved project hooks via declaration-digest trust store - #282

Open
raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:pr/hook-trust
Open

raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:pr/hook-trust

Conversation

@raymondginger2018-sudo

Copy link
Copy Markdown
Contributor

Summary

Treats a project's hooks.json as workspace-supplied code: project hook declarations are gated behind an explicit, content-addressed approval (borrowed from ZCode's trust rule). Discovery defaults are unchanged — the gate activates only when a caller passes a trust_store.

Changes

  • New core/harness/hooks/trust.py:
    • declaration_digest(workspace, *, home=None, paths=None) — sha256 over canonical declaration fields only (event, matcher, command, timeout, priority, type): cosmetic edits keep approval, semantic changes rotate the digest. User-level config never feeds the digest.
    • HookTrustStore — atomic JSON store; a corrupt file degrades to empty (treated as "nothing approved"), never crashes.
  • core/harness/hooks/discovery.py: discover_hooks(..., *, trust_store=None) — when given and the workspace digest is not approved, project hook sources are skipped with a warning (user-level hooks unaffected).
  • core/harness/hooks/engine.py: HooksEngine.discover(..., trust_store=None) passthrough.
  • core/harness/hooks/__init__.py: export the new trust surface.
  • Tests: tests/test_hook_declaration_trust.py (10 tests: digest canonicalization, digest rotation on semantic change, store approve/revoke/corruption, engine opt-in default, and an end-to-end discover_hooks gate test).

Tests

  • tests/test_hook_declaration_trust.py — 10 passed
  • tests/test_hooks.py — failure set identical to upstream baseline (32 baseline reds; zero new failures vs pristine checkout)
  • CI-exact lint: pre-commit run --all-files (ruff 0.15.21) — passed
  • Local preflight verdict recorded against this revision (KNOWN-RED baseline documented)

Notes

  • Independent PR; no follow-up required for callers that don't pass a store (default = today's behavior exactly).

Borrowed from ZCode's rule: a project's hooks.json is workspace-supplied
code. declaration_digest(workspace) hashes only canonical declaration
fields (event, matcher, command, timeout, priority, type) so cosmetic
edits keep approval while semantic changes rotate the digest.

HookTrustStore is an atomic JSON store; a corrupt file degrades to empty.
discover_hooks/HooksEngine.discover accept trust_store= keyword — when
None (default) discovery is exactly the old behavior; when given, project
sources are skipped with a warning until their digest is approved.

This branch has not been deployed

No deployments
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.

1 participant