Skip to content

Stop a dependency this run satisfied from blocking the next epic - #10

Merged
ederign merged 2 commits into
mainfrom
fix/blocked-is-not-failed
Aug 29, 2026
Merged

Stop a dependency this run satisfied from blocking the next epic#10
ederign merged 2 commits into
mainfrom
fix/blocked-is-not-failed

Conversation

@ederign

@ederign ederign commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Why

RHAI-761 was removed from the pipeline permanently by two defects that compounded, forty seconds apart on the RHAISTRAT-2671 run.

The gate read a snapshot the same run had invalidated. check_dependencies.py reads each dependency's jira_status from the on-disk epic-task file, written once at the start of the run by fetch_jira_epics.py. That run then closed RHAI-760 in Jira at 19:06:49 and invoked its dependent at 19:07:29 — which read a snapshot still saying In Progress and refused to start.

The refusal was recorded as a terminal failure. The skill wrote codegen_outcome: failed, and the pipeline maps a codegen that produced no artifacts to CI state Failed. Failed is in CI_TERMINAL_STATES, so the epic is skipped on every subsequent run until someone edits the data repo by hand. Declining to start is a statement about the world, which changes between runs — not about the epic.

What changed

  • transition_issue() writes the new status back to the epic-task snapshot on every successful epic-level transition (sync_epic_task_jira_status). Nine epic-level call sites pass the directory; the two strategy-level sites don't, since strategy keys have no epic-task file.
  • The skill records a gate stop as codegen_outcome=blocked, added to CODEGEN_OUTCOMES — the single constant the codegen-run schema enum and merge_run_metadata validation both derive from.
  • _ci_handle_ready sends blocked back to CI state Blocked with blocked_by intact and no failure_reason. Anything else still yields Failed.

Querying Jira live from the gate was the alternative for the first half. Rejected: it puts a network call in a per-epic gate and leaves every other reader of the snapshot stale anyway.

Note the two vocabularies over one word — lowercase blocked the outcome is not capitalised Blocked the CI state, and read_codegen_outcome has to keep telling them apart.

Tests

772 unit tests pass. New: TestSyncEpicTaskJiraStatus (6, including the end-to-end test_dependent_gate_passes_after_transition which drives the real gate), TestCodegenDeclinedIsNotFailed (3), and test_blocked_ci_state_is_not_the_blocked_outcome pinning the vocabulary split. Ledger: 159 files consistent.

Scope

This fixes the skill declining. The environment breaking — a clone or credential fault — still writes terminal Failed; that stays open as bug-clone-fault-marks-epic-failed, now cross-linked, and the two ad-hoc copies of the retryable-vs-terminal rule should be folded together when it's fixed.

🤖 Generated with Claude Code

ederign and others added 2 commits August 29, 2026 15:28
RHAI-761 was removed from the pipeline permanently by two defects that
compounded, forty seconds apart.

The dependency gate reads each dependency's jira_status from the on-disk
epic-task file, written once at the start of the run by fetch_jira_epics.py.
The same run then closed RHAI-760 in Jira at 19:06:49 and invoked its
dependent at 19:07:29 — which read a snapshot still saying "In Progress" and
refused to start. The run invalidated its own source of truth.

transition_issue() now writes the new status back to the snapshot on every
successful epic-level transition, so the two stay in step. Querying Jira live
from the gate was the alternative; it puts a network call in a per-epic gate
and leaves every other reader of the snapshot stale anyway.

The refusal was then recorded as codegen_outcome=failed, and the pipeline maps
a codegen that produced no artifacts to the terminal CI state Failed. But
declining to start is a statement about the world, which changes between runs,
not about the epic. The skill now writes codegen_outcome=blocked and the
pipeline sends that back to Blocked with blocked_by intact. `blocked` is added
to CODEGEN_OUTCOMES, the single constant the schema enum and merge validation
both derive from.

Note the vocabularies: lowercase `blocked` the outcome is not capitalised
`Blocked` the CI state, and read_codegen_outcome must keep telling them apart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
They carried the SHA of a pre-amend commit that no longer exists in history,
which makes the evidence field unverifiable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ederign
ederign merged commit a886d2e into main Aug 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant