[PR #1160] [MERGED] feat(javascript): report observed export property presence #2694

Closed
opened 2026-10-17 21:09:09 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1160
Author: @mvanhorn
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @morluto

Base: main ← Head: fix/export-shape-property-presence


📝 Commits (10+)

  • 26f8ebe feat(javascript): report observed export property presence
  • 6758ad0 test(javascript): match unknown export-shape values by availability
  • f2910fd fix(javascript): preserve uncertain export property presence and locations
  • d7b625a fix(javascript): normalize presence and preserve local property coverage
  • 415af95 fix(javascript): require present discriminants for return pairing
  • bfd5411 fix(javascript): normalize retained shapes before comparison
  • 05bccbd refactor(javascript): share return projection with executable examples
  • d36666a fix(javascript): localize uncertainty for missing mutated slots
  • fbae22e fix(javascript): bind advertised export examples to exact artifacts
  • eb6cda7 fix(javascript): keep uncertain property flow as candidates

📊 Changes

25 files changed (+1552 additions, -113 deletions)

View changed files

📝 docs/javascript-application-workflows.md (+27 -8)
📝 skill-src/reverse-engineer-anything/references/javascript-applications.md (+7 -1)
📝 src/application/javascript/JavaScriptModuleRelationships.ts (+1 -1)
📝 src/application/javascript/JavaScriptSemanticGraphValueProjection.ts (+4 -1)
📝 src/contracts/applicationToolContracts.ts (+3 -2)
📝 src/contracts/javascript/javascriptApplicationWorkflowExamples.ts (+1 -9)
➕ src/contracts/javascript/javascriptExportShapeComparisonExample.ts (+270 -0)
📝 src/domain/javascript/javascriptExportReturnShapeProjection.ts (+12 -11)
📝 src/domain/javascript/javascriptExportShapeComparison.ts (+7 -0)
📝 src/domain/javascript/javascriptExportShapeComparisonIdentity.ts (+6 -1)
📝 src/domain/javascript/javascriptExportShapeComparisonSchemas.test.ts (+38 -1)
📝 src/domain/javascript/javascriptExportShapeComparisonSchemas.ts (+37 -1)
📝 src/domain/javascript/javascriptExportShapeSelection.ts (+17 -3)
📝 src/domain/javascript/javascriptExportShapeVariants.ts (+104 -19)
📝 src/domain/javascript/javascriptSemanticAnalysis.member_depth.test.ts (+10 -2)
📝 src/domain/javascript/javascriptSemanticMutationValues.ts (+13 -22)
📝 src/domain/javascript/javascriptSemanticReturns.ts (+42 -3)
📝 src/domain/javascript/javascriptSemanticValueTypes.ts (+4 -0)
📝 src/domain/javascript/javascriptSemanticValues.ts (+10 -4)
📝 tests/acceptance/applications/applicationWorkflowCli.test.ts (+98 -0)

...and 5 more files

📄 Description

Summary

compare_javascript_export_shapes now reports observed return-property names and presence/absence independently of value resolution. Fixes #725.

Demo

Export property presence demo

Before After
before after

The sample is a generated two-version search.js, not third-party code.

Problem and expected behavior

Selecting one export on two local JavaScript versions already paired return variants by unique literal discriminants, but a property that was clearly present on one variant and absent on the other was labeled unknown whenever its static value did not project to a literal. Analysts could not see that count left the public object and total/query appeared.

The tool should keep the same selectors and pairing rules, list observed property names per retained variant, and classify complete-coverage presence-only gaps as added or removed while unresolved values stay unknown.

Change and scope

Domain comparison now emits property_inventories and a presence object on each change. fieldChangeStatus uses parent-property coverage for one-sided names even when the remaining value is unknown. Incomplete spreads stay unknown with unknown-coverage. Unpaired variants remain unpaired and still list inventories.

No new tool, no execution, and no change to trace_javascript_semantics.

Contract and boundary impact

  • Semantic owner and earliest changed stage: JavaScript export-shape comparison domain; additive output fields on compare_javascript_export_shapes
  • CLI and MCP/tool-catalog contract: same input schema; output adds property_inventories and per-change presence; summary.added/removed count presence-level add/remove; catalog regenerated via npm run build:cached
  • Provider, bridge, target-format, or platform compatibility: none
  • Evidence, artifact, provenance, or reconstruction contract: comparison Evidence includes the additive fields; comparison_id digests inventories and presence
  • Process execution, authorization, cleanup, or containment impact: none
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: CI generates and validates ignored catalogs and skills/; authored skill text updated in skill-src/

Evidence and regression coverage

  • Tests added or updated: domain schema rejection of missing presence; untagged and tagged search.js fixtures; existing spread-incomplete and parser /depth cases; MCP advertised output schema; CLI tagged presence case
  • Base reproduction or other evidence: generated search.js v1 {kind, matches, count} vs v2 {kind, matches, total, query} through public CLI
  • User-visible CLI/MCP output: inventories list /count vs /total//query; change rows removed /count, added /total, added /query with availability: "unknown" for unresolved values
  • Remaining proof gaps: none for this static comparison; runtime behavior remains a separate probe

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm ci — pass (Node v24.18.0, npm 11.16.0)
  • npm run check:fast — pass
  • npm run test:focused -- src/domain/javascript/javascriptExportShapeComparisonSchemas.test.ts tests/boundary/filesystem/javascriptExportShapeComparison.test.ts tests/boundary/mcp/applicationExportShapeMcp.test.ts tests/acceptance/applications/applicationWorkflowCli.test.ts — pass (36 tests)
  • npm run check — pass
  • npm run docs:check — pass
  • npm run verify:test-discovery — pass (650 test files)

Compatibility, safety, and release

  • Breaking changes or migration steps: additive output fields. Callers that require a closed change object without presence need to read the new required field. summary.unknown no longer includes complete-coverage presence-only gaps; those rows are added or removed.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable; static JavaScript export-shape comparison only
  • Package or release metadata impact: none beyond regenerated ignored catalogs in CI
  • Security, privacy, process, or containment review: static syntax evidence only; no execution

Review checklist

  • This PR addresses a concrete problem or an agreed enhancement.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1160 **Author:** [@mvanhorn](https://github.com/mvanhorn) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/export-shape-property-presence` --- ### 📝 Commits (10+) - [`26f8ebe`](https://github.com/morluto/rea/commit/26f8ebe1a8c03e6bd191c08e5dd14346a899911f) feat(javascript): report observed export property presence - [`6758ad0`](https://github.com/morluto/rea/commit/6758ad0a6c152caae2b300776df398581dce81b7) test(javascript): match unknown export-shape values by availability - [`f2910fd`](https://github.com/morluto/rea/commit/f2910fd3d92c01914c387fc4fce424fad72c1b53) fix(javascript): preserve uncertain export property presence and locations - [`d7b625a`](https://github.com/morluto/rea/commit/d7b625a18706ec968bffd2577a64ded674f41e63) fix(javascript): normalize presence and preserve local property coverage - [`415af95`](https://github.com/morluto/rea/commit/415af9566bcf7c6dd1e62336ae37abae382fe564) fix(javascript): require present discriminants for return pairing - [`bfd5411`](https://github.com/morluto/rea/commit/bfd5411cfbe995fed8dfceb7013104de9a3a3397) fix(javascript): normalize retained shapes before comparison - [`05bccbd`](https://github.com/morluto/rea/commit/05bccbd6d8469d7c8fcdd1f0714d6ea98b446d61) refactor(javascript): share return projection with executable examples - [`d36666a`](https://github.com/morluto/rea/commit/d36666a0941b19afb9f7c7b7904c7c54b57f3583) fix(javascript): localize uncertainty for missing mutated slots - [`fbae22e`](https://github.com/morluto/rea/commit/fbae22ed74f5f64c080f5eb309ab982e61c4c916) fix(javascript): bind advertised export examples to exact artifacts - [`eb6cda7`](https://github.com/morluto/rea/commit/eb6cda7c28257416bcb9d686ae92a2a6594ac555) fix(javascript): keep uncertain property flow as candidates ### 📊 Changes **25 files changed** (+1552 additions, -113 deletions) <details> <summary>View changed files</summary> 📝 `docs/javascript-application-workflows.md` (+27 -8) 📝 `skill-src/reverse-engineer-anything/references/javascript-applications.md` (+7 -1) 📝 `src/application/javascript/JavaScriptModuleRelationships.ts` (+1 -1) 📝 `src/application/javascript/JavaScriptSemanticGraphValueProjection.ts` (+4 -1) 📝 `src/contracts/applicationToolContracts.ts` (+3 -2) 📝 `src/contracts/javascript/javascriptApplicationWorkflowExamples.ts` (+1 -9) ➕ `src/contracts/javascript/javascriptExportShapeComparisonExample.ts` (+270 -0) 📝 `src/domain/javascript/javascriptExportReturnShapeProjection.ts` (+12 -11) 📝 `src/domain/javascript/javascriptExportShapeComparison.ts` (+7 -0) 📝 `src/domain/javascript/javascriptExportShapeComparisonIdentity.ts` (+6 -1) 📝 `src/domain/javascript/javascriptExportShapeComparisonSchemas.test.ts` (+38 -1) 📝 `src/domain/javascript/javascriptExportShapeComparisonSchemas.ts` (+37 -1) 📝 `src/domain/javascript/javascriptExportShapeSelection.ts` (+17 -3) 📝 `src/domain/javascript/javascriptExportShapeVariants.ts` (+104 -19) 📝 `src/domain/javascript/javascriptSemanticAnalysis.member_depth.test.ts` (+10 -2) 📝 `src/domain/javascript/javascriptSemanticMutationValues.ts` (+13 -22) 📝 `src/domain/javascript/javascriptSemanticReturns.ts` (+42 -3) 📝 `src/domain/javascript/javascriptSemanticValueTypes.ts` (+4 -0) 📝 `src/domain/javascript/javascriptSemanticValues.ts` (+10 -4) 📝 `tests/acceptance/applications/applicationWorkflowCli.test.ts` (+98 -0) _...and 5 more files_ </details> ### 📄 Description ## Summary `compare_javascript_export_shapes` now reports observed return-property names and presence/absence independently of value resolution. Fixes #725. ## Demo ![Export property presence demo](https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/export-shape-presence/demo.gif) <video src="https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/export-shape-presence/demo.mp4" controls width="720"></video> | Before | After | |---|---| | ![before](https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/export-shape-presence/screenshot_export_shape_before.png) | ![after](https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/export-shape-presence/screenshot_export_shape_after.png) | The sample is a generated two-version `search.js`, not third-party code. ## Problem and expected behavior Selecting one export on two local JavaScript versions already paired return variants by unique literal discriminants, but a property that was clearly present on one variant and absent on the other was labeled `unknown` whenever its static value did not project to a literal. Analysts could not see that `count` left the public object and `total`/`query` appeared. The tool should keep the same selectors and pairing rules, list observed property names per retained variant, and classify complete-coverage presence-only gaps as `added` or `removed` while unresolved values stay unknown. ## Change and scope Domain comparison now emits `property_inventories` and a `presence` object on each change. `fieldChangeStatus` uses parent-property coverage for one-sided names even when the remaining value is unknown. Incomplete spreads stay `unknown` with `unknown-coverage`. Unpaired variants remain unpaired and still list inventories. No new tool, no execution, and no change to `trace_javascript_semantics`. ## Contract and boundary impact - Semantic owner and earliest changed stage: JavaScript export-shape comparison domain; additive output fields on `compare_javascript_export_shapes` - CLI and MCP/tool-catalog contract: same input schema; output adds `property_inventories` and per-change `presence`; `summary.added`/`removed` count presence-level add/remove; catalog regenerated via `npm run build:cached` - Provider, bridge, target-format, or platform compatibility: none - Evidence, artifact, provenance, or reconstruction contract: comparison Evidence includes the additive fields; comparison_id digests inventories and presence - Process execution, authorization, cleanup, or containment impact: none - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: CI generates and validates ignored catalogs and `skills/`; authored skill text updated in `skill-src/` ## Evidence and regression coverage - Tests added or updated: domain schema rejection of missing `presence`; untagged and tagged `search.js` fixtures; existing spread-incomplete and parser `/depth` cases; MCP advertised output schema; CLI tagged presence case - Base reproduction or other evidence: generated `search.js` v1 `{kind, matches, count}` vs v2 `{kind, matches, total, query}` through public CLI - User-visible CLI/MCP output: inventories list `/count` vs `/total`/`/query`; change rows `removed /count`, `added /total`, `added /query` with `availability: "unknown"` for unresolved values - Remaining proof gaps: none for this static comparison; runtime behavior remains a separate probe For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm ci` — pass (Node v24.18.0, npm 11.16.0) - `npm run check:fast` — pass - `npm run test:focused -- src/domain/javascript/javascriptExportShapeComparisonSchemas.test.ts tests/boundary/filesystem/javascriptExportShapeComparison.test.ts tests/boundary/mcp/applicationExportShapeMcp.test.ts tests/acceptance/applications/applicationWorkflowCli.test.ts` — pass (36 tests) - `npm run check` — pass - `npm run docs:check` — pass - `npm run verify:test-discovery` — pass (650 test files) ## Compatibility, safety, and release - Breaking changes or migration steps: additive output fields. Callers that require a closed change object without `presence` need to read the new required field. `summary.unknown` no longer includes complete-coverage presence-only gaps; those rows are `added` or `removed`. - Real Hopper/Ghidra, browser, or OS coverage: not applicable; static JavaScript export-shape comparison only - Package or release metadata impact: none beyond regenerated ignored catalogs in CI - Security, privacy, process, or containment review: static syntax evidence only; no execution ## Review checklist - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:09 +00:00
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#2694
No description provided.