Skip to content

fix: a stop, an edit and a new acceptance break the autopilot's path #696

Open
0 of 1 issue completed
Open

Description

@soydiloreto

Problem

Two paths of the flow break when their parts meet, and no scenario plays them whole. After the autopilot stops, an edit of the PRD and a new acceptance leave needs-human on, and the G2 "Acceptance withdrawn" comment hides the stop from review-reply.yml, so a maintainer's answer is ignored (#694, 2026-11-08). The autopilot also asks again what a maintainer answered in a comment, because it reads the PRD alone. The release lane covers workflow events one by one, not the paths docs/model.md describes, so these combinations reach people instead of failing the lane.

Scope

  • review-reply.yml finds the autopilot's stop past any later comment of the bot (a G2 "Acceptance withdrawn", a board), not only past the mention.
  • An accepted added again after a stop takes needs-human off and the autopilot goes on.
  • The autopilot reads the answers of those who decide in the issue's comments together with the PRD, and does not ask again what they settled.
  • A table in docs/ maps every path docs/model.md describes (a person's bug to its merge, a reproduced bug merged by policy, a feature accepted and built, a claim and its release, a stop answered, an edit after acceptance and the new acceptance, the release and its watch) and each setting that changes it (acceptance by policy, who-decides, a claim, merge on its own or by a person, its ceiling) to the scenario that plays it, with the scenarios that are missing added.

Out of scope

The release lane's isolation, timing, formats and cost (#695).

Acceptance criteria

C1: Given an issue whose autopilot stopped, when its PRD is edited, accepted again and a person who decides answers in a comment, then the autopilot goes on without autopilot:continue and does not ask again what the answer settled; a scenario plays it.
C2: Given the table of paths in docs/, when release-scenarios.py --test runs, then every path and setting in it names a scenario of tests/release/scenarios.yml, and every one of those scenarios exists.

Criticality

Critical

🤖 AI-assisted · Claude Opus 5.5 (Anthropic)

Spec: approach

  1. review-reply.yml finds the stop past the bot's other comments. The answer job no longer takes the bot's last comment (its mentions aside) and asks whether it is a stop. A new pure function in scripts/autopilot.py, run_end(comments) (exposed as autopilot.py run-end, reading the comments as JSON on stdin), returns the bot's last comment that ends a run with a person: a stop (STOP), a silent end (SILENT), or a cap end. Any other comment of the bot is skipped: the G2 "Acceptance withdrawn" comment, the board (its dx-board marker), its mention, a review record, and the rest. The cap ends (runs cap, rounds cap in autopilot.yml) get a marker of their own, dx-autopilot-cap, written like STOP. Without it a cap end could not be told apart and would not hide an older stop. They still stay with a person, as today. The job brings the autopilot back only when run-end says stop or silent. Labels, who decides and the opinions path stay as they are.

  2. A new accepted after a stop takes needs-human off. In autopilot.yml, the run that a person's accepted starts (start mode, once the seal matches and the acceptor may accept, i.e. after the checks it runs today) takes needs-human off before next-step. It takes it off the issue and off the issue's open autopilot pull request, and only when run-end on that one's comments says stop or silent. A cap end keeps it, because the PRD's "stop" is the agent's stop, not a spent cap. next_step then decides as for any run: the Spec, the draft, or the work on the existing draft. No autopilot:continue is needed. issue-accepted.yml is left alone: it keeps the seal and the board.

  3. The autopilot reads the deciders' answers with the PRD. In start mode, autopilot.yml now collects the issue's comments and their deciders (deciders.py list answer) the same way it already does for the work. prompt_spec gets an answered argument, fenced like the work's <answer>. The Spec prompt drops "Read nothing else from the issue (not its comments…)" and says instead: the maintainers' answers below settle what they answer; do not ask again about it; where an answer and the PRD differ, the PRD wins, since it was sealed later. The work prompt says the same. Which comments count is a choice a maintainer would care about:

    • Option A: what answers() keeps today, i.e. the deciders' comments after the bot's last question, stop, silent or unfinished end. It is small, but an answer to an earlier question is lost once a later question is asked, so that earlier question can be asked again.
    • Option B (recommended): every comment by a decider on the issue and its pull request since the first accepted, in order, with / commands left out. Nothing they settled is lost across stops, edits and new acceptances, which is exactly C1's path. The prompt grows by those comments only, and anyone else's words still never reach it (the opinions' summary stays as it is). It would be a new pure function settled(comments, deciders, since) beside answers(). answers() stays what brings the autopilot back.
  4. The test repository's fixed change can ask. The test repository calls no model, so today no scenario ever stops. The pack gets fixed-change.ask: "<phrase>" (kinds/engine-test/pack.yml). When the PRD carries that phrase and the deciders' answers (step 3) are empty, the fixed Spec step stops through the agent's helper (finish stop "…"), as a model would. With an answer, it goes on. Every scenario that does not use the phrase behaves exactly as before. With this, stop-hint-continue really stops, and a C1 scenario that asks again fails.

  5. Scenarios and the table of paths. tests/release/scenarios.yml gets a bodies: entry asking-feature (with the phrase) and its edited twin. It also gets these new scenarios (serial: they draft):

    • stop-edited-reaccepted-answered (C1): accepted, wait, the Spec stops, the PRD is edited (G2), a decider answers in a comment, accepted again. Expected: needs-human and autopilot:continue absent, a pull request that closes it, and the stop marker exactly once. That last check is a new expect.count: {marker: n}, which release-scenarios.py's preconditions and run learn.
    • stop-answered: a stop answered in a comment alone, with no label.
    • bug-by-person-merges: a bug a maintainer accepts, to its merge.
    • stop-hint-continue keeps its label and moves to asking-feature.

    A new page, docs/paths.md, holds one table: path or setting → scenario ids. It covers every path docs/model.md describes:

    • a person's bug to its merge
    • a reproduced bug merged by policy
    • a feature accepted and built
    • a claim and its release
    • a stop answered
    • an edit after acceptance and the new acceptance
    • the release and its watch

    And every setting that changes them:

    • acceptance by policy
    • who-decides
    • a claim
    • merge on its own or by a person
    • its ceiling

    The engine's own watch (release-lane.py watch) is not a test-repository scenario. Its row names release-issue, and the page says the watch is held by release-lane.py --test. release-scenarios.py gets paths(table_text, scenario_ids): every row names at least one id, every id named exists, and every required path and setting has a row (the list lives in the script, from docs/model.md). It runs in coverage (the scripts job) and in --test, with fixtures for a missing row, an unknown id and an empty cell. docs/model.md links the page.

Nothing widens a permission, secret, lane or limit. In autopilot.yml, the start job's existing token removes needs-human, a label it already adds.

Spec: files

  • .github/workflows/review-reply.yml
  • .github/workflows/autopilot.yml
  • scripts/autopilot.py
  • scripts/release-scenarios.py
  • tests/release/scenarios.yml
  • kinds/engine-test/pack.yml
  • docs/paths.md (new)
  • docs/model.md (the link to the page)
  • docs/workflows.md, docs/versioning.md (where they describe the answer, the re-acceptance and the scenarios)

Spec: tests

  • C1 → tests/release/scenarios.yml (stop-edited-reaccepted-answered), with scripts/autopilot.py --test (run_end past a G2 comment, a board and a cap end; needs-human taken off on re-acceptance only after a stop; the Spec prompt carries the deciders' answers and no one else's; the fixed change stops only without an answer)
  • C2 → scripts/release-scenarios.py --test (paths against docs/paths.md and tests/release/scenarios.yml, with fixtures for a missing row, an unknown scenario and an empty cell)

Activity

  1. added theissue type on Nov 8, 2026
  2. dilux-bot commented on Nov 8, 2026

    @dilux-bot
    Contributor

    The issue's board

    Gate State
    G1 Issue ready ✓ the PRD follows the schema
    G2 Accepted ✓ by soydiloreto, their own Bug, accepted with its writing, at 2026-11-08T03:13:10Z; PRD sealed f82fd3c6f94d
    Waits on the autopilot: the autopilot's work (link)

    🤖 AI-generated · Claude Opus 5.5 (Anthropic)

  3. added a commit that references this issue on Nov 8, 2026
  4. added
    acceptedA maintainer accepted this issue; a pull request may close it
    on Nov 8, 2026
  5. dilux-bot commented on Nov 8, 2026

    @dilux-bot
    Contributor

    You wrote this Bug with the maintain or admin role, so it is accepted with its writing: no triage classifies it and no reproduction runs, and its PRD is sealed in your name. The autopilot codes it now in the organisation's runners, starting from a failing test.

    🤖 AI-generated · Claude Opus 5.5 (Anthropic)

  6. dilux-bot commented on Nov 8, 2026

    @dilux-bot
    Contributor

    The autopilot waits for #689: that open autopilot pull request already changes the engine's core (org.yml core), which this issue's Spec touches too, and two changes to the core at once keep putting each other in conflict. It starts this one on its own once #689 merges or closes.

    🤖 AI-generated · Claude Opus 5.5 (Anthropic)

  7. added
    autopilot:core-waitOn an issue: the autopilot waits for another pull request on the engine's core
    on Nov 8, 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

    acceptedA maintainer accepted this issue; a pull request may close itautopilot:core-waitOn an issue: the autopilot waits for another pull request on the engine's core

    Type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions