os-backlog: bin/os-backlog resolves CC_OS_HOME once into state_dir; library takes paths as parameters; remove CliEnvContext #718
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#718
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?
Blocked-by: #716
Problem
plugins/os-backlog/lib/backlog/cli_env_context.rb:6,21,26stashes a caller-suppliedenv:hash inThread.current[:backlog_cli_env]and falls back toENVwhen nothing is threaded;Backlog::CLI.start(env:)sets it around every dispatch.It is consumed only by
ProjectsCommand.new(env:)(cli.rb:33) andConfigWriteCommand.new(repo_root:, env:)(cli_command_helpers.rb:207), and both use it only to computeProjectIndex.default_path(env:)(project_index.rb:10, readsenv["CC_OS_HOME"]or falls back toenv.fetch("HOME", Dir.home), then.cc-os/projects.json).Wakeup::State.default_path(wakeup/state.rb:9) has the identicalCC_OS_HOME/HOMEfallback but was not threaded through the CLI context at all, even though #707 intended to thread it —bin/wakeup-poll:48,71,72constructBacklog::ProjectIndex.newandBacklog::Wakeup::State.newwith no path, so they always read liveENV.This is the shape #716 supersedes: only
bin/should read process globals; the library should take an explicit path.Approach
Required work:
bin/os-backlogto computestate_dir = Backlog::StateDir.from(ENV)and callBacklog::CLI.start(ARGV, state_dir: state_dir);Backlog::CLI.startstores it in Thor config (mirror ADR-0207'sconfig.fetch(:invocation)pattern) instead ofThread.current[:backlog_cli_env]; deletecli_env_context.rband theextend Backlog::CliEnvContextline incli.rb.Backlog::ProjectIndex.new(path:): deleteself.default_path(env:); callers passFile.join(state_dir, "projects.json")explicitly. Same forBacklog::Wakeup::State.new(path:): deleteself.default_path(env:); callers passFile.join(state_dir, "wakeup-state.json").ProjectsCommand.new(index:)andConfigWriteCommand.new(repo_root:, index:)(both currently build their ownProjectIndexfromenv:) to receive an already-constructedBacklog::ProjectIndexinstead;cli.rb:33andcli_command_helpers.rb:207build the index once fromconfig.fetch(:state_dir)and pass it in.bin/wakeup-pollto computestate_dir = Backlog::StateDir.from(ENV)once (line 48 area) and constructBacklog::ProjectIndex.new(path: File.join(state_dir, "projects.json"))andBacklog::Wakeup::State.new(path: File.join(state_dir, "wakeup-state.json"))explicitly, replacing the no-arg.newcalls at lines 48 and 71; thesummary_pathderivation at line 72 (currentlyFile.dirname(Backlog::Wakeup::State.default_path)) becomesFile.dirname(state.instance_variable_get...)-free by deriving it fromstate_dirdirectly.path:/state_dir:explicitly instead ofenv:;plugins/os-backlog/tests/projects_cli_contract_test.rbkeeps spawning the binary withCC_OS_HOME=in its shell string — that test exercisesbin/itself, which remains the one place that readsENV.Acceptance criteria
grep -rn "CC_OS_HOME\|Thread.current" plugins/os-backlog/lib, then the command prints no matches.grep -rln "CC_OS_HOME" plugins/os-backlog/bin, thenbin/os-backlogandbin/wakeup-pollare the only matches.bin/wakeup-pollrun against aCC_OS_HOMEpointing at a temp directory, when it runs, then it reads and writeswakeup-state.jsonunder that directory rather than the real~/.cc-os.chdirrequirement introduced by this change).Owner sketch
Retired tests
plugins/os-backlog/tests/cli_env_threading_test.rb
plugins/os-backlog/tests/project_index_test.rb#test_default_path_honors_cc_os_home_override
plugins/os-backlog/tests/project_index_test.rb#test_default_path_falls_back_to_home
Non-goals
plugins/os-backlog/lib/backlog/checkout.rb:30'sENV["USER"]fallback stays untouched (out of scope for this ticket).plugins/oschanges (ticket 1, separate ticket).A shared StateDir resolver: two identical lines in bin/ are acceptable until #699 decides on shared code.
Origin
Session: 89876543-c418-46b0-b994-dd6dc6887802
Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/89876543-c418-46b0-b994-dd6dc6887802.jsonl
Trigger: review of #634/#707/#708 (commits
8ef12ae8,e2817ffe, ADR-0218)Improvised this session: none
Chain: env:/thread-local in lib ← ADR-0218 item 1 chose spawn-env-hash + Thread.current ← DESIGN (docs/adr/ADR-0218…, contradicts ADR-0213 and ADR-0207)
Root candidate: #716 (the superseding ADR)
Work started on branch ticket-718 via /os-sdlc:implement (session 89876543).
Resolution
Done: bin/os-backlog and bin/wakeup-poll resolve CC_OS_HOME once; ProjectIndex/Wakeup::State take path:, ProjectsCommand/ConfigWriteCommand take index:; CliEnvContext, thread-local and default_path(env:) deleted; CLI.start requires config state_dir
Evidence: branch ticket-718 commit
289a1654; os-backlog suite 248 runs 0 failures; grep CC_OS_HOME|Thread.current in lib empty; pipeline impl 38 ran to contract-auditor which errored on the ticket's own StateDir-in-lib sketch, sketch corrected and remaining shim hand-finishedFollow-ups: checkout.rb:30 ENV[USER] read stays (non-goal, ADR-0213 shape); shared StateDir resolver deferred to #699