Summary
Repair two post-merge verification gaps in the believed-open list_pull_requests leaf:
- OpenAPI array constraints are declared but do not reach the generated MCP
tools/list schema.
- The default-query regression test imports its expected query from production, so production and oracle can drift together.
This is a narrow successor to the resolved feature ticket and PR. It restores executable contract truth without changing the belief projection, adding an MCP tool, or broadening the response shape.
Problem
The merged OpenAPI source declares maxItems: 100 and uniqueItems: true for believedOpen. The shared OpenAPI-to-Zod compiler currently drops both keywords, so the actual list_pull_requests.inputSchema published through tools/list does not contain the constraints. A raw-YAML assertion can therefore pass while the agent-consumed contract is weaker than declared.
The no-belief regression test also imports the production FETCH_PULL_REQUESTS constant as its expected value. That proves the captured query equals itself, not that the predecessor query bytes remain stable.
Architectural reality
ai/mcp/validation/openApiValidator.mjs owns OpenAPI → Zod → emitted MCP input-schema compilation.
test/playwright/unit/ai/mcp/validation/OpenApiValidatorCompliance.spec.mjs owns the generic compiler contract.
- The GitHub Workflow MCP tool service owns the real
tools/list publication surface.
test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs owns the default-query regression witness.
No new subsystem or file is required.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
Existing list_pull_requests.inputSchema.properties.believedOpen emitted by tools/list |
ai/mcp/server/github-workflow/openapi.yaml through the shared compiler |
Publish an array of unique positive integers with at most 100 entries |
Invalid duplicate, non-positive, or over-cap values remain rejected before GitHub I/O by the direct service guard |
No new docs; preserve the existing OpenAPI declaration |
Generic compiler tests plus the real GitHub tool-service listTools() projection |
Existing no-belief GraphQL request in PullRequestService.listPullRequests() |
Merged predecessor behavior from PR #16170 |
Preserve the predecessor query at 987 bytes and SHA-256 68b60ee57194252d68f3b50f2e174f25ff3859d3ba89bd2a66d7e2d873e1914f |
Any byte drift fails against an independent literal oracle |
JSDoc remains current |
Captured default-path query length and digest assertions |
Acceptance Criteria
Out of Scope
- Refining
unverifiable reasons from GitHub response.errors; that is a separate diagnosability concern.
- Changing the three result buckets or belief-projection semantics.
- Adding an MCP tool, compatibility layer, state, or request.
- General OpenAPI completeness beyond array constraints already present in the current server specifications.
Avoided Traps
- Treating raw YAML as proof of the emitted
tools/list contract.
- Importing the production query as its own regression oracle.
- Reopening the resolved predecessor ticket.
- Mixing response diagnosability into a compiler-and-test restoration.
Decision Record Impact
None. This restores the declared and merged contract; it introduces no architectural decision.
Relationships
Parent: #16136
Successor to #16191
Related: #16192, #16170
Retrieval Hint
#16192 generated tools/list maxItems uniqueItems self-referential FETCH_PULL_REQUESTS oracle
Origin Session
b1ebc46a-5a83-496c-aa8b-385af785e9cb
Summary
Repair two post-merge verification gaps in the believed-open
list_pull_requestsleaf:tools/listschema.This is a narrow successor to the resolved feature ticket and PR. It restores executable contract truth without changing the belief projection, adding an MCP tool, or broadening the response shape.
Problem
The merged OpenAPI source declares
maxItems: 100anduniqueItems: trueforbelievedOpen. The shared OpenAPI-to-Zod compiler currently drops both keywords, so the actuallist_pull_requests.inputSchemapublished throughtools/listdoes not contain the constraints. A raw-YAML assertion can therefore pass while the agent-consumed contract is weaker than declared.The no-belief regression test also imports the production
FETCH_PULL_REQUESTSconstant as its expected value. That proves the captured query equals itself, not that the predecessor query bytes remain stable.Architectural reality
ai/mcp/validation/openApiValidator.mjsowns OpenAPI → Zod → emitted MCP input-schema compilation.test/playwright/unit/ai/mcp/validation/OpenApiValidatorCompliance.spec.mjsowns the generic compiler contract.tools/listpublication surface.test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjsowns the default-query regression witness.No new subsystem or file is required.
Contract Ledger
list_pull_requests.inputSchema.properties.believedOpenemitted bytools/listai/mcp/server/github-workflow/openapi.yamlthrough the shared compilerlistTools()projectionPullRequestService.listPullRequests()68b60ee57194252d68f3b50f2e174f25ff3859d3ba89bd2a66d7e2d873e1914fAcceptance Criteria
list_pull_requestsMCP input schema containstype: array,maxItems: 100,uniqueItems: true, and an integer item minimum of1.minItemsbehavior is also covered.believedOpeninput before GitHub I/O.Out of Scope
unverifiablereasons from GitHubresponse.errors; that is a separate diagnosability concern.Avoided Traps
tools/listcontract.Decision Record Impact
None. This restores the declared and merged contract; it introduces no architectural decision.
Relationships
Parent: #16136
Successor to #16191
Related: #16192, #16170
Retrieval Hint
#16192 generated tools/list maxItems uniqueItems self-referential FETCH_PULL_REQUESTS oracleOrigin Session
b1ebc46a-5a83-496c-aa8b-385af785e9cb