2.8 KiB
Spec: Hook Python Port
Purpose
Defines the requirements for porting the memory plugin's bash hooks to Python, including shared module structure, error handling conventions, and correctness verification via golden fixtures.
Requirements
Requirement: Single config loader
A config.py module SHALL expose load_config() -> Config (frozen dataclass) that parses config.yaml, expands paths, applies defaults, and handles missing file — replacing all duplicated inline YAML parsers.
Scenario: Config loaded once per hook invocation
- WHEN any hook script runs
- THEN it calls
load_config()exactly once and accesses all config values through the returnedConfigdataclass
Requirement: Uniform stdin parser
A hook_io.py module SHALL expose read_input() -> HookInput (dataclass with fields: session_id, cwd, file_path, reason) that parses hook stdin JSON, replacing all inline stdin parsers and eliminating the python3-vs-jq inconsistency.
Scenario: stdin parsed uniformly across all hooks
- WHEN any of the five hook entry points (session_start, session_context, post_tool_use_write, session_end, memsearch_sync) runs
- THEN stdin is parsed via
read_input(), not inline shell commands or ad-hoc python
Requirement: Named session-state contract
A session_state.py module SHALL expose record_touch(session_id, path) and read_touches(session_id) -> list[str], encapsulating the /tmp/claude-vault-touched-$SESSION_ID temp-file handoff between post-tool-use-write and session-end hooks.
Scenario: Touch handoff uses named functions
- WHEN post_tool_use_write records a vault touch
- THEN it calls
record_touch(session_id, path)rather than writing the temp file directly
Scenario: Session-end reads touches via named function
- WHEN session_end reads which vault files were touched
- THEN it calls
read_touches(session_id)rather than reading the temp file directly
Requirement: Fail-open hook mains
Every hook main() function MUST wrap execution in try/except; uncaught exceptions MUST log the error and exit with code 0.
Scenario: Exception does not disrupt session
- WHEN a hook raises an uncaught exception
- THEN the hook logs the exception to stderr and exits 0 (session continues normally)
Requirement: Behavior-faithful port with golden fixtures
The Python port MUST demonstrate identical output to the bash hooks against golden fixtures before any cleanup or refactoring.
Scenario: Golden fixtures captured before port
- WHEN the port task begins
- THEN golden fixture files exist for each of the 4 bash hooks (known stdin → snapshot of side effects)
Scenario: Python output matches bash output
- WHEN Python hooks are run against golden fixtures
- THEN output matches the bash hook snapshots exactly before any refactor proceeds