os-sdlc phase 3: build the map-as-data pipeline per ADR-0112/0113 #341
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#341
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?
Implement the design recorded in ADR-0112 (YAML maps, load-time termination proofs in TransitionTable#validate!, stepper-run gates, map selection argument > project.yaml > default) and ADR-0113 (push brief assembly, verdict.md first-line parsing, park-and-notify escalation, programmer/reviewer skill preloading + programmer tool contract: +Bash, -Edit). Draft map: plugins/os-sdlc/maps/default.yaml. Supersedes SkeletonTable. TDD; sequencing/gate logic only in lib/os_sdlc/runner/.
This was the acceptance criteria from the code-probe. I am curious if this would have been better handled (closer to POODR) by breaking it down further, or considering each acceptance criterion as its own wave:
Ticket #341 Wave 2 — runner semantics (ADR-0113 + stepper-run gates from ADR-0112). Write FAILING minitest tests only; never write implementation. Project root: /home/jared/dev/cc-os/plugins/os-sdlc. Code path lib/os_sdlc/runner/, tests tests/runner/ (auto-globbed by tests/all.rb). Read the existing runner code first — engine.rb, engine_factory.rb, db.rb, dispatch.rb, ticket.rb, skeleton_table.rb, command_result.rb, and existing tests/runner/engine_test.rb — and follow their construction/test idioms (in-memory/temp Sequel db, etc.).
Wave 1 (already green, committed):
TransitionTable.from_yaml(path), extended Row (on_failure {route:, retries:, exhausted:}, kind:, skippable:), termination proofs,MapSelector.new(plugin_maps_dir:, project:).resolve(explicit:),Project#map. The shipped map is maps/default.yaml (states intake→code-probe→test-writer→programmer→lint→review→merge-ready, escalation kind: human, terminal [merge-ready, failed]).Acceptance criteria to cover:
routeand increments a per-ticket-per-state retry counter; failure number N+1 (cap exhausted) routes to theexhaustedtarget instead. retries: 0 = one failure goes straight to exhausted..sdlc/tickets/<ticket>/briefs/<seq>-<from>-to-<to>.md(seq = zero-padded ordinal), records the path on the dispatches row, and includes it in the dispatch action it emits. Briefs are retained (never deleted) after ticket completion..sdlc/tickets/<ticket>/verdict.mdin Ruby (a verdict-reading object, not shell): exactly "APPROVE" → success; exactly "REQUEST-CHANGES" → gate failure counting against review's retry cap, and the verdict body is snapshotted into the numbered review→programmer brief before the next round can overwrite verdict.md; missing file or malformed first line → plain failure counting against the cap.kind: humanstate: persist state "escalation" plus the exhausted-from state and gate-log path in SQLite; notify via injected ports (a tracker port receiving add-waiting-label + blocker comment, a notifier port receiving a push notification) — test with fakes/spies, never real tea/network; the engine then stops emitting dispatches (parked). Resuming a parked ticket surfaces the parked info and supports: retry (counter reset), retry-with-guidance (a note string prepended to the retry brief, counter reset), skip (only legal when the exhausted row has skippable: true → advances to its on_success), abort (→ terminal "failed").Design freedom: name new collaborators as the tests need (e.g. GateTemplate, RetryLedger, BriefAssembler, Verdict, Escalation, TrackerPort/NotifierPort fakes); constructor-injected ports. Don't edit existing test files; new files per concern. Sandi Metz style. If an AC can't be expressed without seeing a piece of existing code behavior, read that file rather than guessing.
Implemented on main: commits
651695f,18803bd,8906a27,5ff06f3,f692b7a. 797 tests green, rubocop clean. Four review rounds by os-sdlc:reviewer (opus); final verdict APPROVE. Tracker/notifier adapters + SkeletonTable legacy-branch retirement deferred to #342. Awaiting human sign-off.Resolution
Done: Implemented map-as-data pipeline per ADR-0112/0113: YAML map loader, load-time termination proofs in TransitionTable#validate!, stepper-run gates, map selection (args > project.yaml > default), push brief assembly, verdict gate, park-and-notify escalation, programmer/reviewer skill preloading. Supersedes SkeletonTable.
Evidence:
651695f,18803bd,8906a27,5ff06f3,f692b7aFollow-ups: none
Approved-by: jared