* docs: align resolution architecture and roadmap
* docs: add language ingestion gap inventories
* test: audit receiver gap targets and coverage
Check exact declaration IDs, expose the Dart await wrong-owner edge, and execute previously excluded C++, Rust, PHP, Dart and Vue shapes. Refresh the baseline and all language inventories from fresh measurements; call-drop counts remain unchanged.
* docs: focus roadmap and shorten project README
Keep the resolution roadmap limited to future work and acceptance criteria. Move detailed editor, CLI, MCP, deployment and wiki instructions into linked guides, preserve their command examples, and correct stale onboarding claims.
* docs: correct setup and audit descriptions
---------
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
* test(bench): type the JS, Ruby and PHP receiver shapes; mark C dispatch N/A
Several shape-arm rows were measuring their fixtures instead of the receiver
spelling.
The JavaScript and Ruby rows had no types anywhere, so each chain cell said
"this code is untyped" and could only flip by guessing from a method name.
They now carry JSDoc and YARD types, the way plain JS and Ruby carry types.
Each row keeps one untyped control as a new extra id, `untypedChain`, so
`plainChain` and the other canonical ids mean the same thing in every row.
Ruby names each function's parameter after its cell, because YARD `@param`
bindings land on the Module scope. A probe showed an untyped `svc` resolving
through a sibling's tag.
PHP `plainDeepChain` and `optionalChain` went through the unannotated
`getUser()`, so they measured the missing return type rather than their own
spelling. They now use `getUserTyped()`, and `arrowCallChain` stays the
unannotated control. `indexElement` gains PHPDoc `@param User[] $repos`.
The C structs lived in `models.h`, which the C++ provider owns, so C never saw
them. They now live in `main.c`. All three measured C cells called through a
function-pointer field. That field has no graph node and no static callee, so
the cells could never resolve and are now N/A.
Shape-arm movement, every target checked:
- javascript: plainChain, plainDeepChain, optionalChain, awaitParen
VISIBLE-GAP -> RESOLVES; untypedChain new, VISIBLE-GAP; indexElement
stays VISIBLE-GAP (no JS elementTypeOf)
- ruby: plainChain, optionalChain VISIBLE-GAP -> RESOLVES; plainDeepChain
VISIBLE-GAP -> INVISIBLE-GAP (base types, untyped attr_reader step);
untypedChain new, VISIBLE-GAP; indexElement stays INVISIBLE-GAP
- php: plainDeepChain, optionalChain INVISIBLE-GAP -> RESOLVES
- c: plainDeepChain, indexElement VISIBLE-GAP -> N/A; fieldReceiverCall
INVISIBLE-GAP -> N/A
The count arm and every other language's cells are unchanged. No resolver
code changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: correct typed shape benchmark states
* docs: qualify Ruby typed shape owner claims (#3663)
The receiver shape gate matches member names only, so the Ruby
plainChain/optionalChain owner (User.save) is a probe observation, as
already stated for the JavaScript and PHP rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: drop unverified #3609 tracking claims (#3663)
#3609 does not document the Ruby YARD @param scope leak or C header
struct visibility, so say both are not yet filed separately.
Also carry the BASELINE.md notes that came from the pre-rebase merge commits
(main c30449394 and stack parent #3667), which the linear replay onto the
rebased walker drops: the post-#3659 and #3667-stack integration notes and
the Ruby indexElement wording on the walker parent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(swift,dart): type chained receivers through hoisted return types (#3498)
Swift and Dart hoist every method's return-type binding out of the class
body onto the Module scope, as C# does, but neither set
hoistTypeBindingsToModule. The receiver walk therefore never looked
there, and svc.getUser().save() had no receiver type. Both now set it.
The flag alone was not safe. The hoisted bindings are keyed by bare
method name, so with class A { getUser() -> User } and
class B { getUser() -> Admin } in one file the Module scope keeps only
B's entry, and a.getUser().save() resolved to Admin.save. C# and
TypeScript already do this on main.
So there is a new ScopeResolver toggle, hoistedTypeBindingsRequireOwner,
which Swift and Dart also set. With it, the walk accepts a hoisted
binding only when its declaration anchor encloses the declaration of a
member of that name owned by the receiver's class. Otherwise it keeps
climbing, and declines if nothing passes. The four walk-ups in
compound-receiver.ts now share one helper.
The toggle is opt-in. With the guard on everywhere, TypeScript loses
correct edges where two same-named methods happen to return the same
type (11 rows in inferred-field-receiver-matrix), because the Module map
cannot hold both. Swift and Dart never had those edges.
Bench: swift plainChain, plainDeepChain, optionalChain and nonNullAssert
(INVISIBLE-GAP) and dart plainChain, plainDeepChain and optionalChain
(VISIBLE-GAP) now RESOLVE with correct targets. No other cell and no
count-arm figure moves. The inferred-field matrix gains correct
Inner.compute edges for Swift (3 rows) and Dart (7 Alien rows).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(scope): guard hoisted return ownership
* fix(scope): gate hoisted return replay checks
* fix(scope): preserve parameterized return replay
Keep exact callee return facts when ancestor candidates have matching
known parameter types, while refusing same-owner overload ties.
Refs #3666
* fix(scope): preserve known variadic return replay
Compare complete captured parameter vectors across distinct ancestor
owners, including variadic methods with unknown numeric arity. Keep
unknown Swift parameter slots instead of compressing them away.
Refs #3666
* test(swift): retain reviewed receiver fixtures
* fix(scope): retain unknown overload candidates
Keep unknown parameter slots possible without hiding conversion overloads.
Check return-owner precision without requiring valid calls to stay unresolved.
Refs #3498
* fix(scope): preserve conversion suppression
Keep explicit empty conversion results final when parameter metadata is
unknown. Add exact positive controls for receiver-fixture liveness.
Refs #3498
---------
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>