Skip to content

[Phase 4] Initiative driver counts human-gated and zombie sub-issues as in-flight — epic #1402 silently deadlocked at slots=0 for days #1494

Closed

Description

@don-petry

Story

As a maintainer relying on the initiative driver to keep an epic's ready work flowing,
I want the in-flight cap to count only sub-issues an agent can actually still act on,
so that human-gated or already-delivered items cannot silently consume slots forever and starve the rest of the epic.

Problem — three dead slots deadlocked epic #1402 for days

scripts/initiative-driver.sh counts in-flight as: every OPEN sub-issue carrying the dev-lead label. Observed on epic #1402 (2026-08-11):

Result: in-flight = 3 vs MAX_IN_FLIGHT = 2 → slots = 0 → the driver ran successfully every ~25 minutes for days while releasing nothing, with 5+ unblocked stories waiting (#1482, #1406, #1408, #1486, #1468, #1469). Every run logged success; the starvation was invisible without manually computing the in-flight set. Resolved manually today by maintainer decisions (split-and-close #687 → #1493, park #1422, retry #1425) — but the class remains.

This is the throughput-level sibling of the two known single-item strand mechanics: the cleared-gate-never-refires issue strand (#1407, see #1402 close-out 2026-08-11) and the merge-ready-PR strand (#1469).

Acceptance Criteria

  1. Sub-issues carrying dev-lead:needs-human do NOT count toward the in-flight cap (they cannot progress without a human; holding a slot buys nothing). They must also not be re-released while gated (already true via label logic — keep it that way).
  2. Zombie detection: an open sub-issue whose dev-lead label predates a merged implementation PR (or that has had no dev-lead activity for a configurable staleness window, default ≥72h) is surfaced — at minimum a driver log line + a comment on the epic naming the stale slot-holder; it must not silently occupy a slot forever.
  3. The driver's per-epic log line reports the slot math explicitly (in-flight=N (M gated excluded), cap=K, releasing R), so a starved epic is visible in any single run log.
  4. A unit/bats test covers: gated items excluded from the count; the release path still respects the cap; a zombie is reported.
  5. No change to release ordering or to the hands-off/hold label semantics (dev-lead:hands-off / initiative:hold still never release).

Tasks

  • Exclude dev-lead:needs-human carriers from the in-flight count in initiative-driver.sh. (AC: 1)
  • Add staleness/zombie reporting. (AC: 2, 3)
  • Tests. (AC: 4)

Dev Notes

  • Counting logic is at scripts/initiative-driver.sh (~lines 142–162): in_flight increments for every open child with DEV_LEAD_LABEL.
  • Be careful NOT to release additional items merely because gated ones stop counting if the maintainer considers gated items "still consuming attention" — that is exactly the behavior change requested here, but call it out in the PR body so the cap's new meaning ("actively workable items") is an explicit, reviewable decision.
  • Do not auto-remove labels from gated/zombie items (that erases human-readable state); exclude/report only.

References

Activity

  1. don-petry commented on Aug 19, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead Implementation Plan

    Issue: #1494 — [Phase 4] Initiative driver counts human-gated and zombie sub-issues as in-flight

    Scope

    Make the in-flight cap in scripts/initiative-driver.sh count only sub-issues an agent can still act on: exclude dev-lead:needs-human carriers from the count, surface stale "zombie" slot-holders (driver log + one idempotent epic comment), and report the slot math explicitly in the per-epic log line.

    Implementation Checklist

    • Add NEEDS_HUMAN_LABEL (default dev-lead:needs-human) and STALE_HOURS (default 72) env vars + validation, documented in the header.
    • In the in-flight count loop, mark dev-lead:needs-human carriers as released (so they are never re-released) but exclude them from in_flight; track a separate gated count.
    • Detect zombies: an in-flight (non-gated) child whose most-recent dev-lead labeled event is older than STALE_HOURS — log a line and collect it.
    • Post one idempotent comment on the epic naming the stale slot-holder(s) (HTML marker keyed on the zombie set; DRY_RUN logs intent only). No label removal.
    • Emit the AC3 per-epic slot-math line: in-flight=N (M gated excluded), cap=K, releasing R.
    • No change to release ordering or hands-off/hold semantics.

    Tests to Write (tests/test_initiative_driver.bats)

    • Gated dev-lead:needs-human carrier excluded from in-flight → a ready story is released in the freed slot; asserts the AC3 log line.
    • Release path still respects the cap (only slots items released even when more are ready).
    • A stale in-flight slot-holder is reported (ZOMBIE log line + epic comment; label not removed).

    Test Command

    bats tests/test_initiative_driver.bats (full suite via .dev-lead/scripts/dev-lead-lint.sh for shellcheck)

  2. don-petry commented on Aug 19, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead: Progress (in progress — not yet durable)

    Provisional. Nothing is pushed yet; the automation posts the authoritative
    completion record (with PR number + head SHA) after the push. Treat the notes
    below as intent, not delivered results.

    Plan Execution (intended)

    • Excluded dev-lead:needs-human carriers from the in-flight count in scripts/initiative-driver.sh; gated carriers stay in released[] so they are still never re-released while paused (AC1, AC5).
    • Added zombie detection: a non-gated in-flight carrier whose most-recent dev-lead labeled event is older than STALE_HOURS (default 72h) is logged and surfaced via one idempotent epic comment keyed on the exact zombie set. No labels are auto-removed (AC2).
    • Per-epic log line now reports the slot math explicitly: in-flight=N (M gated excluded), cap=K, releasing R (AC3).
    • Added three bats tests: gated-exclusion frees a slot, release path still respects the cap, a stale slot-holder is reported (AC4).

    Cap-semantics call-out (for the PR body)

    The in-flight cap's meaning changes from "every open dev-lead carrier" to "actively workable carriers" — gated (dev-lead:needs-human) items no longer consume a slot, so an epic can release more work than before. This is the requested behavior change (per the issue's Dev Notes) and is an explicit, reviewable decision. Zombies still count toward the cap (surfaced, not auto-freed) so no slot is silently released without a human deciding.

    Local check output (provisional — not the pushed run)

    bats tests/test_initiative_driver.bats  → 18/18 (local)
    bats tests/*.bats                       → exit 0, 0 failing (local)
    bash .dev-lead/scripts/dev-lead-lint.sh → all checks passed (shellcheck 111 files + agent profiles)
    

    Files touched (this workspace, not yet pushed)

    • scripts/initiative-driver.sh: gated exclusion, zombie detect + idempotent epic comment, AC3 slot-math log line, NEEDS_HUMAN_LABEL/STALE_HOURS env + validation, header docs.
    • tests/test_initiative_driver.bats: three new tests (gated excluded, cap respected, zombie reported).

    Notes

    • Zombie detection implements the staleness-window branch of AC2's "or" (≥ STALE_HOURS). In practice this also catches the observed [Phase 2] Generalized CI compliance test: reject SHA / # main pins on any first-party reusable #687 case (label ~3 days old after its PR merged). The stricter "label predates a specific merged PR" correlation was not added — the age heuristic covers the documented deadlock without new PR-lookup API traffic.
    • A transient issues/*/events API failure trips errexit and aborts that epic (consistent with the existing labels_of/blocked_by error posture — a failure surfaces rather than masking as a false no-op).
  3. don-petry commented on Aug 19, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead: Implementation Complete — PR #1543

    The implementation for issue #1494 is durable: commits are pushed and a pull request is open. This record is backed by verifiable artifacts you can confirm in one click.

    Review happens on the PR. Acceptance criteria and test results are evidenced by the PR's diff and CI checks — not asserted here. If a later stage fails, this claim is retracted in place.

  4. added a commit that references this issue on Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug reportsdev-leadFor dev-lead agent pickupinitiativeEpic / initiative tracking issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions