Port os Python hooks (session_start.py, pre_tool_use.py, checks.py, state.py) to Ruby #1525

Closed
opened 2026-11-03 14:14:51 +00:00 by jared · 2 comments
Owner

Problem

The journey tracer records in-process Ruby messages only. os ships four Python hook files, 869 lines: hooks/session_start.py (120, aggregated status pass), hooks/pre_tool_use.py (176, file_locked: true frontmatter guard), hooks/checks.py (420, status-check registry) and hooks/state.py (153, per-project state). The two registered hooks are entry points by the 2026-11-02 ruling and are untraceable while Python. Same mechanism as #1522.

Reproduce

n/a: feature ticket; the gap is structural.

Approach

Port the four files to Ruby under a lib module, with thin hooks/session_start.rb and hooks/pre_tool_use.rb wrappers, as #1522 did for os-backlog. Port the Python tests (tests/pre_tool_use_test.py, tests/hook_test.py) to Minitest and delete the Python files. Output must stay byte-identical for the same stdin and project state. The existing ticket "Run the os plugin's Python hook tests under the os-sdlc gates" becomes obsolete once the hooks are Ruby.

Required work: none beyond the acceptance criteria.

Origin

  • Trigger: #1522 shipped; Jared asked 2026-11-03 to port the remaining os-adr and os Python hooks the same way
  • Improvised this session: none
  • Chain: hooks untraceable ← hooks are Python ← DESIGN (plugins/os/hooks/session_start.py, pre_tool_use.py, checks.py, state.py predate the Ruby hook convention in os-aidd-lint, os-me, os-backlog)
  • Root candidate: none found; searched python, hook ruby port, .py, session_start, pre_tool_use
  • Where: plugins/os/hooks/session_start.py, pre_tool_use.py, checks.py, state.py
  • Session: 32008a4e-5b0f-4863-94d9-7afb84ba65b6
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/32008a4e-5b0f-4863-94d9-7afb84ba65b6.jsonl

VERDICT: CREATE

## Problem The journey tracer records in-process Ruby messages only. os ships four Python hook files, 869 lines: `hooks/session_start.py` (120, aggregated status pass), `hooks/pre_tool_use.py` (176, `file_locked: true` frontmatter guard), `hooks/checks.py` (420, status-check registry) and `hooks/state.py` (153, per-project state). The two registered hooks are entry points by the 2026-11-02 ruling and are untraceable while Python. Same mechanism as #1522. ## Reproduce n/a: feature ticket; the gap is structural. ## Approach Port the four files to Ruby under a lib module, with thin `hooks/session_start.rb` and `hooks/pre_tool_use.rb` wrappers, as #1522 did for os-backlog. Port the Python tests (`tests/pre_tool_use_test.py`, `tests/hook_test.py`) to Minitest and delete the Python files. Output must stay byte-identical for the same stdin and project state. The existing ticket "Run the os plugin's Python hook tests under the os-sdlc gates" becomes obsolete once the hooks are Ruby. Required work: none beyond the acceptance criteria. ## Origin - Trigger: #1522 shipped; Jared asked 2026-11-03 to port the remaining os-adr and os Python hooks the same way - Improvised this session: none - Chain: hooks untraceable ← hooks are Python ← DESIGN (plugins/os/hooks/session_start.py, pre_tool_use.py, checks.py, state.py predate the Ruby hook convention in os-aidd-lint, os-me, os-backlog) - Root candidate: none found; searched python, hook ruby port, .py, session_start, pre_tool_use - Where: plugins/os/hooks/session_start.py, pre_tool_use.py, checks.py, state.py - Session: 32008a4e-5b0f-4863-94d9-7afb84ba65b6 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/32008a4e-5b0f-4863-94d9-7afb84ba65b6.jsonl VERDICT: CREATE
Author
Owner

Work started by hand (agent port, as #1522) in worktree ticket-os-hooks.

Work started by hand (agent port, as #1522) in worktree ticket-os-hooks.
Author
Owner

Resolution

Done: Ported the four os hook files to Ruby under OsHooks (Zeitwerk): StatusPass, StateDir, ProjectConfig, LockGuard, Frontmatter, eight checks in OsHooks::Checks with Registry::ALL keeping the same names and output text; thin hooks/session_start.rb and pre_tool_use.rb; hooks.json runs ruby; new bin/status-checks (--json, --stamp-version) replaces the checks.py/state.py calls that /os:fix made; Python hooks and tests deleted; every Python case ported to Minitest with one use_case tag per hook; doc pointers updated.

Evidence: main 88b5e3a5 (6f04fc4f). Parity matrix 82 cases (35 SessionStart, 39 PreToolUse, 4 --json, 3 stamp): 81 byte-identical on stdout, stderr, exit and file tree; the one difference is the internal-error path where Ruby reports one stderr line and Python was silent, kept by the fail-loudly rule and invariant 12 updated. Suite on main after merge: 176 runs, 0 failures. Rubocop: 109 files, no offenses.

Follow-ups: none; invariant 6 names a Python-vs-Ruby ADR-note comparison test that never existed, dropped since the Python is gone; bin/test comment about hook_test.py refers to other plugins, left

## Resolution **Done:** Ported the four os hook files to Ruby under OsHooks (Zeitwerk): StatusPass, StateDir, ProjectConfig, LockGuard, Frontmatter, eight checks in OsHooks::Checks with Registry::ALL keeping the same names and output text; thin hooks/session_start.rb and pre_tool_use.rb; hooks.json runs ruby; new bin/status-checks (--json, --stamp-version) replaces the checks.py/state.py calls that /os:fix made; Python hooks and tests deleted; every Python case ported to Minitest with one use_case tag per hook; doc pointers updated. **Evidence:** main 88b5e3a5 (6f04fc4f). Parity matrix 82 cases (35 SessionStart, 39 PreToolUse, 4 --json, 3 stamp): 81 byte-identical on stdout, stderr, exit and file tree; the one difference is the internal-error path where Ruby reports one stderr line and Python was silent, kept by the fail-loudly rule and invariant 12 updated. Suite on main after merge: 176 runs, 0 failures. Rubocop: 109 files, no offenses. **Follow-ups:** none; invariant 6 names a Python-vs-Ruby ADR-note comparison test that never existed, dropped since the Python is gone; bin/test comment about hook_test.py refers to other plugins, left
jared closed this issue 2026-11-03 14:32:06 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1525
No description provided.