Resolve drafted maps from maps/drafts/ through Map::Catalog #880
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.
Blocks
Depends on
Reference
jared/cc-os#880
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
ADR-0258 decision 9 lets map-router draft a map at
maps/drafts/<name>.yamland the run continues on it. ADR-0261 makes the file location the draft status: there is nodraftcolumn onreroutes(it becomesapplied_at, #895) and nodraft:keyword on load. Nothing resolves a drafted name today.Implementation#current_maplooks formaps/<name>.yamland fails.presenter/brief.rb:6resolvesbrief:paths from the map's directory; a draft inmaps/drafts/must still resolve them from the plugin maps directory (ADR-0258 decision 10). The A/B memo on this ticket is resolved by ADR-0261. Where drafts are written is open (#898); this ticket resolves names under the catalog directory only.Reproduce
n/a: design change, nothing to reproduce.
Approach
plugins/os-sdlc/maps/drafts/(with.gitkeep).Map.newtakespath:(Map::Loader#build_mappasses the@pathit holds). AddMap#pathandMap#drafted?:File.basename(File.dirname(path)) == "drafts".Map#namereturnsFile.basename(path, ".yaml").Map::Catalog(adapter/map/catalog.rb) resolves a name to exactly one file:maps/<name>.yamlfirst, thenmaps/drafts/<name>.yaml. It raisesInvalidMapErrorwhen the name is in both and when it is in neither (Reroute::Draft#loaded_map, reroute/draft.rb:56, rescues onlyInvalidMapErrorandSystemCallError).load(name)takes nodraft:keyword.Implementation#current_mapcallscatalog.load(reroutes.first.map)with no draft flag.Brief.forkeepsMap::Catalog.default.dirasmap_dirfor drafts, sobrief:paths resolve frommaps/, notmaps/drafts/.approved_mapsfact (query/brief/facts.rb) globsmaps/*.yamlonly, so drafts never reach a change-auditor reroute brief (ADR-0258 decision 9). Add a test that pins this. This test and the AC 4 and AC 5 tests pin existing behavior, so they are green from the start.name:line fromplugins/os-sdlc/maps/*.yamland every fixture map underplugins/os-sdlc/tests/fixtures/maps/, and remove:namefromMap::Headersanddata["name"]from the loader. Update the authoring prose inskills/map-making/SKILL.md. ADR-0263 (amends ADR-0261 decisions 2 and 5).name:header differs from their file basename areobjections_loop.yaml(headerobjections-loop) androle_mismatch.yaml(headerrole-mismatch). Tests that assertmap.nameon those fixtures will see the basename after this change and must be checked.Required work:
maps/drafts/— check: present"drafts"inplugins/os-sdlc/lib/os_sdlc/adapter/map/catalog.rbdef drafted?inplugins/os-sdlc/lib/os_sdlc/model/map.rbpath:inplugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rbFile.basename(path, ".yaml")inplugins/os-sdlc/lib/os_sdlc/model/map.rb:nameinplugins/os-sdlc/lib/os_sdlc/model/map/headers.rbdata["name"]inplugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rbname:inplugins/os-sdlc/maps/*.yamlname:inplugins/os-sdlc/tests/fixtures/maps/*.yaml"name" => "built"inplugins/os-sdlc/tests/support/entry_map_builder.rbthe map nameinplugins/os-sdlc/skills/map-making/SKILL.mdAcceptance criteria
maps/drafts/x.yamland nomaps/x.yaml, whenMap::Catalog#load("x")runs, then it returns a map withdrafted?true andpathending inmaps/drafts/x.yaml.maps/x.yamland no draft of that name, whenMap::Catalog#load("x")runs, then it returns a map withdrafted?false.maps/andmaps/drafts/, or in neither, whenMap::Catalog#loadruns, then it raises an error that names the name and the directories searched.brief: briefs/start.md, when that node's brief is composed, then the file resolves from the catalog maps directory, not fromdrafts/.maps/drafts/, when theapproved_mapsfact is resolved, then the joined document has noMap:line for it.maps/drafts/x.yaml, when it is loaded, thenmap.nameis "x" andmap.drafted?is true.Owner sketch
Origin
Parent: #859
Blocked by: #868, #871, #885, #895
Work started: os-sdlc pipeline on branch ticket-880 (worktree .claude/worktrees/ticket-880).
Ruling needed: what does
reroutes.draftmean?Implementation 14 escalated at change-auditor (dispatch 88,
verdict: fail, escalation 6). The run waits atneeds-orchestrator. #880, #881 and #882 wait for this ruling.Conflict. Two Accepted ADRs give the one column
reroutes.drafttwo meanings:drafttrue means "resolvemaps/drafts/<name>.yaml" (a drafted map). #880 AC 1 depends on this meaning.draftmarker" for a pending reroute. #873 implemented that marker with the same column:Landing sets
draft: false, so afterapply!no row can say "this map came frommaps/drafts/". #880 AC 1 ("a reroutes row withdraft: true...current_maploadsmaps/drafts/x.yaml") cannot hold.Option A: a timestamp records application;
draftkeeps its ADR-0258 meaningAmends the ADR-0260 wording ("draft marker" becomes
applied_at). Follows the architecture rule "Record transitions as timestamps. Never add a state or status column" (.claude/rules/os-sdlc-architecture.md).Option B:
draftkeeps the pending meaning; a new column marks a drafted mapAmends the ADR-0258 schema (the drafted-map flag gets a new name). The
draftboolean stays a persisted state flag.Recommendation: A, confidence 80%. The deciding reason: pending-then-applied is a transition, and the repo rule records transitions as timestamps; that also restores ADR-0258's literal schema, so #880 and #881 need no text change.
Ask and default. Reply A or B (or another shape). With A, I file one ticket for the
applied_atchange (schema bump, amending ADR to ADR-0260), run it before #880, and then run #880 -> #881 -> #882. If you say nothing, #880, #881 and #882 stay open and implementation 14 stays waiting; no code changes.Resolve drafted maps from maps/drafts/ through Map::Catalogto Resolve drafted maps from maps/drafts/ through MapCatalogThe A/B memo on this ticket is resolved by ADR-0261 (commit
93202771). The YAML file is the source of truth; the file location (maps/ or maps/drafts/) is the draft status; MapCatalog (#896) resolves a name to exactly one file. Body rewritten. Blocked by #895 and #896; drafts location is open in #898.Resolve drafted maps from maps/drafts/ through MapCatalogto Resolve drafted maps from maps/drafts/ through Map::CatalogImplementation 14 abandoned with os-sdlc-implementation-abandon (#899) on 2026-10-02. #880 re-runs with a fresh implementation-open after #895 lands.
Work started: /os-sdlc:implement on branch ticket-880 (worktree .claude/worktrees/ticket-880), after #895 (schema 30) and ADR-0261/0262/0263.
Blocked 2026-10-02. Implementation 4 failed at change-auditor (dispatch 15): verdict:error. The agent's real pass handoff was refused by the harness as too complex three times and once failed JSON parsing; it then ran os-sdlc-subagent-stop with a stub verdict: error to test the submission, and the Runner accepted it as the dispatch's verdict and closed the run. Earlier today: implementation 1 failed on a stale Required-work path (fixed in the body); implementation 2 escalated on a test-writer stub defect (hand-fixed
c585e62c); implementation 3 hit unexpected_pass because implementation 2's uncommitted production changes were still in the worktree (set aside to the session scratchpad as a patch). Recovery: a fresh implementation-open. Defect ticket: #901.Resumed 2026-10-02: fresh implementation-open (run 5) per user decision; #901 tracks the run-4 defect.
Resolution
Done: Map gains path and drafted?; Map#name is File.basename(path, '.yaml') and the name: header is removed from Map::Headers, the loader, plugin maps and all fixture maps; Map::Catalog resolves maps/ then maps/drafts/ and raises InvalidMapError naming both candidate files when a name is in both or neither; load takes no draft: keyword; maps/drafts/ exists; map-making prose updated.
Evidence: Commits
bd38b788(Runner, implementation 5: 8 dispatches, 0 retries, suite-check green, contract-auditor pass) and21876554(fixture maps + History row); test hand-fixc585e62cfrom implementation 2. ADR-0261, ADR-0262, ADR-0263.Follow-ups: #901 (Runner accepts a test submission as verdict), #903 (test-reviewer stub gap; diff-test stops at first red), #897 and #900 now unblocked; lens proposal on the drafts directory literal is being challenged and, if justified, captured as a ready-for-human Lens proposal ticket.