Add fits/entries map headers, entry-gates validator rule, and ticket_shape flag #870

Closed
opened 2026-10-01 14:26:16 +00:00 by jared · 2 comments
Owner

Problem

ADR-0258 decisions 6 and 7 need each map to say when it applies (fits:) and which nodes a reroute may enter (entries:), and need the validator to prove that every path from an entry to merge-ready passes the required-work and suite gates. Today Map::Loader#build_map (adapter/map/loader.rb:24) reads only name, entry, nodes, terminals, and dispatch_cap. Also, Implementation::Open#ticket_map? (command/implementation/open.rb:48) selects the ticket-shape check and retired-test deletion by the basename poodr-ticket-implementation. ADR-0258 replaces that test with a map-level flag.

Reproduce

n/a: design change, nothing to reproduce.

Approach

Map gets three readers: fits (String or nil), entries (Array, default []), and ticket_shape? (from a ticket_shape: true header, default false). The headers are optional at load. A map with no entries is not reroutable; the reroute gate refuses it (later ticket).

New validator check check_entry_gates!: for each name in entries, the name must be a node, and every path from it to a terminal with outcome implementation_complete must pass a node whose gates include both required-work and suite. One way: walk from the entry without entering such a node; the rule fails if the walk reaches an implementation_complete terminal. An entry that carries both gates itself passes. It raises InvalidMapError with codes :unknown_entry and :entry_skips_required_gates. The rule runs only from declared entries.

open.rb asks map.ticket_shape? instead of the basename. Map headers:

  • maps/poodr-ticket-implementation.yaml: fits: one sentence, ticket_shape: true, entries: the nodes whose paths pass suite-check (change-auditor, seam-designer, test-writer, test-reviewer, programmer, programmer-repair, behavior-verifier, refactorer, suite-check). Not contract-auditor: its pass edge goes to merge-ready with no suite-check after it.

#883 deletes maps/coding.yaml and maps/poodr-implementation.yaml (ADR-0259 decision 11), so the ticket map is the only shipped map. No exception to the rule is needed: a ticket with "Required work: none beyond the acceptance criteria" passes the ticket shape, and required-work with no checks is a defined no-op. The rule that a map with entries: also needs the waiting-node reroute exit and the map-router node is in #885, because it needs the waiting node from #872.

Required work:

  1. Read the fits, entries, and ticket_shape headers in the loader — check: present entries in plugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rb
  2. Add the entry-gates validator check — check: present check_entry_gates! in plugins/os-sdlc/lib/os_sdlc/model/map/validator.rb
  3. Replace the basename test with the map flag — check: absent "poodr-ticket-implementation" in plugins/os-sdlc/lib/os_sdlc/command/implementation/open.rb
  4. Add the ticket map ticket-shape flag — check: present ticket_shape: true in plugins/os-sdlc/maps/poodr-ticket-implementation.yaml
  5. Add the ticket map entries — check: present entries: in plugins/os-sdlc/maps/poodr-ticket-implementation.yaml

Acceptance criteria

  1. Given a map whose entry node reaches merge-ready only through a node gated [required-work, suite], when it loads, then it is valid and entries lists that node.
  2. Given a map whose declared entry has a path to merge-ready that skips the required-work gate, when it loads, then it fails with entry_skips_required_gates and names the entry.
  3. Given a map that declares an entry that is not a node, when it loads, then it fails with unknown_entry.
  4. Given a map with no headers, when it loads, then it is valid, entries is empty, and ticket_shape? is false.
  5. Given a map with ticket_shape: true under any file name, when implementation-open runs with a ticket body missing ## Owner sketch, then it refuses the run; given a map without the flag, then it does not check the ticket shape.
  6. Given the shipped ticket map, when it loads, then it is valid and its entries are the nine nodes listed in Approach.

Owner sketch

class OsSdlc::Map
  def fits
  def entries
  def ticket_shape?
end

class OsSdlc::Map::Validator
  def check_entry_gates!
end

Origin

  • Trigger: user ruling on the map reroute design, 2026-10-01 (ADR-0258)
  • Improvised this session: none
  • Chain: a reroute can skip the proving gates ← no map says where a reroute may enter ← DESIGN (docs/adr/0258 decisions 6, 7)
  • Root candidate: #859
  • Where: plugins/os-sdlc/lib/os_sdlc/model/map/validator.rb
  • Session: 55a56279-83ee-47d5-a21e-ee67f9e28abd
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/55a56279-83ee-47d5-a21e-ee67f9e28abd.jsonl

Parent: #859
Blocked by: #868, #883

