LearnNewsExamplesServices
Frontmatter
id10755
titleCodify Resolves/Fixes (preferred) vs Closes (avoid for shipped work) in pull-request-workflow + DreamPipeline doc
stateClosed
labels
documentationenhancementaimodel-experience
assigneesneo-gpt
createdAtMay 5, 2026, 6:04 PM
updatedAtMay 19, 2026, 10:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/10755
authorneo-opus-4-7
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 19, 2026, 10:35 AM

Codify Resolves/Fixes (preferred) vs Closes (avoid for shipped work) in pull-request-workflow + DreamPipeline doc

Closeddocumentationenhancementaimodel-experience
neo-opus-4-7
neo-opus-4-7 commented on May 5, 2026, 6:04 PM

Context

Lost knowledge per @tobiu 2026-05-05: the rule preferring Resolves (and equivalently Fixes) over Closes for successfully-shipped work was never explicitly codified in the substrate. Empirical anchors:

  • pull-request-workflow §9 Syntax-Exact Keyword Mandate currently treats Resolves #N and Closes #N as interchangeable: "You MUST use the exact GitHub-supported magic keyword syntax (e.g., Resolves #N or Closes #N) on its own line." No semantic-preference clause.
  • Memory Core query (semantic search via query_summaries + query_raw_memories) returned zero hits on the Resolves-vs-Closes preference rule. Either oral / pre-Memory-Core-era / never explicitly memorialized.
  • Knowledge Base check (ask_knowledge_base) surfaced learn/agentos/GitHubWorkflow.md + learn/agentos/DreamPipeline.md. The latter mentions: "Resolves #NNN patterns also create RESOLVES edges, closing the feedback loop between PRs and the issues they address." — only Resolves is documented.
  • Code reality (ai/daemons/services/IssueIngestor.mjs:363): [...content.matchAll(/(?:(?:Resolves|Closes|Fixes)\s+#)(\d+)/gi)] — the regex accepts ALL THREE keywords and creates a RESOLVES graph edge for any of them. Doc/code drift.

@tobiu's calibration: "resolves and fixes are equivalent. closes can include dropped. so a new ticket (doc gap) and maybe logic gap, and codifying it (1-liner inside pull request skill manual) might add value."

Per feedback_truth_in_code + feedback_neo_native_integration_check: the substrate distinguishes intent (Resolves/Fixes = closed-successfully; Closes = could-be-dropped-or-not-planned) but the code doesn't enforce. Convention-only rule today.

The Problem

Two distinct gaps:

  1. Doc gap (concrete): pull-request-workflow §9 doesn't capture the agent-discipline preference. Result: agents (including this session's PR #10754) default to Closes #N because it's the first GitHub-canonical example most LLM training data carries; lose the semantic-distinction signal for graph-ingestion + retrospective ticket-state semantics.

  2. Logic gap (open question): IssueIngestor.mjs:363 regex accepts Resolves|Closes|Fixes and creates RESOLVES edges for all three. Should the regex be tightened to exclude Closes (since Closes could indicate dropped/not-planned)? Or is the substrate-permissiveness intentional (agent uses convention; substrate is liberal in what it accepts)?

The Architectural Reality

Files affected (doc-gap):

  • .agents/skills/pull-request/references/pull-request-workflow.md §3.2 Commit Message Hygiene and/or §9 PR Body Hygiene (Syntax-Exact Keyword Mandate)
  • learn/agentos/DreamPipeline.md (Issue Ingestion Pipeline section — clarify Resolves-canonical vs liberal-regex divergence)

Files affected (logic-gap, IF tightening is the right call):

  • ai/daemons/services/IssueIngestor.mjs:363 — regex narrowing

The Fix

Two-part scope, file under one ticket per @tobiu's framing:

Part 1 — Doc gap (concrete; ship in this ticket):

Add a 1-line clause to pull-request-workflow §9 Syntax-Exact Keyword Mandate:

"Prefer Resolves #N (or Fixes #N for bugs specifically) over Closes #N for successfully-shipped work. Closes #N includes the semantics 'closed but not necessarily delivered' (e.g., not-planned, superseded, dropped scope). GitHub treats all three as auto-close magic keywords mechanically; the distinction is convention-level discipline that downstream graph-ingestion (IssueIngestor.mjs:363 creates RESOLVES graph edges) and retrospective ticket-state analysis depend on."

Update learn/agentos/DreamPipeline.md Issue Ingestion Pipeline mention to clarify:

"Resolves #NNN patterns create RESOLVES edges. (The current implementation also liberally accepts Closes/Fixes for the same edge — see open question in #NEW for whether to tighten.)"

Part 2 — Logic gap (open question; surface as Open Question, defer decision):

Whether IssueIngestor.mjs:363 should narrow the regex to only accept Resolves|Fixes (excluding Closes):

  • Pro tightening: Closes could indicate not-planned / superseded / dropped; creating a RESOLVES edge for those misrepresents the substrate-truth
  • Pro keeping permissive: liberal-in-what-you-accept; agent-discipline already enforces Resolves; tightening would silently break edge creation if an agent uses Closes legitimately (e.g., for a fully-completed-but-keyword-confused PR)
  • Empirical evidence needed: sample IssueIngestor output across recent PRs to count Closes vs Resolves usage; if Closes-usage is rare AND those cases were genuinely-dropped-not-resolved, tightening is justified

Surface the question; let @tobiu decide whether to tighten or keep permissive. Logic-gap implementation is downstream-PR scope, not this ticket.

Acceptance Criteria

  • (AC1) pull-request-workflow §9 includes the Resolves/Fixes preferred / Closes-avoid clause (1-2 sentences)
  • (AC2) learn/agentos/DreamPipeline.md Issue Ingestion Pipeline mention clarified to acknowledge the doc/code permissiveness divergence
  • (AC3) Logic-gap question surfaced as open question in PR body (or as an inline TODO comment in IssueIngestor.mjs:363); resolution deferred to operator-decision
  • (AC4) Empirical search of recent PRs: count Closes #N vs Resolves #N vs Fixes #N usage to give the logic-gap decision substrate; report in PR body

Out of Scope

  • Tightening the IssueIngestor regex — that's a separate logic-gap PR pending @tobiu's decision per AC3
  • Retroactive PR body edits — past Closes #N PRs stay as-is; new convention applies forward
  • GitHub mechanical behavior — both keywords auto-close at merge; we're not changing GitHub semantics

Avoided Traps

  • Trap: silently tighten regex without surfacing the decision. Logic-gap question is genuinely-ambiguous-scope; should be operator-decision territory before code change.
  • Trap: assume Memory Core has the rule. Verified empirically — semantic search returned zero hits. The rule wasn't lost; it was never codified.
  • Trap: over-prescribe at the §0 level. Per feedback_blocker_reserved_for_merge_breaking + the cognitive-load epic discipline: the rule is convention-level (Nit/Polish) for new PRs, not §0 invariant. Skill-payload §9 is the right home, not AGENTS.md §0.

Related

  • Empirical anchor: PR #10754 (this session) used Closes #10738 → Tobi flagged → updated to Resolves #10738 post-discussion
  • Substrate references:
    • ai/daemons/services/IssueIngestor.mjs:363 — the permissive regex
    • learn/agentos/DreamPipeline.md Issue Ingestion Pipeline section
    • .agents/skills/pull-request/references/pull-request-workflow.md §9 Syntax-Exact Keyword Mandate
  • Sibling tickets in MX queue: post-epic-cleanup batch (architectural-pillar Pre-Flight, handshake-gap, bias-disclosure-discipline, post-rebase PR-body audit reflex)

Origin Session ID: 23b9cbcd-4938-4a46-b21a-0d48dd12e7e7

Retrieval Hint: query_raw_memories(query="Resolves Fixes Closes magic keyword preference ticket lifecycle dropped not-planned successful resolution graph edge IssueIngestor RESOLVES doc-code drift")

tobiu referenced in commit bec93cd - "feat(agentos): codify resolves keyword convention (#10755) (#11621) on May 19, 2026, 10:35 AM
tobiu closed this issue on May 19, 2026, 10:35 AM