Migrate os-aidd-lint git show to OsGit read_at #1595

Closed
opened 2026-11-06 16:53:33 +00:00 by jared · 1 comment
Owner

Problem

plugins/os-aidd-lint/lib/aidd_lint/gate.rb runs git show HEAD:<path> in its own call. The PostToolUse hook (Write, Edit, MultiEdit) reaches it through edited_file.rb.

Design: docs/os-git/use-cases-and-domain.md (design) and docs/os-git/call-site-checklist.md (call sites). Settled decisions are in design section 1 (docs/os-git/use-cases-and-domain.md): the gem lives in plugins/os-git with a path: source; git-context and os:worktree merge into os-git; old wrappers go only after all references are updated; design order is use-cases, objects, interfaces; os-context and os-vault become Ruby; ticket tracking stays out of os-git.

Reproduce

n/a: migration of existing call sites; behavior stays the same unless a criterion says otherwise.

Approach

Group A-07. Replace Gate.git_show with Repository#read_at("HEAD", path). A path that is absent at the revision returns nil, and the gate treats it as "all words new", as today. Use RepoRoot or Repository.find to detect the repository. This hook fires on every edit: keep the number of git processes at or below today's count, and wrap the hook edge in OsGit::FailOpen.

Mark every row in the checklist from the Done column as it is replaced. Mark the matching test rows in the same change. Run bin/refresh-plugins after changes to SKILL.md, hooks, or CLIs.

Required work: none beyond the acceptance criteria.

Acceptance criteria

  1. Given an edited file tracked at HEAD, when the gate runs, then it compares against the HEAD text as before.
  2. Given a new file absent at HEAD, when the gate runs, then it treats all words as new and does not raise.
  3. Given a directory outside any repository, when the gate runs, then it skips the git read.
  4. Given plugins/os-aidd-lint/tests/gate_test.rb (row G-175), when it runs, then it uses OsGit::Testing::ScratchRepo and passes.
  5. Given row G-045 and the test row G-175, when the ticket closes, then each row is marked - [x] with Replaced by filled in, or marked out of scope with a reason, in docs/os-git/call-site-checklist.md.
  6. Given the touched code, when it is searched for Open3, system(, %x, backticks, and git argv, then no git call remains outside OsGit adapters, except sites marked out of scope with a reason.

Blocking edges

Blocked by the core ticket (#1588).

Origin

  • Trigger: User request in session 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 on 2026-11-06: one os-git gem for all local git work in cc-os and the user's projects.
  • Improvised this session: none
  • Chain: own git show call on a hot hook ← no shared read-at-revision message ← DESIGN (docs/os-git/call-site-checklist.md group A-07)
  • Root candidate: none found; searched open issues for git, worktree, octokit, ruby port, python, statusline, reset --hard. Related but not a match: #845, #853, #857, #1527, #1554.
  • Where: plugins/os-aidd-lint/lib/aidd_lint/gate.rb
  • Session: 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/1a5b2630-09c9-46cb-aee4-a5a98e2e7d24.jsonl
## Problem `plugins/os-aidd-lint/lib/aidd_lint/gate.rb` runs `git show HEAD:<path>` in its own call. The PostToolUse hook (Write, Edit, MultiEdit) reaches it through `edited_file.rb`. Design: `docs/os-git/use-cases-and-domain.md` (design) and `docs/os-git/call-site-checklist.md` (call sites). Settled decisions are in design section 1 (`docs/os-git/use-cases-and-domain.md`): the gem lives in `plugins/os-git` with a `path:` source; `git-context` and `os:worktree` merge into `os-git`; old wrappers go only after all references are updated; design order is use-cases, objects, interfaces; `os-context` and `os-vault` become Ruby; ticket tracking stays out of `os-git`. ## Reproduce n/a: migration of existing call sites; behavior stays the same unless a criterion says otherwise. ## Approach Group A-07. Replace `Gate.git_show` with `Repository#read_at("HEAD", path)`. A path that is absent at the revision returns `nil`, and the gate treats it as "all words new", as today. Use `RepoRoot` or `Repository.find` to detect the repository. This hook fires on every edit: keep the number of git processes at or below today's count, and wrap the hook edge in `OsGit::FailOpen`. Mark every row in the checklist from the `Done` column as it is replaced. Mark the matching test rows in the same change. Run `bin/refresh-plugins` after changes to `SKILL.md`, hooks, or CLIs. Required work: none beyond the acceptance criteria. ## Acceptance criteria 1. Given an edited file tracked at HEAD, when the gate runs, then it compares against the HEAD text as before. 2. Given a new file absent at HEAD, when the gate runs, then it treats all words as new and does not raise. 3. Given a directory outside any repository, when the gate runs, then it skips the git read. 4. Given `plugins/os-aidd-lint/tests/gate_test.rb` (row G-175), when it runs, then it uses `OsGit::Testing::ScratchRepo` and passes. 5. Given row G-045 and the test row G-175, when the ticket closes, then each row is marked `- [x]` with `Replaced by` filled in, or marked out of scope with a reason, in `docs/os-git/call-site-checklist.md`. 6. Given the touched code, when it is searched for `Open3`, `system(`, `%x`, backticks, and `git` argv, then no git call remains outside `OsGit` adapters, except sites marked out of scope with a reason. ## Blocking edges Blocked by the core ticket (#1588). ## Origin - Trigger: User request in session 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 on 2026-11-06: one os-git gem for all local git work in cc-os and the user's projects. - Improvised this session: none - Chain: own git show call on a hot hook ← no shared read-at-revision message ← DESIGN (docs/os-git/call-site-checklist.md group A-07) - Root candidate: none found; searched open issues for git, worktree, octokit, ruby port, python, statusline, reset --hard. Related but not a match: #845, #853, #857, #1527, #1554. - Where: plugins/os-aidd-lint/lib/aidd_lint/gate.rb - Session: 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/1a5b2630-09c9-46cb-aee4-a5a98e2e7d24.jsonl
Author
Owner

Resolution

Done: Gate reads HEAD through Repository#read_at in FailOpen. OsGit loads only for an in-scope Write.

Evidence: main ea19631d. os-aidd-lint 534 runs, 0 failures. Hook median 97.0 ms to 106.5 ms on an in-scope Write; skipped paths unchanged. read_at is one process (cat-file --batch). Rows G-045, G-175 marked.

Follow-ups: none

## Resolution **Done:** Gate reads HEAD through Repository#read_at in FailOpen. OsGit loads only for an in-scope Write. **Evidence:** main ea19631d. os-aidd-lint 534 runs, 0 failures. Hook median 97.0 ms to 106.5 ms on an in-scope Write; skipped paths unchanged. read_at is one process (cat-file --batch). Rows G-045, G-175 marked. **Follow-ups:** none
jared closed this issue 2026-11-06 22:05:57 +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#1595
No description provided.