validate-template --agent-ready catches a missing Required work header and a literal none in Retired tests before decompose applies ready-for-agent #732

Closed
opened 2026-09-25 19:09:06 +00:00 by jared · 3 comments
Owner

Problem

The "Ticket body style" rules preloaded into /os-backlog:ticket-decompose and /os-backlog:capture say Approach lists are numbered lines.
They do not say the Approach must contain a Required work: header, or the none-line Required work: none beyond the acceptance criteria..
They do not say ## Retired tests entries are parsed as paths, so a literal none fails implementation-open with Retired tests (not found: none).
Only references/templates/capture.md carries the header.
os-backlog validate-template N cannot catch either gap before ready-for-agent is applied.
HeadingContentIssues checks the Required work header only when the issue already carries ready-for-agent (plugins/os-backlog/lib/backlog/heading_content_issues.rb:50), and RetiredTestLines::LINE_PATTERN accepts the word none (plugins/os-backlog/lib/backlog/retired_test_lines.rb:5).
The decompose skill never runs validate-template before applying ready-for-agent.
On 2026-09-25 four procman tickets were decomposed to ready-for-agent and every one failed implementation-open with ticket body missing: Approach has no "Required work:" list; ... Retired tests (not found: none).

Reproduce

1. Decompose a ticket following only the preloaded body rules; write ## Retired tests with none.
2. os-backlog validate-template N   (passes: no readiness label yet, and none matches the regex)
3. Apply ready-for-agent and run os-sdlc-implementation-open.

Observed: implementation-open refuses with both gaps. Expected: validate-template reports both gaps before the label is applied.

Approach

validate-template N gains an --agent-ready flag that runs the ready-for-agent checks as if the label were present.
RetiredTestLines rejects the literal line none, so the validator agrees with the os-sdlc parser, which rejects any entry that is not a path on disk.
The decompose skill runs os-backlog validate-template N --agent-ready and applies ready-for-agent only on exit 0.
The body-style rules name the Required work: header, the exact none-line, and the rule to omit ## Retired tests when there is nothing to retire.

Prose edits (no test):

  • plugins/os-backlog/references/body-style.md: add the Required work: header rule with the exact none-line, and the rule "omit ## Retired tests when there is nothing to retire; never write none; each line is a test path checked on disk by implementation-open".
  • plugins/os-backlog/skills/ticket-decompose/SKILL.md: before each point that applies ready-for-agent, run ${CLAUDE_PLUGIN_ROOT}/bin/os-backlog validate-template <n> --agent-ready and apply the label only on exit 0.

Required work:

  1. Add --agent-ready to validate-template so the Required work check runs without the label — check: os-backlog validate-template N --agent-ready on an unlabeled body with no Required work: exits nonzero and names the header.
  2. Make RetiredTestLines reject the literal line none — check: os-backlog validate-template N on a body whose ## Retired tests holds none exits nonzero and names the entry.
  3. Update body-style.md and ticket-decompose SKILL.md as listed under prose edits.

Rejected: checking each Retired tests entry against the filesystem in validate-template — the validator runs from any cwd and has no repo root parameter; the literal none is the observed failure.
Rejected: shortening the ticket to prose only — the four failures show prose rules alone do not hold.

Acceptance criteria

  1. Given an issue with no readiness label whose ## Approach has no Required work: header, when os-backlog validate-template N --agent-ready runs, then it exits nonzero and reports the missing Required work: list.
  2. Given the same issue, when os-backlog validate-template N runs without --agent-ready, then the Required work check does not run, as today.
  3. Given an issue whose ## Retired tests section contains the line none, when os-backlog validate-template N runs, then it exits nonzero and reports the none entry as invalid.
  4. Given an issue whose ## Approach has Required work: with numbered items and no ## Retired tests section, when os-backlog validate-template N --agent-ready runs, then it exits 0.

Owner sketch

class Backlog::TemplateValidator
  def validate(body, labels:, agent_ready: false)
  end
end

class Backlog::RetiredTestLines
  def invalid
  end
end

