Skip to content

feat(lanes): run limits by task class that save progress and resume from pushed state #7677

Description

@kyle-sexton

Refs: #6958

Context

The claude.dev post "Building effective agent automations" (2026-10-08, https://claude.dev/blog/building-effective-agent-automations/) recommends a per-run cap and a job timeout on every scheduled agent. A harness cap ends the run, so a blunt cap can spend usage and leave nothing behind. Digest entry 3.

Decision

  • Q24, C16: limits are set per task class (implementation runs long, a review short), generous, in versioned config next to each lane. A run that hits one saves its progress instead of ending with nothing.
  • Q40: a stopped run is requeued and resumes in a new session from its pushed branch and a progress note: on the same plan once the window resets, on another account only through a manual reassign.
  • C24: agents commit and push their feature branches often and check for concurrent work.
  • C21: budget and limit mechanics stay outside agent context.

Acceptance criteria

  • Each lane's config declares its task class and that class's limits; prose docs point at that config for this repository's values instead of restating them (built-in defaults may stay in prose, since they document the code's contract).
  • Implementation lanes only: IF a credential is revoked or a window is hit mid-run, THEN progress is saved and the work queues with an alert. (Review lanes rerun instead, per D14 (a).)
  • Implementation lanes only: a queued run resumes in a new session from the pushed branch plus a progress note, never from the stopped session.
  • The runner, not the agent, carries a stopped run's work to the remote (the agent holds no write token), and agents check for concurrent work before their changes are pushed.
  • No budget or limit appears in any agent prompt.
  • A limit hit is recorded in lane telemetry from the run's result subtype as the existing class=max-turns / outcome=turn-cap tokens (no new capped token, which would clash with the WIP pause's capped), and the job timeout stays as the outer backstop.
  • Q34 (how Action-run review lanes salvage, and the ceiling per task class): the user decides; not for the implementer.

