Run os-aidd-lint hook and CLI tests in-process #1334

Closed
opened 2026-10-25 19:48:33 +00:00 by jared · 2 comments
Owner

Problem

The os-aidd-lint hooks post_tool_use (10 tests), session_start (4), and session_end (4) have a top-level def main. HookInput.read reads $stdin. Tests can only start them as subprocesses. aidd_lint_test also spawns the CLI once. About 1.5 s of the 2.4 s suite goes to spawns.

Approach

Extract each hook body into a class with an injectable stdin, for example AiddLint::Hooks::PostToolUse#run(invocation). The hook script calls the class. Convert the aidd_lint_test spawn to AiddLint::CLI.new(invocation).run(argv).

Behavior is unchanged. The existing suite is the proof. Each bin or hook keeps exactly one smoke test, in a file named <bin>_bin_smoke_test.rb. The smoke test runs it as a subprocess to prove the plain-ruby boot and the shebang. Calls to external tools (git, rubocop) stay as subprocess calls.

Required work:

  1. Extract AiddLint::Hooks::PostToolUse, AiddLint::Hooks::SessionStart, and AiddLint::Hooks::SessionEnd from the hook scripts.
  2. Convert the hook tests and aidd_lint_test to call the classes and AiddLint::CLI.
  3. Add one <bin>_bin_smoke_test.rb file per hook and for the CLI.

Acceptance criteria

  1. Given the converted tests, when the suite runs, then no test outside a *_bin_smoke_test.rb file starts a plugin bin/ or hooks/ script as a subprocess.
  2. Given each bin and hook, when its smoke test runs, then it boots with plain ruby and exits 0 on --help or on empty valid input.
  3. Given a hook class and an invocation with a stdin string, when run is called, then it gives the same output as the hook script did.
  4. Given the converted tests, when they run, then they pass with the same assertions as before.

Owner sketch

AiddLint::Hooks::PostToolUse#run(invocation) and AiddLint::CLI.new(invocation).run(argv).

Origin

  • Trigger: ruby plugins/os-sdlc/tests/all.rb took 65.8 s against a 60 s budget. About 70% of summed test time is tests that start our own bin scripts with Open3.
  • Improvised this session: none
  • Chain: suite over budget ← tests start our own Ruby bin, hook, or CLI as a subprocess (Ruby boot cost per call) ← no rule says to call the in-process entry (Jared ruling, 2026-10-25; habit, no ADR)
  • Root candidate: none found; searched Open3, subprocess, in-process, bin_test, run_bin, Boot.run, ProcessIO
  • Where: plugins/os-aidd-lint/hooks, plugins/os-aidd-lint/bin, plugins/os-aidd-lint/tests
  • Session: 01c29715-c945-43b4-86fc-6c5fc6c4dd3f
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/01c29715-c945-43b4-86fc-6c5fc6c4dd3f.jsonl
## Problem The os-aidd-lint hooks `post_tool_use` (10 tests), `session_start` (4), and `session_end` (4) have a top-level `def main`. `HookInput.read` reads `$stdin`. Tests can only start them as subprocesses. `aidd_lint_test` also spawns the CLI once. About 1.5 s of the 2.4 s suite goes to spawns. ## Approach Extract each hook body into a class with an injectable stdin, for example `AiddLint::Hooks::PostToolUse#run(invocation)`. The hook script calls the class. Convert the `aidd_lint_test` spawn to `AiddLint::CLI.new(invocation).run(argv)`. Behavior is unchanged. The existing suite is the proof. Each bin or hook keeps exactly one smoke test, in a file named `<bin>_bin_smoke_test.rb`. The smoke test runs it as a subprocess to prove the plain-ruby boot and the shebang. Calls to external tools (git, rubocop) stay as subprocess calls. Required work: 1. Extract `AiddLint::Hooks::PostToolUse`, `AiddLint::Hooks::SessionStart`, and `AiddLint::Hooks::SessionEnd` from the hook scripts. 2. Convert the hook tests and `aidd_lint_test` to call the classes and `AiddLint::CLI`. 3. Add one `<bin>_bin_smoke_test.rb` file per hook and for the CLI. ## Acceptance criteria 1. Given the converted tests, when the suite runs, then no test outside a `*_bin_smoke_test.rb` file starts a plugin `bin/` or `hooks/` script as a subprocess. 2. Given each bin and hook, when its smoke test runs, then it boots with plain ruby and exits 0 on `--help` or on empty valid input. 3. Given a hook class and an invocation with a stdin string, when `run` is called, then it gives the same output as the hook script did. 4. Given the converted tests, when they run, then they pass with the same assertions as before. ## Owner sketch `AiddLint::Hooks::PostToolUse#run(invocation)` and `AiddLint::CLI.new(invocation).run(argv)`. ## Origin - Trigger: `ruby plugins/os-sdlc/tests/all.rb` took 65.8 s against a 60 s budget. About 70% of summed test time is tests that start our own bin scripts with Open3. - Improvised this session: none - Chain: suite over budget ← tests start our own Ruby bin, hook, or CLI as a subprocess (Ruby boot cost per call) ← no rule says to call the in-process entry (Jared ruling, 2026-10-25; habit, no ADR) - Root candidate: none found; searched Open3, subprocess, in-process, bin_test, run_bin, Boot.run, ProcessIO - Where: plugins/os-aidd-lint/hooks, plugins/os-aidd-lint/bin, plugins/os-aidd-lint/tests - Session: 01c29715-c945-43b4-86fc-6c5fc6c4dd3f - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/01c29715-c945-43b4-86fc-6c5fc6c4dd3f.jsonl
Author
Owner

Work started in /os-sdlc:fast-batch fast-batch-15, branch fast-batch-15.

Work started in /os-sdlc:fast-batch fast-batch-15, branch fast-batch-15.
Author
Owner

Resolution

Done: os-aidd-lint hook bodies moved to AiddLint::Hooks classes with an injected Invocation; tests in-process; a missing cwd warns and exits 0 as before (R12).

Evidence: Finding F a7e0ae2e, 605b77d9; fixes R12 784126ce, R17 1ae9c537. Suites at c9f5db8f: os-sdlc 2701 runs 0 failures (53.1 s, budget 60 s), os 47, os-backlog 327, os-aidd-lint 491, os-adr 111, os-me 399, cc-architect plugin_config 106, all green. Merged to main c9f5db8f, pushed be5d2c5d. Batch state and rulings: docs/crc/os-sdlc/fast-batch-15/.

Follow-ups: #1337 (cop). Nothing else.

## Resolution **Done:** os-aidd-lint hook bodies moved to AiddLint::Hooks classes with an injected Invocation; tests in-process; a missing cwd warns and exits 0 as before (R12). **Evidence:** Finding F a7e0ae2e, 605b77d9; fixes R12 784126ce, R17 1ae9c537. Suites at c9f5db8f: os-sdlc 2701 runs 0 failures (53.1 s, budget 60 s), os 47, os-backlog 327, os-aidd-lint 491, os-adr 111, os-me 399, cc-architect plugin_config 106, all green. Merged to main c9f5db8f, pushed be5d2c5d. Batch state and rulings: docs/crc/os-sdlc/fast-batch-15/. **Follow-ups:** #1337 (cop). Nothing else.
jared closed this issue 2026-10-26 21:21:27 +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#1334
No description provided.