inward-dependencies lint crashes on reroute/; take roles from a map, not the folder #947
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#947
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?
Problem
bin/lint-inward-dependenciescrashes on os-sdlc.It reads the layer of a constant from the first path segment of its file. The folder
reroute/is not inROLE_LAYER, soHash#fetchraises.ADR-0272 retired the role directories, so the path no longer gives the role. The lint has crashed since 2026-10-01 (
d3f4888faddedlib/os_sdlc/reroute/draft.rb) and nobody saw it for four days.Observed
add_role_entry(line 39) andSourceFile#role(line 65) both takesplit("/").firstof the path.crosses_inward?(line 107) callsrole_layer.fetch(ref_role).Reproduce
Approach
Decision: G2 option A, pass-scoped. The role comes from the
role_by_const:map (the existing input) in every place. The folder-derived map stays as the default when no map is given. The bin script may read the crc ledger as the map source: the G2 document (step 1) says to key the ledgerrolecolumn bynew_constant, or byconstantwhen the verdict iskeep(ledger format:plugins/os-sdlc/skills/crc-refactor/references/ledger.md). Add the ledger input as an optional bin argument. Do not change the default.Required work:
SourceFile#rolelooks up the constant that the file defines in therole_by_constmap. It does not read the path. — check: absentsplit("/").firstinplugins/os-sdlc/lib/os_sdlc/lint/inward_dependencies.rbunmapped <path> <Constant>, and does not raiseKeyError. — check: presentunmappedinplugins/os-sdlc/lib/os_sdlc/lint/inward_dependencies.rbclassormodulenode that only reopens its parent class or module.bin/lint-inward-dependenciesaccepts an optional ledger path and buildsrole_by_constfrom the ledgerrolecolumn (its values are theROLE_LAYERkeys). — check: presentrole_by_constinplugins/os-sdlc/bin/lint-inward-dependenciesROLE_LAYERand asserts that no exception is raised. — check: presentunmappedinplugins/os-sdlc/tests/lint/inward_dependencies_test.rbRejected: suffix convention (G2 candidate 1) — renames concepts and conflicts with A15 and ADR-0272.
Rejected:
LAYERdeclaration in each class — about 360 one-line claims that nothing checks.Rejected: retire the lint (option C) — crc gate 3 loses its outward-reference signal.
Acceptance criteria
ROLE_LAYER, when the lint runs, then it raises no exception.role_by_const, when the lint runs, then the output has oneunmapped <path> <Constant>line for it.bin/lint-inward-dependenciesruns, then it takes each role from the ledger.Owner sketch
OsSdlc::InwardDependenciesowns the role of a constant. It keeps its constructor and gains one collaborator for the ledger.SourceFile#outward_referencesasksrole(role_by_const)and printsunmappedinstead of callingrole_layer.fetch.bin/lint-inward-dependenciesreads the optional ledger path, buildsrole_by_constfrom the ledger, and passes it toInwardDependencies.new.Non-goals
Checking the layer rule between crc passes. Jared rules on that separately (G2 memo 1).
Origin
4b8a1730. Runningbundle exec ruby bin/lint-inward-dependenciesin plugins/os-sdlc raised theKeyError.reroute←SourceFile#rolereads the first path segment ← the lint was written for the ADR-0222 role directories, and ADR-0272 retired them. Stop: DESIGN (ADR-0272 item 3; docs/crc/os-adr/lens-challenge-g2-layer-signal.md).Work started on branch crc-os-adr-2026-10-04 (persistent worktree) via /os-sdlc:implement.
Dropped follow-up: map edge for test-writer unexpected_pass after a behavior-verifier fail. It treats a symptom; the root is the behavior-verifier failing without a probe (now filed).
Resolution
Done: inward-dependencies lint takes each file's role from role_by_const, prints 'unmapped ' instead of raising KeyError, skips reopen-only class/module nodes; bin/lint-inward-dependencies accepts an optional crc ledger TSV and builds role_by_const from its role column (InwardDependencies::Ledger).
Evidence: Commit
d4ff3c09on branch crc-os-adr-2026-10-04 (implementation 29, 20 dispatches, one orchestrator reroute after a wrong verifier verdict). 7/7 lint tests green, suite green twice, contract audit pass. bin/lint-inward-dependencies on real os-sdlc lib now exits 0 and prints 'unmapped lib/os_sdlc/reroute/draft.rb Reroute::Draft' (crashed with KeyError before).Follow-ups: #950 behavior-verifier can fail without a probe; #951 escalation procedure has no recovery for a wrong verdict; map unexpected_pass edge DROPPED by skeptic (root is #950). Branch not yet merged to main: merge waits for the user's decision on the whole crc-os-adr branch.