[PR #6190] fix(javascript): include slotless accesses in property traces #7195

Open
opened 2026-11-01 21:46:03 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/6190
Author: @jacobmalibiran
Created: 10/22/2026
Status: 🔄 Open

Base: main ← Head: fix/property-seed-unresolved-accesses


📝 Commits (1)

  • a170b73 fix(javascript): include slotless accesses in property traces

📊 Changes

4 files changed (+234 additions, -2 deletions)

View changed files

📝 docs/javascript-application-workflows.md (+3 -0)
📝 src/domain/javascript/javascriptSemanticGraphQuery.test.ts (+93 -0)
📝 src/domain/javascript/javascriptSemanticQueryIdentity.ts (+27 -2)
📝 tests/acceptance/applications/applicationWorkflowCli.test.ts (+111 -0)

📄 Description

Summary

Fixes #6189.

A property seed in trace_javascript_semantics returned no seeds and no
unknowns when every access to the property went through a receiver REA doesn't
resolve, such as this in an ES5 constructor/prototype or an ES2015 class. The
graph already recorded those accesses and their unknowns, so the empty result
read as "absent". Property seeds now also return those accesses, with their
unknowns.

Problem and expected behavior

Smallest trigger: this.speed += this.config.ACCEL inside a prototype method.
{kind: "property", name: "ACCEL"} gave total_seed_matches: 0 and
relevant_unknowns: 0, although the graph held read:/config/ACCEL with an
object-flow / ambiguous-target unknown. This breaks the rule that unresolved
facts stay unknown rather than being treated as absent.

Change and scope

resolveJavaScriptSemanticQuerySeeds keeps matching property-slot nodes by
name. It now also matches expression accesses whose last property_path
segment equals the name and which anchor their own object-flow unknown.
Object projection anchors that unknown on the access only when it retained no
slot (target.slot ?? occurrence), so accesses that already have a slot are not
added, and their results are unchanged. This follows #4213 / #4217, which
extended endpoint seeds to a second carrier of the same value.

Not included: resolving this receivers (related: #4437), modelling objects
assigned onto functions (so literal seeds such as 0.001 there still match
nothing), and following compound assignment. Those are listed in #6189.

Follow the contribution scope.
Ordinary fix within existing boundaries: maintainer scope decision not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: semantic query seed resolution
    (src/domain/javascript/javascriptSemanticQueryIdentity.ts); graph
    construction is unchanged.
  • Contribution scope fit and linked maintainer decision: bug fix in an existing
    tool; not applicable.
  • CLI and MCP/tool-catalog contract: no schema change. Property-seed results can
    now include expression seeds and their unknowns. Docs updated in
    docs/javascript-application-workflows.md.
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: the trace returns
    more retained graph facts; no new facts are created.
  • Target selection, authority, upstream behavior, and cleanup details: not applicable.
  • Generated metadata, package, or installation impact: none.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:

    • src/domain/javascript/javascriptSemanticGraphQuery.test.ts: slot plus
      slotless access match. A slotted access, a data-flow-only unknown, a
      non-expression node and a path prefix do not. Executed against the base
      seed resolver: this test fails (1 failed, 19 passed).
    • tests/acceptance/applications/applicationWorkflowCli.test.ts: real CLI
      analysis and trace of a mixed fixture (a module object plus this accesses).
      It checks exact seeds, the returned unknowns, status and coverage for
      ACCEL, speed and a missing name, with CLI/MCP Evidence parity.
  • Base reproduction: the script in #6189, run on 2451e187b before and after
    this change (executed):

    Fixture / seed Before After
    es5 ACCEL partial, 0 seeds, 0 unknowns found, 1 seed, 1 unknown
    es5 speed partial, 0 seeds, 0 unknowns ambiguous, 4 seeds, 4 unknowns
    class ACCEL partial, 0 seeds, 0 unknowns found, 1 seed, 1 unknown
    class speed partial, 0 seeds, 0 unknowns ambiguous, 4 seeds, 4 unknowns
    module (control) rows unchanged unchanged
  • User-visible CLI/MCP output: on the public T-Rex runner index.js from #6189,
    currentSpeed now returns its 11 access sites (write:/currentSpeed at
    lines 43, 344, 346 and 570, and so on), where it previously returned nothing.

  • Remaining proof gaps: object-literal methods and .call/.bind receivers are
    untested. CI has not run yet.

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

All run on the final commit:

  • npm run test:local -- src/domain/javascript/javascriptSemanticGraphQuery.test.ts src/application/javascript/JavaScriptSemanticGraphBuilder.test.ts src/application/javascript/JavaScriptSemanticGraphResources.test.ts src/application/javascript/JavaScriptSemanticUnknownCapacity.test.ts: 112 passed
  • npm run test:focused -- tests/acceptance/applications/applicationWorkflowCli.test.ts tests/boundary/javascriptSemanticTraceEvidence.test.ts tests/boundary/mcp/agentKnownAnswerMcp.test.ts: 46 passed
  • npm run check:fast: passed
  • npm run docs:check: passed

Cost on the T-Rex index.js graph (CLI trace-javascript-semantics, warm, macOS
arm64; tokens from --token-count; time and memory are single runs unless noted).
"Before" used an older local build (c374c2fe7 base) whose seed resolver is
identical to 2451e187b; both sides traced the same graph Evidence:

Seed Tokens before → after Peak RSS before → after
ACCELERATION 1,159 → 2,083 407 → 389 MB
currentSpeed 1,159 → 8,897 426 → 435 MB
width (already had slots) 8,437 → 17,964 425 → 437 MB

currentSpeed over 5 runs, median wall/CPU: 0.95 s / 1.33 s before, 1.10 s /
1.40 s after, mostly process startup. Token growth comes from the previously
omitted accesses. The whole task (agent tokens, including the grep fallback the
empty result caused) was not measured.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Callers that treated an empty
    property trace as absence now receive the unresolved accesses instead.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable (static JavaScript
    analysis); macOS arm64 only.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no new target interaction.

Author readiness

Human owner: @jacobmalibiran

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • 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.

🤖 Generated with Claude Code


🔄 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/6190 **Author:** [@jacobmalibiran](https://github.com/jacobmalibiran) **Created:** 10/22/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/property-seed-unresolved-accesses` --- ### 📝 Commits (1) - [`a170b73`](https://github.com/morluto/rea/commit/a170b73477d104116459e210a239f698ff7d5633) fix(javascript): include slotless accesses in property traces ### 📊 Changes **4 files changed** (+234 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `docs/javascript-application-workflows.md` (+3 -0) 📝 `src/domain/javascript/javascriptSemanticGraphQuery.test.ts` (+93 -0) 📝 `src/domain/javascript/javascriptSemanticQueryIdentity.ts` (+27 -2) 📝 `tests/acceptance/applications/applicationWorkflowCli.test.ts` (+111 -0) </details> ### 📄 Description ## Summary Fixes #6189. A `property` seed in `trace_javascript_semantics` returned no seeds and no unknowns when every access to the property went through a receiver REA doesn't resolve, such as `this` in an ES5 constructor/prototype or an ES2015 class. The graph already recorded those accesses and their unknowns, so the empty result read as "absent". Property seeds now also return those accesses, with their unknowns. ## Problem and expected behavior Smallest trigger: `this.speed += this.config.ACCEL` inside a prototype method. `{kind: "property", name: "ACCEL"}` gave `total_seed_matches: 0` and `relevant_unknowns: 0`, although the graph held `read:/config/ACCEL` with an `object-flow` / `ambiguous-target` unknown. This breaks the rule that unresolved facts stay unknown rather than being treated as absent. ## Change and scope `resolveJavaScriptSemanticQuerySeeds` keeps matching `property-slot` nodes by name. It now also matches `expression` accesses whose last `property_path` segment equals the name **and** which anchor their own `object-flow` unknown. Object projection anchors that unknown on the access only when it retained no slot (`target.slot ?? occurrence`), so accesses that already have a slot are not added, and their results are unchanged. This follows #4213 / #4217, which extended endpoint seeds to a second carrier of the same value. Not included: resolving `this` receivers (related: #4437), modelling objects assigned onto functions (so `literal` seeds such as `0.001` there still match nothing), and following compound assignment. Those are listed in #6189. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Ordinary fix within existing boundaries: maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: semantic query seed resolution (`src/domain/javascript/javascriptSemanticQueryIdentity.ts`); graph construction is unchanged. - Contribution scope fit and linked maintainer decision: bug fix in an existing tool; not applicable. - CLI and MCP/tool-catalog contract: no schema change. Property-seed results can now include `expression` seeds and their unknowns. Docs updated in `docs/javascript-application-workflows.md`. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: the trace returns more retained graph facts; no new facts are created. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none. Expected effects: - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [x] Inject instrumentation or run scripts/code. - [x] Change process memory, registers, files, or configuration. - [x] Contact network services. - [x] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [x] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `src/domain/javascript/javascriptSemanticGraphQuery.test.ts`: slot plus slotless access match. A slotted access, a data-flow-only unknown, a non-expression node and a path prefix do not. Executed against the base seed resolver: this test fails (1 failed, 19 passed). - `tests/acceptance/applications/applicationWorkflowCli.test.ts`: real CLI analysis and trace of a mixed fixture (a module object plus `this` accesses). It checks exact seeds, the returned unknowns, status and coverage for `ACCEL`, `speed` and a missing name, with CLI/MCP Evidence parity. - Base reproduction: the script in #6189, run on `2451e187b` before and after this change (executed): | Fixture / seed | Before | After | | --- | --- | --- | | es5 `ACCEL` | partial, 0 seeds, 0 unknowns | found, 1 seed, 1 unknown | | es5 `speed` | partial, 0 seeds, 0 unknowns | ambiguous, 4 seeds, 4 unknowns | | class `ACCEL` | partial, 0 seeds, 0 unknowns | found, 1 seed, 1 unknown | | class `speed` | partial, 0 seeds, 0 unknowns | ambiguous, 4 seeds, 4 unknowns | | module (control) rows | unchanged | unchanged | - User-visible CLI/MCP output: on the public T-Rex runner `index.js` from #6189, `currentSpeed` now returns its 11 access sites (`write:/currentSpeed` at lines 43, 344, 346 and 570, and so on), where it previously returned nothing. - Remaining proof gaps: object-literal methods and `.call`/`.bind` receivers are untested. CI has not run yet. 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 All run on the final commit: - `npm run test:local -- src/domain/javascript/javascriptSemanticGraphQuery.test.ts src/application/javascript/JavaScriptSemanticGraphBuilder.test.ts src/application/javascript/JavaScriptSemanticGraphResources.test.ts src/application/javascript/JavaScriptSemanticUnknownCapacity.test.ts`: 112 passed - `npm run test:focused -- tests/acceptance/applications/applicationWorkflowCli.test.ts tests/boundary/javascriptSemanticTraceEvidence.test.ts tests/boundary/mcp/agentKnownAnswerMcp.test.ts`: 46 passed - `npm run check:fast`: passed - `npm run docs:check`: passed Cost on the T-Rex `index.js` graph (CLI `trace-javascript-semantics`, warm, macOS arm64; tokens from `--token-count`; time and memory are single runs unless noted). "Before" used an older local build (`c374c2fe7` base) whose seed resolver is identical to `2451e187b`; both sides traced the same graph Evidence: | Seed | Tokens before → after | Peak RSS before → after | | --- | --- | --- | | `ACCELERATION` | 1,159 → 2,083 | 407 → 389 MB | | `currentSpeed` | 1,159 → 8,897 | 426 → 435 MB | | `width` (already had slots) | 8,437 → 17,964 | 425 → 437 MB | `currentSpeed` over 5 runs, median wall/CPU: 0.95 s / 1.33 s before, 1.10 s / 1.40 s after, mostly process startup. Token growth comes from the previously omitted accesses. The whole task (agent tokens, including the grep fallback the empty result caused) was not measured. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Callers that treated an empty property trace as absence now receive the unresolved accesses instead. - Real Hopper/Ghidra, browser, or OS coverage: not applicable (static JavaScript analysis); macOS arm64 only. - Package or release metadata impact: none. - Security, privacy, process, or containment review: no new target interaction. ## Author readiness Human owner: @jacobmalibiran - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#7195
No description provided.