[GH-ISSUE #1113] [Bug] Builds can ship a stale unused generated MCP catalog artifact #396

Closed
opened 2026-10-15 18:24:43 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @N0zoM1z0 on GitHub (Oct 8, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1113

Originally assigned to: @N0zoM1z0 on GitHub.

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Setup, packaging, or upgrade; generated artifacts and validation.

Observed behavior

A successful cached build restored a package whose generated TypeScript catalog was current but whose compiled generated catalog contained older input/output definitions. Direct conversion of all 139 canonical contracts matched the generated source. The compiled artifact differed at 78 leaf locations across seven tools: observe_native_calls, trace_dylib_resolution, analyze_javascript_application, trace_javascript_semantics, observe_web_execution, inspect_web_event_listeners, and binary_session.

Scope correction after tracing the actual consumer: this compiled artifact is not imported by the current production server. A real stdio tools/list call against the same baseline advertised all 139 tools and matched the freshly generated source for every input/output schema, while differing from the stale compiled artifact for exactly those seven tools. The initial report incorrectly described the generated file as the server's source. No stale-schema client failure is established; the report now concerns generated-artifact consistency and unnecessary package contents.

Reproduction

  1. Build a checkout, then change a canonical schema or update to a revision with schema changes while retaining previously generated catalog source.
  2. Run npm run build:cached once.
  3. Compare dist/generatedMcpToolCatalog.js with the current generated source and canonical post-SDK contracts.
  4. Also connect to the built production MCP server and compare the actual tools/list result, rather than assuming it consumes the compiled generated module.

Observed at cc0ee2edc60dda42d7b7cfb2c08e39b0b736b5e9:

{
  "live_tools": 139,
  "live_matches_fresh_generated_source": true,
  "compiled_generated_matches_fresh_source": false,
  "live_vs_stale_compiled_difference_tools": 7
}

Expected behavior

Generated artifacts included in a package should match the current build. If an artifact exists only for source-level schema/conformance tests, consider excluding its compiled form from the shipping package instead of adding unnecessary runtime generation or compilation. Preserve the useful generated source tests.

Impact and scope

The package contains a stale, unused generated module, and the current source generator check does not validate its compiled form. Source-level tests can pass while this unused compiled output drifts. The observed module was about 6.7 MB on disk; compressed archive impact has not yet been measured independently.

Actual live discovery/validation continues to use the registered canonical contracts. Existing production MCP behavior, target Evidence, graph identity and full real Notion/Obsidian analyses remain unaffected by this compiled-file discrepancy.

REA version

Source revision cc0ee2edc60dda42d7b7cfb2c08e39b0b736b5e9; package version 6.0.0. This is a concrete build observation, not a claim about every published package.

Runtime and platform

Linux x64, Node.js 24.18.0; package-file inspection also performed on native Windows x64, Node.js 22.19.0. This generation boundary is not Windows-specific.

Target and artifact context

Generated MCP catalog source and compiled package output. Discovered during actual complete Notion/Obsidian verification for #1065/#1112. Target code is unnecessary for a reduced regression.

Interface

Build/package and generated-schema validation.

Earliest failure stage

Compiled generated artifact consistency. Actual production tools/list was verified current.

Relevant output or evidence

The stale artifact contained 2,030,334 serialized characters versus 2,035,845 for the freshly generated source. Structural comparison, not byte count, established the mismatch. A separate real stdio consumer check verified all 139 current advertised input/output schemas.

Typed outcome or recovery expected

One build should produce internally consistent necessary artifacts. Do not add runtime errors or user configuration to address an unused build artifact.

Analysis or suspected cause

build:unlocked compiles TypeScript before generate-mcp-tool-catalog.mjs writes its updated TypeScript source. An older existing source can therefore be compiled before regeneration, and this compiled output can be cached. The generated catalog is used by source-level tests; current production registration uses named contracts and toolRegistrationOptions directly. Exact cache population history was not reconstructed.

Additional context

  • Related roadmap: #1065 T3; package storage and generated conformance boundaries.
  • #1076 moved derived outputs out of Git; preserve that design.
  • #1001 concerns missing generated shard inputs and is distinct.
  • #919 requires checking the representation actually consumed by clients; that check corrected this report's original impact assumption.

Acceptance: seed older generated source and run one build/cache restoration; verify the necessary generated test source remains current, compiled/package outputs contain only appropriate current artifacts, actual packaged tools/list matches post-SDK contracts, and inventory/identity/packaged skill metadata agree. Keep the build/resource budget small.

Originally created by @N0zoM1z0 on GitHub (Oct 8, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1113 Originally assigned to: @N0zoM1z0 on GitHub. ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Setup, packaging, or upgrade; generated artifacts and validation. ## Observed behavior A successful cached build restored a package whose generated TypeScript catalog was current but whose compiled generated catalog contained older input/output definitions. Direct conversion of all 139 canonical contracts matched the generated source. The compiled artifact differed at 78 leaf locations across seven tools: `observe_native_calls`, `trace_dylib_resolution`, `analyze_javascript_application`, `trace_javascript_semantics`, `observe_web_execution`, `inspect_web_event_listeners`, and `binary_session`. **Scope correction after tracing the actual consumer:** this compiled artifact is not imported by the current production server. A real stdio `tools/list` call against the same baseline advertised all 139 tools and matched the freshly generated source for every input/output schema, while differing from the stale compiled artifact for exactly those seven tools. The initial report incorrectly described the generated file as the server's source. No stale-schema client failure is established; the report now concerns generated-artifact consistency and unnecessary package contents. ## Reproduction 1. Build a checkout, then change a canonical schema or update to a revision with schema changes while retaining previously generated catalog source. 2. Run `npm run build:cached` once. 3. Compare `dist/generatedMcpToolCatalog.js` with the current generated source and canonical post-SDK contracts. 4. Also connect to the built production MCP server and compare the actual `tools/list` result, rather than assuming it consumes the compiled generated module. Observed at `cc0ee2edc60dda42d7b7cfb2c08e39b0b736b5e9`: ```json { "live_tools": 139, "live_matches_fresh_generated_source": true, "compiled_generated_matches_fresh_source": false, "live_vs_stale_compiled_difference_tools": 7 } ``` ## Expected behavior Generated artifacts included in a package should match the current build. If an artifact exists only for source-level schema/conformance tests, consider excluding its compiled form from the shipping package instead of adding unnecessary runtime generation or compilation. Preserve the useful generated source tests. ## Impact and scope The package contains a stale, unused generated module, and the current source generator check does not validate its compiled form. Source-level tests can pass while this unused compiled output drifts. The observed module was about 6.7 MB on disk; compressed archive impact has not yet been measured independently. Actual live discovery/validation continues to use the registered canonical contracts. Existing production MCP behavior, target Evidence, graph identity and full real Notion/Obsidian analyses remain unaffected by this compiled-file discrepancy. ## REA version Source revision `cc0ee2edc60dda42d7b7cfb2c08e39b0b736b5e9`; package version 6.0.0. This is a concrete build observation, not a claim about every published package. ## Runtime and platform Linux x64, Node.js 24.18.0; package-file inspection also performed on native Windows x64, Node.js 22.19.0. This generation boundary is not Windows-specific. ## Target and artifact context Generated MCP catalog source and compiled package output. Discovered during actual complete Notion/Obsidian verification for #1065/#1112. Target code is unnecessary for a reduced regression. ## Interface Build/package and generated-schema validation. ## Earliest failure stage Compiled generated artifact consistency. Actual production `tools/list` was verified current. ## Relevant output or evidence The stale artifact contained 2,030,334 serialized characters versus 2,035,845 for the freshly generated source. Structural comparison, not byte count, established the mismatch. A separate real stdio consumer check verified all 139 current advertised input/output schemas. ## Typed outcome or recovery expected One build should produce internally consistent necessary artifacts. Do not add runtime errors or user configuration to address an unused build artifact. ## Analysis or suspected cause `build:unlocked` compiles TypeScript before `generate-mcp-tool-catalog.mjs` writes its updated TypeScript source. An older existing source can therefore be compiled before regeneration, and this compiled output can be cached. The generated catalog is used by source-level tests; current production registration uses named contracts and `toolRegistrationOptions` directly. Exact cache population history was not reconstructed. ## Additional context - Related roadmap: #1065 T3; package storage and generated conformance boundaries. - #1076 moved derived outputs out of Git; preserve that design. - #1001 concerns missing generated shard inputs and is distinct. - #919 requires checking the representation actually consumed by clients; that check corrected this report's original impact assumption. Acceptance: seed older generated source and run one build/cache restoration; verify the necessary generated test source remains current, compiled/package outputs contain only appropriate current artifacts, actual packaged `tools/list` matches post-SDK contracts, and inventory/identity/packaged skill metadata agree. Keep the build/resource budget small.
Author
Owner

@N0zoM1z0 commented on GitHub (Oct 8, 2026):

Correction after tracing and testing the actual consumer: the production server registers live canonical contracts and does not import dist/generatedMcpToolCatalog.js. A real stdio tools/list call at the same cc0ee2ed baseline matched all 139 freshly generated input/output schemas and differed from the stale compiled file for the seven reported tools. I have corrected the issue body and lowered its priority to P2. The compiled-file drift is real, but the original stale-advertisement/client-impact claim was inaccurate. This now tracks generated-artifact consistency and unnecessary package contents; it must not trigger a runtime catalog rewrite.

<!-- gh-comment-id:6066526104 --> @N0zoM1z0 commented on GitHub (Oct 8, 2026): Correction after tracing and testing the actual consumer: the production server registers live canonical contracts and does not import `dist/generatedMcpToolCatalog.js`. A real stdio `tools/list` call at the same `cc0ee2ed` baseline matched all 139 freshly generated input/output schemas and differed from the stale compiled file for the seven reported tools. I have corrected the issue body and lowered its priority to P2. The compiled-file drift is real, but the original stale-advertisement/client-impact claim was inaccurate. This now tracks generated-artifact consistency and unnecessary package contents; it must not trigger a runtime catalog rewrite.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#396
No description provided.