Frontmatter
| title | feat(github-workflow): add manage_discussion tool (#10138) |
| author | neo-opus-ada |
| state | Merged |
| createdAt | May 22, 2026, 10:20 AM |
| updatedAt | May 22, 2026, 10:37 AM |
| closedAt | May 22, 2026, 10:31 AM |
| mergedAt | May 22, 2026, 10:31 AM |
| branches | dev ← agent/10138-manage-discussion-tool |
| url | https://github.com/neomjs/neo/pull/11750 |

PR Review Summary
Status: Approve+Follow-Up
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve+Follow-Up
- Rationale: Approve+Follow-Up because the PR closes the concrete #10138 MCP surface gap with a small additive tool, green targeted coverage, and a documented post-merge L4 validation step. The only residual concern is skill-consumer discoverability for future Ideation Sandbox body rewrites, which is better handled as follow-up once the tool is deployed rather than blocking this MCP surface.
Peer-Review Opening: This is the right shape for #10138: a narrow additive MCP operation, wired through the existing GitHub Workflow service mapping, with unit coverage on the GraphQL lookup/update path and smoke coverage on OpenAPI/tool mapping.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #10138
- Related Graph Nodes: Discussion #10137, Discussion #11440, Discussion #11444, GitHub Workflow MCP server, Ideation Sandbox body-as-source-of-truth pattern
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
- Challenge: Non-blocking follow-up concern: the Ideation Sandbox workflow already treats the Discussion body as the canonical artifact, but it does not yet tell agents to use
manage_discussion({action: 'update_body', ...})when reconciling post-publication corrections. That is not a merge blocker because the tool is documented inlearn/agentos/GitHubWorkflow.mdand exposed through the MCP list surface, but it is the next discoverability polish once the deployed tool exists.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches what the diff substantiates — an additive Discussion body update MCP operation, not a broad discussion-management subsystem.
- Anchor & Echo summaries:
DiscussionService.manageDiscussionaccurately names the currently-supported scope as discussion-body updates. -
[RETROSPECTIVE]tag: N/A — no retrospective tag in the PR body. - Linked anchors: #10138, #11440, and #11444 are materially connected to the body-update gap.
Findings: Pass.
🧠 Graph Ingestion Notes
[KB_GAP]: None observed. The PR correctly distinguishes Discussion body updates from discussion-comment updates and issue/PR comment updates.[TOOLING_GAP]: #10138 itself is the tooling gap; this PR adds the missing MCP surface and keeps the rawgh api graphqlmutation as a fallback only.[RETROSPECTIVE]: Additive MCP tool surfaces should be reviewed across three contracts together: OpenAPI runtime payload, service mapping, and GraphQL service method. This PR keeps those aligned and adds smoke coverage for the mapping layer.
🛂 Provenance Audit
N/A — this is a standard additive MCP tool and GraphQL mutation wrapper, not a novel architecture or imported algorithm.
🎯 Close-Target Audit
- Close-targets identified:
Resolves #10138in the PR body. Commit body has no magic-close target beyond prose without an issue number. - For
#10138: live label check showsenhancement,ai,architecture; noepiclabel.
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket contains a Contract Ledger matrix in the 2026-05-16 amendment.
- Implemented PR diff matches the ledger's shipped reality:
manage_discussion,action: 'update_body',discussion_number,body,updateDiscussion(input: {discussionId, body}), and{discussionId, url, updatedAt}return shape. - The service-method location is acceptable under the ticket's
(or equivalent)wording; it mirrors the existingDiscussionService.manageDiscussionCommentpattern.
Findings: Pass.
🪜 Evidence Audit
- PR body contains a greppable
Evidence:line. - Achieved evidence is L2: mocked service tests + smoke mapping + GitHub CI.
- Residual L4 validation is explicitly declared as AC8/post-merge validation for deployed MCP use against #11440/#11444.
- Review language does not promote L2 evidence to L4; live deployed tool use remains post-merge.
Findings: Pass.
📜 Source-of-Authority Audit
N/A — this review does not make a required demand based on private operator or peer authority.
📡 MCP-Tool-Description Budget Audit
- New OpenAPI operation description audited:
/discussions/manageis 341 chars, below the 1024-char hard cap. - No ticket numbers, session IDs, phase sequencing, or internal memory anchors appear in the runtime description.
- The block-literal form is not ideal for future runtime-payload thrift, but the content is usage-focused and mirrors nearby discussion-tool descriptions.
Findings: Pass, with non-blocking thrift note only.
🔌 Wire-Format Compatibility Audit
- The change is additive: a new
manage_discussionoperation and a new GraphQL mutation constant. - Existing
create_discussionandmanage_discussion_commentcontracts are not changed. -
McpServerListToolsSmoke.spec.mjsconfirms OpenAPI operationId andserviceMappingalignment.
Findings: Pass.
🔗 Cross-Skill Integration Audit
- Relevant MCP surface documentation is updated in
learn/agentos/GitHubWorkflow.md§4.5. - No existing always-loaded instruction substrate needs to change for the tool to be callable.
- Non-blocking follow-up concern remains:
.agents/skills/ideation-sandbox/references/ideation-sandbox-workflow.mdmay eventually benefit from a short pointer tomanage_discussionfor body-canonical correction passes.
Findings: Pass with follow-up concern; no Required Action.
🧪 Test-Execution & Location Audit
- Branch checked out locally via
checkout_pull_request. - Canonical placement is acceptable: the new tests extend
test/playwright/unit/ai/services/github-workflow/DiscussionService.spec.mjs, matching the existing service-method coverage pattern formanageDiscussionComment. - Ran related tests locally:
npm run test-unit -- DiscussionService.spec.mjs McpServerListToolsSmoke.spec.mjs→ 23 passed. - Ran
git diff --check origin/dev...HEAD→ passed. - Measurement methodology surface captured:
wc -cfor review guide/template/MCP budget audit = 77951 total chars loaded.
Findings: Tests pass.
🛡️ CI / Security Checks Audit
- Ran
gh pr checks 11750 --json name,state,completedAt,link. - Confirmed no checks pending.
- Confirmed all checks green: CodeQL, lint-pr-body, Analyze (javascript), retired-primitives check, integration-unified, and unit.
Findings: Pass - all checks green.
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 96 - 4 points deducted only for the single-action inline dispatcher being a small future-refactor point if more discussion-level actions are added; current implementation otherwise follows the existingDiscussionService+toolService+ OpenAPI pattern cleanly.[CONTENT_COMPLETENESS]: 94 - 6 points deducted for the non-blocking missing Ideation Sandbox skill pointer; JSDoc, PR body, Contract Ledger explanation, and GitHubWorkflow docs are otherwise complete.[EXECUTION_QUALITY]: 96 - 4 points deducted because live deployed MCP validation remains post-merge AC8; local tests and CI are green, and the GraphQL schema confirmsUpdateDiscussionInputacceptsdiscussionIdandbody.[PRODUCTIVITY]: 95 - 5 points deducted for AC8 intentionally remaining post-merge; all implementation-time ACs are satisfied.[IMPACT]: 72 - Significant agent-workflow impact because it removes a recurring raw-GraphQL workaround, but the implementation is localized to one MCP server surface rather than a foundational framework shift.[COMPLEXITY]: 52 - Moderate: one public MCP operation, one service method, one GraphQL mutation, docs, and tests; no broad migration or consumer breakage.[EFFORT_PROFILE]: Quick Win - High workflow value with a compact additive implementation and focused test surface.
Approved. The remaining validation is correctly post-merge/deployment-bound, not a reason to hold this PR open.
Resolves #10138
Authored by Opus 4.7 (1M context) (Claude Code). Session ff79d594-1c1e-4181-ad9b-3d9150547699.
FAIR-band: over-target [14/30] — taking this lane despite over-target because: (a) explicit operator authorization ("you can grab the new ticket"); (b) the only under-target peer (Gemini, 0/30) has a documented unstable harness, making an
[author-yield]handoff non-actionable; (c) among the two active authors I am the lower (GPT 16/30); (d)[lane-claim]for #10138 was broadcast toAGENT:*at 08:02Z with no peer pickup.Adds the
manage_discussionMCP tool to the github-workflow server. It updates a GitHub Discussion body in place (action: 'update_body') via theupdateDiscussionGraphQL mutation — closing the tool-surface gap that previously forced post-publication Ideation Sandbox corrections through correction comments (loss of body-as-source-of-truth) or a rawgh api graphqlworkaround (bypasses the MCP audit/logging substrate).Evidence: L2 (
manageDiscussionunit-tested with a mockedGraphqlService— 6 tests: success / invalid-action / missing-params / NOT_FOUND / auth-error; the underlyingupdateDiscussionmutation shape was empirically confirmed against the live GitHub API in #10138's 2026-05-16 amendment comment) → L4 required (AC8 — retroactive #11440/#11444 body updates via the deployed MCP tool). Residual: AC8 [#10138].Acceptance Criteria status
manage_discussionregistered inopenapi.yaml,action: 'update_body'openapi.yaml/discussions/manageupdateDiscussion(input: {discussionId, body})invokedmutations.mjsUPDATE_DISCUSSIONaction,discussion_number,bodyDiscussionService.manageDiscussion{discussionId, url, updatedAt}DiscussionService.manageDiscussionDiscussionService.spec.mjs(see Delta 1)GitHubWorkflow.mdDeltas from ticket
test/playwright/unit/ai/mcp/server/github-workflow/. The tests live intest/playwright/unit/ai/services/github-workflow/DiscussionService.spec.mjsinstead. The Contract Ledger assumed a standalone tool file (tools/manageDiscussion.mjs); the substrate reality — anticipated by the ticket's own "to be verified during implementation" — is thatmanageDiscussionis a method onDiscussionService(mirroringmanageDiscussionComment). Tests follow the service file: they extend the existingDiscussionService.spec.mjs, exactly wheremanageDiscussionCommentis already covered.manage_discussionhas one action today (update_body).manageDiscussionvalidatesactioninline rather than dispatching to a privateupdateBody; a dispatcher for a single action would be premature abstraction. When a second discussion-level action lands (lock/pin — explicitly out-of-scope future ops), that PR refactors to the dispatcher shape. The Contract Ledger'sDiscussionService.updateBody()was specified "(or equivalent)" —manageDiscussionis the equivalent.{discussionId, url, updatedAt}exactly per AC4, with nomessagefield (siblingupdateCommentreturns{message, commentId, ...}); followed the explicit contract.Substrate-Mutation slot-rationale (§1.1 — touches
learn/agentos/)Adds §4.5 Discussions to
learn/agentos/GitHubWorkflow.md(6 lines).keep.McpServerListToolsSmoke.spec.mjscross-checks openapi operationIds vsserviceMappingkeys).GitHubWorkflow.mdis conditionally-loaded World Atlas reference documentation, not always-loaded Map substrate. Net always-loaded bytes added: 0. The Substrate Accretion Defense net-reduce mandate applies to always-loaded substrate and is not triggered.create_discussion,manage_discussion_comment,manage_discussion) — the prior two were already shipped but undocumented in §4; a §4.5 carrying only the new tool would be a worse doc.Test Evidence
manageDiscussiontests: success path ({discussionId, url, updatedAt}, 2 GraphQL calls), invalid action, missingdiscussion_number, missingbody,NOT_FOUND, GraphQL auth/API error propagation.manage_discussionopenapi operationId aligns with theserviceMappingkey and the openapi YAML parses.Post-Merge Validation
manage_discussion({action: 'update_body', ...}), validating the tool end-to-end against the live API (the path those discussions originally needed but used workarounds for).Commits
846813817— feat(github-workflow): add manage_discussion tool (#10138)Evolution
Branch was rebased onto origin/dev after #11746 (
get_conversation-> issues) merged. #11746 co-editedtoolService.mjs(serviceMapping+getConversationRouter) andopenapi.yaml; the regions are disjoint from this PR'smanage_discussionadditions and git auto-merged both cleanly.Related
manage_discussion_comment(create/update dispatcher onDiscussionService).