Give the .sdlc artifact directory one owner: Project::ArtifactDir [capture] #572
Labels
No labels
P0
P1
P2
P3
bug
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
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#572
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?
Context
The responsibility audit found that Project.sdlc_dir is the stated owner of
the .sdlc directory name, but eight sites build the path from the literal.
The .sdlc/tmp subdirectory has no owner at all. The repository cop at
lib/os_sdlc/cops/repeated_literal_argument.rb:81 already prescribes a
sdlc_dir(root) method for ".sdlc". Callers that would delegate:
Project.sdlc_dir, Project::Yaml#path, Runner::Db, hooks/post_tool_use.rb,
Timing, Lint, AutocorrectPrepass, LintWorklistTarget, RubocopReportFetcher,
Runner::GateHandoff.
Observed
List these sites verbatim:
lib/os_sdlc/project.rb:152 File.join(dir, ".sdlc")
lib/os_sdlc/project/yaml.rb:31 File.join(Project.sdlc_dir(root),
"project.yaml")
lib/os_sdlc/runner/db.rb:12 File.join(root, ".sdlc",
"pipeline.db")
hooks/post_tool_use.rb:42 File.join(root, ".sdlc",
"pipeline.db")
lib/os_sdlc/timing.rb:53 log_path = File.join(root, ".sdlc",
"tmp", "timing.jsonl")
lib/os_sdlc/lint.rb:65 File.join(@root ||
Array(@project_dir).first, ".sdlc", "tmp")
lib/os_sdlc/autocorrect_prepass.rb:101 File.join(@root || @project_dir,
".sdlc", "tmp")
lib/os_sdlc/lint_worklist_target.rb:99 File.join(root, ".sdlc", "tmp")
lib/os_sdlc/rubocop_report_fetcher.rb:12 LintWorklistRubocopConfig.
new(project_root).write(File.join(project_root, ".sdlc", "tmp"))
lib/os_sdlc/runner/gate_handoff.rb:121 LessonLibrary.new(dir: File.
join(project_root, ".sdlc", "lint-lessons"))
Reproduce
n/a: design ticket, no failing behavior
Expected
Prose: every .sdlc child path is produced by one object, and rg '".sdlc"'
lib hooks returns one definition site.
Illustration
illustration, not spec
class Project::ArtifactDir #
lib/os_sdlc/project/artifact_dir.rb
DIRNAME = ".sdlc"
def initialize(root) = @root = root
end
Origin
• Trigger: /os-sdlc:responsibility-audit run 13 on plugins/os-
sdlc/lib/os_sdlc/project.rb, 2026-09-14
• Improvised this session: none
• Chain: eight literal sites ← no owner for child paths ← Project.sdlc_dir
added without a migration of existing callers (DESIGN, lib/os_sdlc/project.
rb:152)
• Root candidate: this ticket
• Where: lib/os_sdlc/project.rb
• Session: 23a382aa-f78e-495f-9cbd-0934e163b37d
• Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/23a382aa-
f78e-495f-9cbd-0934e163b37d.jsonl
Tasks
Project::ArtifactDirat lib/os_sdlc/project/artifact_dir.rb withpath,tmp,pipeline_db,lint_lessons.Project.sdlc_dir(dir)returnsProject::ArtifactDir.new(dir).path.Acceptance criteria
Project::ArtifactDir.new("/r").pathis/r/.sdlc.Project::ArtifactDir.new("/r").tmpis/r/.sdlc/tmp.Project::ArtifactDir.new("/r").pipeline_dbis/r/.sdlc/pipeline.db.Project.sdlc_dir("/r")still returns/r/.sdlc.Structural follow-through
Project::ArtifactDir:Project::Yaml#path,Runner::Db,hooks/post_tool_use.rb,Timing,Lint,AutocorrectPrepass,LintWorklistTarget,RubocopReportFetcher,Runner::GateHandoff.rg -n '"\.sdlc"' plugins/os-sdlc/lib plugins/os-sdlc/hooksreturns only project/artifact_dir.rb.SCHEMA_VERSIONinRunner::Db.ADR case
Amends ADR-0177 (the
.sdlcname moves fromProjectto the nestedProject::ArtifactDir; still underProject). Create the amending ADR when this ticket lands. ADR-0128 (thin hooks) unchanged.Batch
Map: #570. Position 4 of 4. Follows #574. Last in batch. Map: maps/poodr-ticket-implementation.yaml.
Work started via /os-sdlc:responsibility-refactor batch 2 (map #570). Branch: ticket-572, worktree .claude/worktrees/ticket-572, map poodr-ticket-implementation.yaml.
Resolution
Done: Project::ArtifactDir (project/artifact_dir.rb) owns .sdlc and its child paths: path, tmp, pipeline_db, lint_lessons. Project.sdlc_dir and nine sites delegate (Yaml via sdlc_dir, Runner::Db, post_tool_use hook, Timing, Lint, AutocorrectPrepass, LintWorklistTarget, RubocopReportFetcher, GateHandoff). ADR-0181 amends ADR-0177.
Evidence: Merged to main
ca5e3d9(code7734902). Suite 1233 runs, 0 failures; rubocop clean on 11 touched files; pre- and post-tool-use hooks smoke-tested; rg for the .sdlc literal under lib/hooks/bin returns only artifact_dir.rb and the cop catalog entry. Pipeline: 10 dispatches, 632 s, implementation_complete, one test-reviewer rejection; two await_completion stalls hand-settled by gating and subagent-stop. Deviation: structural follow-through applied by hand; first attempt broke both hooks at boot (project.rb required json pre-boot), caught by TimingBootSafetyTest; fixed by moving the json require into Project::Config. SCHEMA_VERSION untouched. Position 4 of 4 on map #570.Follow-ups: none. Re-audit of the batch runs next per map #570.