LearnNewsExamplesServices
Frontmatter
id14702
titleDraft agent PRs need a close-target-safe lint path
stateClosed
labels
enhancementaibuildmodel-experience
assigneesneo-gpt
createdAt7:55 AM
updatedAt10:46 AM
githubUrlhttps://github.com/neomjs/neo/issues/14702
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAt10:46 AM

Draft agent PRs need a close-target-safe lint path

Closed Backlog/active-chunk-3 enhancementaibuildmodel-experience
neo-gpt
neo-gpt commented on 7:55 AM

Context

PR #14698 exposed a workflow contradiction rather than a DockZoneModel implementation problem: the PR is draft by design, uses Refs only, and its lint-pr-body check fails because .github/workflows/agent-pr-body-lint.yml requires every agent PR body to contain a standalone Resolves #N. The current close-target discipline is also correct: .agents/skills/pull-request/references/pull-request-workflow.md says Resolves #N targets only a leaf ticket fully delivered by the PR, and learn/agentos/process/evidence-ladder.md says close keywords are only permitted when achieved evidence satisfies the close target or the residual/deferred contract is explicit.

The specific falsifier is #14698: head 8553518dc1d8f01c9d341305374b5ad362292016, draft state, failed lint-pr-body, body intentionally names Refs #14667 because issue #14667 requires whole-topology capture while the PR currently ships only the slot-ordered topology fingerprint composition helper. Adding Resolves #14667 would make CI green by overclaiming the close target.

Live latest-open sweep: checked the latest 20 open issues at 2026-07-04T05:54:25Z; no equivalent ticket found. All-state GitHub search for draft agent PR body lint Resolves Refs Related close-target returned no candidates. Recent A2A all-state sweep over the latest 30 messages found no competing [lane-claim] / [lane-intent] for this scope. KB query confirmed the current strict rule shape; team Memory Core query returned zero prior matches.

The Problem

The current lint contract gives draft agent PRs only two bad choices when the branch is intentionally partial or stacked:

  • keep the PR body honest with Refs only and carry a red PR-body lint check while the PR remains draft;
  • add Resolves #N before the PR actually delivers the target ticket, creating a false close-target claim that reviewers must catch manually.

That turns the close-target guard against itself. The rule that prevents overclaiming at ready/merge time is forcing overclaiming at draft/open time unless the author files an extra narrow ticket first. Sometimes the right answer is indeed a narrower ticket, but the workflow currently does not say whether draft PRs are allowed to be temporary planning carriers, whether lint should distinguish draft from ready, or whether authors must always create the narrow delivered leaf before opening the draft.

The Architectural Reality

Current anchors verified before filing:

  • .github/workflows/agent-pr-body-lint.yml:71 through :92 enforces Resolves #N for all agent PR bodies and explicitly says Refs / Related never substitute for it.
  • .agents/skills/pull-request/references/pull-request-workflow.md:277 through :283 makes the same close-target rule mandatory and CI-enforced.
  • learn/agentos/process/evidence-ladder.md:81 through :88 defines the Close-Target Gate and permits Related: #N when the PR does not satisfy the close target.
  • #14698 is draft, has only Refs #14667, and fails only lint-pr-body in the observed status rollup.
  • #14667 ACs require topology-scope capture, not just a reusable composition helper.

Agent OS structure-map gate: ran npm run --silent ai:structure-map -- --files --loc at creation time. The implementation owner for GitHub workflow tooling is ai/services/github-workflow/ when MCP/tooling code is touched; this ticket can also be satisfied by the existing .github/workflows/agent-pr-body-lint.yml plus .agents/skills/pull-request/ workflow substrate without creating new ai/ files.

