Skip to content

Route PEP 723 scripts to inline environments (PEP 723 PR 9/16) - #7

Closed
StellaHuang95 wants to merge 7 commits into
mainfrom
pep723-pr9-explicit-setup-v2
Closed

Route PEP 723 scripts to inline environments (PEP 723 PR 9/16)#7
StellaHuang95 wants to merge 7 commits into
mainfrom
pep723-pr9-explicit-setup-v2

Conversation

@StellaHuang95

@StellaHuang95 StellaHuang95 commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Fork-review PR; do not send upstream yet.

Part of microsoft#1602. Complete roadmap PR9 automatic routing implementation.

Summary

  • route a local .py file to the inline-script manager only when saved PEP 723 metadata and a validated cached/persisted association agree
  • use one per-window routing registry shared by detector, environment managers, and the inline manager
  • preserve exact project settings and explicit non-inline overrides
  • keep dirty, missing, renamed, deleted, stale, and unvalidated scripts on normal fallback routing

Persistence and provenance

  • versioned composite association records with conservative PR7 legacy handling
  • saved metadata identity rather than dirty editor text
  • bounded SHA-256 source metadata hashes in cache sidecars
  • current launcher, ownership, path, sidecar, metadata, and association-revision proof before route publication
  • non-destructive handling of future sidecar/persisted schemas

Default-off guarantee

python-envs.inlineScripts.enabled is latched once at activation and is authoritative for that extension-host lifetime.

When absent/false:

  • no routing registry is allocated
  • environment managers do not subscribe to or check routeability
  • the inline manager is not constructed or registered
  • the lazy detector runs in its original bde7cf8 telemetry-only mode: workspace .py open/save/change listeners only
  • no routing-only delete/rename listeners, loose-file tracking, metadata identity normalization, or registry writes occur
  • restored dirty-document inlineScript.detected / edited telemetry semantics remain baseline-equivalent

A window reload is required for flag changes, preventing mixed activation states.

Scope

No activation-time environment listing, pythonProjects[] registration, setup UI, cache cleanup, lifecycle telemetry, or status treatment.

Validation

  • TypeScript test and extension compilation
  • ESLint and diff checks
  • full unit suite: 1668 passing, 5 expected platform skips
  • complete routing reviews plus two dedicated default-off reviews; no significant findings remain

@StellaHuang95 StellaHuang95 changed the title Add explicit PEP 723 script environment setup (preview) Route PEP 723 scripts to inline environments (PEP 723 PR 9/16) Aug 17, 2026
@StellaHuang95

StellaHuang95 commented Aug 17, 2026

Copy link
Copy Markdown
Owner Author

🔒 Automated review in progress — @StellaHuang95 is auto-reviewing this PR.

Comment thread src/common/inlineScript/cacheLayout.ts
Comment thread src/managers/builtin/inlineScript/envManager.ts
Comment thread src/managers/builtin/inlineScript/envManager.ts
@StellaHuang95

Copy link
Copy Markdown
Owner Author

GitHub cannot anchor PR review comments to unchanged lines in the diff. Falling back to a general PR comment for src/features/inlineScript/lazyDetector.ts:L162.

Warning · Non-blocking recommendation

URI-level coalescing can let an in-flight open read absorb a concurrent save. If the saved contents change before the open read completes, the stale open result can be published as routing metadata. Add a controlled regression test and replay or separate the save read when this race occurs.

[verified]

@StellaHuang95 StellaHuang95 added the review-auto:changes-requested Automated review: posted blocking findings to address. label Aug 17, 2026
@StellaHuang95

Copy link
Copy Markdown
Owner Author

Addressed the open/save coalescing feedback from #7 (comment) in 50555f3. Routing-enabled detection now tracks per-URI generations: a save arriving during an older open read schedules a fresh post-save read, and stale results cannot publish routing metadata. The telemetry-only/default-off path retains its previous coalescing behavior. The same commit also adds document-compatible source offsets so CRLF metadata edits invalidate routing correctly.

