required-work gate skips check: commands written mid-line, the capture template's own form #820

Closed
opened 2026-09-28 22:13:56 +00:00 by jared · 2 comments
Owner

Problem

The #814 parser TicketShape::RequiredWork::Item finds a check only on a line that starts with check: (CHECK_LINE = /^\s*check:(.*)$/ in plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb). The capture template writes checks in the middle of the line: 1. <item> — check: `<command>` . So the required-work gate step never runs those checks and passes. implementation-open also does not refuse a free-text check in the middle of a line. The deterministic gate from #814 is bypassed for every ticket written from the template.

Observed

body = "## Approach\nRequired work:\n1. Delete the foo helper — check: `! grep -rn foo lib`\n2. Other item\n   check: `true`\n3. Free text — check: grep foo prints nothing\n"
OsSdlc::TicketShape.new(body).required_work_checks   # => ["true"]   item 1 missed
OsSdlc::TicketShape.new(body).missing.grep(/check/)  # => []         item 3 not refused

Found when the #817 behavior-verifier (dispatch 722) failed the os-backlog twin rule for the same narrowing.

Reproduce

cd plugins/os-sdlc && ruby -Ilib -e 'require "os_sdlc"; p OsSdlc::TicketShape.new("## Approach\nRequired work:\n1. Delete foo — check: `true`\n").required_work_checks'

Expected ["true"], actual [].

Approach

An item's check is the first check: anywhere in the item's lines, on the numbered line or on a later line. The command is the backticked text that follows that check:. Backticks before check: do not count. This is the same rule as the os-backlog checker in #817 (ADR-0209 lockstep, ADR-0244).

Decision record: ADR-0244.

Required work:

  1. TicketShape::RequiredWork::Item finds check: anywhere in the item's lines and takes the command only from backticked text after it.

Acceptance criteria

  1. Given a Required work item 1. Delete the foo helper — check: true``, when the required work checks are read, then the list contains true.
  2. Given a Required work item 1. Delete the foo helper; check: grep -r foo lib prints nothing, when implementation-open runs, then it refuses and names the item.
  3. Given a Required work item 1. Update `foo.rb`; check: grep foo prints nothing, when implementation-open runs, then it refuses and names the item.
  4. Given a Required work item whose check: is on its own line under the numbered line with a backticked command, when the required work checks are read, then the list contains that command.

Owner sketch

class TicketShape::RequiredWork
  Item = Data.define(:lines) do
    def check
    def command
  end
end

Origin

  • Trigger: #817 behavior-verifier fail, dispatch 722
  • Improvised this session: none
  • Chain: gate skips template-form checks <- CHECK_LINE anchored at line start <- #814 implementation, whose tests used own-line checks only (plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb)
  • Root candidate: this ticket
  • Where: plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb
  • Session: 47a537c2-08a1-4d3c-9688-75df56dfdd3d
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-808/47a537c2-08a1-4d3c-9688-75df56dfdd3d.jsonl
  • Related: #814, #817

VERDICT: CREATE
REASON: The CHECK_LINE anchor in the #814 parser silently skips the capture template's own mid-line check: form. That is an observed failure, and it bypasses a validation gate. The Origin chain has no improvisation, and this file is the root, separate from the os-backlog rule in #817.

