Skip to content

feat: type discussion and notification tool outputs - #3388

Open
SamMorrowDrums wants to merge 4 commits into
sammorrowdrums-typed-security-outputsfrom
sammorrowdrums-typed-discussion-notification-outputs
Open

SamMorrowDrums wants to merge 4 commits into
sammorrowdrums-typed-security-outputsfrom
sammorrowdrums-typed-discussion-notification-outputs

Conversation

@SamMorrowDrums

Copy link
Copy Markdown
Collaborator

Summary

Migrate all 5 discussion and 6 notification tools to typed input/output registration, compact concrete DTOs, and protocol-gated modern output schemas and structured results. Preserve existing legacy text responses and input schemas.

Why

Next typed-output migration layer, stacked on #3387. Exact refreshed base: 7ef5714b5880d9205610219ce6e3a16df13f8bd9. No issue closure or native stack metadata changes.

What changed

  • Add 11 concrete input DTOs, compatibility normalizers, and compact discussion/notification outputs. Preserve legacy casing and numeric coercions, optional parameter presence, pagination, RFC3339 errors, sanitization, IFC attachment, permissions, and reply ownership validation.
  • Register all 11 tools through NewTool[In, Out]. Model comment write results as a strict comment-reference versus discussion-answer-reference union; subscription tools return a strict subscription-versus-deletion-message union. Discussion replies have a concrete one-level DTO matching the queried API rather than a recursive schema.
  • Add modern/legacy tools/list and tools/call tests for all tools, all six comment methods, both dismissal states, all subscription actions, output-schema conformance, impossible-union rejection, byte-exact legacy text, and error responses without structured success output. Update three explicit union schema snapshots; remaining schemas are SDK-inferred.
  • Keep deletions coupled to migration: replace inline WeakDecode input structs and anonymous answer output structs, remove the superseded handler import, and type subscription API result variables. No unrelated code removal.

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Modern protocol 2026-07-28 receives output schemas and compact structured results for these 11 tools; legacy protocol 2025-11-25 remains text-only. Names and advertised input schemas remain unchanged; legacy text is checked byte-for-byte.

Prompts tested (tool changes only)

  • Equivalent mocked tool calls, not live prompt sessions: “List my notifications,” “Show notification 123,” “Mark notification 123 read/done,” and “Mark all notifications read.”
  • “Watch/ignore/delete a thread or repository subscription.” All six subscription-action branches tested.
  • “List organization discussions and categories,” “Get discussion 1,” and “Show discussion comments with replies.” Numeric strings, legacy casing, fractional WeakDecode coercion, cursor pagination, and explicit zero defaults tested.
  • “Add/reply/update/delete a discussion comment; mark/unmark it as the answer.” All six mutation branches tested, including reply ownership and missing/blank parameter errors.

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Existing scope requirements and IFC labels are preserved. Structured results trim repository details while legacy text retains its full existing response; discussion comment bodies continue using existing sanitization. Pagination and the API's one-level, up-to-100-reply query remain unchanged.

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR

No tool names or aliases changed.

Note: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Commands and results:

  • UPDATE_TOOLSNAPS=true go test ./pkg/github -run 'Test_(ListNotifications|DismissNotification|MarkAllNotificationsRead|GetNotificationDetails|Manage.*NotificationSubscription|ListDiscussions|GetDiscussion|ListDiscussionCategories|DiscussionCommentWrite)' -count=1 — passed; updated intentional union snapshots.
  • go test ./pkg/github -run 'Test(TypedDiscussionNotificationOutputs|DiscussionNotificationUnionsRejectImpossibleResults)|Test_(ListNotifications|DismissNotification|MarkAllNotificationsRead|GetNotificationDetails|Manage.*NotificationSubscription|ListDiscussions|GetDiscussion|ListDiscussionCategories|DiscussionCommentWrite)' -count=1 — passed.
  • script/lint — passed, 0 issues.
  • script/test — passed, full go test -race ./... suite, including mcpcurl.
  • script/generate-docs — passed; generated documentation unchanged.
  • git diff --check and git diff --cached --check — passed.

Live PAT-dependent E2E tests were not run.

Docs

  • Not needed
  • Updated (README / docs / examples)

script/generate-docs passed with no documentation content changes; tool descriptions and advertised input schemas are unchanged. Explicit union output contracts are captured in toolsnap updates.

@SamMorrowDrums
SamMorrowDrums added this pull request to stack #3385 October 2, 2026 11:38
@SamMorrowDrums
SamMorrowDrums force-pushed the sammorrowdrums-typed-discussion-notification-outputs branch from b9c2a32 to ed9ac2e Compare October 2, 2026 20:50
@SamMorrowDrums
SamMorrowDrums requested a balanced review from Copilot October 3, 2026 04:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The discussion read normalizer inserts absent required fields, allowing invalid requests to bypass schema validation.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Migrates discussion and notification tools to typed, protocol-gated structured outputs while preserving legacy text responses and input compatibility.

Changes:

  • Adds typed input/output DTOs and compatibility normalizers for 11 tools.
  • Adds strict union schemas and protocol compatibility tests.
  • Updates explicit output-schema snapshots.
File Description
pkg/​github/​discussion_notification_inputs.go Adds typed inputs and normalizers.
pkg/​github/​discussion_notification_outputs.go Defines compact structured outputs.
pkg/​github/​discussions.go Migrates discussion tools to typed registration.
pkg/​github/​notifications.go Migrates notification tools to typed registration.
pkg/​github/​typed_discussion_notification_outputs_test.go Tests schemas, protocol gating, and compatibility.
pkg/​github/​__toolsnaps__/​discussion_comment_write.snap Records comment-write union schema.
pkg/​github/​__toolsnaps__/​manage_notification_subscription.snap Records thread-subscription union schema.
pkg/​github/​__toolsnaps__/​manage_repository_notification_subscription.snap Records repository-subscription union schema.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +110 to +112
args["owner"] = input.Owner
args["repo"] = input.Repo
args["discussionNumber"] = input.DiscussionNumber
SamMorrowDrums and others added 4 commits October 3, 2026 15:42
Migrate all eleven tools to typed registration and compact output DTOs. Preserve legacy text, parameter compatibility, pagination, and mutation validation while publishing honest modern output unions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Trim notification hypermedia, preserve useful HTML links, and record all modern schemas in canonical snapshots. Preserve source presence during discussion read normalization and cover the Copilot review regression alongside empty/null outputs, IFC labels, sanitization, and output enums.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…O expectations

Add an explicit {} (fully-empty args) case to
TestDiscussionReadRequiredArguments proving the normalizer never
synthesizes placeholder owner/repo/discussionNumber values that would
let an empty request satisfy SDK required-schema validation and reach
GraphQL; verified both protocols reject it pre-handler with zero
GraphQL calls (addresses readiness-audit re-flag of already-fixed
Copilot review comment 4171698931 in 578e9929).

Also record the pending modern-text==structuredContent DTO contract
(2026-07-28 protocol) in test expectations; these assertions are
intentionally red pending the coordinator's central once-marshal
wrapper in pkg/inventory/typed_output.go, which this branch does not
yet have.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums
SamMorrowDrums force-pushed the sammorrowdrums-typed-discussion-notification-outputs branch from ed9ac2e to eb11e13 Compare October 3, 2026 13:46
@SamMorrowDrums
SamMorrowDrums marked this pull request as ready for review October 3, 2026 13:48
@SamMorrowDrums
SamMorrowDrums requested a review from a team as a code owner October 3, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants