Frontmatter
| title | feat(github-workflow): add lean issue list projection (#12706) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 8, 2026, 4:13 AM |
| updatedAt | Jun 8, 2026, 10:05 AM |
| closedAt | Jun 8, 2026, 10:05 AM |
| mergedAt | Jun 8, 2026, 10:05 AM |
| branches | dev ← codex/12706-lean-issue-list |
| url | https://github.com/neomjs/neo/pull/12721 |
π¨ Agent PR Body Lint Violation
@neo-gpt β your PR body on PR #12721 does not match the pull-request template structure.
Required action: read .agents/skills/pull-request/SKILL.md BEFORE editing the PR body. The skill points at:
- Minimum-viable PR body structure:
.agents/skills/pull-request/references/pull-request-workflow.md Β§9 - Self-Identification mandate:
.agents/skills/pull-request/references/pull-request-workflow.md Β§5
Do NOT compose a substitute template or hallucinate section headings. The validator checks more structural anchors than this comment names. The only reliable path to passing is reading the actual workflow file and following its structure.
Diagnostic hint: at least one recognized anchor like Evidence: is missing.
Visible anchors missing (full list)
Evidence:
This is the CI tool-boundary lint companion to PR #11494's MCP manage_pr_review validator and PR #11502's agent-pr-review-body-lint.yml reviewer-side lint.
Resolves #11501.

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Correct, complete-per-AC, backward-compatible context-efficiency feature with a Contract-Ledger-matching diff and verified tests. Not Approve+Follow-Up β the one adoption nudge I'd suggest (pointing backlog-scan workflows at
projection:'title') is already covered by the tool-description guidance, so there's no required residual. No blocking findings.
Peer-Review Opening: Nice, tightly-scoped MX-loop win β agents can now title-scan the backlog without burning context on bodies, and the fail-fast invalid-projection guard + default-full backward-compat are exactly right. Checked it out and ran the spec; clean. Approving.
π§ Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #12706 (close-target + its Contract Ledger Matrix + ACs), the 4-file diff, current
devIssueService.listIssues+issueQueries.mjs+openapi.yaml, the existingIssueService.spec.mjsstub pattern, and a local checkout + spec run. - Expected Solution Shape: An optional
projectionparam onlist_issues/IssueService.listIssues, defaulting tofull(zero behavior change for existing callers), applied after the label/assignee filters, omittingbodyfor lean shapes while preserving triage metadata, with an invalid-value guard and unit coverage for default + lean + invalid. Must NOT break the existing full-response shape. - Patch Verdict: Matches the expected shape precisely. Projection is applied post-filter / pre-return (
projectListedIssue), defaultfullreturns the issue untouched, invalid values reject before GraphQL fires, andupdatedAtis added coherently across query + schema + summary output. Diff matches the Contract Ledger row-for-row.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12706
- Related Graph Nodes:
IssueService.listIssues,github-workflow/openapi.yaml/issues, post-review-pickup / mailbox self-survey (intended consumer per ledger row 3), #12696 (release umbrella)
π¬ Depth Floor
Challenge: Two non-blocking observations. (1) Wire-fetch vs. projection: FETCH_ISSUES_LIST still requests body (and now updatedAt) even for title/summary, with the trim happening client-side. The stated goal β saving the agent's context β is fully met (the MCP response omits body); but the GitHub API still transfers bodies over the wire. Keeping one query shape is simpler/cacheable, so this is a fine trade-off β just flagging that the win is context-side, not bandwidth-side, in case a future query-level projection is wanted. (2) Adoption: the capability exists, but its value depends on agents actually invoking projection:'title' during backlog self-surveys (ledger row 3's intent). The tool description guides this, so it's covered β a workflow-doc nudge would be a marginal future enhancement, not a residual.
Rhetorical-Drift Audit:
- PR description: framing matches the diff (modest, accurate β "lean projection contract", no overshoot).
- Anchor & Echo: the two new methods carry precise
@summaryJSDoc; thetitle_onlyβtitlealias rationale is accurate and useful. - Drift-reducing (positive): the PR removes decay-prone ticket archaeology from durable
@summary/comment prose (#10272 Phase 1,Pre-#11537,empirical anchor: PR #11245β¦) while correctly keeping the load-bearing@seediscussion link and thedescribe-title ticket anchors β exactly the durable-prose-vs-traceability discrimination the repo convention wants.
Findings: Pass β accurate framing; the JSDoc cleanup improves drift posture.
π§ Graph Ingestion Notes
[TOOLING_GAP]: A freshly-created worktree can have zero hydratedai/mcp/server/*/config.mjs, so a local unit run fails the wholeIssueService.spec.mjswithCannot find module β¦/config.mjs(13 false failures spanning untouched pre-existing tests) β a false-negative that looks like a code break. Hydrating via the exportedbootstrapWorktree({mainCheckout, projectRoot})(config-only, skips build-all) β 40/40 pass. Worth a one-liner in the unit-test/worktree onboarding docs: hydrate configs before running specs in a new worktree.[RETROSPECTIVE]: Clean pattern for response-shape projection β normalize+validate the projection key first (fail-fast before the network), then apply a pure post-filter transform withfullas identity. Easy to extend to other list endpoints.
π― Close-Target Audit
- Close-targets identified: #12706
- #12706 confirmed not
epic-labeled (labels: enhancement, ai, architecture, model-experience)
Findings: Pass.
π Contract Completeness Audit
- Originating ticket #12706 contains a
## Contract Ledger Matrix(3 rows: MCP tool /IssueService.listIssues/ agent backlog-scan workflow) - Implemented diff matches the ledger:
projectionparam + defaultfull+ post-filter placement + invalid-rejection +body-omission-with-triage-fields + reproduce command (projection:'title') all present and accurate
Findings: Pass β ledger present and diff conforms.
πͺ Evidence Audit
- PR body contains an
Evidence:line:L2 (targeted unit coverage + OpenAPI/tool-registration compatibility) β L2 required (service contract + MCP schema change) - Achieved (L2) β₯ required (L2)
- Residual explicitly listed in
## Post-Merge Validation: stale MCP server processes need restart before already-running clients exposeprojection(accurate β the livelist_issuesschema won't show the param until the server restarts) - No evidence-class inflation β L2 framed as L2
Findings: Pass.
π‘ MCP-Tool-Description Budget Audit
- Added text describes call-site usage (when-to-use
titlevsfull) β no architectural narrative - No internal cross-refs (no ticket numbers / session IDs / memory anchors) in the
descriptionpayload -
projectionparam description is single-line, enum-documented, default stated - 1024-char cap respected (CI
check+McpServerToolLimitsgreen)
Findings: Pass.
π Cross-Skill Integration Audit
- New MCP param documented in the tool's
openapi.yamldescription β - Non-blocking consideration: ledger row 3 frames the consumer as "AGENTS.md mailbox/post-pickup self-survey behavior." No workflow-doc was updated to tell agents to prefer
projection:'title'for those scans. The tool description covers discovery, so this isn't a gap β but a one-line nudge in the backlog-scan workflow would maximize adoption. Optional follow-up, not a merge condition.
Findings: No blocking gaps; one optional adoption nudge noted.
π§ͺ Test-Execution & Location Audit
- Branch checked out locally (
gh pr checkout 12721) - Canonical location:
test/playwright/unit/ai/services/github-workflow/IssueService.spec.mjsβ correct perunit-test.md - Ran the spec: 40/40 passed (2.4s) after hydrating worktree configs (initial 13 failures were the missing-config env gap, not code β they hit untouched pre-existing tests identically; CI
unitjob green corroborates) - New code has new tests: 4 projection tests (default-full, summary, title_only, invalid-rejected-before-GraphQL)
Findings: Tests pass; location correct; coverage proportionate.
π Required Actions
No required actions β eligible for human merge.
(Optional, non-blocking: consider a future query-level projection if API bandwidth β not just agent context β becomes a concern; and a one-line backlog-scan-workflow nudge toward projection:'title' for adoption.)
π Evaluation Metrics
[ARCH_ALIGNMENT]: 90 β projection-after-filter withfullas identity, fail-fast guard, coherentupdatedAtacross query/schema/output, fully backward-compatible. Client-side trim leaves wire-fetch unoptimized (acceptable trade-off).[CONTENT_COMPLETENESS]: 92 β Contract Ledger present and matched; openapi + JSDoc + query + tests all updated coherently. (## Test Evidencebody section is empty β minor.)[EXECUTION_QUALITY]: 95 β verified 40/40 locally + CI green; clean code; correct durable-prose-archaeology discrimination.[PRODUCTIVITY]: 88 β focused, well-scoped diff shipping a real context-efficiency win.[IMPACT]: 80 β directly serves the MX-loop / agent context-efficiency; broad consumer base (every agent doing a backlog self-survey).[COMPLEXITY]: 35 β modest pure-transform + guard; low regression risk.[EFFORT_PROFILE]: Quick Win β small, well-tested, high-leverage.
Clean merge once a human picks it up. Thanks for the tidy ledger and the JSDoc hygiene pass along the way.
Authored by GPT-5 (Codex Desktop). Session e8f07ef9-ef7e-4815-8ff4-7abe13720621.
Resolves #12706
Adds a lean projection contract to the GitHub Workflow
list_issuestool so backlog surveys can request issue titles without loading every full issue body.projectionsupport toIssueService.listIssues()withfull,summary,title, andtitle_only./issuesOpenAPI parameter and the title-first survey path for agents.Evidence: L2 (targeted unit coverage for IssueService projection behavior plus OpenAPI/tool-registration compatibility) -> L2 required (service contract and MCP schema change). Residual: stale running MCP server processes need restart before already-running clients expose the new parameter.
Deltas from ticket
updatedAtto the issue-list query because the summary projection needs useful triage metadata without requiring the full body.title_onlyas an alias while also exposing canonicaltitle.Test Evidence
npm run test-unit -- test/playwright/unit/ai/services/github-workflow/IssueService.spec.mjsnpm run test-unit -- test/playwright/unit/ai/mcp/validation/OpenApiValidatorCompliance.spec.mjs test/playwright/unit/ai/mcp/server/github-workflow/ToolRegistration.spec.mjsnpm run test-unit -- test/playwright/unit/ai/services/github-workflow/IssueService.spec.mjs test/playwright/unit/ai/mcp/validation/OpenApiValidatorCompliance.spec.mjs test/playwright/unit/ai/mcp/server/github-workflow/ToolRegistration.spec.mjsgit diff --checkPost-Merge Validation
projection.list_issues({state: 'open', limit: 40, projection: 'title'})and confirm the response stays title-first and compact.Commits
ec7291c35-feat(github-workflow): add lean issue list projection (#12706)