Skip to content

Named symbol backends behind a fixed-precedence composite - #384

Merged
Firehed merged 13 commits into
mainfrom
slice/S3.3
Jul 31, 2026
Merged

Named symbol backends behind a fixed-precedence composite#384
Firehed merged 13 commits into
mainfrom
slice/S3.3

Conversation

@Firehed

@Firehed Firehed commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Slice

  • Slice: S3.3 — Named backends + fixed-precedence composite
  • Plan step: Plan 0002 Step 3a(iii) (docs/architecture/0002-execution-plan.md)
  • RFC: 0001-foundational-architecture.md §4.2 (Symbol Discovery Authority), §4.3 (Read/Write Segregation), §5.1 (SymbolSource read contract), §5.3 (Backend Substitutability and Caching Policy)

What this does

Replaces the ad-hoc symbol-resolution tiering (baked into DefaultClassRepository
and the namespace-catalog composite) with one shared read seam — a
CompositeSymbolSource over four named SymbolBackends at fixed precedence:

  1. OpenDocument — the editor's open documents (never cached); overrides the rest.
  2. Workspace — the project's own on-disk code (non-vendor/ autoload prefixes).
  3. Vendor — installed dependencies (vendor/ prefixes). Same FilesystemBackend, a different autoload-map subset.
  4. Builtin — PHP built-ins via reflection.

A lookup takes the first backend that answers; enumeration and search merge every
backend with the earlier (more authoritative) one winning a name clash. The write
path is a single SymbolSink (DocumentSymbolSink); KnowledgeStack::forProject
assembles the read composite and the write sink over a shared open-document backend
and index, and is used by both Server and the tests.

This is behavior-preserving (Step 3a): the Step P parity goldens
(class-like lookup, namespace enumeration) are unchanged, and TypeGraphParityTest
stays green. MemberResolver now reads through SymbolSource so there is no second
lookup authority — the discovery-axis M×N is closed, enforced by the (updated) §4.2
SymbolDiscoveryAuthorityExtension PHPStan rule.

Acceptance criteria

  • SymbolBackend contract — lookupClassLike / childrenOf / searchClassLikes, absence as null / empty (§5.3)
  • Four named backends: OpenDocument, Workspace, Vendor, Builtin
  • CompositeSymbolSource at fixed precedence — open document overrides workspace › vendor › built-in (§5.3)
  • Workspace/Vendor split via ComposerAutoloadMap::partitionByVendorDirectory; the union resolves exactly as before
  • Per-backend PSR-16 caching preserved (§5.3); open documents never cached
  • Single write path (DocumentSymbolSink) registers class metadata + indexes from one document (§4.3)
  • MemberResolver reads through SymbolSource; no consumer names a concrete repository/index directly
  • DefaultClassRepository, DelegatingSymbolSource, NamespaceCatalogFactory, CompositeNamespaceCatalog, and the ClassRepository interface retired; §4.2 confined set updated (their coverage migrated to the new backend/composite/sink unit tests)
  • Behavior-preserving: Step P parity goldens unchanged; full suite green

Deferred / tracked gaps

  • Class-like prefix search over unopened workspace/vendor files is the deferred workspace-index scope (RFC §3); it stays open-document-only here. The narrow current-namespace slice of it is tracked in Bare-name completion misses current-namespace classes in unopened files #383.
  • The Builtin backend is reflection-backed and describes the server runtime, not the project target — a known §4.7 gap whose fix is the deferred Step 5. Per the build manifest, the tracked §4.7 issue should be filed when this slice lands.

Candidate closes

None — the manifest lists no Closes for S3.3.

Firehed and others added 11 commits July 30, 2026 13:47
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.23%. Comparing base (afd1ff5) to head (ad52c35).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main     #384      +/-   ##
============================================
+ Coverage     98.14%   98.23%   +0.08%     
- Complexity     1708     1725      +17     
============================================
  Files           109      111       +2     
  Lines          4311     4356      +45     
============================================
+ Hits           4231     4279      +48     
+ Misses           80       77       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@Firehed
Firehed merged commit 98a7cea into main Jul 31, 2026
7 checks passed
@Firehed
Firehed deleted the slice/S3.3 branch July 31, 2026 18:09
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