hooks: config-file path for global hooks, and per-execution-environment placement
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
What
mecatl has a full hook system: the port.HookRunner port, the internal/adapter/hookexec shell-exec runner, the six lifecycle phases (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, SubagentStop), the stdin/exit-code contract, and per-agent-def hooks: maps. See docs/usage/hooks.md.
The gap: there is no config-file path for global hooks. docs/usage/hooks.md states it plainly:
Wiring a global hook requires editing the shared composition layer and rebuilding — there is no config-file path for global hooks in v1. An agent definition's per-def
hooks:map is the config-driven path.
Claude Code exposes hooks as a hooks map in settings.json (user / project), which is the on-ramp most operators expect.
Two separable asks
-
Config-file path for global hooks. A
hooks:subtree in the operator/project settings file (permconfig-adjacent), mapping phase → command(s), threaded intohookexec.Newat composition. This is the plain feature. -
Per-execution-environment placement. As execution environments separate out (ADR 0211, and the microVM work in #526), a hook is not obviously host-global: a
PreToolUseguard that inspects a file path or runs a linter wants to run inside the session's environment, while aSessionStartaudit hook may belong on the host harness. Today theHookRunneris a single engine-construction-time value with no environment dimension. The design question: does the hook config carry an environment/placement qualifier, or does the runner resolve placement from the session'sEnvironmentRef?
These can land independently — (1) is useful on its own; (2) can be deferred until the environment model settles — but the config schema should not paint us into a host-only corner.
Trust note
Project-tier hooks are ungated shell on the harness host (same trust boundary as agent-def hooks: and project-tier ingestion) — they must ride the projectIngestionAdmitted(cfg) gate, not a new grant.
Related
- #526 — MicroVM-backed local execution environments (the placement question's driver)
- ADR 0211 — execution-environment seam
docs/usage/hooks.md,user-docs/extension-points/hook-runner.md
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read docs/usage/hooks.md and user-docs/extension-points/hook-runner.md, then trace port.HookRunner, internal/adapter/hookexec, and the permconfig-adjacent composition path. Define how a global hooks map reaches hookexec.New while preserving projectIngestionAdmitted(cfg); document or implement a schema that does not preclude later execution-environment placement.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, shell
- Domain
- backend, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100