hooks: unify registry, fix 5 systemic bugs across both hook systems#30860
hooks: unify registry, fix 5 systemic bugs across both hook systems#30860mcaxtr wants to merge 6 commits intoopenclaw:mainfrom
Conversation
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🔵 Hook source spoofing allows file-loaded code to register persistent hooks that evade hot-reload clearing
Description
Impact:
Vulnerable code: const registrySource: HookRegistrySource =
(source ? (FILE_SOURCE_TO_REGISTRY[source] ?? (source as HookRegistrySource)) : undefined) ??
"config";Notes on data/control flow:
RecommendationEnforce a strict runtime allowlist for Suggested fix (runtime validation + narrower API): import type { HookSource } from "./types";
const ALLOWED_REGISTRY_SOURCES = new Set<HookRegistrySource>([
"bundled",
"workspace",
"managed",
"config",
"plugin",
]);
export function registerInternalHook(
eventKey: string,
handler: InternalHookHandler,
source?: HookSource | HookRegistrySource,
): void {
const mapped = source && source in FILE_SOURCE_TO_REGISTRY
? FILE_SOURCE_TO_REGISTRY[source as HookSource]
: source;
const registrySource: HookRegistrySource =
mapped && ALLOWED_REGISTRY_SOURCES.has(mapped as HookRegistrySource)
? (mapped as HookRegistrySource)
: "config";
// Optional: if called from file loader, explicitly disallow "plugin".
registerHook(eventKey, handler as (...args: unknown[]) => unknown, { source: registrySource });
}Additionally:
Analyzed PR: #30860 at commit Last updated on: 2026-03-02T19:04:56Z |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70b9b1d47a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Greptile SummaryThis PR successfully unifies two independent hook systems (internal HOOK.md + plugin HookRunner) into a single Key Changes:
Architecture:
Testing:
The refactor is well-architected with clear separation of concerns, defensive programming (metadata cloning), and thorough test coverage. Confidence Score: 4/5
Last reviewed commit: 7cd3939 |
|
@greptile please re-review this PR. Since the initial review (70b9b1d), commit 7cd3939 addresses two issues:
|
|
Re: Aisle security finding — the unbounded |
7cd3939 to
bc6182c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc6182cb6f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
bc6182c to
8006f37
Compare
8006f37 to
b77dc60
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8006f37f6e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b77dc60298
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b77dc60298
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b77dc60298
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary
clearInternalHooks()wipes plugin hooks.gateway:startupraces with hook loading.sessions.resetnever firesbefore_reset.after_compactionmissingsessionKey.globalThis[Symbol.for()]-backed registry with source-tagged entries, source-scoped clearing, unified dispatch helpers, missing hook event fixesChange Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
None. All changes are internal to hook dispatch infrastructure. Existing hooks fire at the same times with the same arguments.
Security Impact (required)
NoNoNoNoNoRepro + Verification
Environment
hooks.internal.enabled: trueSteps
api.registerHook("message:received", handler)message_receivedExpected
Actual
handlers.clear()and never fires againEvidence
28 new tests:
hook-registry.test.ts(18 tests),dispatch-unified.test.ts(10 tests). All 229 existing tests pass.Human Verification (required)
pnpm build(type-check),pnpm check(lint/format),pnpm test(229 tests pass), 3 rounds of codex reviewCompatibility / Migration
YesNoNoFailure Recovery (if this breaks)
gateway:startuptiming changesRisks and Mitigations
Risk:
clearAllHooks()on SIGUSR1 restart clears plugin-source hooks from the unified registryhandlers.clear()behavior exactly. Plugin typed hooks on HookRunner are stored separately and unaffected. Plugin internal hooks are re-registered byloadGatewayPlugins()at the start of each gateway iteration.Risk: Dispatch helpers change hook firing order for overlapping events