> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/phases/phase_09/session_02_hook_runtime_normalization.md).

# Session 02: Hook Runtime Normalization

**Session ID**: `phase09-session02-hook-runtime-normalization` **Package**: apps/hooks **Status**: Complete **Validated**: 2026-05-31 **Estimated Tasks**: \~16-24 **Estimated Duration**: 2-4 hours

***

## Objective

Normalize hook runtime inputs so Claude and Codex-shaped payloads can share the same safe posting, spooling, logging, and redaction behavior.

***

## Scope

### In Scope (MVP)

* Add provider normalization helpers in `apps/hooks/src/_lib.js`.
* Update existing handlers to use normalized helpers.
* Keep Claude hook map behavior unchanged.
* Add Codex-shaped fixture tests against shared handlers where possible.
* Preserve sanitized logging, spool, and listener behavior.

### Detailed Requirements

* `detectCli()` returns `codex-cli` when `FACTIONOS_CLI=codex-cli` is set.
* `hookEventName(event)` reads `hook_event_name`, `eventName`, or `hook`.
* `resolveSessionId(event, tty)` continues reading `session_id` and `sessionId`.
* `toolName(event)` reads `tool_name`, `tool`, or provider-specific aliases.
* `toolInput(event)` reads `tool_input` and returns an object.
* `modelId(event)` reads `model`, `modelId`, or provider-specific env fallbacks.
* `permissionMode(event)` reads `permission_mode` and maps it to compact diagnostic metadata.
* `promptText(event)` reads Codex `prompt` and Claude `user_message`.
* `subagentMetadata(event)` prefers Codex `agent_id` and `agent_type`, then falls back to the current Claude transcript-path parser.
* Spool and log sanitization must cover Codex fields including `prompt`, `tool_input`, `tool_response`, `transcript_path`, `agent_transcript_path`, and MCP args.

### Provider-Specific Gaps

* Codex has no Claude `AskUserQuestion` matcher in reviewed docs. Keep existing Claude input-wait hooks but do not claim Codex awaiting-input parity.
* Codex file reads are not equivalent to Claude `Read` hooks. Observe `apply_patch` edits and relevant MCP filesystem calls first.
* Codex `PostToolUse` cannot undo executed tools; treat it as observability and feedback only.

### Out of Scope

* Codex hook installation.
* New web labels or server lifecycle changes.
* Parsing full transcripts or raw tool bodies.

***

## Prerequisites

* [ ] Session 01 complete.
* [ ] Existing Claude hook payload tests reviewed.
* [ ] Codex hook input fields confirmed against current OpenAI documentation.

***

## Deliverables

1. Provider normalization helpers for hook payloads.
2. Handler updates that use normalized provider, session, tool, cwd, model, and permission fields.
3. Claude fixture coverage showing unchanged behavior.
4. Codex lifecycle, Bash, prompt, and minimal permission fixtures.
5. Sanitization assertions for Codex-specific sensitive fields.

***

## Success Criteria

* [ ] Existing Claude hook payload tests pass.
* [ ] New Codex lifecycle, Bash, and prompt fixtures pass.
* [ ] Hook logs and spool output remain sanitized.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/phases/phase_09/session_02_hook_runtime_normalization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
