Skip to content

A claim that outlives its session needs releasing, not just reporting — and the release point is the ladder's not-continuing decision, not an age #218

Description

@genesis-dev-bot

issues.sh unselectable-work now reports a claim that outlived the run holding it (#216). Nothing releases one. The report is the right primitive for a stale blocked label, where a person or an agent has to decide the dependency is really gone, but it is the wrong one for in-progress: the label was written by machinery at pickup, so machinery should take it back, and a line of output every tick asking someone to do it by hand is the noise that gets the whole report skipped.

The measured instance

T6 #195, on 2026-08-16 (UTC), from the human's comment on #216:

Time Event
02:18:40 a session claimed #195 through issues.sh next, which applied in-progress
03:17:38 last tool call — the session went quiet
03:33:28 Session timeout (3600s total) - terminating orchestrator, ending error_during_execution
03:33:30 session deadline reached - not continuing
~03:36 the human removed the label by hand

Afterwards: clean tree, on main, no branch, no commit, no PR — so no part of T6 was underway. The next session picked a different issue, and with the label present next --milestone 6 skipped #195; with it removed, next returned 195 immediately.

Why age is not the mechanism

The window in #216 is deliberately a report and not an expiry, and the reason is the one the human named: in-progress looks identical whether it was applied four seconds ago by a live session or an hour ago by one that has since been killed. A bare "clear it after N minutes" races a slow but healthy session and hands its issue to a second worker, which is strictly worse than the invisibility it fixes — two runs on one issue produce two branches and a merge conflict, and neither knows the other exists.

So the release needs liveness, not age.

Where the decision already exists

The control plane already distinguishes success, error_max_turns and error_during_execution, and it already logs session deadline reached - not continuing when it decides a chain is over. That decision point knows both that the session is finished and that it will not be resumed, which makes it the natural place to release what the session claimed.

Releasing on every session end would be wrong: an error_max_turns session that gets resumed should keep its claim, because the resumed run is still the worker.

Two layers, in this order:

  1. Release at the not-continuing decision. When the ladder decides a chain will not be resumed, release the claims that chain made. This needs an association from session to claimed issue — claim currently writes a label and records nothing about who wrote it.
  2. A timeout sweep as backstop, not as the primary. A control plane that dies without deciding anything reaches no decision point, so nothing releases. The sweep covers exactly that case and must clear the session cap for the same reason the report's window does (see DEFAULT_CLAIM_STALE_HOURS).

Done criteria

  1. A claim carries enough identity to be attributed to the session that made it.
  2. A chain the ladder declines to continue releases its claims; a chain that is resumed keeps them.
  3. A backstop sweep releases claims whose session cannot be accounted for at all, with a window above the session cap.
  4. A test that a healthy in-flight claim is never released — the false-positive case is the expensive one here, unlike in the report.

Routed to the evolver: the release point is in the control plane's continuation ladder, which is genesis, not this repo. issues.sh claim is genesis scaffolding too. Same route as PR #209 and PR #213: fix upstream in Sayfan-AI/genesis, backport. Every seeded project inherits a claim that never expires. Note #217 is also about rung 3 of that ladder and is adjacent but distinct — that one is about what counts as progress, this one is about what a finished session owes back.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmilestone:6Milestone 6 — chaos engineeringneeds:evolverFramework-level finding to propagate to Sayfan-AI/genesis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions