Documentation Index
Fetch the complete documentation index at: https://mintlify.com/XxYouDeaDPunKxX/canon-boundary-guard-codex/llms.txt
Use this file to discover all available pages before exploring further.
inject_frame.py is intentionally small. It reads references/frame.md, strips surrounding whitespace, and emits a JSON hook payload on stdout. Codex invokes it as an external subprocess through the PreToolUse hook configured in hooks.json — once before each matched write tool call (apply_patch, Write, or Edit). The script does not modify files, does not communicate with any external service, and does not block the tool call. Its sole purpose is to put the compact provenance classification frame back into the model’s instruction stream at the moment a write operation is about to happen.
Source
Output JSON Structure
Whenframe.md is found and readable, the script prints a single JSON object to stdout:
Output Fields
The model-visible context path for
PreToolUse hooks. This is how the compact provenance frame reaches the model’s instruction stream — Codex reads this field and includes its contents as additional context before the tool call executes. The value is the full text of frame.md with surrounding whitespace stripped.Identifies the hook event type this payload is responding to. Always
"PreToolUse" for this script.Surfaces the hook activity in the Codex UI or event stream. It carries the same frame text as
additionalContext, making the hook’s activity visible outside the model’s instruction stream — in the UI status area, event log, or hook review view. This field does not affect what the model sees; it is for observability.Fallback Behavior
Ifreferences/frame.md is not found at the resolved path, the script catches the FileNotFoundError and substitutes a degraded message:
additionalContext and systemMessage. The failure is visible — the Codex UI will display the degraded message through systemMessage, and the model will receive it through additionalContext — but it does not block the tool call or crash the hook. The deliberate design principle is: the skill should not make normal work impossible because a local file is missing, but it should not fail silently either.
Path Resolution
The script resolvesframe_path relative to its own location using:
pathlib.Path(__file__).resolve() gives the absolute path of inject_frame.py itself. .parents[1] steps up two directory levels — from scripts/ to the canon-boundary-guard/ skill root. From there, references/frame.md is always at a known relative position. This approach means the script finds frame.md correctly regardless of the working directory from which Codex launches the hook subprocess.
The resolved directory structure is:
The script calls
sys.stdin.read() and discards the result before attempting to read frame.md. Codex PreToolUse hooks receive the tool’s input arguments on stdin as JSON. The script does not use that data — its only job is to emit the frame — but it must consume stdin before exiting. Leaving stdin unread can cause a broken pipe or hang depending on the platform and Python version.Related Pages
hooks.json
The hook wiring manifest that invokes this script before matched write tools.
frame.md
The compact classification frame that this script reads and emits.
Plugin Structure
The full plugin file layout showing where inject_frame.py lives.
SKILL.md
The full session-level operating frame that the hook reinforces.