Skip to content

Commit 652f55a

Browse files
Pigbibicodex
andcommitted
feat: add descriptor-relative qpk vnext n2 store
Co-Authored-By: Codex <noreply@openai.com>
1 parent a06a99f commit 652f55a

3 files changed

Lines changed: 352 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# QPK-N2 descriptor-relative store
2+
3+
This fresh reslice is local-only and consumes only the merged N1 vNext contract.
4+
It opens and traverses every path component relative to verified directory file
5+
descriptors with `O_NOFOLLOW`; pathname `resolve()` checks are not used as a
6+
security boundary. Missing directories are created one segment at a time and
7+
new ancestor descriptors are fsynced. Payload files are fsynced and installed
8+
with create-only linking, preserving write-once/idempotent semantics under
9+
concurrency. Selector listing decodes every candidate before returning it.
10+
11+
The store accepts durable records only, rejects ephemeral before filesystem I/O,
12+
has exact reads and explicit selector listing, and defers latest. Legacy paths,
13+
network/S3, callers, orchestrators, exporters, and live behavior are excluded.
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
"""Descriptor-relative local store for the clean-slate qpk-vnext/result/v2 contract."""
2+
from __future__ import annotations
3+
4+
import errno
5+
import json
6+
import os
7+
import stat
8+
import tempfile
9+
from pathlib import Path
10+
from typing import Any
11+
12+
from quant_platform_kit.strategy_lifecycle.qpk_vnext_n1 import (
13+
NAMESPACE, ContractError, ResultContract, _segment, decode_wire,
14+
)
15+
16+
17+
class StoreError(ValueError):
18+
"""Sanitized isolated-store failure."""
19+
20+
21+
def _fail() -> None:
22+
raise StoreError("invalid qpk-vnext isolated store operation")
23+
24+
25+
class IsolatedResultStore:
26+
"""Filesystem store using descriptor-relative, no-follow operations only."""
27+
28+
_DIR_FLAGS = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0)
29+
_FILE_FLAGS = os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0)
30+
31+
def __init__(self, root: str | os.PathLike[str]) -> None:
32+
if not isinstance(root, (str, os.PathLike)) or not os.name == "posix":
33+
_fail()
34+
self.root = Path(root).expanduser()
35+
if not self.root.is_absolute():
36+
_fail()
37+
38+
@staticmethod
39+
def _fsync(fd: int) -> None:
40+
try:
41+
os.fsync(fd)
42+
except OSError:
43+
_fail()
44+
45+
def _root_fd(self) -> int:
46+
try:
47+
return os.open(self.root, self._DIR_FLAGS)
48+
except OSError:
49+
_fail()
50+
51+
@staticmethod
52+
def _validate_key(key: str) -> list[str]:
53+
if not isinstance(key, str) or "\\" in key:
54+
_fail()
55+
parts = key.split("/")
56+
if len(parts) != 11 or parts[:3] != NAMESPACE.split("/") or not parts[-1].endswith(".json"):
57+
_fail()
58+
if any(not part or part in {".", ".."} for part in parts):
59+
_fail()
60+
for part in parts[3:-1]:
61+
try:
62+
_segment(part.removeprefix("i").removeprefix("p") if part[:1] in {"i", "p"} else part)
63+
except ContractError:
64+
_fail()
65+
return parts
66+
67+
@classmethod
68+
def _open_child_dir(cls, parent: int, name: str, *, create: bool, created: list[int]) -> int:
69+
try:
70+
return os.open(name, cls._DIR_FLAGS, dir_fd=parent)
71+
except FileNotFoundError:
72+
if not create:
73+
_fail()
74+
try:
75+
os.mkdir(name, mode=0o700, dir_fd=parent)
76+
cls._fsync(parent)
77+
except FileExistsError:
78+
pass
79+
except OSError:
80+
_fail()
81+
try:
82+
child = os.open(name, cls._DIR_FLAGS, dir_fd=parent)
83+
except OSError:
84+
_fail()
85+
created.append(child)
86+
return child
87+
except OSError:
88+
_fail()
89+
90+
@classmethod
91+
def _walk(cls, root_fd: int, parts: list[str], *, create: bool) -> tuple[int, list[int]]:
92+
current = root_fd
93+
opened: list[int] = []
94+
for part in parts:
95+
current = cls._open_child_dir(current, part, create=create, created=opened)
96+
return current, opened
97+
98+
@staticmethod
99+
def _wire_bytes(contract: ResultContract) -> bytes:
100+
if not isinstance(contract, ResultContract) or contract.persist_mode != "durable":
101+
_fail()
102+
try:
103+
checked = decode_wire(contract.to_wire())
104+
return json.dumps(checked.to_wire(), ensure_ascii=False, sort_keys=True,
105+
separators=(",", ":"), allow_nan=False).encode("utf-8")
106+
except (ContractError, TypeError, ValueError, UnicodeError):
107+
_fail()
108+
109+
def put(self, contract: ResultContract) -> str:
110+
payload = self._wire_bytes(contract)
111+
parts = self._validate_key(contract.key)
112+
root_fd = self._root_fd()
113+
parent_fd = None
114+
created: list[int] = []
115+
temp_name: str | None = None
116+
try:
117+
parent_fd, created = self._walk(root_fd, parts[:-1], create=True)
118+
target = parts[-1]
119+
try:
120+
existing_fd = os.open(target, self._FILE_FLAGS, dir_fd=parent_fd)
121+
except FileNotFoundError:
122+
existing_fd = None
123+
except OSError:
124+
_fail()
125+
if existing_fd is not None:
126+
try:
127+
existing = os.read(existing_fd, len(payload) + 1)
128+
finally:
129+
os.close(existing_fd)
130+
if existing == payload:
131+
return "idempotent"
132+
_fail()
133+
for _ in range(8):
134+
candidate = f".{target}.{os.getpid()}.{next(tempfile._RandomNameSequence())}.tmp"
135+
try:
136+
fd = os.open(candidate, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0), 0o600, dir_fd=parent_fd)
137+
temp_name = candidate
138+
break
139+
except FileExistsError:
140+
continue
141+
except OSError:
142+
_fail()
143+
else:
144+
_fail()
145+
with os.fdopen(fd, "wb") as handle:
146+
handle.write(payload)
147+
handle.flush()
148+
os.fsync(handle.fileno())
149+
try:
150+
os.link(temp_name, target, src_dir_fd=parent_fd, dst_dir_fd=parent_fd, follow_symlinks=False)
151+
except FileExistsError:
152+
try:
153+
existing_fd = os.open(target, self._FILE_FLAGS, dir_fd=parent_fd)
154+
existing = os.read(existing_fd, len(payload) + 1)
155+
os.close(existing_fd)
156+
except OSError:
157+
_fail()
158+
if existing != payload:
159+
_fail()
160+
return "idempotent"
161+
self._fsync(parent_fd)
162+
for fd in reversed(created):
163+
self._fsync(fd)
164+
os.unlink(temp_name, dir_fd=parent_fd)
165+
temp_name = None
166+
self._fsync(parent_fd)
167+
return "created"
168+
except (OSError, ValueError):
169+
_fail()
170+
finally:
171+
if temp_name and parent_fd is not None:
172+
try:
173+
os.unlink(temp_name, dir_fd=parent_fd)
174+
except OSError:
175+
pass
176+
for fd in reversed(created):
177+
try:
178+
os.close(fd)
179+
except OSError:
180+
pass
181+
os.close(root_fd)
182+
183+
def get(self, key: str) -> ResultContract:
184+
parts = self._validate_key(key)
185+
root_fd = self._root_fd()
186+
parent_fd = None
187+
try:
188+
parent_fd, opened = self._walk(root_fd, parts[:-1], create=False)
189+
fd = os.open(parts[-1], self._FILE_FLAGS, dir_fd=parent_fd)
190+
try:
191+
data: Any = json.loads(os.read(fd, 10_000_000).decode("utf-8"))
192+
finally:
193+
os.close(fd)
194+
item = decode_wire(data)
195+
if item.key != key:
196+
_fail()
197+
return item
198+
except (OSError, UnicodeError, json.JSONDecodeError, ContractError):
199+
_fail()
200+
finally:
201+
for fd in reversed(opened if 'opened' in locals() else []):
202+
os.close(fd)
203+
os.close(root_fd)
204+
205+
def list_keys(self, *, domain: str, profile: str, timing: str) -> tuple[str, ...]:
206+
try:
207+
domain, profile = _segment(domain), _segment(profile)
208+
except ContractError:
209+
_fail()
210+
if timing not in {"next_open", "next_close"}:
211+
_fail()
212+
root_fd = self._root_fd()
213+
profile_fd = None
214+
try:
215+
profile_fd, opened = self._walk(root_fd, NAMESPACE.split("/") + [domain, profile], create=False)
216+
found: list[str] = []
217+
218+
def scan(fd: int, rel: list[str]) -> None:
219+
try:
220+
names = os.listdir(fd)
221+
except OSError:
222+
_fail()
223+
for name in names:
224+
if not name or name in {".", ".."}:
225+
continue
226+
try:
227+
info = os.stat(name, dir_fd=fd, follow_symlinks=False)
228+
except OSError:
229+
_fail()
230+
if stat.S_ISLNK(info.st_mode):
231+
_fail()
232+
if stat.S_ISDIR(info.st_mode):
233+
child = os.open(name, self._DIR_FLAGS, dir_fd=fd)
234+
try:
235+
scan(child, rel + [name])
236+
finally:
237+
os.close(child)
238+
elif name.endswith(".json"):
239+
key = "/".join(NAMESPACE.split("/") + [domain, profile] + rel + [name])
240+
parts = self._validate_key(key)
241+
if parts[7] != timing:
242+
continue
243+
item = self.get(key)
244+
found.append(item.key)
245+
246+
scan(profile_fd, [])
247+
return tuple(sorted(set(found)))
248+
finally:
249+
for fd in reversed(opened if 'opened' in locals() else []):
250+
os.close(fd)
251+
os.close(root_fd)

