Extract Class.new constants as class cards in system-model #1513
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#1513
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
The system-model extractor does not see a constant made with
Class.new(...).DataDeclaration::KINDSholds onlyData.defineandStruct.new.The os-backlog plugin has six such constants, for example
TrackerCommandFailed,Close::FailedandRefused.None of them has a card in the model.
Each one is an error class.
The model misses them in cards, in inheritance facts, and in class counts.
Observed
plugins/os-sdlc/lib/os_sdlc/system_model/extractor/data_declaration.rb:9:The six os-backlog constants (found with
grep -rnE "[A-Z]\w* = Class\.new" plugins/os-backlog/lib):Reproduce
The count is 0 because no card exists for the class.
Approach
Fact kind choice, decided from the code.
Foo = Class.new(Parent)defines a class, so its card has kind:classandsuperclass"Parent" (the same card thatclass Foo < Parent; endgives viaClassDeclaration,extractor/class_declaration.rb:6-10). It does not get kind:dataor:struct, and it does not get thevalue?fact:FactScan#visit_constant_write_node(extractor/fact_scan.rb:28-34) calls@ledger.value_objectfor everyDataDeclarationmatch, and an error class is not a value object.FactLedger#within(name, superclass:)(extractor/fact_ledger.rb:13-19) already records the superclass, soSubclassessees it. The block form (MissingParts = Class.new(StandardError) do ... end) uses the block body for methods, asDataDeclaration#bodydoes.A new declaration object takes the
Class.newmatch, soDataDeclaration::KINDSstays a lookup of fixed kinds. The three call sites that testDataDeclaration.match?(extractor/walk.rb:22,extractor/body.rb:39,extractor/fact_scan.rb:29) also routeClass.newconstants. A nested form (module A; B = Class.new(StandardError); end) gets the nameA::Bthrough the existing nesting.The argument must be a constant path (
StandardError,Foo::Bar);Class.newwith no argument or a non-constant argument gives superclass nil.Required work:
Class.newconstants — check: presentClassinplugins/os-sdlc/lib/os_sdlc/system_model/extractor/class_new_declaration.rbClassNewDeclarationinplugins/os-sdlc/lib/os_sdlc/system_model/extractor/walk.rbClassNewDeclarationinplugins/os-sdlc/lib/os_sdlc/system_model/extractor/fact_scan.rbClassNewDeclarationinplugins/os-sdlc/lib/os_sdlc/system_model/extractor/body.rbClass.new(StandardError)inplugins/os-sdlc/tests/system_model_*_test.rbOrchestrator work: run
bin/refresh-plugins; add one History row todocs/implementation-status/os-sdlc-system-model.md; run/os-adr:findonce (blast radius found no ADR on extractor kinds).Rejected: add
%i[Class new] => :classtoKINDS— the superclass is the first argument andDataDeclaration#superclassreturns nil, and thevalue?fact would be wrong for an error class.Acceptance criteria
Given
Foo = Class.new(StandardError)at the top level of a file underlib/, when the extractor runs, then the model has a cardFoowith kind:classand superclassStandardError.Given the same constant inside
module Shop, when the extractor runs, then the card is namedShop::Foowith the same kind and superclass.Given
Foo = Class.new(StandardError) do def message = "x" end, when the extractor runs, then the card forFoolistsmessageas a public method.Given
Foo = Class.new(StandardError), when the extractor runs, then the facts forFoodo not havevalue?set.Given the
plugins/os-backlogroot, when the extractor runs, then the model has a card for each ofBacklog::TrackerCommandFailed,Backlog::IssueCreate::Refused,Backlog::Config::WriteCommand::Refused,Backlog::IssueShow::CommandFailed,Backlog::Close::FailedandBacklog::Resolution::MissingParts, each with superclassStandardError.Given a
Data.defineorStruct.newconstant, when the extractor runs, then its card and itsvalue?fact are unchanged.Given
plugins/os-sdlc/lib/os_sdlc/detector/reach_through/parent_answers.rb:37(Forwarders = Class.new(Prism::Visitor) do, the one block-form constant in os-sdlc), when the extractor runs, thenForwardershas its own:classcard and the suite andfast-gatestay green.Given a plugin whose
design/generatedoutput is checked for drift, when the output is regenerated in the same change, then the drift check passes.Owner sketch
Non-goals
Other constructors (
Module.new,Class.newassigned to a non-constant). TheBoot::Commandslazy loads.Origin
plugins/os-sdlc/bin/system-model coverage plugins/os-backloglists no error class thatClass.new(StandardError)defines.DataDeclaration::KINDShas only Data.define and Struct.new ← DESIGN (plugins/os-sdlc/lib/os_sdlc/system_model/extractor/data_declaration.rb:9)VERDICT: CREATE
Work started on branch
ticket-1513through /os-sdlc:implement.Resolution
Done: system-model extracts a constant assigned Class.new(...) { ... } as a class card (name, superclass from the first argument, body facts), beside Data.define value objects. New Extractor::ClassNewDeclaration; Walk, Body and FactScan route it.
Evidence: Commit
a463d6c1on ticket-1513 (implementation 224). New tests in plugins/os-sdlc/tests/system_model_class_new_declaration_test.rb. Suite gate green (dispatch 2050); behavior-verifier pass (2049); contract audit pass (2051).Follow-ups: none