Project::Yaml owns .sdlc/project.yaml: one path, one reader, one guarded writer (supersedes ADR-0088 in part) #567
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#567
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: #568
Blocked by #566
Context
Responsibility audit of
project.rbon 2026-09-13. Batch position 4 of 4. Runs last.Projectwrites.sdlc/project.yamlfrom three sites, checks the git prerequisite twice, reads the file twice without refusing an empty file, and builds the path by hand in two places.Observed
save_tracker(lines 147-149) bypassesraise_targets_shaped_write!(line 97) and the existence check. An empty file makesYAML.safe_load_filereturn nil, thenNoMethodErrorat line 98 andnil.fetchat line 31 instead ofHarnessError.Reproduce
Expected
Illustration
Callers that delegate:
Project.load,Project.create,Project.upsert,Project#save_tracker,Project#tracker_required_error,Project.discover_root,ProjectConfigCommand#reportand#report_unreadable.User decisions 2026-09-13:
.sdlcdirectory name belongs toProject. It is the per-project os-sdlc artifact directory. Onlyproject.yamlbelongs toYaml.Project.discover_rootandProject#preflight_summary_line. No senders outside their own tests, verified across lib, bin, hooks, skills, and agents.Project.createas a one-line delegator. The error text atproject.rb:48names it and test support uses it.Tasks
/os-adr:create(supersedes ADR-0088 in part: write refusal moves fromProject.upsertand the project-config command intoProject::Yaml; consistent with ADR-0055, root derived from file location;.sdlcdirname stays withProject)OsSdlc::Project::Yamlatlib/os_sdlc/project/yaml.rbdiscover_rootandpreflight_summary_lineand their testsAcceptance criteria
File.writeand one path expression forproject.yamlunder libOrigin
/os-sdlc:responsibility-audit plugins/os-sdlc/lib/os_sdlc/project.rbon 2026-09-13; analysis at.sdlc/tmp/responsibility-audit/2026-09-13-project/analysis.yamlOsSdlc::Project← DESIGN (plugins/os-sdlc/lib/os_sdlc/project.rb, ADR-0055/0074/0088/0169/0174)OsSdlc::Project,plugins/os-sdlc/lib/os_sdlc/project.rbWork started via /os-sdlc:implement on branch ticket-567 (worktree). Map: #568.
BLOCKED: pipeline implementation 4 ended implementation_failed, reason bound_exhausted:test-reviewer/fail after 32 dispatches. Failed step: test-writer could not express 'callers delegate to Project::Yaml' as a public-boundary test; its last attempt (test_create_delegates_the_write_to_project_yaml) monkey-patched Yaml#write and was rejected. Done and green on branch ticket-567 (WIP commit, not merged): Project::Yaml class at lib/os_sdlc/project/yaml.rb with read/write/path and targets-shaped refusal plus tests/project/yaml_test.rb; Project.load raises HarnessError on an empty file; save_tracker refuses a targets-shaped file; ADR-0177 written. Outstanding: Project.load/create/upsert/save_tracker/tracker_required_error and ProjectConfigCommand do not yet delegate to Yaml (the guards are duplicated inside Project); Yaml lacks containing/exist?/merge_keys; discover_root and preflight_summary_line not deleted. Resume: hand pass or code-write on the delegation, then suite, then worktree finish. Suite at stop: 1215 runs, 0 failures.
Resolution
Done: Project::Yaml owns .sdlc/project.yaml: containing/path/exist?/read/write/merge_keys; Project.load/create/upsert/save_tracker and Runner::TeaTracker delegate; discover_root and preflight_summary_line deleted; ADR-0177.
Evidence: Merged to main
f2639b1(WIPa9b2838from the pipeline + hand structural follow-through9d22487). Under lib: one File.write and one path expression for project.yaml, both in project/yaml.rb. Suite 1215 runs, 0 failures. Pipeline stop root-caused: test-reviewer/fail bound counted ticket-wide; fixed by progress_reset in4bbea74.Follow-ups: #569 token columns empty for implementations 2 and 3; ADR-0177 affected-paths lists a cli/ segment that does not exist (typo, dropped as trivial)