Skip to content

feat(codegraph): improve call tracing and unresolved call evidence - #4863

Open
ScriptedAlchemy wants to merge 24 commits into
masterfrom
feat/codegraph-receiver-context
Open

ScriptedAlchemy wants to merge 24 commits into
masterfrom
feat/codegraph-receiver-context

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Why

Common TypeScript receiver patterns can break an otherwise useful call trace. Agents also need to connect two known symbols and understand where the recorded graph stops.

This adopts those capabilities from the comparison with @colbymchenry/codegraph, using TraceDecay's existing extraction, sealed graph, admitted query, source, and generated contract authorities.

Changes

Resolve supported TypeScript receivers

  • Persist parser-derived receiver and declared-return evidence through extraction, sealed artifacts, resolution indexes, and resident-memory accounting.
  • Resolve constructor-backed and explicitly typed instance receivers, including awaited imported factories with supported named return types. Resolve return names in their declaring module and preserve import aliases.
  • Follow immutable const alias = receiver chains using the initializer's declaration scope. Generic constraints/defaults, parameter initializers, and computed property keys no longer create false receiver bindings.
  • Keep mutable, reassigned, optional, ambiguous, cyclic, forward, and unsupported receivers unresolved. Every accepted edge stays bound to its call site and lexical scope.
  • Re-resolve unchanged callers after factory-return edits, including after a sealed-generation restore. Scope changes re-extract the changed TypeScript file from its retained parse tree so distant binding edits cannot retain stale proof.

Return a connecting call path with context

  • Add optional call_path to tracedecay_context, with exact endpoint IDs and a bounded depth. Reuse the admitted shortest-path query over indexed call edges.
  • Return distinct found, no_path, truncated, and unavailable outcomes, ordered symbols, edge authority/evidence, and graph generation/freshness.
  • When requested, include intermediate source within the existing code-block/token limits. Verify file identity and digest, sanitize content, and report explicit omission or unavailability.
  • Bound source waiting by live cancellation, request deadline, and grant expiry, including completion races and dropped waiters. A blocked native file read cannot keep the requesting task waiting past its admitted lifetime.
  • Preserve ordinary task context when graph authority is unavailable and existing behavior when no path is requested.

Explain recorded unresolved calls

  • Add the required NodeDetailsV1.unresolved_calls report to the existing node operation, carrying its graph generation, caller/file identities, recorded reference name/span, optional argument count, and supported limitation reasons.
  • Examine at most 16 retained evidence records for that exact caller and disclose complete, truncated, or unavailable. Non-call limitations consume the same read budget.
  • Use the resident catalog and canonical admission/read-cost authority. Ordinary node metadata remains available while the catalog is rewarming; corrupt or unavailable evidence becomes a typed subreport.
  • Preserve the same report in the ChatGPT extension's existing symbol inspection and chat-sharing journey. Show coverage state and snapshot mismatches, safely render unusual extracted names, and reject malformed required reports.
  • Update the user guide, tool descriptions, canonical TypeScript SDK, and both embedded plugin bundles.

Scope and compatibility

The sealed format and affected extractor/chunker revisions are bumped. Older generations use the existing typed rebuild path; no compatibility shim is added.

Receiver inference remains bounded to parser-attested named types and supported declarations. The unresolved-call report describes retained extraction evidence: even a complete empty report does not prove that every possible runtime call resolves, and a recorded span may cover the enclosing declaration when extraction lacks an exact call token.

Framework-specific route discovery, event/job dispatch, and state-store/observer callback modeling remain outside this PR.

Validation

Passed locally on the updated source:

  • Code-extraction main suite: 663 tests.
  • TypeScript allocation/retained-extraction regressions: 2 tests, using the nonzero-test helper.
  • TypeScript SDK typecheck, 111 Vitest tests across 6 files, and package build.
  • ChatGPT plugin typecheck and 93 relevant tests across 6 files, including 15 new symbol-inspection tests.
  • Canonical SDK generation, both embedded plugin builds, and the byte-exact embedded regeneration check.
  • Rust formatting for 9 crates; all 61 generated BUILD.bazel files are current.
  • Commit formatting/commitlint hooks and git diff --check.

The plugin's initial combined run passed 92 tests and failed the existing IPv6 loopback case because the local proxy exclusions lacked bracketed [::1]. With that entry added only to the test process's existing exclusions, all 13 adapter tests passed. No source, global proxy settings, test assertions, skips, or timeouts were changed for this environment issue.