Skill-shape gate: because the likely documentation substrate includes .agents/skills/pull-request/**, the create-skill skill was consulted. Any skill payload change must keep the router as a lightweight map, place the rule detail in the existing workflow payload or an edge-case sibling, and avoid expanding always-loaded substrate.

The Fix

Define and implement one sanctioned path for agent-authored draft PRs whose diff is intentionally not yet a delivered close target, while preserving the strict ready/merge invariant.

Acceptable implementation shapes include either:

  1. Draft-aware lint path: agent-pr-body-lint.yml accepts a draft-only non-closing reference shape when pull_request.draft === true, but fails the PR once it is ready for review unless it has a valid standalone Resolves #N close target; or
  2. Workflow-only no-draft-partial policy: the pull-request workflow explicitly forbids agent-authored partial draft PRs without a narrow delivered leaf ticket, and the linter message points authors to create that leaf instead of adding a bogus Resolves line.

The implementation should choose one path and make it mechanically obvious. The goal is not to weaken Resolves #N; the goal is to remove the incentive to misuse it.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
.github/workflows/agent-pr-body-lint.yml This ticket; current close-target rule in .agents/skills/pull-request/references/pull-request-workflow.md Agent PR body lint distinguishes the sanctioned draft/partial path from ready-for-review close-target enforcement, or explicitly keeps strict enforcement with a clear no-partial-draft policy. Ready/non-draft agent PRs without standalone Resolves #N still fail. Closes and Fixes remain forbidden. Yes, if behavior changes or the message changes. Workflow lint fixture or equivalent test that covers draft refs-only, ready refs-only, and ready resolves cases.
.agents/skills/pull-request/references/pull-request-workflow.md Current PR workflow and learn/agentos/process/evidence-ladder.md Authors get a clear instruction for draft/stacked partial PRs that does not encourage bogus close targets. If no lint change is made, the workflow states the required narrow-ticket-before-draft path. Yes. Keep detail in the payload, not the SKILL.md router. Skill/docs diff plus PR body lint evidence.
learn/agentos/process/evidence-ladder.md Existing Close-Target Gate No change unless the chosen policy needs a cross-reference; the close-target invariant stays intact. If touched, preserve the rule that Resolves #N requires delivered evidence or explicit residual/deferred annotation. Optional. Reviewer audit against unchanged Close-Target Gate.

Decision Record impact

Aligned with the existing Close-Target Gate in learn/agentos/process/evidence-ladder.md; no ADR change expected.

Acceptance Criteria

  • The selected policy is explicit: either draft-aware linting exists, or the workflow forbids partial draft agent PRs without a narrow delivered leaf ticket.
  • Ready/non-draft agent PRs still require at least one standalone Resolves #N and still reject Closes #N / Fixes #N.
  • The path does not encourage adding Resolves to a PR that only partially delivers its referenced issue.
  • The lint diagnostic, workflow prose, or both point authors toward the honest action when they have only Refs / Related evidence.
  • Tests or fixture evidence cover the #14698 shape: draft, agent-authored, Refs only, no bogus close target.
  • If .agents/skills/** changes, the PR body includes the required /turn-memory-pre-flight load-effect audit and this ticket's Contract Ledger remains the source-ticket contract.

Out of Scope

  • Weakening the Resolves #N invariant for ready PRs.
  • Allowing agent-authored merge candidates to close parent epics or broad tickets accidentally.
  • Solving all stacked-PR review policy. This ticket is only about the PR-body lint / close-target honesty gap.
  • Changing DockZoneModel or perspective-capture implementation details from #14698 / #14667.

Avoided Traps

  • Bogus green CI: adding Resolves #14667 to #14698 would satisfy the current linter but violate the close-target rule.
  • Blanket draft exemption: allowing any draft PR to skip body hygiene would regress the graph-ingestion substrate. The exception, if chosen, must be narrowly draft-only and non-mergeable.
  • Skill bloat: do not move a long rule body into .agents/skills/pull-request/SKILL.md; keep the router light and put operational detail in the workflow payload or a trigger-scoped sibling.

Related

Refs #14698 Refs #14667 Refs #14688

Handoff Retrieval Hints

Retrieval Hint: draft agent PR body lint Resolves Refs-only close target stacked PR Retrieval Hint: agent-pr-body-lint.yml draft pull_request.draft Resolves #N

tobiu referenced in commit 83f88db - "feat(build): allow draft PR body refs-only lint path (#14702) (#14703)" on 10:46 AM
tobiu closed this issue on 10:46 AM