stacklok / stacklok/mecatl

hooks: config-file path for global hooks, and per-execution-environment placement

Open
#604 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

config enhancement
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

  1. Config-file path for global hooks. A hooks: subtree in the operator/project settings file (permconfig-adjacent), mapping phase → command(s), threaded into hookexec.New at composition. This is the plain feature.

  2. 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 PreToolUse guard that inspects a file path or runs a linter wants to run inside the session's environment, while a SessionStart audit hook may belong on the host harness. Today the HookRunner is 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's EnvironmentRef?

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.