fix(hooks): render Codex hooks in native shape - #3060
Ugaitz Urien (uurien) wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Resolve the integration test regression and legacy flat-entry reconciliation issue.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
Fixes Codex hook serialization by rendering portable entries in Codex’s required nested hooks structure.
Changes:
- Adds Codex-native hook rendering.
- Applies the renderer during hook integration.
- Updates unit and architecture coverage.
| File | Summary |
|---|---|
tests/unit/integration/test_hook_integrator.py |
Updates Codex integration expectations. |
tests/integration/test_architecture_contract_guards.py |
Adds coverage for Codex shape and preservation. |
src/apm_cli/integration/hook_native_formats.py |
Adds nested Codex rendering. Nit (3 votes): update maintained documentation to describe the Codex shape. |
src/apm_cli/integration/hook_integrator.py |
Applies Codex rendering. Critical (2 votes): an existing integration test raises KeyError on nested entries. Moderate (1 vote): legacy flat entries are not reconciled during stale-root healing. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| elif config.target_key == "codex": | ||
| entries = _to_codex_hook_entries(entries) |
| def _to_codex_hook_entries(entries: list) -> list: | ||
| """Render portable bindings in Codex's nested hook schema.""" | ||
| return _render_nested_document( | ||
| _entries_to_ir(entries), | ||
| timeout_milliseconds=False, | ||
| ) |
There was a problem hiding this comment.
I’ve updated hooks-and-commands.md, adding the Codex behavior alongside the existing Claude description. This level of target-specific serialization detail isn’t covered in package-authoring.md, so I don’t think we should document it only for Codex there without also documenting the equivalent behavior for the other targets.
|
@microsoft-github-policy-service agree company="Arima Software Design SL" |


Description
Fixes #3059.
When APM installs a portable hook for the Codex target, it currently writes the command handler directly into the event array:
{ "hooks": { "SessionStart": [ { "type": "command", "command": "echo session-start" } ] } }Codex requires an intermediate hook group containing a nested
hooksarray:{ "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "echo session-start" } ] } ] } }This PR converts portable Codex hook entries to that native shape while preserving already nested entries. The required structure is documented in the Codex hooks configuration shape and configuration reference.
Note
A two-line comment and one blank line were removed from
hook_integrator.pysolely to keep the file within CI's 2100-line limit. This has no functional effect.Issue and approved scope
Issue: #3059
Human scope-approval comment: Pending — the issue currently has no maintainer approval comment.
Does this PR complete the issue, or what remains? The reported serialization bug is fixed; maintainer scope approval and CI review remain.
Type of change
Testing
Focused test result:
The lint, formatting, duplication, authentication-boundary, architecture-boundary, YAML I/O, path-portability, and file-length checks pass locally.
Spec conformance (OpenAPM v0.1)
docs/src/content/docs/specs/openapm-v0.1.mdupdated.@pytest.mark.req("req-XXX")conformance test added or extended.CONFORMANCE.{md,json}regenerated.