Canonical SDK generation succeeded using command-local allocator settings and panic=abort only for the contracts crate and exporter binary. No tracked build policy or production/test configuration was changed, and no Rust tests were run under those exporter settings.

Backend verification remains incomplete locally. A final production metadata build with normal panic settings stopped in tracedecay-contracts with process_wrapper exit 1 and no Rust diagnostic. The host was under memory pressure, and its kernel OOM-kill counter increased from 95 to 98 over the verification period. This is not counted as a passing typecheck. Earlier full integration builds also stopped in the pinned runtime dependency/build environment.

The code-index/MCP integration suites and the new context-source lifetime unit tests have not run locally. Full Clippy and the combined dashboard contract freshness check also remain unverified. Source inspection found that the dashboard exporter uses separate schema roots, so there is no identified additional dashboard artifact change; the fresh canonical SDK export includes application.ts and the affected operations.ts.

Added backend regressions cover receiver resolution and sealed restores, exact caller/file evidence isolation, actual import/ambiguity limitations, bounded truncation/read cost, catalog rewarming, path source bounds, cancellation/deadline races, and disconnected/missing/zero-edge paths. Final-head repository CI is still required to verify these runtime behaviors.

@devin-ai-integration devin-ai-integration Bot 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@ScriptedAlchemy ScriptedAlchemy left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Current-head CI blocker (exact head f7f99115bbcd243da816ac1b2c2b01d2b3995279): Dashboard job 130214053904 executed its Bazel frontend/SDK targets, then the embedded-artifact verification failed with Error: embedded/server.mjs is stale; run pnpm run build and commit the result (job log near its final check). The PR changes the context operation schema and generated TypeScript SDK but its current diff contains no corresponding refreshed embedded/server.mjs. Please regenerate through the documented pnpm/build/codegen authority, commit generated outputs together with the canonical source changes, run the actual dashboard bundle/determinism + SDK contract checks, and get a new complete exact-head matrix. No hand-edits to generated output or bypassing the artifact check. This is a real current-head artifact drift failure, not a TypeScript unit-test failure or full Rust acceptance. I made no branch changes.

Regenerate the ChatGPT extension server bundle after the SDK added context
call-path request/result, source and edge-authority schemas. Preserve the
canonical pnpm package layout used by the embedded artifact check.

Run the existing producer through Bazel's pinned Node target. Its --check
reproduces the stale server failure before regeneration and passes after it.
Only server.mjs changes; app.html, source, manifests and workflows are unchanged.
@changeset-bot

changeset-bot Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9ec3e68

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ScriptedAlchemy ScriptedAlchemy changed the title feat(codegraph): resolve receivers and add context call paths feat(codegraph): improve call tracing and unresolved call evidence Nov 11, 2026
ScriptedAlchemy and others added 10 commits November 10, 2026 23:59
# Conflicts:
#	crates/tracedecay-code-index/src/production/sealed_codec.rs
Resolve the generated plugin/chatgpt-extension/embedded bundle conflict
by rebuilding it from the merged sources (`pnpm run build`;
`pnpm run check:embedded` reports the artifacts are current).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read schema assertions directly from the fixture store and avoid reopening an already completed cancelled upgrade. Preserve cancellation recovery and actual reopen checks.
Cache declarations, var blockers, and writes by exact syntax scope and name during one owner call walk. Preserve per-site declaration-order checks and discard every borrowed fact when the walk ends.

Cover repeated receiver work with a deterministic AST-visit scaling regression and retain use-before-declaration, inner shadow, and later-write refusals.
Build complete declaration and write indexes on the first scope lookup so distinct receiver names cannot each rescan the same AST. Preserve binding-side destructuring, scope boundaries, and per-site ordering checks. Add a deterministic distinct-name scaling regression with a single written receiver and retain every unresolved call site.
Carry graph admission and live cancellation through path-source reads.
Recheck them and request deadlines before ordinary source hydration,
and exclude path nodes before attempting another source read.

Exercise the composed graph-tool owner with a blocked real source,
live cancellation, and an ordinary non-path match. Require owner
settlement before releasing the source while preserving typed metadata.
Replace the redundant closure reported by exact-head strict Clippy.
Behavior and cancellation semantics are unchanged; hosted verification
will run on the new head.
Seed the same 10,001 overlap rows through the canonical batch transaction before staging composer rows. Preserve every paging and publication assertion. The unmodified branch passes 501 tests locally in 130 seconds; its overlap fixture alone takes 10.271 seconds. This removes unnecessary durable setup work without claiming to identify the Linux fleet timeout.

This branch has not been deployed

No deployments
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.

1 participant