Skip to content

feat(roadmap): stage retry time follows the failure class #4060

Open

Description

@dan-petty

Problem

The stage wait after a failure is one number of hours: roadmap.stage.retry_hours (settings.py, default 6, DEFAULT_ROADMAP_STAGE_RETRY_HOURS). _Judge._failed_lately (stage.py) reads it.

A provider 5xx and a refused plan wait the same 6 hours. An edit race (RoadmapItemChangedError) waits 6 hours too, and it needs no wait.

After the issue #4056, the item record holds stage.failed_class. Nothing reads it yet.

Expected

In roadmap/failure.py add RETRY_AFTER, a mapping from FailureClass to timedelta. The values are:

  • provider: 1 h.
  • parser: 6 h.
  • plan_defect: 6 h.
  • ci_infra: 1 h.
  • head_moved: 0 (the next round).

There is no None value. A test requires the keys of RETRY_AFTER to be exactly the values of CLASS_BY_EXCEPTION.

The stage selection (_Judge._failed_lately) computes failed_at + RETRY_AFTER[failed_class]. It does not store the retry time. A record from before the previous issue has no class. It waits as ci_infra.

Remove the setting roadmap.stage.retry_hours and DEFAULT_ROADMAP_STAGE_RETRY_HOURS. The project is alpha, so add no shim. Change every place that names the setting:

  • docs/ROADMAP_WORKFLOW.md (line 126) and docs/roadmap/stage.md (line 73);
  • k8s/README.md (item 15 of the Roadmap service list);
  • the comments in stage.py and run.py;
  • the requirement 'A failed item waits for the retry delay' in openspec/specs/roadmap-stage/spec.md;
  • the requirement 'The command reports an item that the stage job holds for a retry' in openspec/specs/roadmap-explain/spec.md;
  • the tests tests/roadmap/stage/test_roadmap_stage_retry.py and tests/roadmap/test_roadmap_limit_classes.py.

Regenerate docs/CONFIGURATION.md with uv run devops docs generate.

Rollout rule. The live ConfigMap may set roadmap.stage.retry_hours. An unknown key can fail the settings load. Show the diff, then remove the key from the live ConfigMap in the same deploy.

Not in this issue: a comment on the issue for a class whose action is wait. No stage failure maps to such a class.

Acceptance criteria

  • uv run pytest tests/roadmap/stage/test_roadmap_stage_retry_after.py - a provider 5xx waits 1 h and a refused plan waits 6 h. An item-changed error waits 0. A record with no class waits as ci_infra.
  • uv run pytest tests/roadmap/test_roadmap_failure.py -k retry_after - the keys of RETRY_AFTER are exactly the values of CLASS_BY_EXCEPTION.
  • ! grep -rIiq 'retry_hours' src docs k8s tests README.md openspec/specs && uv run devops docs generate --check - no file names the removed setting, and the generated documents are up to date (the grep part fails today).

Every command above fails on the unchanged code. The pull request cites the fail-to-pass run (devops ci fail-to-pass --base <ref>).

Feasibility

I read these files at origin/main: stage.py (_Judge._failed_lately), settings.py (line 924), defaults.py (line 880), run.py and the two specs. I searched the repository for retry_hours outside openspec/changes/archive. The files above are the result. In the roadmap-stage spec the requirement is at line 1755, and the text that names the setting is at line 1756. In the roadmap-explain spec the requirement is at line 126.

I did not run the code or the tests. I did not read the live ConfigMap, and I did not check if an unknown key fails the settings load. The consumer of RETRY_AFTER is the stage selection in this same issue, so the table is not dead code. uv run devops docs generate --check exists (checked with --help).

Existing tool considered

roadmap/failure.py (FailureClass, ACTION_BY_CLASS, #3065) and plain isinstance. No library is needed.

Cost

Build: about 45k tokens and 2.5 h (one table, one selection change, a setting removal in 12 places, 5 tests). Keep: about 2k tokens per quarter. Fix: about 10k tokens and 1 h.

Related

Part of #3027. Depends on the issue #4056. #3650, #3727, #3493 (closed, the fixed delay). Order: before the issues #4061 and #4065.

Activity

  1. added
    type/featureNew user-facing functionality or capability addition
    scope/roadmapThe roadmap jobs: intake, refine, stage, implement and the Service that runs them
    status/newStatus New: the item is not ready yet
    on Nov 7, 2026
  2. dan-petty commented on Nov 7, 2026

    @dan-petty
    OwnerAuthor

    Intake placed this item to the backlog: intake puts every new item in the backlog. A person plans the milestones.

    • Type: type/feature. The feat prefix of the title gives the type.
    • Scope: scope/roadmap. The (roadmap) scope of the title gives the scope.
    • Priority: P2-Medium. It improves retry accuracy in an alpha project but is not a defect or a security gap.
    • Value: Medium. It removes a 6-hour wait for classes that need none and shortens waits for transient provider errors.
    • Effort: Medium. One mapping table, one selection change, a setting removal in 12 places, and 5 tests.
    • Related: feat(roadmap): record the failure class and step of a stage item #4056, which asks for a different change. Both work on stage failure classification; #4056 writes the class into the record, while this issue reads it to set a per-class retry delay.
  3. added
    priority/p2-mediumStandard priority feature work and architectural improvements
    on Nov 7, 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

    effort/mediumEffort Mediumpriority/p2-mediumStandard priority feature work and architectural improvementsscope/roadmapThe roadmap jobs: intake, refine, stage, implement and the Service that runs themsource/agentFiled by an agentstatus/newStatus New: the item is not ready yettype/featureNew user-facing functionality or capability additionvalue/mediumValue Medium

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions