os-sdlc: replace code_path with an explicit target root; every role sees the whole target #645
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#645
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
Found during #638 impl 13 root-cause analysis: the behavior-verifier reported no evidence for a bin/ change because bin/ is outside the target's code_path.
Observed
Each target has one
code_pathstring (plugins/os-sdlc/lib/os_sdlc/model/project/code.rb:5-11, default "lib",include?= start_with?).Model::Project::Changes(changes.rb:8-21) drops every changed file outside it, so behavior-verifiercode_changes(brief_facts.rb:86) and the diff-test gate (gate_commands.rb:35-44) never seebin/or other code dirs (Rails: app/, config/, db/). Agent charters also limit reading to code_path with no stated reason: change-auditor.md:11 (--root <code_path>), reviewer.md:9, seam-designer.md:11, test-writer.md:25-26, programmer.md:24. Lint worklist already goes past code_path (lint/worklist_target.rb:29,51,59adds bin/ and lint_paths).Absorbs #629 (verifier misses bin/ changes; on #638 impl 13 the verifier said "code_changes has no hunk for plugins/os-sdlc/bin/os-sdlc-runner"). Also: a bin/-only change passes diff-test untested, because bin/ never enters
code_pathsand never trips the unmapped full-suite fallback (gate_commands.rb:37). Separate but related: #625 (fallback fires on every run because new files have no test yet).Restrictions WITH a stated reason stay: refactorer/lint-fixer write scope (production only), test-reviewer tests only, responsibility-audit production only.
Reproduce
n/a: design/cross-cutting ticket, not a single reproducible bug
Expected
Every pipeline role sees the whole target root, not just code_path. code_changes and diff-test gates cover files like bin/os-sdlc-runner.
Approach (proposed, for discussion)
Replace
code_pathwith an explicit per-target root key (no name→path object exists today:Project#rootis the repo root,project_targets.rbhas no directory concept; andcc-plugins/.sdlc/project.yamltargetrendererhas code_pathapi-wrapper/skills/api-wrapper/renderer/lib, so the target name cannot derive the path). Rule: code = under target root, not under test_path, not in an exclusion list.Blast radius (from lsp-probe/ast-grep/grep):
tests_forraises outside code_path, :13-19), changes.rb, flat_attrs.rb:7, yaml/document.rb:8-9, project.rb:44-46 (to_flat_h), gate_commands.rb, lint/worklist_target.rb (~9 files).Highest risks:
Test#covering(test.rb:14-18) mirrors the path after stripping code_path (lib/os_sdlc/x.rb→tests/os_sdlc/x_test.rb); stripping only the root givestests/lib/os_sdlc/...which does not exist; needs an explicit rule..sdlc/dirs inside plugins,tmp/(plugins/os-aidd-lint/tmp), generated dirs would count as code.Related: #629, #625, #643, #639-#641 (all change bin/).
Origin
Decision memo: open choices in #645 (design review claude-opus-5-5, 2026-09-23)
Two facts the body does not record:
Changes#changed_pathsuses the default glob"*.rb"(adapter/git/repo.rb:50), sobin/os-sdlc-runner(no extension) is dropped before any path check.plugins/os-aidd-lint/tmp/andplugins/os-sdlc/.sdlc/tmp/are gitignored, andchanged_pathsusesls-files --exclude-standard.D1. Key: add
root_path, keepcode_pathas the test-mirroring anchorA (additive, chosen):
B (replace):
root:withcode_pathas a deprecated alias.Recommendation: A, 75%. The default
dirname(code_path)is the anchor ADR-0100/0103 already use, so every other repo's.sdlc/project.yamlworks unchanged.root_path, notroot, becauseProject#rootalready means the repo root.D2. Test-name mapping: keep mirroring relative to
code_pathA (chosen):
tests_for(file)returns nil whenfileis outsidecode_path; mapping is unchanged.B: strip the root and drop a leading
lib|app|srcsegment.Recommendation: A, 80%. All existing mappings stay byte-identical in every repo.
D3. Exclusions: git ignore rules plus a fixed segment constant, no config key
Recommendation: A, 75%. ADR-0102: no exclude mechanism until a real need appears.
D4. Unmapped fallback: a code file with no resolvable test (bin/, hooks/) widens diff-test to the full suite
Recommendation: A, 75%. Closes "bin/-only change passes untested" with no new naming convention. A
bin/<name>→<name>_bin_test.rbmapping is a possible follow-up.D5. Charters: widen every read scope without a stated reason to
root_pathchange-auditor.md, reviewer.md, seam-designer.md, test-writer.md, programmer.md, code-probe SKILL.md + cheatsheet; responsibility-audit stays production-only ("root_path excluding test_path"); setup-project adds
root_path.Recommendation: A, 70%. Otherwise code-probe docs contradict the charters.
D6. File kind: code =
*.rbor an extensionless file with a ruby shebangB would treat every
.md/.jsonedit as code and force full-suite runs.Recommendation: A, 70%.
Taking all recommendations. Recorded as an ADR amending ADR-0180, 0173, 0174, 0100, 0103.
Resolution
Done: Per-target root_path (default parent of code_path). Code = Ruby file (*.rb or ruby shebang) under root_path, not under test_path, not in .sdlc/vendor/node_modules/tmp. Changes reads every changed file, so bin/ reaches code_changes; a code file with no resolvable test widens diff-test to the full suite. tests_for returns nil outside code_path. Lint bin/ anchor = root_path. --root-path CLI flag. Charters and code-probe read root_path. ADR-0208 amends 0100/0103/0173/0174/0180. Other repos' .sdlc/project.yaml need no edit.
Evidence: main
1725c5bc(fast-forward from ticket-645). os-sdlc suite 1411 runs, 3211 assertions, 0 failures (48.8 s). New tests: code_root_test, codebase_code_test, changes_bin_files_test, gate_commands_bin_fallback_test, brief_facts_bin_file_test, validation_root_path_test, lint_worklist_target_root_path_test. Plugins refreshed.Follow-ups: #629 stays open for non-Ruby files (charters, settings.json) in code_changes. New: LSP timing-test flake under load; worktree .cc-os ignore pattern. Rejected: bin/ test mapping (no observed cost).