Comment thread src/common/inlineScript/cacheLayout.ts
): void {
if (!this.inlineScriptRouting) {
return;
}

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.

Warning · Non-blocking recommendation

_inlineRoutingOverrides is not cleared when a script is deleted or renamed, so an override from the old file can win after a new script is created at the same path. Clear old-path overrides from delete/rename handling and cover delete–recreate behavior.

public readonly log: LogOutputChannel,
) {}
private readonly routingRegistry: InlineScriptRoutingRegistry = new InlineScriptRoutingRegistry(),
) {

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.

Info · Optional note

The default registry creates a disconnected routing registry despite production activation requiring one shared instance. Require constructor injection so every caller explicitly provides the activation-scoped registry.

@StellaHuang95

Copy link
Copy Markdown
Owner Author

GitHub cannot anchor PR review comments to unchanged lines in the diff. Falling back to a general PR comment for src/managers/builtin/inlineScript/envManager.ts:L168.

Warning · Non-blocking recommendation

The per-script environment, persisted association, validation, provenance, revision, and pending-work state is coordinated through parallel maps. Consolidate the durable lifecycle fields into one keyed record so invalidation and publication cannot update only part of the state.

@StellaHuang95 StellaHuang95 added review-auto:approved Automated review: no blocking findings (approval posted). and removed review-auto:changes-requested Automated review: posted blocking findings to address. labels Aug 18, 2026
StellaHuang95 and others added 6 commits August 19, 2026 15:36
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3cb82ae9-7424-40a4-9156-8c54ac6e0895
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3cb82ae9-7424-40a4-9156-8c54ac6e0895
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3cb82ae9-7424-40a4-9156-8c54ac6e0895
Preserve sidecars across replacement failures, replay saves after in-flight reads, and use document-compatible metadata offsets.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6b12d843-8011-4bfc-9ba9-f75761eadee2
Restore compatible sidecars after replacement failures without reviving invalid cache artifacts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6b12d843-8011-4bfc-9ba9-f75761eadee2
Adapt versioned associations, telemetry coalescing, discovery, and cache clearing after rebase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6b12d843-8011-4bfc-9ba9-f75761eadee2
@StellaHuang95
StellaHuang95 force-pushed the pep723-pr9-explicit-setup-v2 branch from 3245bb0 to 021a198 Compare August 19, 2026 22:59
Retain up to 128 distinct metadata identity proofs per shared cache entry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6b12d843-8011-4bfc-9ba9-f75761eadee2
await this.refreshEnvironment(uri);
}
return;
}

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.

Warning · Non-blocking recommendation

_inlineRoutingOverrides is not cleared for deleted or renamed scripts, so an override for the old file can still win if a new script is later created at the same path. Clear old-path overrides on delete/rename and add a delete-recreate regression test.

@StellaHuang95

Copy link
Copy Markdown
Owner Author

Upstream review continues in microsoft#1729. Closing this fork-only review PR as superseded.

export async function writeMetaJson(envDir: Uri, meta: InlineScriptEnvMeta): Promise<void> {
await fsapi.ensureDir(envDir.fsPath);
export function writeMetaJson(envDir: Uri, meta: InlineScriptEnvMeta): Promise<void> {
const finalPath = getMetaJsonPath(envDir).fsPath;

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.

Issue · Please address or respond

queued is assigned once. Declare it as const queued = operation.finally(...); the deferred callback can safely reference that binding.

[verified]

await this.refreshEnvironment(uri);
}
return;
}

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.

Issue · Please address or respond

Delete and rename handling never clears _inlineRoutingOverrides, so a newly created script at the old path inherits the deleted file's override. Clear old-path overrides from filesystem lifecycle events and add delete-recreate and rename-recreate coverage.

[verified]

@StellaHuang95

Copy link
Copy Markdown
Owner Author

GitHub cannot anchor PR review comments to unchanged lines in the diff. Falling back to a general PR comment for src/managers/builtin/inlineScript/envManager.ts:L214.

Warning · Non-blocking recommendation

Per-script lifecycle state is coordinated manually across numerous parallel maps. Consolidate the persisted association, resolved environment, validation proof, revisions, and pending operations into a per-script state record before adding further transitions.

[verified]

const next = updater(previous);

if (!next.metadata && !next.validatedAssociation) {
this.states.delete(scriptPath);

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.

Warning · Non-blocking recommendation

Deleting an empty state also discards its revision, allowing a later metadata update to reuse revision 1. Preserve a monotonic revision independently of routeability state and add a deferred-refresh test that deletes and recreates the same path.

[verified]

start: sourceOffsetForNormalizedOffset(sourceText, matchStart),
end: sourceOffsetForNormalizedOffset(sourceText, end),
},
};

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.

Warning · Non-blocking recommendation

sourceRange is computed after removing the BOM, while VS Code change offsets include it. Editing the final metadata character can therefore fail the < metadataEnd invalidation check. Return offsets relative to the original document and add a BOM-at-EOF edit test.

[verified]

}
this.routingRegistry.clearMetadata(uri);
this.routingRegistry.setValidatedAssociation(uri, false);
}

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.

Warning · Non-blocking recommendation

Delete and rename clear routeability without advancing the routing-read generation, so an older disk read can republish metadata for the removed path. Invalidate the generation in clearRouteability and test deletion while an open read is deferred.

[verified]

@StellaHuang95 StellaHuang95 added review-auto:changes-requested Automated review: posted blocking findings to address. and removed review-auto:approved Automated review: no blocking findings (approval posted). labels Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-auto:changes-requested Automated review: posted blocking findings to address.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant