LearnNewsExamplesServices
Frontmatter
id10758
titleAdd age-aware successor-risk audit to ticket-intake
stateClosed
labels
documentationenhancementaiarchitecturemodel-experience
assigneesneo-gemini-pro, neo-gpt
createdAtMay 5, 2026, 6:57 PM
updatedAtJun 2, 2026, 5:54 PM
githubUrlhttps://github.com/neomjs/neo/issues/10758
authorneo-gpt
commentsCount7
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 2, 2026, 5:54 PM

Add age-aware successor-risk audit to ticket-intake

Closed Backlog/active-chunk-9 documentationenhancementaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on May 5, 2026, 6:57 PM

Context

We are walking the open issue backlog toward zero. During maintainer review of #9958, the issue was closed as superseded by the later #10733 work. That exposed a gap in ticket intake: duplicate and superseded are already allowed verdicts, but the workflow does not make ticket age, stale bot state, or missing PR close-link hygiene a first-class audit input.

#10555 completed the Ticket Reality Classification protocol. It deliberately did not add a backlog sweeper. This ticket keeps that boundary: intake should get sharper when an agent chooses a ticket; it should not spawn a mass sweep.

The repo stale workflow currently marks inactive issues stale after days-before-issue-stale and closes them after days-before-issue-close unless no auto close is present (.github/workflows/close-inactive-issues.yml). At filing time, those values are 90 and 14 days, but the intake rule should read the workflow config rather than hard-code arbitrary bands.

The Problem

Same-day duplicates happen, but the older a ticket is relative to the stale workflow config, the higher the chance that a later ticket, PR, epic decision, discussion, or current source state has resolved or reshaped the premise. Current ticket-intake already asks for duplicate and superseded checks, but it does not require agents to record createdAt, updatedAt, stale, or no auto close, and it does not scale the successor-risk sweep depth by workflow-derived age state before emitting valid-as-written.

A related edge case: a PR can fully implement a ticket but miss the GitHub close keyword (Resolves #N, Closes #N, etc.). GitHub then leaves the issue open even though the correct intake verdict is already-resolved, not new implementation work.

Architectural Reality

  • .agents/skills/ticket-intake/references/ticket-intake-workflow.md owns the Pre-Execution Reflection Gate.
  • .github/workflows/close-inactive-issues.yml owns the stale timing and no auto close exemption.
  • #10555 added the reality verdicts, including duplicate, superseded, and already-resolved, but not age-aware successor-risk handling.
  • Ticket reality is not equivalent to GitHub auto-close state. A missing close keyword can leave completed work looking open.
  • ticket-triage may later deserve a narrow extension for never-triaged stale tickets, but that is not part of this ticket.

The Fix

Add an Age / Successor-Risk Audit to ticket-intake, preferably inside Section 1 before Ticket Reality Classification, with a compact required artifact:

  • Ticket age: created date, updated date, workflow-derived age state, and relevant labels.
  • Successor-risk sweep: newer tickets, PRs, epics, discussions, and current source/docs/tests checked when the ticket is older, stale, or exempted.
  • Missing close-link sweep: merged PRs that reference the ticket, touch the target surface, or appear in the issue conversation are checked even when they did not use a GitHub close keyword.
  • Stale renewal: if stale is present and the ticket remains valid, refresh the issue with a renewal comment and remove stale as intake routine.
  • Exemption discipline: applying no auto close is not routine intake cleanup. It requires explicit operator intent or a blocked/parked-state rationale.
  • Verdict integration: age is a risk signal, not a verdict. It raises search depth before valid-as-written.

Suggested workflow-derived states:

  • pre-stale: issue age/inactivity is below days-before-issue-stale; run the normal duplicate/successor sweep.
  • stale-window: issue has stale or is at/after days-before-issue-stale but before the stale-plus-close window; run explicit newer-ticket and merged-PR sweeps before valid-as-written.
  • post-stale-with-exemption: issue remains open beyond days-before-issue-stale + days-before-issue-close, usually because it is exempted or recently refreshed; run the highest-risk audit against newer tickets, PRs, epics, discussions, current source/docs/tests, and merged PRs without close keywords.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
ticket-intake Validation Sweep #10555 plus stale workflow config Intake records age/stale metadata and scales successor-risk depth before reality verdict If metadata cannot be fetched, halt with clarification instead of accepting ticket-intake-workflow.md Local workflow text check
Workflow-derived age states .github/workflows/close-inactive-issues.yml Bands derive from days-before-issue-stale and days-before-issue-close, not arbitrary constants If config shape changes, cite observed config and use conservative high-risk audit ticket-intake-workflow.md Cite workflow lines for stale/close/exemption keys
Ticket Reality Classification artifact ticket-intake-workflow.md Classification includes the age audit line before valid-as-written can proceed Non-valid verdicts route to existing rejection/re-triage paths Same file Markdown grep for required artifact fields
Missing PR close-link hygiene Live issue conversation, linked PRs/commits, current source/docs/tests A merged PR can produce already-resolved even if it omitted Resolves #N / Closes #N If evidence is ambiguous, halt with clarification instead of branching ticket-intake-workflow.md Evidence lists PR number, merge status, touched surface, and issue/thread link
Stale renewal vs exemption .github/workflows/close-inactive-issues.yml plus maintainer intent Valid stale tickets get renewal; no auto close requires explicit parked/blocked rationale If rationale is unclear, ask maintainer instead of applying exemption Same workflow plus intake doc Cite 90/14/no-auto-close config and renewal comment

Acceptance Criteria

  • ticket-intake-workflow.md adds an explicit Age / Successor-Risk Audit before Ticket Reality Classification.
  • The classification artifact records createdAt, updatedAt, workflow-derived age state, stale, and no auto close state when available.
  • The workflow states that age is never a verdict by itself; it only raises successor-risk search depth.
  • Age bands are derived from .github/workflows/close-inactive-issues.yml values instead of hard-coded arbitrary thresholds.
  • The audit distinguishes same-day duplicates from older-ticket supersession.
  • The audit explicitly checks for merged PRs that completed the ticket but missed a GitHub close keyword, routing those cases to already-resolved rather than branch/code work.
  • Missing close-link evidence must name the PR, prove merged status, identify the target surface touched, and cite the issue conversation or source/docs/tests that establish completion.
  • Stale renewal and no auto close exemption are separated: renewal is intake routine for still-valid stale tickets; exemption requires explicit parked/blocked rationale.
  • The stale bot contract is documented with the current config keys for stale, close, and no auto close exemption.
  • The ticket remains scoped to ticket-intake; no new sweep skill, scheduled backlog sweeper, stale bot timing change, or ticket-triage extension is introduced.

Out of Scope

  • Automated mass backlog sweeping.
  • Closing or editing existing tickets as part of this work.
  • Creating a new skill.
  • Changing .github/workflows/close-inactive-issues.yml timing or labels.
  • Extending ticket-triage for never-triaged stale tickets.

Avoided Traps

  • Do not treat old age as negative ROI by itself.
  • Do not hard-code age bands that drift from the stale workflow config.
  • Do not treat open GitHub state as proof that no PR implemented the issue.
  • Do not use keyword-only mass closure. Superseded, duplicate, and already-resolved findings still need evidence.
  • Do not bloat ticket-intake/SKILL.md; keep the detailed logic in the referenced workflow file.
  • Do not auto-apply no auto close as a convenience label.

Related

Origin Session ID: 2821a9d4-7634-4fe7-a8a2-daf49253b929

Handoff Retrieval Hint: ticket-intake age stale no auto close successor risk duplicate superseded older tickets missing close keyword already-resolved merged PR

tobiu referenced in commit bb6f682 - "fix(ai): add successor-risk and enforcement sufficiency audit to ticket-intake (#10758) (#11357) on May 14, 2026, 5:10 PM
tobiu closed this issue on May 14, 2026, 5:10 PM
tobiu closed this issue on Jun 2, 2026, 5:54 PM
tobiu referenced in commit ab8aba9 - "fix(agentos): separate bot stale bands from ticket currency (#10758) (#12374) on Jun 2, 2026, 5:54 PM