Origin

  • Trigger: os-sdlc-runner implementation-open on procman #2, 2026-09-25; reshaped 2026-09-27 after implementation 51 failed at seam-designer (validate-template cannot observe either gap before the label)
  • Improvised this session: a haiku agent inserted Required work: and removed the ## Retired tests sections on procman #1-#4
  • Chain: implementation-open refuses ← body lacks header ← decompose rules omit it and validate-template checks the header only when ready-for-agent is already set ← DESIGN (plugins/os-backlog/lib/backlog/heading_content_issues.rb:50, retired_test_lines.rb:5; parser at plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape.rb:85)
  • Root candidate: this ticket
  • Where: plugins/os-backlog/lib/backlog/template_validator.rb, heading_content_issues.rb, retired_test_lines.rb; skills/ticket-decompose/SKILL.md; references/body-style.md
  • Session: 8dde24ae-74d3-4884-810d-e4c873a6c2ab
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-ruby-gems-procman/8dde24ae-74d3-4884-810d-e4c873a6c2ab.jsonl

VERDICT: CREATE — real observed failure on four tickets with clear provenance; validate-template exists but is not wired into decompose and cannot run the check before the label; distinct from #727/#728/#730.

## Problem The "Ticket body style" rules preloaded into /os-backlog:ticket-decompose and /os-backlog:capture say Approach lists are numbered lines. They do not say the Approach must contain a `Required work:` header, or the none-line `Required work: none beyond the acceptance criteria.`. They do not say `## Retired tests` entries are parsed as paths, so a literal `none` fails implementation-open with `Retired tests (not found: none)`. Only references/templates/capture.md carries the header. `os-backlog validate-template N` cannot catch either gap before `ready-for-agent` is applied. `HeadingContentIssues` checks the Required work header only when the issue already carries `ready-for-agent` (plugins/os-backlog/lib/backlog/heading_content_issues.rb:50), and `RetiredTestLines::LINE_PATTERN` accepts the word `none` (plugins/os-backlog/lib/backlog/retired_test_lines.rb:5). The decompose skill never runs validate-template before applying `ready-for-agent`. On 2026-09-25 four procman tickets were decomposed to ready-for-agent and every one failed implementation-open with `ticket body missing: Approach has no "Required work:" list; ... Retired tests (not found: none)`. ## Reproduce ``` 1. Decompose a ticket following only the preloaded body rules; write ## Retired tests with none. 2. os-backlog validate-template N (passes: no readiness label yet, and none matches the regex) 3. Apply ready-for-agent and run os-sdlc-implementation-open. ``` Observed: implementation-open refuses with both gaps. Expected: validate-template reports both gaps before the label is applied. ## Approach `validate-template N` gains an `--agent-ready` flag that runs the ready-for-agent checks as if the label were present. `RetiredTestLines` rejects the literal line `none`, so the validator agrees with the os-sdlc parser, which rejects any entry that is not a path on disk. The decompose skill runs `os-backlog validate-template N --agent-ready` and applies `ready-for-agent` only on exit 0. The body-style rules name the `Required work:` header, the exact none-line, and the rule to omit `## Retired tests` when there is nothing to retire. Prose edits (no test): - plugins/os-backlog/references/body-style.md: add the `Required work:` header rule with the exact none-line, and the rule "omit `## Retired tests` when there is nothing to retire; never write `none`; each line is a test path checked on disk by implementation-open". - plugins/os-backlog/skills/ticket-decompose/SKILL.md: before each point that applies `ready-for-agent`, run `${CLAUDE_PLUGIN_ROOT}/bin/os-backlog validate-template <n> --agent-ready` and apply the label only on exit 0. Required work: 1. Add `--agent-ready` to `validate-template` so the Required work check runs without the label — check: `os-backlog validate-template N --agent-ready` on an unlabeled body with no `Required work:` exits nonzero and names the header. 2. Make `RetiredTestLines` reject the literal line `none` — check: `os-backlog validate-template N` on a body whose `## Retired tests` holds `none` exits nonzero and names the entry. 3. Update body-style.md and ticket-decompose SKILL.md as listed under prose edits. Rejected: checking each Retired tests entry against the filesystem in validate-template — the validator runs from any cwd and has no repo root parameter; the literal `none` is the observed failure. Rejected: shortening the ticket to prose only — the four failures show prose rules alone do not hold. ## Acceptance criteria 1. Given an issue with no readiness label whose `## Approach` has no `Required work:` header, when `os-backlog validate-template N --agent-ready` runs, then it exits nonzero and reports the missing `Required work:` list. 2. Given the same issue, when `os-backlog validate-template N` runs without `--agent-ready`, then the Required work check does not run, as today. 3. Given an issue whose `## Retired tests` section contains the line `none`, when `os-backlog validate-template N` runs, then it exits nonzero and reports the `none` entry as invalid. 4. Given an issue whose `## Approach` has `Required work:` with numbered items and no `## Retired tests` section, when `os-backlog validate-template N --agent-ready` runs, then it exits 0. ## Owner sketch ```ruby class Backlog::TemplateValidator def validate(body, labels:, agent_ready: false) end end class Backlog::RetiredTestLines def invalid end end ``` ## Origin - Trigger: os-sdlc-runner implementation-open on procman #2, 2026-09-25; reshaped 2026-09-27 after implementation 51 failed at seam-designer (validate-template cannot observe either gap before the label) - Improvised this session: a haiku agent inserted Required work: and removed the ## Retired tests sections on procman #1-#4 - Chain: implementation-open refuses ← body lacks header ← decompose rules omit it and validate-template checks the header only when ready-for-agent is already set ← DESIGN (plugins/os-backlog/lib/backlog/heading_content_issues.rb:50, retired_test_lines.rb:5; parser at plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape.rb:85) - Root candidate: this ticket - Where: plugins/os-backlog/lib/backlog/template_validator.rb, heading_content_issues.rb, retired_test_lines.rb; skills/ticket-decompose/SKILL.md; references/body-style.md - Session: 8dde24ae-74d3-4884-810d-e4c873a6c2ab - Transcript: /home/jared/.claude/projects/-home-jared-dev-ruby-gems-procman/8dde24ae-74d3-4884-810d-e4c873a6c2ab.jsonl VERDICT: CREATE — real observed failure on four tickets with clear provenance; validate-template exists but is not wired into decompose and cannot run the check before the label; distinct from #727/#728/#730.
Author
Owner