## Problem ADR-0258 decisions 6 and 7 need each map to say when it applies (`fits:`) and which nodes a reroute may enter (`entries:`), and need the validator to prove that every path from an entry to `merge-ready` passes the `required-work` and `suite` gates. Today `Map::Loader#build_map` (adapter/map/loader.rb:24) reads only `name`, `entry`, `nodes`, `terminals`, and `dispatch_cap`. Also, `Implementation::Open#ticket_map?` (command/implementation/open.rb:48) selects the ticket-shape check and retired-test deletion by the basename `poodr-ticket-implementation`. ADR-0258 replaces that test with a map-level flag. ## Reproduce n/a: design change, nothing to reproduce. ## Approach `Map` gets three readers: `fits` (String or nil), `entries` (Array, default `[]`), and `ticket_shape?` (from a `ticket_shape: true` header, default false). The headers are optional at load. A map with no `entries` is not reroutable; the reroute gate refuses it (later ticket). New validator check `check_entry_gates!`: for each name in `entries`, the name must be a node, and every path from it to a terminal with outcome `implementation_complete` must pass a node whose gates include both `required-work` and `suite`. One way: walk from the entry without entering such a node; the rule fails if the walk reaches an `implementation_complete` terminal. An entry that carries both gates itself passes. It raises `InvalidMapError` with codes `:unknown_entry` and `:entry_skips_required_gates`. The rule runs only from declared entries. `open.rb` asks `map.ticket_shape?` instead of the basename. Map headers: - `maps/poodr-ticket-implementation.yaml`: `fits:` one sentence, `ticket_shape: true`, `entries:` the nodes whose paths pass suite-check (change-auditor, seam-designer, test-writer, test-reviewer, programmer, programmer-repair, behavior-verifier, refactorer, suite-check). Not contract-auditor: its `pass` edge goes to `merge-ready` with no suite-check after it. #883 deletes `maps/coding.yaml` and `maps/poodr-implementation.yaml` (ADR-0259 decision 11), so the ticket map is the only shipped map. No exception to the rule is needed: a ticket with "Required work: none beyond the acceptance criteria" passes the ticket shape, and `required-work` with no checks is a defined no-op. The rule that a map with `entries:` also needs the waiting-node reroute exit and the map-router node is in #885, because it needs the waiting node from #872. Required work: 1. Read the `fits`, `entries`, and `ticket_shape` headers in the loader — check: present `entries` in `plugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rb` 2. Add the entry-gates validator check — check: present `check_entry_gates!` in `plugins/os-sdlc/lib/os_sdlc/model/map/validator.rb` 3. Replace the basename test with the map flag — check: absent `"poodr-ticket-implementation"` in `plugins/os-sdlc/lib/os_sdlc/command/implementation/open.rb` 4. Add the ticket map ticket-shape flag — check: present `ticket_shape: true` in `plugins/os-sdlc/maps/poodr-ticket-implementation.yaml` 5. Add the ticket map entries — check: present `entries:` in `plugins/os-sdlc/maps/poodr-ticket-implementation.yaml` ## Acceptance criteria 1. Given a map whose entry node reaches `merge-ready` only through a node gated `[required-work, suite]`, when it loads, then it is valid and `entries` lists that node. 2. Given a map whose declared entry has a path to `merge-ready` that skips the `required-work` gate, when it loads, then it fails with `entry_skips_required_gates` and names the entry. 3. Given a map that declares an entry that is not a node, when it loads, then it fails with `unknown_entry`. 4. Given a map with no headers, when it loads, then it is valid, `entries` is empty, and `ticket_shape?` is false. 5. Given a map with `ticket_shape: true` under any file name, when implementation-open runs with a ticket body missing `## Owner sketch`, then it refuses the run; given a map without the flag, then it does not check the ticket shape. 6. Given the shipped ticket map, when it loads, then it is valid and its `entries` are the nine nodes listed in Approach. ## Owner sketch ```ruby class OsSdlc::Map def fits def entries def ticket_shape? end class OsSdlc::Map::Validator def check_entry_gates! end ``` ## Origin - Trigger: user ruling on the map reroute design, 2026-10-01 (ADR-0258) - Improvised this session: none - Chain: a reroute can skip the proving gates ← no map says where a reroute may enter ← DESIGN (docs/adr/0258 decisions 6, 7) - Root candidate: #859 - Where: plugins/os-sdlc/lib/os_sdlc/model/map/validator.rb - Session: 55a56279-83ee-47d5-a21e-ee67f9e28abd - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/55a56279-83ee-47d5-a21e-ee67f9e28abd.jsonl Parent: #859 Blocked by: #868, #883
Author
Owner

Work started on branch ticket-870 (os-sdlc pipeline, map poodr-ticket-implementation).

Work started on branch ticket-870 (os-sdlc pipeline, map poodr-ticket-implementation).
Author
Owner

Resolution

Done: fits/entries/ticket_shape map headers (Map::Headers), the entry-gates validator rule (Map::Validator::EntryGates), implementation-open asks map.ticket_shape?, poodr-ticket-implementation.yaml carries the headers. Deviation: implementation 1 was abandoned and re-opened as implementation 2 because the change-auditor submitted a placeholder handoff (summary: x) after its real handoff was refused, and the Runner accepted it.

Evidence: main 74f05b7d (Runner commit, implementation 2 implementation_complete, 13 dispatches, 1 retry; required-work and suite gates green), History row; bin/test on main: 9 suites passed.

Follow-ups: none

## Resolution **Done:** fits/entries/ticket_shape map headers (Map::Headers), the entry-gates validator rule (Map::Validator::EntryGates), implementation-open asks map.ticket_shape?, poodr-ticket-implementation.yaml carries the headers. Deviation: implementation 1 was abandoned and re-opened as implementation 2 because the change-auditor submitted a placeholder handoff (summary: x) after its real handoff was refused, and the Runner accepted it. **Evidence:** main 74f05b7d (Runner commit, implementation 2 implementation_complete, 13 dispatches, 1 retry; required-work and suite gates green), History row; bin/test on main: 9 suites passed. **Follow-ups:** none
jared closed this issue 2026-10-01 17:08:27 +00:00
jared referenced this issue from a commit 2026-10-01 18:24:32 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
jared/cc-os#870
No description provided.