f-layer 2.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. f_layer-2.0.1.dist-info/METADATA +232 -0
  2. f_layer-2.0.1.dist-info/RECORD +45 -0
  3. f_layer-2.0.1.dist-info/WHEEL +4 -0
  4. f_layer-2.0.1.dist-info/entry_points.txt +2 -0
  5. f_layer-2.0.1.dist-info/licenses/LICENSE +201 -0
  6. flayer/__init__.py +5 -0
  7. flayer/__main__.py +247 -0
  8. flayer/_vpn_guest.py +130 -0
  9. flayer/core/__init__.py +1 -0
  10. flayer/core/config.py +198 -0
  11. flayer/core/contracts.py +114 -0
  12. flayer/core/lifecycle.py +767 -0
  13. flayer/core/state.py +351 -0
  14. flayer/diagnostics/__init__.py +20 -0
  15. flayer/diagnostics/benchmark.py +272 -0
  16. flayer/diagnostics/contracts.py +167 -0
  17. flayer/diagnostics/health.py +154 -0
  18. flayer/diagnostics/reporting.py +24 -0
  19. flayer/extensions/__init__.py +25 -0
  20. flayer/extensions/builtins.py +165 -0
  21. flayer/extensions/contracts.py +196 -0
  22. flayer/extensions/discovery.py +152 -0
  23. flayer/extensions/registry.py +347 -0
  24. flayer/guest.py +270 -0
  25. flayer/integrations/__init__.py +23 -0
  26. flayer/integrations/adapters.py +92 -0
  27. flayer/integrations/contracts.py +241 -0
  28. flayer/integrations/wire.py +273 -0
  29. flayer/profiles/__init__.py +33 -0
  30. flayer/profiles/_amnezia_export.py +176 -0
  31. flayer/profiles/_vless_guest.py +432 -0
  32. flayer/profiles/amneziawg.py +555 -0
  33. flayer/profiles/artifacts.py +609 -0
  34. flayer/profiles/gateway.py +729 -0
  35. flayer/profiles/static_site.py +596 -0
  36. flayer/profiles/vless.py +422 -0
  37. flayer/profiles/vpn.py +524 -0
  38. flayer/providers/__init__.py +1 -0
  39. flayer/providers/contracts.py +207 -0
  40. flayer/providers/lifecycle.py +177 -0
  41. flayer/providers/yandex.py +387 -0
  42. flayer/providers/yandex_lifecycle.py +781 -0
  43. flayer/py.typed +0 -0
  44. flayer/vpn_export.py +72 -0
  45. flayer/vpn_project.py +828 -0
