PineForge HPO 1.11.0
Native hyperparameter optimization for PineForge strategies
Loading...
Searching...
No Matches
window_plan.py
Go to the documentation of this file.
1"""Recorded identity and hash-only admission for the native planner companion.
2
3This module never loads a library. The native consumer must independently verify
4and load a private snapshot to close the pathname race, then check the planner
5exports, ABI and frozen self-test. Association records bytes, not proof of co-build.
6"""
7
8from __future__ import annotations
9
10from dataclasses import dataclass, fields
11import os
12from pathlib import Path
13import platform
14import re
15from typing import TYPE_CHECKING, Any, Literal, Mapping
16
17from .error import HpoError
18
19if TYPE_CHECKING:
20 from .artifact import _EngineLayout
21
22
23
24
25
26
27
28
29
30
31
32class WindowPlanError(HpoError, RuntimeError):
33 """A selected-execution refusal with a closed, HPO-owned reason."""
34
35 def __init__(self, reason: WindowPlanReason, message: str) -> None:
36 diagnostic = message.encode("utf-8", errors="replace")[:4096].decode(
37 "utf-8",
38 errors="ignore",
39 )
40 super().__init__(diagnostic)
41 self.with_failure("hpo_walkforward_unavailable", {"reason": reason})
42
43
44@dataclass(frozen=True)
46 """The exact additive v1 block, outside the strategy compilation identity."""
47
48 schema: str
49 build_path: str
50 sha256: str
51 planner_abi_version: int
52 engine_version: str
53 engine_abi_version: int
54 engine_headers_sha256: str
55 engine_static_library_sha256: str
56 platform_system: str
57 platform_machine: str
58 self_test_id: str
59
60 def __post_init__(self) -> None:
61 for field in fields(self):
62 value = getattr(self, field.name)
63 expected_type = (
64 int
65 if field.name in {"planner_abi_version", "engine_abi_version"}
66 else str
67 )
68 if type(value) is not expected_type or (
69 expected_type is str and (not value or "\0" in value)
70 ):
71 raise WindowPlanError(
72 "window_plan_manifest_invalid",
73 f"manifest.window_plan.{field.name} has an invalid type or value",
74 )
75 if (
76 self.schema != "pineforge-hpo-window-plan/v1"
77 or self.planner_abi_version != 1
78 or self.self_test_id != "selected-plan-utc-six-hours/v1"
79 or not 0 < self.engine_abi_version <= 0xFFFFFFFF
80 or not Path(self.build_pathbuild_path).is_absolute()
81 ):
82 raise WindowPlanError(
83 "window_plan_manifest_invalid",
84 "manifest.window_plan has an invalid schema, ABI, self-test or path",
85 )
86 for name in (
87 "sha256",
88 "engine_headers_sha256",
89 "engine_static_library_sha256",
90 ):
91 if re.fullmatch(r"[0-9a-f]{64}", getattr(self, name)) is None:
92 raise WindowPlanError(
93 "window_plan_manifest_invalid",
94 f"manifest.window_plan.{name} must be 64 lowercase hex characters",
95 )
96
97 def to_dict(self) -> dict[str, Any]:
98 return {field.name: getattr(self, field.name) for field in fields(self)}
99
100 @classmethod
101 def from_dict(cls, value: object) -> WindowPlanIdentity:
102 if not isinstance(value, Mapping) or set(value) != {
103 field.name for field in fields(cls)
104 }:
105 raise WindowPlanError(
106 "window_plan_manifest_invalid",
107 "manifest.window_plan must contain exactly the v1 identity fields",
108 )
109 return cls(**value)
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160def require_window_plan_block(
161 manifest: Mapping[str, Any],
162 provenance: Mapping[str, Any] | None = None,
163) -> dict[str, Any]:
164 """Admit selected metadata, including optional supplied provenance.
165
166 An explicit helper path cannot replace a missing expected identity. Ordinary
167 precompiled loading does not call this function; selected callers must do so.
168 This checks association metadata only, not plugin bytes or helper exports.
169 """
170
171 if not isinstance(manifest, Mapping) or (
172 provenance is not None and not isinstance(provenance, Mapping)
173 ):
174 raise WindowPlanError(
175 "window_plan_manifest_invalid",
176 "manifest and supplied provenance must be JSON objects",
177 )
178 if "window_plan" not in manifest:
179 if provenance is not None and "window_plan" in provenance:
180 WindowPlanIdentity.from_dict(provenance["window_plan"])
181 raise WindowPlanError(
182 "window_plan_identity",
183 "manifest.window_plan is missing but provenance.window_plan is present",
184 )
185 raise WindowPlanError(
186 "window_plan_manifest_missing",
187 "selected execution requires manifest.window_plan with the expected helper "
188 "identity; an explicit path alone cannot supply it",
189 )
190 identity = WindowPlanIdentity.from_dict(manifest["window_plan"])
191 if provenance is not None:
192 if "window_plan" not in provenance:
193 raise WindowPlanError(
194 "window_plan_identity",
195 "provenance.window_plan is missing; the metadata pair is incomplete",
196 )
197 companion = WindowPlanIdentity.from_dict(provenance["window_plan"])
198 if companion != identity:
199 raise WindowPlanError(
200 "window_plan_identity",
201 "manifest.window_plan differs from provenance.window_plan",
202 )
203 _check_compile_identity(
204 companion,
205 provenance.get("request_identity"),
206 "provenance",
207 )
208 if manifest.get("request_identity") != provenance.get("request_identity"):
209 raise WindowPlanError(
210 "window_plan_identity",
211 "manifest and provenance request_identity differ",
212 )
213 _check_compile_identity(identity, manifest.get("request_identity"), "manifest")
214 return identity.to_dict()
215
216
217def derive_window_plan_path(engine_layout: _EngineLayout) -> Path | None:
218 """Derive only the sibling of archive candidate 1 or 2; never search."""
219
220 from .artifact import ArtifactBuildError, _platform_link_mode
221
222 candidates = (
223 engine_layout.root / "build" / "lib" / "libpineforge.a",
224 engine_layout.root / "lib" / "libpineforge.a",
225 )
226 archive = engine_layout.selected_archive_path or engine_layout.static_library
227 if archive not in candidates:
228 return None
229 try:
230 suffix, _ = _platform_link_mode()
231 except ArtifactBuildError as error:
232 raise WindowPlanError(
233 "window_plan_path",
234 "window_plan derivation requires a supported platform",
235 ) from error
236 return archive.with_name(f"libpineforge_window_plan{suffix}")
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293def associate_window_plan(engine_layout: _EngineLayout) -> dict[str, Any] | None:
294 """Record a controlled build's optional sibling, without changing compile keys."""
295
296 path = derive_window_plan_path(engine_layout)
297 if path is None or not path.is_file():
298 return None
299 return _associate_window_plan_path(engine_layout, path)
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328def resolve_window_plan_path(
329 explicit_path: str | os.PathLike[str] | None,
330 engine_root: str | os.PathLike[str] | None,
331 recorded_block: WindowPlanIdentity | Mapping[str, Any],
332) -> Path:
333 """Resolve a run-machine path; call :func:`verify_window_plan` before handoff.
334
335 Explicit paths take precedence with no fallback. Derivation uses only a
336 caller-supplied local engine root with matching compile content. The recorded
337 build_path is audit data and is never used for lookup.
338 """
339
340 from .artifact import ArtifactBuildError, ArtifactBuilder
341
342 identity = _identity(recorded_block)
343 explicit = (
344 _absolute_helper_path(explicit_path) if explicit_path is not None else None
345 )
346 _check_fields(
347 {"system": platform.system(), "machine": platform.machine()},
348 {"system": identity.platform_system, "machine": identity.platform_machine},
349 "runtime.platform",
350 )
351 if explicit is not None:
352 return explicit
353 if engine_root is None:
354 raise WindowPlanError(
355 "window_plan_path",
356 "an absolute window_plan path is required without a local engine_root",
357 )
358 try:
359 engine = ArtifactBuilder(
360 engine_root=engine_root,
361 cache_dir=engine_root,
362 )._resolve_engine_layout()
363 except (ArtifactBuildError, OSError, RuntimeError, ValueError) as error:
364 raise WindowPlanError(
365 "window_plan_identity",
366 f"cannot establish local engine association: {engine_root}: {error}",
367 ) from error
368 _check_compile_identity(
369 identity,
370 {
371 "engine": engine.identity_dict(),
372 "platform": {"system": platform.system(), "machine": platform.machine()},
373 },
374 "local engine",
375 )
376 derived = derive_window_plan_path(engine)
377 if derived is None:
378 raise WindowPlanError(
379 "window_plan_path",
380 "the selected engine archive has no derivable window_plan sibling; "
381 "supply an explicit absolute path",
382 )
383 return _absolute_helper_path(derived)
384
385
386def verify_window_plan(
387 block: WindowPlanIdentity | Mapping[str, Any],
388 path: str | os.PathLike[str],
389) -> None:
390 """Check only the helper file's SHA-256 against the recorded expected bytes.
391
392 This pathname-based hash check is not race-free loading. Lane 2's native
393 consumer must copy/hash an opened file into a private snapshot and load that
394 verified snapshot, then validate exports, ABI and the frozen self-test.
395 """
396
397 from .artifact import _file_sha256
398
399 identity = _identity(block)
400 resolved = _absolute_helper_path(path)
401 try:
402 actual = _file_sha256(resolved)
403 except OSError as error:
404 raise WindowPlanError(
405 "window_plan_missing",
406 f"cannot hash window_plan helper: {resolved}: {error}",
407 ) from error
408 if actual != identity.sha256:
409 raise WindowPlanError(
410 "window_plan_hash_mismatch",
411 f"window_plan helper SHA-256 differs from manifest.window_plan.sha256: "
412 f"{resolved}",
413 )
414
415
416
417
418
419
420
421
422
423
424
with_failure(self, str|None code, dict[str, Any]|None args, str origin="hpo")
Definition error.py:25
None __init__(self, WindowPlanReason reason, str message)
WindowPlanIdentity from_dict(cls, object value)