os-sdlc: POODR/standards cleanup of phase-3 runner code #347
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#347
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
Post-#341 review (standards axis, opus) found the new runner code under
plugins/os-sdlc/lib/os_sdlc/runner/violates the plugin's own Forbidden Moves and several POODR rules. Behavior is correct (797 tests green); this is a refactor-only ticket. All findings are in code added by commits 651695f..f692b7a.Findings to fix (each with location)
engine.rb:4-6,engine_factory.rb:6-10,ticket_flow.rb:20-21and:33-36,transition_table.rb:59-60, plus the "Holds X as instance state so it isn't threaded through parameter lists" refactor-rationale sentence copy-pasted into ~10 class comments (brief_assembler, event_handler, gate_evaluator, gate_failure_flow, stage_brief_writer, transition_applier, row_builder, row_validator, terminal_reachability, cycle_checker). Delete them all from lib/; ADR-citing headers in TEST files are accepted house style and stay. Also delete the false comment onEngine#handle_eventclaiming a parked ticket "never returns nil" (the parking event itself returns nil).TransitionTable#reaches_terminal_via_success?newsTerminalReachabilityper call;GateFailureFlow#retry_ledgernewsRetryLedgerper call;Resumer/StageBriefWriterinlineBriefAssembler.new. Inject with sensible defaults (def initialize(..., ledger: RetryLedger.new(db))-style) so tests can substitute.validate!buildsRowValidator.new(row:, table: self)which calls back intotable.known_state?/row_lookup/reaches_terminal_via_success?. Pass the validator the data (state set, lookup, reachability checker) instead of the whole table.on_failurePrimitive Obsession: the{route:, retries:, exhausted:}Hash is poked inRetryLedger,GateFailureFlow,RowValidator,TransitionTable#edges_from. Introduce a smallOnFailurevalue type (Data.define) withroute/retries/exhaustedreaders; construct it inRowBuilder.Brief.read,BriefAssembler#read,TransitionTable#skippable?,attr_reader :entry_state,Engine#parked_infohave no production caller. Delete each unless a test legitimately depends on it as the observable seam (e.g.entry_stateis asserted in map_loader_test — keep anything a spec-level test observes; delete the rest).Engine.for(**options)+options.fetch(:table): restore an explicit keyword signature.map_namedeclared in bothadd_ticket_columnsandensure_column!(ColumnSpec.new(:tickets, :map_name, String))(db.rb:44,73) — one declaration.extract_flag's bare secondargs.delete_at(idx)as the return value is unreadable; make the return explicit, and fold theextract_map_flagmiddle-man.NOTE: the shared-brief-writer duplication (resumer.rb:56-83 / stage_brief_writer.rb:14-33) is deliberately EXCLUDED — it is fixed by the brief-seq ticket filed alongside this one. Skip it here to avoid a collision; if that ticket lands first, rebase on its extraction.
Scope
.equal?branches — already tracked there), Repeated-Switchesrow.kindpolymorphism (judgement call — leave unless it falls out naturally of item 4), GateEvaluator CQS restructuring (flag if trivial, else leave).Acceptance criteria
grep -rn "so .* isn't threaded\|legacy\|per ADR\|ADR-01" plugins/os-sdlc/lib/returns nothing that is narrative — test files exempt).ast-grep run --lang ruby -p '$C.new($$$A)'over lib/os_sdlc/runner shows no collaborator construction inside public method bodies of TransitionTable/GateFailureFlow/Resumer/StageBriefWriter (defaults ininitializeare fine).RowValidatorno longer receivestable: self.on_failure[:route]-style Hash access is gone; all readers go through the OnFailure type.Shipped in
e988002: narrative comments stripped, collaborators injected, OnFailure value type, RowValidator decoupled from table, dead surface removed (Brief.read kept — house cop seam). 799 runs green, rubocop clean.Restored coverage for escalation clearing on resume (retry/abort/skip) lost in e988002's cleanup, via Escalation.fetch returning nil post-deactivate. Commit
e6523b6. GateFailureFlow's guarded retry-counter reset checked and confirmed live (it doesn't route through TransitionApplier), so left as-is.Resolution
Done: POODR cleanup: narrative comments stripped, collaborators injected, OnFailure value type introduced, RowValidator decoupled from table, dead public surface removed (Brief.read retained as house seam). Escalation clearing on resume restored. 799 tests green, rubocop clean.
Evidence:
e988002,e6523b6Follow-ups: none
Approved-by: jared