Skip to content

core: plan the programmatic extension path in the core too - #1127

Merged
thekevinscott merged 4 commits into
mainfrom
claude/1122-ext-cleanup
Sep 18, 2026
Merged

thekevinscott merged 4 commits into
mainfrom
claude/1122-ext-cleanup

Conversation

@thekevinbot

@thekevinbot thekevinbot commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Slice D of #1072/#1111: the last piece of extension resolution both SDKs still
ported from one another — the programmatic extensions=[{path}] probe — moves
into the core, and the binding exports it made necessary go away.

dirsql::extension_resolution::plan_extension_path classifies one path the same
way the config planner classifies a config entry: a path-looking value is a
Literal (made absolute against base only when asked), a bare name is a
Package with a shadow probe. Python's resolve_extension_path and
TypeScript's resolveExtensionPath are now one call to the planner plus the
existing plan_entry_path / planEntryPath, so each host keeps only the
package lookup it alone can do (importlib.util.find_spec / require.resolve).

is_bare_name / isBareName were that probe's only callers; both bindings drop
them in favor of plan_extension_path / planExtensionPath.

Resolved paths and error messages are unchanged, so no migration fragment.

Fixes #1122.

Parity

Restores parity rather than drifting: both SDKs move onto the same core
contract, and Rust stays file-path-only by design (the #227 carve-out).
PARITY.md's "Where the planning lives" paragraph is updated.

Manual verification

Built the packages/rust/tests/fixtures/testext cdylib, installed it as a fake
package, and resolved it by bare name through both SDKs:

# Python (programmatic + config entry), PYTHONPATH=<tmp>/pkgroot
programmatic bare name -> [{'a': 42}]
config bare name       -> [{'a': 42}]

# Node (programmatic), package in a resolvable node_modules
programmatic bare name -> [ { a: 42 } ]

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass (37 passed)
  • TypeScript SDK e2e: pass (17 passed)
  • Rust core e2e (if applicable): pass (cargo test --workspace --features cli via preflight)
  • packages/python/e2e-attestations/<branch>.json receipt written if packages/python changed (just e2e-attest-python)
  • packages/ts/e2e-attestations/<branch>.json receipt written if packages/ts changed (just e2e-attest-ts)
  • Command(s) run: just test-e2e, just e2e-attest-python, just e2e-attest-ts, just preflight
  • Result summary: all green; just preflight reports 0 failing pairs.

Changelog / Migrations

  • Changelog fragment added under <root>/<pkg>/changelog.d/ for each changed package (rust, python, ts)
  • Migration fragment added under <root>/<pkg>/migrations.d/ (not required — internal refactor, no observable change)

Red/green

600349e pushed the core contract with the implementation stubbed; CI was
observed red for the right reason (not implemented: plan_extension_path, 4
failing tests in dirsql Rust CI). c053177 implements it.

Add `extension_resolution::plan_extension_path` with its unit tests,
implementation stubbed. Pushed on its own so CI is observed red before the
implementation lands.

The config-entry planner already lives in the core (#1119); the programmatic
`extensions=[{path}]` probe is the last piece both SDKs still port from one
another.

Part of #1122.
Implement `extension_resolution::plan_extension_path` and route both SDKs'
`resolve_extension_path` / `resolveExtensionPath` through it, so a programmatic
`extensions=[{path}]` entry is classified by the same code as a config entry
and each host keeps only the package lookup it alone can do.

The `is_bare_name` / `isBareName` binding exports were that probe's only
callers, so they go; `plan_extension_path` / `planExtensionPath` replaces them.
Resolved paths and error messages are unchanged.

Part of #1122.
@thekevinbot
thekevinbot marked this pull request as ready for review September 18, 2026 14:40
@thekevinscott
thekevinscott merged commit b9250a1 into main Sep 18, 2026
77 checks passed
@thekevinscott
thekevinscott deleted the claude/1122-ext-cleanup branch September 18, 2026 15:00
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.

#1111 Slice D: remove duplicate extension resolvers and finish parity cleanup

2 participants