Work started 2026-09-27 on branch ticket-732 via /os-sdlc:implement.

Work started 2026-09-27 on branch ticket-732 via /os-sdlc:implement.
Author
Owner

Implementation 51 failed at seam-designer (dispatch 528, verdict fail). Gate details: validate-template runs the Required work check only when the issue already has ready-for-agent (heading_content_issues.rb:50), and RetiredTestLines::LINE_PATTERN accepts the literal none (retired_test_lines.rb:5), so the ticket's acceptance criteria 2 and 3 cannot be observed without a validator change. Reshaping the ticket to add --agent-ready and the none rejection, then re-opening on branch ticket-732.

Implementation 51 failed at seam-designer (dispatch 528, verdict fail). Gate details: validate-template runs the Required work check only when the issue already has ready-for-agent (heading_content_issues.rb:50), and RetiredTestLines::LINE_PATTERN accepts the literal none (retired_test_lines.rb:5), so the ticket's acceptance criteria 2 and 3 cannot be observed without a validator change. Reshaping the ticket to add --agent-ready and the none rejection, then re-opening on branch ticket-732.
jared changed title from ticket-decompose runs validate-template before ready-for-agent and its body rules state the Required work header to validate-template --agent-ready catches a missing Required work header and a literal none in Retired tests before decompose applies ready-for-agent 2026-09-27 15:26:21 +00:00
Author
Owner

Resolution

Done: validate-template accepts --agent-ready so the Required work check runs before the label is applied; RetiredTestLines rejects the literal line none; body-style.md names the Required work header, the exact none-line, and the omit-Retired-tests rule; ticket-decompose runs validate-template --agent-ready before both points that apply ready-for-agent.

Evidence: Implementation 52 on branch ticket-732, 8 dispatches, zero retries, all gates green; tests in plugins/os-backlog/tests/template_validator_test.rb; os-backlog suite green. Implementation 51 (first attempt) failed at seam-designer because the original ticket premise was false: validate-template ran the Required work check only when ready-for-agent was already set, so the ticket was reshaped to add the validator changes.

Follow-ups: none

## Resolution **Done:** validate-template accepts --agent-ready so the Required work check runs before the label is applied; RetiredTestLines rejects the literal line none; body-style.md names the Required work header, the exact none-line, and the omit-Retired-tests rule; ticket-decompose runs validate-template --agent-ready before both points that apply ready-for-agent. **Evidence:** Implementation 52 on branch ticket-732, 8 dispatches, zero retries, all gates green; tests in plugins/os-backlog/tests/template_validator_test.rb; os-backlog suite green. Implementation 51 (first attempt) failed at seam-designer because the original ticket premise was false: validate-template ran the Required work check only when ready-for-agent was already set, so the ticket was reshaped to add the validator changes. **Follow-ups:** none
jared closed this issue 2026-09-27 15:36:05 +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.

Dependencies

No dependencies set

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