Related

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 16, 2026
  2. github-actions commented on Oct 16, 2026

    @github-actions
    Contributor

    Thanks for the report. Automated triage handed this issue to a maintainer.

    Proposed work class: work-class: structural
    Basis: automated intake triage; a maintainer confirms or changes it.

    Automated triage. A maintainer reviews it.

  3. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 16, 2026
  4. kyle-sexton commented on Oct 18, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded.

    Question: Lanes get limits per task class, and a run that hits its limit saves progress and resumes. Q34 asks how Action-run review lanes salvage a capped run. Options: (a) review lanes rerun from scratch on the next trigger, with a short ceiling; (b) post partial findings and a capped marker; (c) defer until #6967 picks the executor.

    Owner's answer: (a), and build the implementation-lane half. A rerun needs no executor change, so it does not wait on #6967. A review is short and leaves nothing worth salvaging, and (a) is the option with no new mechanism. Revisit only if #6967 moves review lanes to claude -p. Basis: #7677 body (Q24 "a review short"; #6967 dependency is about resume and fallback); judgment.

    The owner accepted this recommendation as item D14 of a 21-decision batch in an attended backlog-shaping session on 2026-10-18. The batch question: "Accept all 21 batch 7 decisions, with my change to D13 (#6008 goes to the lane, but you merge its PR because it edits AGENTS.md)? I post a 'Decision recorded.' comment on each issue." The owner answered: "Accept, with my D13 change (Recommended)".

    Posted by AI from the owner's answer in that session.

  5. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 19, 2026
  6. kyle-sexton commented on Oct 20, 2026

    @kyle-sexton
    MemberAuthor

    Status after #8281 and #7918 (Attended Build, 2026-10-20; read-only scoping against origin/main c27c3d2)

    #8281 built most of the implementation-lane half: issue-field budgets, turn-cap / limited / funding outcomes, and resume from the pushed branch (report-outcome.mjs, write-issue.mjs resume record). What remains:

    1. Criteria wording (committee alignment with the owner's 10-18 decision). Criteria 2 and 3 apply to implementation lanes only; review lanes rerun from scratch under option (a). Criterion 6's capped token is met by the lane record's existing max-turns class and the issue lane's outcome=turn-cap. capped already names the WIP pause (.github/actions/check-wip-cap/action.yml:22), so no second meaning is added.
    2. Limit values in prose: docs/conventions/pr-pipeline/README.md restates this repo's values (around lines 1256-1344). Replace them with pointers to the pr-pipeline.yaml keys.
    3. Leftover commit on a stop (feat(pr-pipeline): budget issue runs by issue fields and resume capped runs #8281's unbuilt "plan PR 4"): uncommitted edits are lost when a run stops. This edits pr-run-activity-write.yml, which Lane Funding's Phase 6a is moving, so it waits for 6a to merge.
    4. Alert: a funding or limit stop posts only an issue comment; no maintenance signal fires.

    Risk: #8500's system prompt carries the turn budget, which would break criterion 5 ("No budget or limit appears in any agent prompt").

  7. kyle-sexton commented on Oct 21, 2026

    @kyle-sexton
    MemberAuthor

    Reopened: #8797 closed this by mistake (its body said "does not close #7677", which GitHub's keyword parser still reads as a close). #8797 delivered Q1 (README pointers to pr-pipeline.yaml) and Q3 (monitor signal 9, lane stop); Q4 (criteria rewording) was edited here. Still open: Q2, turn-cap-restarts 0 to 1 after the sandbox timeout probe passes and a Security & Cost review (owner, 2026-10-21).

  8. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 21, 2026
  9. kyle-sexton commented on Oct 21, 2026

    @kyle-sexton
    MemberAuthor

    Q2: what the code says about the "sandbox timeout probe" (origin/main, 2026-10-21)

    The gate comment at docs/conventions/pr-pipeline.yaml:455-459 makes turn-cap-restarts wait on a sandbox timeout probe. Reading the code shows a turn-cap stop and a job timeout take different paths, and turn-cap-restarts only applies to the turn-cap path:

    • Turn-cap stop. The skill step fails (continue-on-error in issue mode). After that:
      • "Collect the patch" still runs, because act-skill.outcome is failure (.github/workflows/pr-run-activity-read.yml:1083-1095).
      • The patch is uploaded (:1097-1104) and applied to a lane branch.
      • A restart is counted against turn-cap-restarts (.github/scripts/work-unblock/label-unblocked.mjs:593-602).
    • Job timeout. act-skill.outcome is neither success nor failure, so the collect step's condition is false. No patch is collected and no turn-cap record is written. That makes turn-cap-restarts irrelevant to this case. Work-unblock instead re-fires the run as a crash, since timed_out is in FAILED (label-unblocked.mjs:95). That re-fire happens once per version of the lane workflow files on main (:30-36), whatever turn-cap-restarts is set to.

    What follows from that:

    • Raising turn-cap-restarts from 0 to 1 changes only turn-capped runs, which already hand over their partial patch.
    • A timeout leaves no patch whatever this value is. The lost uncommitted edits are the 10-20 "leftover commit on a stop" item, not Q2.
    • No sandbox probe harness exists in the repo. The only mention of the probe is the yaml comment.
    • Not verified at runtime: whether GitHub runs always() steps after a job timeout. The step conditions above skip collection either way.

    Owner decision pending: accept this reading as the probe result, or require a live timed-out run. Either way a GitHub Security & Cost review comes next, then the config PR.

  10. kyle-sexton commented on Oct 21, 2026

    @kyle-sexton
    MemberAuthor

    Done: Q1, Q3 and Q4 shipped in #8797, and Q2 (turn-cap-restarts 0 -> 1, approved by the owner as W-89 on 2026-10-21) shipped in #8927. One related item is separate and not covered here: a run killed by a job timeout loses its uncommitted edits (no patch is collected), the 10-20 'leftover commit on a stop' item. It isn't part of this issue's criteria.

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

    needs-triageNot yet classified. Floor until a type and one priority tier are set.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions