59 lines
3.5 KiB
Markdown
59 lines
3.5 KiB
Markdown
---
|
|
id: 20260603-122317-hook-public-surface-hardening
|
|
slug: hook-public-surface-hardening
|
|
title: Hook: harden public hook surface before plugin exposure
|
|
status: closed
|
|
kind: task
|
|
priority: P1
|
|
labels: [hooks, plugin, safety, tests]
|
|
created_at: 2026-06-03T12:23:17Z
|
|
updated_at: 2026-06-03T17:07:44Z
|
|
assignee: null
|
|
legacy_ticket: null
|
|
---
|
|
|
|
## Issue
|
|
|
|
`crates/pod/src/hook.rs` is already positioned as the public orchestration extension point over the internal `llm_worker::Interceptor`, but actual production usage is still light. Current usage is mostly manifest permission policy (`PreToolCall`) and usage tracking (`PreLlmRequest`). Before external or plugin-like features rely on Hooks, the public Hook surface needs tighter safety boundaries and better Pod-layer test coverage.
|
|
|
|
The main concern is that some Hook outputs still reuse internal `llm_worker::interceptor` action types. In particular, `PreRequestAction::ContinueWith(Vec<Item>)` and `TurnEndAction::ContinueWithMessages(Vec<Item>)` allow model-visible item injection from a Hook path. That conflicts with the intended public rule that Hooks must not mutate history/context except through approved durable paths.
|
|
|
|
## Requirements
|
|
|
|
- Audit the public Hook API against the intended plugin/feature contract.
|
|
- Replace or wrap internal interceptor action types with safe public Hook action subsets where needed.
|
|
- `OnPromptSubmit` already has a safe `HookPromptAction`; use the same pattern for other public Hook events.
|
|
- Public Plugin/Feature Hooks should not be able to return raw `Item` vectors for hidden context/history mutation.
|
|
- Preserve internal mechanisms that legitimately need richer interceptor actions, but keep them separate from public feature/plugin Hooks.
|
|
- Keep manifest permission policy behavior intact.
|
|
- Deny/ask still fails closed with synthetic tool results as today.
|
|
- Clarify which Hook events are observational only and which can cancel/abort/yield/deny.
|
|
- Add Pod-layer tests for Hook behavior that is currently only lightly covered.
|
|
|
|
## Suggested test coverage
|
|
|
|
- `OnPromptSubmit` Hook can cancel a submitted prompt through the safe public action type.
|
|
- `PreLlmRequest` public Hook runs under normal conditions and cannot inject raw `Item` context.
|
|
- `PreToolCall` Hook can deny/skip with a synthetic result through the intended path.
|
|
- `PostToolCall` Hook can observe a bounded summary and abort when allowed, but cannot rewrite tool output unless an explicit safe transform capability is introduced.
|
|
- `OnTurnEnd` public Hook cannot append arbitrary messages through raw internal action types.
|
|
- `OnAbort` Hook is called on abort paths.
|
|
- Multiple Hooks execute in registration order and short-circuit on non-continue actions.
|
|
- Internal mechanisms run in the expected order relative to public Hooks.
|
|
|
|
## Non-goals
|
|
|
|
- Implementing a Plugin runtime.
|
|
- Implementing a feature registry.
|
|
- Adding declarative hooks.
|
|
- Adding new Hook event kinds unless a gap is found during the audit.
|
|
- Allowing Hooks to rewrite arbitrary history/tool/model context.
|
|
|
|
## Acceptance criteria
|
|
|
|
- Public `pod::hook` APIs no longer expose internal action types that allow raw model-visible `Item` injection.
|
|
- Internal interceptor capabilities remain available only through internal mechanisms where justified.
|
|
- Existing manifest permission policy and usage tracking behavior remain intact.
|
|
- Focused Pod-layer tests cover the Hook events and short-circuit behavior needed by the feature registry/plugin surface.
|
|
- The resulting Hook surface is safe to reference from `plugin-feature-contribution-registry` as the public Hook contribution boundary.
|