Skip to content

Deferred items: a register column nothing fills - #509

Merged
m2ux merged 1 commit into
workflowsfrom
workflow/491-raise-deferred-items
Aug 25, 2026
Merged

Deferred items: a register column nothing fills#509
m2ux merged 1 commit into
workflowsfrom
workflow/491-raise-deferred-items

Conversation

@m2ux

@m2ux m2ux commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Summary

While a work package runs, it keeps meeting things that need doing and do not belong in this piece of work. Each is written into a single table — the deferred items register — one row per item, with what it was and why it was out of scope. The last column of each row is for the tracker issue that will carry the item forward, and until one is raised it holds a dash.

Nothing raises the issue, so the dash stays. This adds the step that fills it.

What happens today

The register is written faithfully and read once. At the end of the package a closing document counts the rows and writes a line saying how many are open and how many became issues, and the second number is always zero. The package then finishes, the worktree is removed, and the register sits in a planning folder nobody opens again.

The register's own instructions claim the opposite. One of its rules states that issue creation reads the register and that deferred-item issues are raised from its rows carrying the row ID. There is no such reader anywhere in any workflow, so someone reading the rule would believe a mechanism exists that does not.

This is the finding that caused #491 to be written. Three of that issue's four findings were set aside on the understanding they would be filed, and there was no way to file them.

The fix

Completion gains three things, placed before the closing document is written so its count is true when it is taken.

The register is read for rows whose Follow-up cell holds a dash. A run that deferred nothing has no register at all, and that is reported as having deferred nothing rather than as a missing file.

Each unraised row is then put to the run at its own gate, showing the item and the reason it was set aside. Raising creates something other people see, and every other outward-facing action in this workflow asks first — the package's own issue is created behind exactly such a gate.

An approved row is raised against whichever tracker the package's own issue lives in, and the new issue's link is written into that row, leaving the ID, item and reason as the deferring activity wrote them. A row the run leaves alone keeps its dash and stays open for a later package.

The register's rule now describes the mechanism that exists and names the technique that performs it.

A note on the gate flag

The gate sets a flag that the raise step reads, and both of its options set it — approving sets it true, declining sets it false. A flag only ever set true would survive into the next pass of the loop and raise an issue for a row the run had just declined.

That is the defect #491 reports as its second finding, in a different activity: an exit gated on a flag no step can clear. It would have been easy to reproduce here.

Verification

The full corpus sweep passes, 27 of 27, measured against a code branch carrying the loop-consumer fix this depends on.

Depends on

The guard that reports a declared output nothing consumes does not count a loop's collection as a consumer, so the technique that collects the open rows reads as producing something dead. That is a gap in the guard rather than in this change, and it is fixed separately on the code branch. Until that merges, the corpus check here reports one finding against open_deferred_items.

Scope

Reading the register, gating each open row, raising the approved ones, and linking each row to its issue. The register's rule updated to describe it.

Acceptance criteria

  • A deferred row's Follow-up cell acquires its issue link through an owned step.
  • A row the run declines keeps its dash, and declining one row does not raise the next.
  • A run that deferred nothing completes without being asked anything.
  • The register describes the mechanism that fills its Follow-up column.

Non-goals

This does not change what may be deferred, who may defer it, or the shape of a row. The register keeps having no owning activity, because any activity may be the first to defer something.

This does not raise anything in review mode, where the package is reviewing someone else's change and its deferrals are not its own to file.

The deferred-items register holds a Follow-up column for the issue each
row is raised as. Completion now fills it: the open rows are collected,
each is put to the run at its own gate, and an approved row is raised
against the tracker the package's own issue lives in, with the new
issue's link written into that row.

A row the run leaves unraised keeps its dash and stays open for a later
package. The gate flag is set by both options, so each pass through the
loop decides on its own row.

The register states the mechanism that fills the column, and names the
technique that does it.

Closes #491 finding 4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@m2ux
m2ux merged commit d07c2c7 into workflows Aug 25, 2026
1 of 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