os-aidd-lint: move bin/aidd-lint logic into AiddLint::CLI with an Invocation; bin tests run in-process #639
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#639
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Map: #631
Blocked by #638
Problem
Child of #631. Uses the seam shape that #638 records in its ADR. The plugins have no shared load path, so os-aidd-lint defines its own Invocation value.
Observed
All of the CLI logic lives in plugins/os-aidd-lint/bin/aidd-lint as top-level methods (
main,fix,tier2_prepare,tier2_collect, 193 lines). All 20 tests in plugins/os-aidd-lint/tests/aidd_lint_bin_test.rb forkBIN(13Open3.capture3sites, lines 22-374). The file takes 2.8 s alone (2026-09-23).Reproduce
Expected
One prose sentence:
AiddLint::CLI.new(invocation).run(argv)returns the exit status, writes only toinvocation.stdout/stderr, and bin/aidd-lint only builds the Invocation and calls it.Origin
Owner sketch
Acceptance criteria
AiddLint::CLI.new(invocation).run([path])runs, then the offense line is oninvocation.stdoutand the status is 1.--fixon a correctable file, when run in-process, then the file is rewritten andfixed <path>: <cops>is oninvocation.stdout.--tier2-prepareon two files, when run in-process, then a workdir under the plugin's tmp/ holds manifest.json and one NN.prompt.md per subject, andworkdir <dir>is on stdout.--tier2-collectwithout--tier2-workdir, when run in-process, then the message is oninvocation.stderrand the status is 3.invocation.stderrand the status is 3.Open3, then only the smoke test matches.Approach
exit(AiddLint::CLI.new(AiddLint::Invocation.new(...process...)).run(ARGV)). Keep the existing$LOAD_PATH/require lines in bin.File.expand_path('../tmp', __dir__); from lib/aidd_lint/cli.rb that is'../../tmp'). Move the existing comment that explains the per-prepare workdir with the code. It records an external constraint.run_cli(*args)helper. Do not rename them.Required work:
AiddLint::CLIbehind anAiddLint::Invocation, leaving bin/aidd-lint to build the Invocation and callexit(...). (check:! grep -nE '^def (main|fix|tier2_prepare|tier2_collect)' plugins/os-aidd-lint/bin/aidd-lint)AiddLint::CLIin-process through one shared helper. (proven by AC 7)Structural follow-through
Body before Required-work migration, 2026-09-23
Map: #631
Blocked by #638
Problem
Child of #631. Uses the seam shape that #638 records in its ADR. The plugins have no shared load path, so os-aidd-lint defines its own Invocation value.
Observed
All of the CLI logic lives in plugins/os-aidd-lint/bin/aidd-lint as top-level methods (
main,fix,tier2_prepare,tier2_collect, 193 lines). All 20 tests in plugins/os-aidd-lint/tests/aidd_lint_bin_test.rb forkBIN(13Open3.capture3sites, lines 22-374). The file takes 2.8 s alone (2026-09-23).Reproduce
Expected
One prose sentence:
AiddLint::CLI.new(invocation).run(argv)returns the exit status, writes only toinvocation.stdout/stderr, and bin/aidd-lint only builds the Invocation and calls it.Origin
Owner sketch
Acceptance criteria
AiddLint::CLI.new(invocation).run([path])runs, then the offense line is oninvocation.stdoutand the status is 1.--fixon a correctable file, when run in-process, then the file is rewritten andfixed <path>: <cops>is oninvocation.stdout.--tier2-prepareon two files, when run in-process, then a workdir under the plugin's tmp/ holds manifest.json and one NN.prompt.md per subject, andworkdir <dir>is on stdout.--tier2-collectwithout--tier2-workdir, when run in-process, then the message is oninvocation.stderrand the status is 3.invocation.stderrand the status is 3.Open3, then only the smoke test matches.Approach
exit(AiddLint::CLI.new(AiddLint::Invocation.new(...process...)).run(ARGV)). Keep the existing$LOAD_PATH/require lines in bin.File.expand_path('../tmp', __dir__); from lib/aidd_lint/cli.rb that is'../../tmp'). Move the existing comment that explains the per-prepare workdir with the code. It records an external constraint.run_cli(*args)helper. Do not rename them.Structural follow-through
Work started via /os-sdlc:implement on branch ticket-639 (worktree .claude/worktrees/ticket-639).
Resolution
Done: AiddLint::CLI.new(invocation).run(argv) returns the exit status and writes only to invocation.stdout/stderr; bin/aidd-lint only builds the Invocation and calls it; aidd_lint_bin_test.rb runs in-process with no Open3 forks.
Evidence: Branch ticket-639 commit
9df1d511via os-sdlc implementation 16 (dispatches 181-188, all pass). os-aidd-lint suite: 502 runs, 1196 assertions, 0 failures. Two earlier implementations (14, 15) terminated on a charter defect: judgment charters forbade the ADR-0206 brief fetch over the hook cap; fixed infc8a9686and53697f26on the same branch.Follow-ups: #662 (ticket-skeptic: root cause, charter/ADR-0206 mismatch; audit remaining charters and amend ADR-0206).