## Problem The #814 parser `TicketShape::RequiredWork::Item` finds a check only on a line that starts with `check:` (`CHECK_LINE = /^\s*check:(.*)$/` in `plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb`). The capture template writes checks in the middle of the line: ``1. <item> — check: `<command>` ``. So the `required-work` gate step never runs those checks and passes. `implementation-open` also does not refuse a free-text check in the middle of a line. The deterministic gate from #814 is bypassed for every ticket written from the template. ## Observed ```ruby body = "## Approach\nRequired work:\n1. Delete the foo helper — check: `! grep -rn foo lib`\n2. Other item\n check: `true`\n3. Free text — check: grep foo prints nothing\n" OsSdlc::TicketShape.new(body).required_work_checks # => ["true"] item 1 missed OsSdlc::TicketShape.new(body).missing.grep(/check/) # => [] item 3 not refused ``` Found when the #817 behavior-verifier (dispatch 722) failed the os-backlog twin rule for the same narrowing. ## Reproduce ``` cd plugins/os-sdlc && ruby -Ilib -e 'require "os_sdlc"; p OsSdlc::TicketShape.new("## Approach\nRequired work:\n1. Delete foo — check: `true`\n").required_work_checks' ``` Expected `["true"]`, actual `[]`. ## Approach An item's check is the first `check:` anywhere in the item's lines, on the numbered line or on a later line. The command is the backticked text that follows that `check:`. Backticks before `check:` do not count. This is the same rule as the os-backlog checker in #817 (ADR-0209 lockstep, ADR-0244). Decision record: ADR-0244. Required work: 1. `TicketShape::RequiredWork::Item` finds `check:` anywhere in the item's lines and takes the command only from backticked text after it. ## Acceptance criteria 1. Given a Required work item `1. Delete the foo helper — check: `true``, when the required work checks are read, then the list contains `true`. 2. Given a Required work item `1. Delete the foo helper; check: grep -r foo lib prints nothing`, when `implementation-open` runs, then it refuses and names the item. 3. Given a Required work item ``1. Update `foo.rb`; check: grep foo prints nothing``, when `implementation-open` runs, then it refuses and names the item. 4. Given a Required work item whose `check:` is on its own line under the numbered line with a backticked command, when the required work checks are read, then the list contains that command. ## Owner sketch ```ruby class TicketShape::RequiredWork Item = Data.define(:lines) do def check def command end end ``` ## Origin - Trigger: #817 behavior-verifier fail, dispatch 722 - Improvised this session: none - Chain: gate skips template-form checks <- CHECK_LINE anchored at line start <- #814 implementation, whose tests used own-line checks only (plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb) - Root candidate: this ticket - Where: plugins/os-sdlc/lib/os_sdlc/parser/ticket_shape/required_work.rb - Session: 47a537c2-08a1-4d3c-9688-75df56dfdd3d - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-808/47a537c2-08a1-4d3c-9688-75df56dfdd3d.jsonl - Related: #814, #817 VERDICT: CREATE REASON: The `CHECK_LINE` anchor in the #814 parser silently skips the capture template's own mid-line `check:` form. That is an observed failure, and it bypasses a validation gate. The Origin chain has no improvisation, and this file is the root, separate from the os-backlog rule in #817.
Author
Owner

Work started on branch ticket-820 via /os-sdlc:implement, target os-sdlc.

Work started on branch ticket-820 via /os-sdlc:implement, target os-sdlc.
Author
Owner

Resolution

Done: TicketShape::RequiredWork::Item finds check: anywhere in an item line (CHECK_LINE unanchored); mid-line template-form checks now reach the required-work gate and free-text mid-line checks are refused at implementation-open. ADR-0244 decision 5 records the placement rule.

Evidence: Implementation 73 complete: 8 dispatches, 5 min 57 s, all pass. Commits 44943074, d6555c8f on ticket-820. Original repro now returns ['! grep -rn foo lib', 'true'] and refuses the free-text item. os-sdlc suite 1306 runs, 0 failures, 16.2 s. Suite-check ran [required-work, suite] live.

Follow-ups: #821 (os-backlog reads only numbered lines; lockstep). Greedy BACKTICKED_COMMAND and 'recheck:' matching: dropped, no ticket asks for them and no case was observed. Stray .sdlc/pipeline.db in the edited source folder (second time): under investigation this session.

## Resolution **Done:** TicketShape::RequiredWork::Item finds check: anywhere in an item line (CHECK_LINE unanchored); mid-line template-form checks now reach the required-work gate and free-text mid-line checks are refused at implementation-open. ADR-0244 decision 5 records the placement rule. **Evidence:** Implementation 73 complete: 8 dispatches, 5 min 57 s, all pass. Commits 44943074, d6555c8f on ticket-820. Original repro now returns ['! grep -rn foo lib', 'true'] and refuses the free-text item. os-sdlc suite 1306 runs, 0 failures, 16.2 s. Suite-check ran [required-work, suite] live. **Follow-ups:** #821 (os-backlog reads only numbered lines; lockstep). Greedy BACKTICKED_COMMAND and 'recheck:' matching: dropped, no ticket asks for them and no case was observed. Stray .sdlc/pipeline.db in the edited source folder (second time): under investigation this session.
jared closed this issue 2026-09-28 22:28:01 +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#820
No description provided.