@@ -0,0 +1,196 @@
1
+ """Typed, versioned extension identities and bounded credential-free contexts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ import re
7
+ from collections.abc import Mapping
8
+ from dataclasses import dataclass, field
9
+ from enum import StrEnum
10
+ from pathlib import Path
11
+ from typing import Protocol, runtime_checkable
12
+
13
+ from flayer.core.contracts import ContractError, StackIdentity, ValidateName
14
+ from flayer.profiles.artifacts import ArtifactBundle
15
+ from flayer.providers.contracts import CloudProvider, ValidateIdentifier
16
+ from flayer.providers.lifecycle import LifecycleProvider
17
+
18
+ PROVIDER_GROUP = "flayer.providers.v1"
19
+ PROFILE_GROUP = "flayer.profiles.v1"
20
+ VERSION_PATTERN = re.compile(r"(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\Z")
21
+ DISTRIBUTION_PATTERN = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*\Z")
22
+ TARGET_PATTERN = re.compile(
23
+ r"[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*"
24
+ r":[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*\Z"
25
+ )
26
+ SHA256_PATTERN = re.compile(r"[a-f0-9]{64}\Z")
27
+
28
+
29
+ class ExtensionError(ContractError):
30
+ """An extension violates discovery, identity, compatibility, or loading policy."""
31
+
32
+
33
+ class ExtensionKind(StrEnum):
34
+ """The two implemented extension contracts; their ABI is encoded in the group."""
35
+
36
+ PROVIDER = "provider"
37
+ PROFILE = "profile"
38
+
39
+
40
+ @dataclass(frozen=True, slots=True)
41
+ class ExtensionDescriptor:
42
+ """A static identity; external metadata snapshots are not package authenticity proof."""
43
+
44
+ kind: ExtensionKind
45
+ plugin_id: str
46
+ distribution: str
47
+ version: str
48
+ group: str
49
+ target: str
50
+ metadata_directory: Path | None = field(default=None, repr=False)
51
+ metadata_sha256: str | None = field(default=None, repr=False)
52
+
53
+ def __post_init__(self) -> None:
54
+ """Validate direct construction as strictly as statically decoded metadata."""
55
+
56
+ if not isinstance(self.kind, ExtensionKind):
57
+ raise ExtensionError("Extension kind must be an ExtensionKind member")
58
+
59
+ ValidateName(self.plugin_id, "extension.plugin_id")
60
+
61
+ if (
62
+ not isinstance(self.distribution, str) or len(self.distribution) > 128
63
+ or DISTRIBUTION_PATTERN.fullmatch(self.distribution) is None
64
+ or not isinstance(self.version, str) or len(self.version) > 32
65
+ or VERSION_PATTERN.fullmatch(self.version) is None
66
+ ):
67
+ raise ExtensionError("Extension distribution and stable release version are invalid")
68
+
69
+ expected_group = PROVIDER_GROUP if self.kind is ExtensionKind.PROVIDER else PROFILE_GROUP
70
+
71
+ if self.group != expected_group:
72
+ raise ExtensionError("Extension group uses an unsupported contract version")
73
+
74
+ if (
75
+ not isinstance(self.target, str) or len(self.target) > 256
76
+ or TARGET_PATTERN.fullmatch(self.target) is None
77
+ ):
78
+ raise ExtensionError("Extension target must be an exact module:attribute without extras")
79
+
80
+ if self.metadata_directory is None:
81
+ if self.distribution != "f-layer" or self.metadata_sha256 is not None:
82
+ raise ExtensionError("Only F-Layer built-ins may omit the metadata snapshot")
83
+
84
+ elif (
85
+ not isinstance(self.metadata_directory, Path)
86
+ or not self.metadata_directory.is_absolute()
87
+ or not self.metadata_directory.name.endswith(".dist-info")
88
+ or not isinstance(self.metadata_sha256, str)
89
+ or SHA256_PATTERN.fullmatch(self.metadata_sha256) is None
90
+ or self.distribution == "f-layer"
91
+ or self.target.split(":", 1)[0].split(".", 1)[0] == "flayer"
92
+ ):
93
+ raise ExtensionError("External extensions require a valid non-reserved metadata snapshot")
94
+
95
+
96
+ @dataclass(frozen=True, slots=True)
97
+ class ProviderContext:
98
+ """Explicit scope, external CLI authentication reference, and bounded execution limits."""
99
+
100
+ scope_id: str
101
+ authentication_reference: str
102
+ command_timeout: float = 45.0
103
+ inventory_limit: int = 10000
104
+
105
+ def __post_init__(self) -> None:
106
+ """Reject credential bytes, malformed references, and unbounded execution settings."""
107
+
108
+ ValidateIdentifier(self.scope_id)
109
+ ValidateIdentifier(self.authentication_reference)
110
+
111
+ if (
112
+ isinstance(self.command_timeout, bool)
113
+ or not isinstance(self.command_timeout, (int, float))
114
+ or not math.isfinite(self.command_timeout)
115
+ or not 0 < self.command_timeout <= 300
116
+ or type(self.inventory_limit) is not int or not 1 <= self.inventory_limit <= 100000
117
+ ):
118
+ raise ExtensionError("Provider context requires bounded timeout and inventory limits")
119
+
120
+
121
+ @dataclass(frozen=True, slots=True)
122
+ class ProfileContext:
123
+ """Exact stack ownership context; profile configuration and artifacts stay separate."""
124
+
125
+ identity: StackIdentity
126
+
127
+ def __post_init__(self) -> None:
128
+ """Require the existing validated immutable ownership contract."""
129
+
130
+ if not isinstance(self.identity, StackIdentity):
131
+ raise ExtensionError("Profile context requires a validated StackIdentity")
132
+
133
+
134
+ @runtime_checkable
135
+ class ProviderExtension(Protocol):
136
+ """Factory for the existing read-only provider contract, without mandatory mutation."""
137
+
138
+ @property
139
+ def Descriptor(self) -> ExtensionDescriptor:
140
+ """Return the exact static identity registered before factory loading."""
141
+
142
+ ...
143
+
144
+ def CreateProvider(self, context: ProviderContext) -> CloudProvider:
145
+ """Construct a scoped read-only adapter without probing or mutating infrastructure."""
146
+
147
+ ...
148
+
149
+
150
+ @runtime_checkable
151
+ class LifecycleProviderExtension(ProviderExtension, Protocol):
152
+ """Optional separate factory for the existing owned resource lifecycle contract."""
153
+
154
+ def CreateLifecycleProvider(self, context: ProviderContext) -> LifecycleProvider:
155
+ """Construct a mutation-capable adapter without performing provider operations."""
156
+
157
+ ...
158
+
159
+
160
+ @runtime_checkable
161
+ class CompiledProfile(Protocol):
162
+ """Validated profile adapter that preserves existing artifact and lifecycle boundaries."""
163
+
164
+ @property
165
+ def Identity(self) -> StackIdentity:
166
+ """Return the exact identity validated during profile compilation."""
167
+
168
+ ...
169
+
170
+ def BuildServerBundle(self) -> ArtifactBundle:
171
+ """Generate owned server initialization bytes without writing or deploying them."""
172
+
173
+ ...
174
+
175
+ def RenderPlan(self, *, user_data_file: str | Path) -> str:
176
+ """Render lifecycle TOML after verifying the exact owned server artifact."""
177
+
178
+ ...
179
+
180
+
181
+ @runtime_checkable
182
+ class ProfileExtension(Protocol):
183
+ """Compile explicit profile configuration using its own strict versioned schema."""
184
+
185
+ @property
186
+ def Descriptor(self) -> ExtensionDescriptor:
187
+ """Return the exact static identity registered before factory loading."""
188
+
189
+ ...
190
+
191
+ def CompileProfile(
192
+ self, configuration: Mapping[str, object], context: ProfileContext,
193
+ ) -> CompiledProfile:
194
+ """Validate configuration and exact ownership without accessing infrastructure."""
195
+
196
+ ...
@@ -0,0 +1,152 @@
1
+ """Bounded static discovery from exact caller-selected installed distribution metadata."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import configparser
6
+ import hashlib
7
+ import os
8
+ import stat
9
+ from collections.abc import Sequence
10
+ from email import policy
11
+ from email.parser import BytesParser
12
+ from pathlib import Path
13
+
14
+ from .contracts import (
15
+ PROFILE_GROUP,
16
+ PROVIDER_GROUP,
17
+ ExtensionDescriptor,
18
+ ExtensionError,
19
+ ExtensionKind,
20
+ )
21
+
22
+ MAX_METADATA_BYTES = 262144
23
+ MAX_METADATA_DIRECTORIES = 128
24
+ MAX_EXTENSIONS = 256
25
+ METADATA_FILES = ("METADATA", "entry_points.txt", "RECORD")
26
+
27
+
28
+ class _EntryPointsParser(configparser.ConfigParser):
29
+ """Preserve externally declared entry-point names instead of case-folding them."""
30
+
31
+ def optionxform(self, optionstr: str) -> str:
32
+ """Honor ConfigParser's callback naming contract while preserving identity."""
33
+
34
+ return optionstr
35
+
36
+
37
+ def ReadMetadataFile(path: Path, maximum: int = MAX_METADATA_BYTES) -> bytes:
38
+ """Read one regular non-linked bounded file without following a final symlink."""
39
+
40
+ try:
41
+ descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
42
+
43
+ with os.fdopen(descriptor, "rb") as stream:
44
+ receipt = os.fstat(stream.fileno())
45
+
46
+ if (
47
+ not stat.S_ISREG(receipt.st_mode) or receipt.st_nlink != 1
48
+ or receipt.st_size > maximum
49
+ ):
50
+ raise ExtensionError("Extension metadata or source must be a bounded regular file")
51
+
52
+ content = stream.read(maximum + 1)
53
+ final_receipt = os.fstat(stream.fileno())
54
+
55
+ if (
56
+ len(content) > maximum or len(content) != receipt.st_size
57
+ or (receipt.st_ino, receipt.st_size, receipt.st_mtime_ns, receipt.st_ctime_ns)
58
+ != (
59
+ final_receipt.st_ino, final_receipt.st_size,
60
+ final_receipt.st_mtime_ns, final_receipt.st_ctime_ns,
61
+ )
62
+ ):
63
+ raise ExtensionError("Extension metadata or source changed during its bounded read")
64
+
65
+ except OSError:
66
+ raise ExtensionError("Unable to read exact extension metadata or source") from None
67
+
68
+ return content
69
+
70
+
71
+ def ReadMetadataSnapshot(directory: Path) -> tuple[tuple[bytes, ...], str]:
72
+ """Pin only the three explicit metadata files under one selected dist-info directory."""
73
+
74
+ try:
75
+ if (
76
+ not isinstance(directory, Path) or not directory.is_absolute()
77
+ or not directory.name.endswith(".dist-info") or directory.is_symlink()
78
+ or directory.resolve() != directory or not directory.is_dir()
79
+ ):
80
+ raise ExtensionError("Discovery requires an exact absolute non-redirected dist-info directory")
81
+
82
+ except (OSError, RuntimeError):
83
+ raise ExtensionError("Unable to resolve exact non-redirected extension metadata") from None
84
+
85
+ contents = tuple(ReadMetadataFile(directory / name) for name in METADATA_FILES)
86
+ digest = hashlib.sha256()
87
+
88
+ for name, content in zip(METADATA_FILES, contents, strict=True):
89
+ digest.update(name.encode("ascii") + b"\x00")
90
+ digest.update(len(content).to_bytes(8, "big") + content)
91
+
92
+ return contents, digest.hexdigest()
93
+
94
+
95
+ def DiscoverExtensions(metadata_directories: Sequence[Path]) -> tuple[ExtensionDescriptor, ...]:
96
+ """Parse selected metadata without importing code, calling finders, or searching paths."""
97
+
98
+ if (
99
+ not isinstance(metadata_directories, (tuple, list))
100
+ or len(metadata_directories) > MAX_METADATA_DIRECTORIES
101
+ or any(not isinstance(directory, Path) for directory in metadata_directories)
102
+ or len(set(metadata_directories)) != len(metadata_directories)
103
+ ):
104
+ raise ExtensionError("Discovery requires bounded unique explicit metadata directories")
105
+
106
+ descriptors: list[ExtensionDescriptor] = []
107
+ identities: set[tuple[ExtensionKind, str]] = set()
108
+
109
+ for directory in metadata_directories:
110
+ contents, digest = ReadMetadataSnapshot(directory)
111
+
112
+ try:
113
+ metadata = BytesParser(policy=policy.default).parsebytes(contents[0])
114
+ names = metadata.get_all("Name", [])
115
+ versions = metadata.get_all("Version", [])
116
+
117
+ if len(names) != 1 or len(versions) != 1 or metadata.defects:
118
+ raise ExtensionError("Distribution metadata requires one valid Name and Version")
119
+
120
+ distribution = str(names[0]).lower().replace("_", "-").replace(".", "-")
121
+ version = str(versions[0])
122
+ parser = _EntryPointsParser(interpolation=None, strict=True, delimiters=("=",))
123
+ parser.read_string(contents[1].decode("utf-8"))
124
+
125
+ if parser.defaults():
126
+ raise ExtensionError("Entry-point metadata cannot contain default entries")
127
+
128
+ for group in parser.sections():
129
+ if not group.startswith("flayer."):
130
+ continue
131
+
132
+ if group not in {PROVIDER_GROUP, PROFILE_GROUP}:
133
+ raise ExtensionError("Entry-point metadata uses an unsupported F-Layer group")
134
+
135
+ kind = ExtensionKind.PROVIDER if group == PROVIDER_GROUP else ExtensionKind.PROFILE
136
+
137
+ for plugin_id, target in parser.items(group):
138
+ descriptor = ExtensionDescriptor(
139
+ kind, plugin_id, distribution, version, group, target, directory, digest,
140
+ )
141
+ identity = (kind, plugin_id)
142
+
143
+ if identity in identities or len(descriptors) >= MAX_EXTENSIONS:
144
+ raise ExtensionError("Extension metadata contains duplicate or excess identities")
145
+
146
+ identities.add(identity)
147
+ descriptors.append(descriptor)
148
+
149
+ except (UnicodeError, configparser.Error, ValueError):
150
+ raise ExtensionError("Extension metadata is malformed or incompatible") from None
151
+
152
+ return tuple(sorted(descriptors, key=lambda item: (item.kind.value, item.plugin_id)))
@@ -0,0 +1,347 @@
1
+ """Explicit registry and opt-in loading of metadata-pinned, owned extension sources."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import base64
6
+ import csv
7
+ import hashlib
8
+ import importlib.abc
9
+ import importlib.util
10
+ import io
11
+ import sys
12
+ from collections.abc import Sequence
13
+ from dataclasses import dataclass, field
14
+ from pathlib import Path, PurePosixPath
15
+ from types import ModuleType
16
+
17
+ from .builtins import BuiltinDescriptors, LoadBuiltin
18
+ from .contracts import (
19
+ ExtensionDescriptor,
20
+ ExtensionError,
21
+ ExtensionKind,
22
+ ProfileExtension,
23
+ ProviderExtension,
24
+ )
25
+ from .discovery import (
26
+ MAX_EXTENSIONS,
27
+ DiscoverExtensions,
28
+ ReadMetadataFile,
29
+ ReadMetadataSnapshot,
30
+ )
31
+
32
+ MAX_MODULE_BYTES = 1048576
33
+ MAX_MODULE_DEPTH = 16
34
+ _LOADED_SOURCES: dict[str, tuple[ModuleType, Path, str]] = {}
35
+
36
+
37
+ @dataclass(frozen=True, slots=True)
38
+ class _ModuleSource:
39
+ """Verified immutable Python bytes owned by one selected distribution RECORD."""
40
+
41
+ name: str
42
+ path: Path
43
+ content: bytes = field(repr=False)
44
+ package: bool = False
45
+
46
+
47
+ class _SnapshotImporter(importlib.abc.MetaPathFinder, importlib.abc.Loader):
48
+ """Serve only already verified selected-chain imports from immutable source snapshots."""
49
+
50
+ def __init__(
51
+ self, sources: tuple[_ModuleSource, ...], created: list[tuple[str, ModuleType]],
52
+ ) -> None:
53
+ """Bind the exact source chain and cleanup receipts for one explicit load attempt."""
54
+
55
+ self._sources = {source.name: source for source in sources}
56
+ self._created = created
57
+
58
+ def find_spec(
59
+ self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None,
60
+ ) -> importlib.machinery.ModuleSpec | None:
61
+ """Honor Python's finder callback only for exact selected source identities."""
62
+
63
+ source = self._sources.get(fullname)
64
+
65
+ if source is None:
66
+ return None
67
+
68
+ return importlib.util.spec_from_file_location(
69
+ fullname, source.path, loader=self,
70
+ submodule_search_locations=[str(source.path.parent)] if source.package else None,
71
+ )
72
+
73
+ def create_module(self, spec: importlib.machinery.ModuleSpec) -> ModuleType | None:
74
+ """Honor Python's loader callback with the standard module construction behavior."""
75
+
76
+ return None
77
+
78
+ def exec_module(self, module: ModuleType) -> None:
79
+ """Execute selected verified bytes and register exact module-object provenance."""
80
+
81
+ source = self._sources[module.__name__]
82
+ self._created.append((source.name, module))
83
+ exec(compile(source.content, str(source.path), "exec"), module.__dict__)
84
+ _LOADED_SOURCES[source.name] = (
85
+ module, source.path, hashlib.sha256(source.content).hexdigest(),
86
+ )
87
+ _RequireReceipt(source, module)
88
+
89
+
90
+ def _ReadSources(descriptor: ExtensionDescriptor) -> tuple[_ModuleSource, ...]:
91
+ """Validate exact metadata and every parent/target source before any plugin execution."""
92
+
93
+ directory = descriptor.metadata_directory
94
+
95
+ if directory is None:
96
+ raise ExtensionError("External loading requires a selected metadata directory")
97
+
98
+ contents, digest = ReadMetadataSnapshot(directory)
99
+
100
+ if digest != descriptor.metadata_sha256 or descriptor not in DiscoverExtensions((directory,)):
101
+ raise ExtensionError("Selected extension metadata changed after discovery")
102
+
103
+ records: dict[str, tuple[str, str]] = {}
104
+
105
+ try:
106
+ for row in csv.reader(io.StringIO(contents[2].decode("utf-8")), strict=True):
107
+ if (
108
+ len(row) != 3 or not row[0] or row[0] in records
109
+ or PurePosixPath(row[0]).is_absolute() or "\\" in row[0]
110
+ ):
111
+ raise ExtensionError("Distribution RECORD contains malformed or duplicate paths")
112
+
113
+ records[row[0]] = (row[1], row[2])
114
+
115
+ except (UnicodeError, csv.Error):
116
+ raise ExtensionError("Distribution RECORD is malformed") from None
117
+
118
+ module = descriptor.target.split(":", 1)[0]
119
+ parts = module.split(".")
120
+
121
+ if len(parts) > MAX_MODULE_DEPTH:
122
+ raise ExtensionError("Extension import target exceeds the supported package depth")
123
+
124
+ sources: list[_ModuleSource] = []
125
+
126
+ for index in range(1, len(parts) + 1):
127
+ stem = "/".join(parts[:index])
128
+ candidates: tuple[str, ...] = (stem + "/__init__.py",)
129
+
130
+ if index == len(parts):
131
+ candidates += (stem + ".py",)
132
+
133
+ matches = tuple(candidate for candidate in candidates if candidate in records)
134
+
135
+ if len(matches) != 1:
136
+ raise ExtensionError("Extension target and parent packages require exact RECORD ownership")
137
+
138
+ relative = matches[0]
139
+ path = directory.parent / relative
140
+
141
+ try:
142
+ if path.resolve() != path or not path.is_relative_to(directory.parent):
143
+ raise ExtensionError("Extension source cannot redirect outside its selected installation")
144
+
145
+ except (OSError, RuntimeError):
146
+ raise ExtensionError("Unable to resolve exact non-redirected extension source") from None
147
+
148
+ content = ReadMetadataFile(path, MAX_MODULE_BYTES)
149
+ source_digest = base64.urlsafe_b64encode(hashlib.sha256(content).digest()).decode().rstrip("=")
150
+
151
+ if records[relative] != ("sha256=" + source_digest, str(len(content))):
152
+ raise ExtensionError("Extension source does not match its exact RECORD hash and size")
153
+
154
+ sources.append(_ModuleSource(
155
+ ".".join(parts[:index]), path, content, relative.endswith("/__init__.py"),
156
+ ))
157
+
158
+ return tuple(sources)
159
+
160
+
161
+ def _LoadFactory(descriptor: ExtensionDescriptor) -> ProviderExtension | ProfileExtension:
162
+ """Execute verified selected sources directly, rejecting ambient module shadowing."""
163
+
164
+ sources = _ReadSources(descriptor)
165
+
166
+ for source in sources:
167
+ existing = sys.modules.get(source.name)
168
+
169
+ if existing is not None:
170
+ _RequireReceipt(source, existing)
171
+
172
+ created: list[tuple[str, ModuleType]] = []
173
+ importer = _SnapshotImporter(sources, created)
174
+ sys.meta_path.insert(0, importer)
175
+
176
+ try:
177
+ for source in sources:
178
+ existing = sys.modules.get(source.name)
179
+
180
+ if existing is not None:
181
+ _RequireReceipt(source, existing)
182
+
183
+ continue
184
+
185
+ spec = importer.find_spec(source.name, None)
186
+
187
+ if spec is None:
188
+ raise ExtensionError("Unable to construct the selected extension module")
189
+
190
+ module = importlib.util.module_from_spec(spec)
191
+ sys.modules[source.name] = module
192
+ importer.exec_module(module)
193
+
194
+ if "." in source.name:
195
+ parent_name, _, child_name = source.name.rpartition(".")
196
+ setattr(sys.modules[parent_name], child_name, module)
197
+
198
+ factory: object = sys.modules[sources[-1].name]
199
+
200
+ for attribute in descriptor.target.split(":", 1)[1].split("."):
201
+ factory = getattr(factory, attribute)
202
+
203
+ if not callable(factory):
204
+ raise ExtensionError("Selected entry-point target is not a callable factory")
205
+
206
+ return _ValidateExtension(factory(), descriptor)
207
+
208
+ except (Exception, SystemExit):
209
+ for name, module in reversed(created):
210
+ if sys.modules.get(name) is module:
211
+ del sys.modules[name]
212
+
213
+ receipt = _LOADED_SOURCES.get(name)
214
+
215
+ if receipt is not None and receipt[0] is module:
216
+ del _LOADED_SOURCES[name]
217
+
218
+ if "." in name:
219
+ parent_name, _, child_name = name.rpartition(".")
220
+ parent = sys.modules.get(parent_name)
221
+
222
+ if parent is not None and parent.__dict__.get(child_name) is module:
223
+ del parent.__dict__[child_name]
224
+
225
+ raise ExtensionError("Selected extension factory failed to load") from None
226
+
227
+ finally:
228
+ if importer in sys.meta_path:
229
+ sys.meta_path.remove(importer)
230
+
231
+
232
+ def _RequireReceipt(source: _ModuleSource, module: ModuleType) -> None:
233
+ """Reject cached code unless this loader executed this exact verified byte snapshot."""
234
+
235
+ receipt = _LOADED_SOURCES.get(source.name)
236
+
237
+ if (
238
+ receipt is None or receipt[0] is not module or receipt[1] != source.path
239
+ or receipt[2] != hashlib.sha256(source.content).hexdigest()
240
+ or sys.modules.get(source.name) is not module
241
+ or module.__dict__.get("__file__") != str(source.path)
242
+ or getattr(module.__dict__.get("__spec__"), "origin", None) != str(source.path)
243
+ ):
244
+ raise ExtensionError("An unverified cached module shadows the selected extension source")
245
+
246
+
247
+ def _ValidateExtension(
248
+ loaded: object, descriptor: ExtensionDescriptor,
249
+ ) -> ProviderExtension | ProfileExtension:
250
+ """Check exact identity and callable protocol before a factory transaction commits."""
251
+
252
+ expected = ProviderExtension if descriptor.kind is ExtensionKind.PROVIDER else ProfileExtension
253
+ method = "CreateProvider" if descriptor.kind is ExtensionKind.PROVIDER else "CompileProfile"
254
+
255
+ try:
256
+ if (
257
+ not isinstance(loaded, expected) or loaded.Descriptor != descriptor
258
+ or not callable(getattr(loaded, method, None))
259
+ ):
260
+ raise ExtensionError("Loaded extension does not match its declared identity and contract")
261
+
262
+ except (Exception, SystemExit):
263
+ raise ExtensionError("Loaded extension does not match its declared identity and contract") from None
264
+
265
+ return loaded
266
+
267
+
268
+ class ExtensionRegistry:
269
+ """A bounded explicit catalog; neither construction nor lookup imports external code."""
270
+
271
+ def __init__(
272
+ self, descriptors: Sequence[ExtensionDescriptor] = (), *, include_builtins: bool = True,
273
+ ) -> None:
274
+ """Validate complete registration before publishing any catalog entries."""
275
+
276
+ if type(include_builtins) is not bool or not isinstance(descriptors, (tuple, list)):
277
+ raise ExtensionError("Registry requires explicit bounded descriptor registration")
278
+
279
+ entries = (*BuiltinDescriptors(), *descriptors) if include_builtins else tuple(descriptors)
280
+
281
+ if len(entries) > MAX_EXTENSIONS:
282
+ raise ExtensionError("Registry exceeds its extension bound")
283
+
284
+ registered: dict[tuple[ExtensionKind, str], ExtensionDescriptor] = {}
285
+
286
+ for descriptor in entries:
287
+ if not isinstance(descriptor, ExtensionDescriptor):
288
+ raise ExtensionError("Registry accepts only validated ExtensionDescriptor objects")
289
+
290
+ identity = (descriptor.kind, descriptor.plugin_id)
291
+
292
+ if identity in registered:
293
+ raise ExtensionError("Duplicate extension identity would shadow a registered extension")
294
+
295
+ if descriptor.metadata_directory is None and descriptor not in BuiltinDescriptors():
296
+ raise ExtensionError("Registry rejects invented or incompatible built-in identities")
297
+
298
+ registered[identity] = descriptor
299
+
300
+ self._descriptors = registered
301
+ self._loaded: dict[ExtensionDescriptor, ProviderExtension | ProfileExtension] = {}
302
+
303
+ def Descriptors(self) -> tuple[ExtensionDescriptor, ...]:
304
+ """Return immutable descriptors in deterministic kind and identifier order."""
305
+
306
+ return tuple(sorted(self._descriptors.values(), key=lambda item: (item.kind.value, item.plugin_id)))
307
+
308
+ def Get(self, kind: ExtensionKind, plugin_id: str) -> ExtensionDescriptor:
309
+ """Select one registered identity without imports or capability probes."""
310
+
311
+ if not isinstance(kind, ExtensionKind) or not isinstance(plugin_id, str):
312
+ raise ExtensionError("Registry lookup requires an exact extension kind and identifier")
313
+
314
+ descriptor = self._descriptors.get((kind, plugin_id))
315
+
316
+ if descriptor is None:
317
+ raise ExtensionError("Extension identity is not registered")
318
+
319
+ return descriptor
320
+
321
+ def Load(
322
+ self, descriptor: ExtensionDescriptor, *, allowed: Sequence[ExtensionDescriptor] = (),
323
+ ) -> ProviderExtension | ProfileExtension:
324
+ """Load an exact registered factory; external code requires an exact descriptor pin."""
325
+
326
+ if (
327
+ not isinstance(descriptor, ExtensionDescriptor)
328
+ or self.Get(descriptor.kind, descriptor.plugin_id) != descriptor
329
+ or not isinstance(allowed, (tuple, list)) or len(allowed) > MAX_EXTENSIONS
330
+ or any(not isinstance(item, ExtensionDescriptor) for item in allowed)
331
+ or len(set(allowed)) != len(allowed)
332
+ ):
333
+ raise ExtensionError("Loading requires an exact registered descriptor and bounded unique pins")
334
+
335
+ if descriptor.metadata_directory is not None and descriptor not in allowed:
336
+ raise ExtensionError("External loading requires an explicit exact descriptor allowlist")
337
+
338
+ if descriptor in self._loaded:
339
+ return self._loaded[descriptor]
340
+
341
+ loaded = (
342
+ _ValidateExtension(LoadBuiltin(descriptor), descriptor)
343
+ if descriptor.metadata_directory is None else _LoadFactory(descriptor)
344
+ )
345
+ self._loaded[descriptor] = loaded
346
+
347
+ return loaded