tests/test_qpk_vnext_n2_store.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from __future__ import annotations
2+
3+
from concurrent.futures import ThreadPoolExecutor
4+
from dataclasses import replace
5+
6+
import pytest
7+
8+
from quant_platform_kit.strategy_lifecycle.qpk_vnext_n1 import ResultContract
9+
from quant_platform_kit.strategy_lifecycle.qpk_vnext_n2_store import IsolatedResultStore, StoreError
10+
11+
12+
def contract(**changes):
13+
values = dict(domain="us_equity", profile="SOXL", timing="next_open", identity_version=1,
14+
persist_mode="durable", strategy_id="strategy", run_id="run-1",
15+
param_set_id="baseline", param_version=1, source_revision="rev1",
16+
computed_at="2026-07-15T00:00:00.000000Z", params={"x": 1})
17+
values.update(changes)
18+
return ResultContract(**values)
19+
20+
21+
def test_write_read_idempotent_and_ephemeral_side_effect_free(tmp_path):
22+
store = IsolatedResultStore(tmp_path)
23+
item = contract()
24+
assert store.put(item) == "created"
25+
assert store.put(item) == "idempotent"
26+
assert store.get(item.key) == item
27+
before = sorted(tmp_path.rglob("*"))
28+
with pytest.raises(StoreError):
29+
store.put(replace(item, persist_mode="ephemeral"))
30+
assert sorted(tmp_path.rglob("*")) == before
31+
32+
33+
def test_symlink_root_and_key_segments_fail_closed(tmp_path):
34+
target = tmp_path / "target"
35+
target.mkdir()
36+
link = tmp_path / "link"
37+
link.symlink_to(target, target_is_directory=True)
38+
store = IsolatedResultStore(link)
39+
with pytest.raises(StoreError):
40+
store.get(contract().key)
41+
store = IsolatedResultStore(target)
42+
with pytest.raises(StoreError):
43+
store.get("qpk-vnext/result/v2/us_equity/SOXL/../run/next_open/i1/p1/x.json")
44+
item = contract()
45+
store.put(item)
46+
outside = tmp_path / "outside"
47+
outside.mkdir()
48+
leaf = target.joinpath(*item.key.split("/")[:-1])
49+
leaf.rename(target / "leaf-backup")
50+
leaf.symlink_to(outside, target_is_directory=True)
51+
with pytest.raises(StoreError):
52+
store.get(item.key)
53+
54+
55+
def test_concurrent_identical_and_conflicting_writers(tmp_path):
56+
store = IsolatedResultStore(tmp_path)
57+
item = contract()
58+
with ThreadPoolExecutor(max_workers=8) as pool:
59+
outcomes = list(pool.map(lambda _: store.put(item), range(8)))
60+
assert outcomes.count("created") == 1
61+
assert outcomes.count("idempotent") == 7
62+
with pytest.raises(StoreError):
63+
store.put(contract(computed_at="2026-07-16T00:00:00.000000Z"))
64+
65+
66+
def test_validated_listing_exact_timing_and_corrupt_rejection(tmp_path):
67+
store = IsolatedResultStore(tmp_path)
68+
first = contract()
69+
second = contract(timing="next_close")
70+
store.put(first)
71+
store.put(second)
72+
assert store.list_keys(domain="us_equity", profile="SOXL", timing="next_open") == (first.key,)
73+
assert store.list_keys(domain="us_equity", profile="SOXL", timing="next_close") == (second.key,)
74+
path = tmp_path / second.key
75+
path.write_bytes(b"{}")
76+
with pytest.raises(StoreError):
77+
store.list_keys(domain="us_equity", profile="SOXL", timing="next_close")
78+
for profile in ("..", "SOXL/../x"):
79+
with pytest.raises(StoreError):
80+
store.list_keys(domain="us_equity", profile=profile, timing="next_open")
81+
82+
83+
def test_temp_cleanup_on_atomic_failure(tmp_path, monkeypatch):
84+
store = IsolatedResultStore(tmp_path)
85+
monkeypatch.setattr("quant_platform_kit.strategy_lifecycle.qpk_vnext_n2_store.os.link", lambda *_a, **_k: (_ for _ in ()).throw(OSError("injected")))
86+
with pytest.raises(StoreError):
87+
store.put(contract())
88+
assert not list(tmp_path.rglob("*.tmp"))

0 commit comments

Comments
 (0)