From 190a9feb98dd7bf4b5b1d8490dd98d45098068cb Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:25:22 +0800 Subject: [PATCH 01/15] =?UTF-8?q?feat(compat):=20=E6=94=B6=E6=95=9B?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=8E=9F=E8=AF=AD=EF=BC=8C=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=20Windows=20=E5=85=BC=E5=AE=B9=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此前包内直接使用 fcntl / os.pread / os.pwrite / os.getuid / 目录 fsync, 其中 infrastructure/checkpoint.py 是顶层 import fcntl —— 在 Windows 上连 import pyvdisk 都会失败,不只是功能缺失。 新增 pyvdisk/compat.py 作为唯一的平台原语入口: - 定位读写:POSIX 用 os.pread/os.pwrite,Windows 退化为互斥锁保护的 lseek+read/write(全局 RLock,保证定位与读写不可分割); - 文件锁:POSIX 用 fcntl.flock,Windows 用 msvcrt.locking 锁整个文件区间。 刻意不用 LK_LOCK:它在 Windows 上有约 10 秒超时后会直接抛错,而 flock 是无限等待;这里用 LK_NBLCK 轮询自己实现 blocking/timeout 语义; - 目录 fsync:Windows 无法把目录当文件打开,返回 False 表示"未执行"而非成功; - uid/gid:Windows 返回 0,另提供 uid_or/gid_or 以免把 root(0) 当成"未设置"; - can_symlink():Windows 需要开发者模式,探测结果供调用方决定是否降级。 四个使用点全部改走 compat:disk.py、infrastructure/checkpoint.py、 vscript/host.py、fuse_mount.py。 tests/test_compat.py 覆盖两层: - 真实平台上的行为(定位读写、锁竞争、超时放弃、解锁重取、目录 fsync); - 用 compat.use_implementation("windows") + 替身 msvcrt 在 Linux 上真正执行 模拟实现,包括锁竞争与 timeout 分支,并在模拟下跑通 VFS/DataDisk/事务/ 检查点的完整往返,以及与原生实现的逐字节对照。 注意:替身锁是进程内的,无法证明两个**进程**之间互斥,这需要 Windows runner。 最后一条守卫测试固定住"只有 compat.py 可以直接触碰平台原语"这一约束—— Windows 缺口正是从这条约束缺失开始的。 --- pyvdisk/compat.py | 283 ++++++++++++++++++++++++++ pyvdisk/disk.py | 84 ++------ pyvdisk/fuse_mount.py | 5 +- pyvdisk/infrastructure/checkpoint.py | 38 +--- pyvdisk/vscript/host.py | 14 +- tests/test_compat.py | 285 +++++++++++++++++++++++++++ 6 files changed, 592 insertions(+), 117 deletions(-) create mode 100644 pyvdisk/compat.py create mode 100644 tests/test_compat.py diff --git a/pyvdisk/compat.py b/pyvdisk/compat.py new file mode 100644 index 0000000..ea85bbc --- /dev/null +++ b/pyvdisk/compat.py @@ -0,0 +1,283 @@ +"""Platform compatibility layer: the one place the OS primitives live. + +Everything in pyvdisk that is not plain buffered file IO is funnelled through +this module: + +====================== ========================== ============================== +primitive POSIX Windows +====================== ========================== ============================== +whole-file lock ``fcntl.flock(LOCK_EX)`` ``msvcrt.locking`` byte range +positional read ``os.pread`` ``os.lseek`` + ``os.read`` +positional write ``os.pwrite`` ``os.lseek`` + ``os.write`` +directory fsync ``os.fsync`` on the dir fd no-op (no directory handles) +uid / gid ``os.getuid/getgid`` ``0`` +====================== ========================== ============================== + +Why a lock on the emulated positional IO: ``os.pread``/``os.pwrite`` are +atomic, ``lseek`` + ``read`` is not. Two threads sharing one handle could +interleave and read the wrong block, so the emulation serialises through a +module-level lock. That costs throughput on Windows only, and only while a +block IO is in flight; it is not a global lock over the whole disk. + +The Windows byte-range lock covers ``[0, LOCK_BYTES)`` -- the same "whole file" +scope ``flock`` gives us, because every handle in this package locks from +offset 0. It is advisory in the same sense ``flock`` is: both processes have +to cooperate by calling this module. + +No third-party imports, and importing this module never fails: ``describe()`` +reports which implementation is live, which is what the tests and the +``pyvdisk doctor`` style diagnostics read. +""" + +from __future__ import annotations + +import contextlib +import os +import sys +import threading +import time + +try: # POSIX + import fcntl as _fcntl +except ImportError: # pragma: no cover - platform dependent + _fcntl = None + +try: # Windows + import msvcrt as _msvcrt +except ImportError: + _msvcrt = None + +IS_WINDOWS = sys.platform.startswith("win") +IS_POSIX = os.name == "posix" + +#: Byte range the Windows emulation locks: every caller locks from offset 0, so +#: a single wide range is equivalent to ``flock``'s whole-file scope. +LOCK_BYTES = 0x7FFFFFFF + +#: How long ``lock()`` waits between attempts when it cannot block in the kernel. +POLL_SECONDS = 0.01 + +#: Positional IO is emulated with a shared lock unless the OS provides real +#: ``pread``/``pwrite``. +_HAS_POSITIONAL = hasattr(os, "pread") and hasattr(os, "pwrite") + +_POSITIONAL_LOCK = threading.RLock() + +# Test seams: the emulation is exercised on POSIX by forcing it and injecting a +# stand-in for ``msvcrt``. Production code never touches these. +_FORCED: str | None = None + + +def implementation() -> str: + """Return the live implementation name: ``"posix"`` or ``"windows"``.""" + if _FORCED is not None: + return _FORCED + return "posix" if (_HAS_POSITIONAL and _fcntl is not None) else "windows" + + +@contextlib.contextmanager +def use_implementation(name: str): + """Force an implementation for the duration of the block (tests only).""" + global _FORCED + previous, _FORCED = _FORCED, name + try: + yield + finally: + _FORCED = previous + + +def describe() -> dict: + """What this platform gives us, for diagnostics and test assertions.""" + return { + "platform": sys.platform, + "implementation": implementation(), + "positional_io": "os.pread/os.pwrite" if _HAS_POSITIONAL else "lseek+read/write", + "locking": "fcntl.flock" if _fcntl is not None else ("msvcrt.locking" if _msvcrt is not None else "none"), + "directory_fsync": IS_POSIX, + "uid_gid": hasattr(os, "getuid") and hasattr(os, "getgid"), + "symlinks": hasattr(os, "symlink"), + } + + +# ---- positional IO ------------------------------------------------------- + +def pread(fd: int, length: int, offset: int) -> bytes: + """Read up to ``length`` bytes at ``offset`` without moving the file cursor. + + Returns fewer bytes only at end of file, like ``os.pread``. + """ + if _HAS_POSITIONAL and implementation() == "posix": + return os.pread(fd, length, offset) + with _POSITIONAL_LOCK: + os.lseek(fd, offset, os.SEEK_SET) + return os.read(fd, length) + + +def pwrite(fd: int, data: bytes, offset: int) -> int: + """Write ``data`` at ``offset`` without moving the file cursor. + + Returns the number of bytes written, like ``os.pwrite``. + """ + if _HAS_POSITIONAL and implementation() == "posix": + return os.pwrite(fd, data, offset) + with _POSITIONAL_LOCK: + os.lseek(fd, offset, os.SEEK_SET) + return os.write(fd, data) + + +# ---- whole-file locking -------------------------------------------------- + +def _retry(attempt, *, blocking: bool, timeout: float | None) -> bool: + """Poll ``attempt`` until it succeeds, the timeout expires, or once if non-blocking. + + ``LK_LOCK`` gives up after about ten seconds on Windows, so the emulation + never uses it: it polls ``LK_NBLCK`` instead and keeps the wait semantics + ``flock`` has (wait forever by default, or for ``timeout`` seconds). + """ + if blocking and timeout is None: + while True: + try: + attempt() + return True + except OSError: + time.sleep(POLL_SECONDS) + deadline = None if timeout is None else time.monotonic() + timeout + while True: + try: + attempt() + return True + except OSError: + if not blocking: + return False + if deadline is not None and time.monotonic() >= deadline: + return False + time.sleep(POLL_SECONDS) + + +def _windows_locking(fd: int, *, blocking: bool, timeout: float | None) -> bool: + if _msvcrt is None: + raise OSError("no locking primitive available on this platform") + + def attempt(): + os.lseek(fd, 0, os.SEEK_SET) + _msvcrt.locking(fd, _msvcrt.LK_NBLCK, LOCK_BYTES) + + return _retry(attempt, blocking=blocking, timeout=timeout) + + +def lock(fd: int, *, blocking: bool = True, timeout: float | None = None) -> bool: + """Take an exclusive whole-file lock. + + Returns True when the lock is held. With ``blocking=False`` a contended + lock returns False instead of waiting; with a ``timeout`` it gives up after + that many seconds. Raises OSError only when the platform offers no locking + primitive at all. + """ + if implementation() == "posix" and _fcntl is not None: + if blocking and timeout is None: + _fcntl.flock(fd, _fcntl.LOCK_EX) + return True + + def attempt(): + _fcntl.flock(fd, _fcntl.LOCK_EX | _fcntl.LOCK_NB) + + return _retry(attempt, blocking=blocking, timeout=timeout) + return _windows_locking(fd, blocking=blocking, timeout=timeout) + + +def unlock(fd: int) -> None: + """Release a lock taken by :func:`lock`. Never raises on a stale handle.""" + try: + if implementation() == "posix" and _fcntl is not None: + _fcntl.flock(fd, _fcntl.LOCK_UN) + elif _msvcrt is not None: + os.lseek(fd, 0, os.SEEK_SET) + _msvcrt.locking(fd, _msvcrt.LK_UNLCK, LOCK_BYTES) + except OSError: + # Losing the lock because the descriptor is gone is not an error worth + # raising: close() is on every teardown path, including failure paths. + pass + + +# ---- durability ---------------------------------------------------------- + +def fsync_dir(path: str) -> bool: + """Flush a directory entry so a rename inside it survives a crash. + + Returns True when the platform actually flushed something. Windows cannot + open a directory as a file and has no directory-fsync, so this is a no-op + there and returns False -- NTFS journals the rename itself. + """ + if not IS_POSIX or not hasattr(os, "O_DIRECTORY"): + return False + try: + fd = os.open(path, os.O_RDONLY | getattr(os, "O_DIRECTORY", 0)) + except OSError: + return False + try: + os.fsync(fd) + return True + except OSError: + return False + finally: + with contextlib.suppress(OSError): + os.close(fd) + + +# ---- identity ------------------------------------------------------------ + +def uid() -> int: + """Effective uid, or 0 where the platform has no such notion.""" + getter = getattr(os, "getuid", None) + return int(getter()) if getter is not None else 0 + + +def gid() -> int: + """Effective gid, or 0 where the platform has no such notion.""" + getter = getattr(os, "getgid", None) + return int(getter()) if getter is not None else 0 + + +def uid_or(default: int) -> int: + """Effective uid, or ``default`` where the platform has no such notion. + + Prefer this over ``uid() or default``: uid 0 is root, not "unset". + """ + getter = getattr(os, "getuid", None) + return int(getter()) if getter is not None else int(default) + + +def gid_or(default: int) -> int: + """Effective gid, or ``default`` where the platform has no such notion.""" + getter = getattr(os, "getgid", None) + return int(getter()) if getter is not None else int(default) + + +def can_symlink(directory: str) -> bool: + """Whether a real symlink can be created in ``directory`` right now. + + Windows only allows this with developer mode or elevation, so callers that + want to exercise symlink paths have to ask rather than assume. + """ + if not hasattr(os, "symlink"): + return False + target = os.path.join(directory, ".pyvdisk-symlink-probe") + link = target + ".lnk" + try: + with contextlib.suppress(OSError): + os.unlink(link) + os.symlink(target, link) + except (OSError, NotImplementedError): + return False + finally: + with contextlib.suppress(OSError): + os.unlink(link) + return True + + +__all__ = [ + "IS_WINDOWS", "IS_POSIX", "LOCK_BYTES", + "implementation", "use_implementation", "describe", + "pread", "pwrite", "lock", "unlock", "fsync_dir", + "uid", "gid", "uid_or", "gid_or", "can_symlink", +] diff --git a/pyvdisk/disk.py b/pyvdisk/disk.py index d384b96..63a3126 100644 --- a/pyvdisk/disk.py +++ b/pyvdisk/disk.py @@ -7,87 +7,26 @@ from __future__ import annotations import os -import threading import warnings import contextlib from typing import Optional -try: # POSIX advisory locking; Windows remains a safe no-op fallback. - import fcntl -except ImportError: # pragma: no cover - platform dependent - fcntl = None +from . import compat DEFAULT_BLOCK_SIZE = 4096 -# ---- 定位 IO(pread/pwrite)的可移植层 ------------------------------------- -# -# os.pread / os.pwrite 只在 POSIX 上存在,Windows 的 CPython 没有这两个函数。 -# 它们位于块设备这一层,每一次读/写一个块都要经过,所以缺了它们整个包在 -# Windows 上一个用例都跑不了。这里补一个等价实现:在同一块句柄上 -# lseek -> read/write -> lseek 回原位。 -# -# 与 pread/pwrite 的差异只有"不是原子的"这一点,而这在本项目里是可接受的: -# * 镜像句柄以 buffering=0 打开,os.read/os.write 直达 OS,绕过 Python 缓冲, -# "跨句柄立即可见"的语义保持不变; -# * 同一进程内的并发由 FS 的读写锁(fs.py 的 _read_locked / _write_locked) -# 串行化,这里再按 fd 加一道锁,保证 lseek 与 read 之间不被同句柄的另一次 -# 定位 IO 插队; -# * 跨进程互斥仍依赖 flock,Windows 上没有 flock, disk.py 顶部已按 no-op 降级, -# 多进程共享同一镜像的用法因此只在 POSIX 上有保证。 -_HAS_POSITIONAL_IO = hasattr(os, "pread") and hasattr(os, "pwrite") -_PIO_LOCKS: dict = {} -_PIO_LOCKS_GUARD = threading.Lock() - - -def _pio_lock(fd: int) -> threading.Lock: - """每个镜像句柄一把定位 IO 锁(fd 复用只会多抢一次锁,不影响正确性)。""" - with _PIO_LOCKS_GUARD: - lock = _PIO_LOCKS.get(fd) - if lock is None: - lock = _PIO_LOCKS[fd] = threading.Lock() - return lock - - -def _pread(f, length: int, offset: int) -> bytes: - """在 offset 处读最多 length 字节,不改变句柄自身的使用方式。""" - if _HAS_POSITIONAL_IO: - return os.pread(f.fileno(), length, offset) - # 走文件对象而不是 os.lseek/os.read:同一个句柄上还会发生 - # f.truncate()(mkfs/grow),Windows 下让 CRT 与 FileIO 各自记一份位置 - # 会读到错位的块。统一用文件对象,位置就只有一份。 - with _pio_lock(f.fileno()): - saved = f.tell() - f.seek(offset) - try: - return f.read(length) - finally: - f.seek(saved) - - -def _pwrite(f, data, offset: int) -> int: - """在 offset 处写 data,返回写入字节数。""" - if _HAS_POSITIONAL_IO: - return os.pwrite(f.fileno(), data, offset) - with _pio_lock(f.fileno()): - saved = f.tell() - f.seek(offset) - try: - return f.write(data) - finally: - f.seek(saved) - - def _pread_all(f, offset: int, length: int) -> bytes: """从文件 f 的 offset 处读取 length 字节,保证读满(EOF 除外)。 - 使用 os.pread:原子定位读取,不依赖文件游标,且绕过 Python 缓冲。 + 使用 compat.pread:原子定位读取,不依赖文件游标,且绕过 Python 缓冲。 + POSIX 上是 os.pread;Windows 上退化为加锁的 seek+read。 """ chunks = [] remaining = length cur = offset while remaining > 0: - n = _pread(f, remaining, cur) + n = compat.pread(f.fileno(), remaining, cur) if not n: break # EOF chunks.append(n) @@ -102,14 +41,15 @@ def _pread_all(f, offset: int, length: int) -> bytes: def _pwrite_all(f, offset: int, data: bytes) -> None: """向文件 f 的 offset 处写入 data,保证写满。 - 使用 os.pwrite:原子定位写入,绕过 Python 缓冲,跨句柄立即可见。 + 使用 compat.pwrite:定位写入,绕过 Python 缓冲,跨句柄立即可见。 + POSIX 上是 os.pwrite;Windows 上退化为加锁的 seek+write。 """ view = memoryview(data) cur = offset written = 0 total = len(data) while written < total: - n = _pwrite(f, view[written:], cur) + n = compat.pwrite(f.fileno(), view[written:], cur) cur += n written += n @@ -162,12 +102,14 @@ def open(self, mode: str = "r+b") -> "VirtualDisk": # 这样多个文件句柄(多线程各自 open 同一镜像)能通过 OS 页缓存 # 立即看到彼此的写入,避免陈旧读。 self._f = open(self.path, mode, buffering=0) - if fcntl is not None and any(c in mode for c in "wa+"): + if any(c in mode for c in "wa+"): try: # Blocking acquisition serializes writers across threads/processes. # Non-blocking failure caused ordinary concurrent VFS operations to # fail spuriously instead of waiting for the image lock. - fcntl.flock(self._f.fileno(), fcntl.LOCK_EX) + # compat.lock is fcntl.flock on POSIX and a whole-file msvcrt byte + # range on Windows, so both platforms actually serialize. + compat.lock(self._f.fileno()) self._locked = True except OSError: self._f.close(); self._f = None @@ -178,8 +120,8 @@ def open(self, mode: str = "r+b") -> "VirtualDisk": def close(self) -> None: if self._f is not None: self._f.flush() - if self._locked and fcntl is not None: - fcntl.flock(self._f.fileno(), fcntl.LOCK_UN) + if self._locked: + compat.unlock(self._f.fileno()) self._f.close() self._f = None self._locked = False diff --git a/pyvdisk/fuse_mount.py b/pyvdisk/fuse_mount.py index 99dcfd9..1058e0d 100644 --- a/pyvdisk/fuse_mount.py +++ b/pyvdisk/fuse_mount.py @@ -21,6 +21,7 @@ import time from typing import Any, Optional +from . import compat from .fs import FSError, T_DIR, T_FILE, T_SYMLINK from .vfs import VFS @@ -62,8 +63,8 @@ def _getattr(self, path: str): "st_mode": mode, "st_dev": 0, "st_nlink": st.nlink, - "st_uid": os.getuid() if hasattr(os, "getuid") else st.uid, - "st_gid": os.getgid() if hasattr(os, "getgid") else st.gid, + "st_uid": compat.uid_or(st.uid), + "st_gid": compat.gid_or(st.gid), "st_size": st.size, "st_atime": st.atime or now, "st_mtime": st.mtime or now, diff --git a/pyvdisk/infrastructure/checkpoint.py b/pyvdisk/infrastructure/checkpoint.py index 73bf62c..08f733e 100644 --- a/pyvdisk/infrastructure/checkpoint.py +++ b/pyvdisk/infrastructure/checkpoint.py @@ -12,39 +12,7 @@ import time from pathlib import Path -try: # POSIX 建议锁;与 pyvdisk/disk.py 的写法保持一致。 - import fcntl -except ImportError: # pragma: no cover - platform dependent - fcntl = None - -try: # Windows 用字节范围锁顶上,保住"跨进程互斥"这条契约而不是直接降级。 - import msvcrt -except ImportError: # pragma: no cover - platform dependent - msvcrt = None - - -def _acquire(fd: int) -> None: - if fcntl is not None: - fcntl.flock(fd, fcntl.LOCK_EX) - return - if msvcrt is None: # pragma: no cover - 既无 flock 也无 locking 的平台 - return - while True: - try: - msvcrt.locking(fd, msvcrt.LK_LOCK, 1) - return - except OSError: # LK_LOCK 重试约 10 次后放弃,这里自己等下去 - time.sleep(0.01) - - -def _release(fd: int) -> None: - if fcntl is not None: - fcntl.flock(fd, fcntl.LOCK_UN) - elif msvcrt is not None: # pragma: no cover - platform dependent - try: - msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) - except OSError: - pass +from .. import compat class CheckpointStore: """JSON checkpoints using an explicit VFS or host storage backend.""" @@ -102,7 +70,7 @@ def locked(self): lockfile.parent.mkdir(parents=True, exist_ok=True) fd = os.open(str(lockfile), os.O_CREAT | os.O_RDWR, 0o644) try: - _acquire(fd) + compat.lock(fd) local.held = True local.fd = fd local.depth = 1 @@ -112,7 +80,7 @@ def locked(self): local.depth -= 1 if local.depth <= 0: try: - _release(fd) + compat.unlock(fd) finally: os.close(fd) local.held = False diff --git a/pyvdisk/vscript/host.py b/pyvdisk/vscript/host.py index defbd33..061edd1 100644 --- a/pyvdisk/vscript/host.py +++ b/pyvdisk/vscript/host.py @@ -3,6 +3,7 @@ import os import stat import tempfile +from .. import compat from .errors import CapabilityError, RuntimeError class HostCapability: @@ -71,15 +72,10 @@ def write(self, path, data, overwrite=True): raise CapabilityError("目标不是普通文件") os.replace(tmp, p) tmp = None - if os.name == "posix": - # 目录项 fsync 是 POSIX 的做法:Windows 上不能 os.open 一个目录, - # 会抛 OSError,于是写入明明成功却被下面的 except 报成 - # "写入宿主文件失败"。NTFS 的元数据持久性由 OS 负责,这里跳过。 - dirfd = os.open(parent, os.O_RDONLY) - try: - os.fsync(dirfd) - finally: - os.close(dirfd) + # Make the rename itself durable. Windows cannot open a directory as + # a file, so compat.fsync_dir is a no-op there and returns False -- + # NTFS journals the rename, and the file data was already flushed. + compat.fsync_dir(parent) except OSError as e: raise RuntimeError("写入宿主文件失败") from e finally: if tmp is not None: diff --git a/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 0000000..64565f7 --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,285 @@ +"""Windows compatibility layer (``pyvdisk.compat``). + +CI runs on Linux, so the Windows branches would otherwise never execute. Two +things make them testable from here: ``compat.describe()`` says which +implementation is live, and ``compat.use_implementation("windows")`` plus a +stand-in for ``msvcrt`` runs the emulation against real files. + +That is not a substitute for a Windows runner -- the stand-in's lock is +in-process, so it cannot show that two *processes* contend -- but it does +execute the emulation, including the contention and timeout paths, which is +where the interesting logic is. + +The last test is the regression guard for the whole exercise: nothing outside +``compat`` may reach for ``fcntl``, ``msvcrt``, ``os.pread`` or ``os.pwrite`` +directly, because that is how the Windows gap opened in the first place. +""" +from __future__ import annotations + +import os +import re +import sys +import time +from pathlib import Path + +import pytest + +from pyvdisk import DataDisk, VFS, compat + +ROOT = Path(__file__).resolve().parents[1] + + +class FakeMsvcrt: + """In-process stand-in for the Windows locking API. + + ``msvcrt.locking`` locks a byte range of an open file. Keying the held + ranges by ``(st_dev, st_ino)`` reproduces the part the emulation depends on: + a second lock on the same file fails until the first is released. + """ + + LK_NBLCK, LK_UNLCK = 2, 0 + + def __init__(self): + self.held = {} + + def locking(self, fd, mode, nbytes): + stat = os.fstat(fd) + key = (stat.st_dev, stat.st_ino) + if mode == self.LK_UNLCK: + self.held.pop(key, None) + return + if key in self.held: + raise OSError(13, "already locked") + self.held[key] = nbytes + + +@pytest.fixture +def windows_emulation(monkeypatch): + """Force the emulated implementation, with a stand-in for msvcrt.""" + fake = FakeMsvcrt() + monkeypatch.setattr(compat, "_msvcrt", fake) + with compat.use_implementation("windows"): + yield fake + + +def _lock_file(tmp_path, name="lock"): + path = tmp_path / name + return os.open(str(path), os.O_CREAT | os.O_RDWR) + + +# ---- the live platform ---------------------------------------------------- + +def test_describe_reports_the_live_implementation(): + info = compat.describe() + assert info["implementation"] in ("posix", "windows") + assert info["implementation"] == ("posix" if os.name == "posix" else "windows") + assert set(info) >= {"platform", "positional_io", "locking", "directory_fsync", "uid_gid", "symlinks"} + if os.name == "posix": + assert info["locking"] == "fcntl.flock" + assert info["positional_io"] == "os.pread/os.pwrite" + assert info["directory_fsync"] is True + + +def test_uid_and_gid_are_integers(): + assert isinstance(compat.uid(), int) + assert isinstance(compat.gid(), int) + if os.name == "posix": + assert compat.uid() == os.getuid() + assert compat.gid() == os.getgid() + else: + assert (compat.uid(), compat.gid()) == (0, 0) + + +def test_can_symlink_agrees_with_the_platform(tmp_path): + supported = compat.can_symlink(str(tmp_path)) + assert isinstance(supported, bool) + if os.name == "posix": + assert supported is True + assert not list(tmp_path.iterdir()), "the probe must clean up after itself" + + +# ---- positional IO ------------------------------------------------------- + +def test_positional_io_reads_and_writes_at_an_offset(tmp_path): + path = tmp_path / "data.bin" + path.write_bytes(b"0" * 64) + fd = os.open(str(path), os.O_RDWR) + try: + assert compat.pwrite(fd, b"HELLO", 10) == 5 + assert compat.pread(fd, 5, 10) == b"HELLO" + # Reads are positioned: the cursor is irrelevant and nothing else moved. + assert compat.pread(fd, 3, 0) == b"000" + assert path.read_bytes()[10:15] == b"HELLO" + finally: + os.close(fd) + + +def test_positional_read_returns_short_only_at_end_of_file(tmp_path): + path = tmp_path / "short.bin" + path.write_bytes(b"abc") + fd = os.open(str(path), os.O_RDONLY) + try: + assert compat.pread(fd, 10, 0) == b"abc" + assert compat.pread(fd, 10, 3) == b"" + finally: + os.close(fd) + + +def test_the_disk_helpers_pad_a_short_read(tmp_path): + """``_pread_all`` pads to the requested length; that path uses compat.pread.""" + from pyvdisk.disk import _pread_all, _pwrite_all + + path = tmp_path / "block.bin" + with open(path, "w+b", buffering=0) as handle: + _pwrite_all(handle, 4, b"ABCD") + assert handle.seek(0, os.SEEK_END) == 8 + assert _pread_all(handle, 0, 8) == b"\x00\x00\x00\x00ABCD" + + +# ---- locking ------------------------------------------------------------- + +def test_locking_is_exclusive_between_handles(tmp_path): + first, second = _lock_file(tmp_path), _lock_file(tmp_path) + try: + assert compat.lock(first) is True + assert compat.lock(second, blocking=False) is False + compat.unlock(first) + assert compat.lock(second, blocking=False) is True + finally: + compat.unlock(first) + compat.unlock(second) + os.close(first) + os.close(second) + + +def test_lock_timeout_gives_up_instead_of_waiting_forever(tmp_path): + first, second = _lock_file(tmp_path), _lock_file(tmp_path) + try: + assert compat.lock(first) is True + started = time.monotonic() + assert compat.lock(second, timeout=0.05) is False + waited = time.monotonic() - started + assert 0.04 <= waited < 5.0, f"timeout waited {waited:.3f}s" + finally: + compat.unlock(first) + compat.unlock(second) + os.close(first) + os.close(second) + + +def test_unlock_on_a_closed_handle_is_not_an_error(tmp_path): + fd = _lock_file(tmp_path) + os.close(fd) + compat.unlock(fd) # must not raise: close() runs on every teardown path + + +def test_fsync_dir_flushes_a_real_directory(tmp_path): + if os.name != "posix": + pytest.skip("directory fsync is a POSIX facility") + assert compat.fsync_dir(str(tmp_path)) is True + assert compat.fsync_dir(str(tmp_path / "missing")) is False + + +# ---- the emulated implementation ----------------------------------------- + +def test_emulated_positional_io_matches_the_native_one(tmp_path, windows_emulation): + path = tmp_path / "emulated.bin" + path.write_bytes(bytes(range(64))) + fd = os.open(str(path), os.O_RDWR) + try: + assert compat.pwrite(fd, b"XY", 8) == 2 + assert compat.pread(fd, 4, 7) == bytes([7, 88, 89, 10]) + assert compat.pread(fd, 4, 61) == bytes([61, 62, 63]) + finally: + os.close(fd) + + +def test_emulated_locking_contends_and_times_out(tmp_path, windows_emulation): + first, second = _lock_file(tmp_path), _lock_file(tmp_path) + try: + assert compat.lock(first) is True + assert compat.lock(second, blocking=False) is False + assert compat.lock(second, timeout=0.05) is False + compat.unlock(first) + assert compat.lock(second, blocking=False) is True + finally: + compat.unlock(first) + compat.unlock(second) + os.close(first) + os.close(second) + + +def test_a_disk_round_trips_under_the_windows_emulation(tmp_path, windows_emulation): + """The emulated positional IO and locking must carry real disk workloads.""" + plain = tmp_path / "plain.vdisk" + VFS.create(str(plain), 8 << 20) + with VFS(str(plain)) as vfs: + vfs.makedirs("/deep/nested") + vfs.write_file("/deep/nested/small.txt", b"windows path") + assert vfs.read_file("/deep/nested/small.txt") == b"windows path" + # Big enough to span many blocks, so pwrite is exercised repeatedly. + payload = bytes(range(256)) * 4096 + vfs.write_file("/big.bin", payload) + assert vfs.read_file("/big.bin") == payload + + container = tmp_path / "container.vdisk" + DataDisk.create(str(container), 16 << 20) + with DataDisk(str(container)) as disk: + disk.fs.write_file("/state.json", b'{"step": 1}') + with disk.transaction(): + disk.fs.write_file("/state.json", b'{"step": 2}') + assert disk.fs.read_file("/state.json") == b'{"step": 2}' + disk.checkpoints.set("cursor", {"page": 7}) + disk.checkpoints.save() + assert disk.checkpoints.get("cursor") == {"page": 7} + + +def test_the_two_implementations_agree_on_a_whole_workload(tmp_path, windows_emulation): + """Same operations, same bytes: only the primitives underneath differ.""" + def run(directory): + directory.mkdir(parents=True, exist_ok=True) + path = directory / "agree.vdisk" + VFS.create(str(path), 4 << 20) + with VFS(str(path)) as vfs: + vfs.write_file("/a.txt", b"payload") + vfs.write_file("/b.txt", b"x" * 5000) + return [vfs.read_file("/a.txt"), vfs.read_file("/b.txt"), sorted(vfs.listdir("/"))] + + # The fixture forced the emulation; nest the native one back in for the A/B. + with compat.use_implementation("posix"): + native = run(tmp_path / "native") + emulated = run(tmp_path / "emulated") + assert native == emulated + + +# ---- the regression guard ------------------------------------------------ + +#: Reaching for these directly is what made the package POSIX-only. +FORBIDDEN = ( + (re.compile(r"^\s*import\s+fcntl\b|^\s*from\s+fcntl\s+import\b"), "imports fcntl directly"), + (re.compile(r"^\s*import\s+msvcrt\b|^\s*from\s+msvcrt\s+import\b"), "imports msvcrt directly"), + (re.compile(r"\bos\.pread\s*\("), "calls os.pread (POSIX only)"), + (re.compile(r"\bos\.pwrite\s*\("), "calls os.pwrite (POSIX only)"), + (re.compile(r"\bos\.getuid\s*\(|\bos\.getgid\s*\("), "calls os.getuid/getgid (POSIX only)"), +) + + +def test_only_compat_reaches_for_platform_primitives(): + offenders = [] + for path in sorted((ROOT / "pyvdisk").rglob("*.py")): + if path.name == "compat.py": + continue + for number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), start=1): + if line.lstrip().startswith("#"): + continue + for pattern, why in FORBIDDEN: + if pattern.search(line): + offenders.append(f"{path.relative_to(ROOT)}:{number} {why}") + assert not offenders, "route these through pyvdisk.compat:\n" + "\n".join(offenders) + + +def test_host_writes_flush_the_directory_through_compat(): + """host.py used to fsync a directory fd, which Windows cannot open at all.""" + source = (ROOT / "pyvdisk" / "vscript" / "host.py").read_text(encoding="utf-8") + assert "compat.fsync_dir(" in source + assert not re.search(r"os\.fsync\s*\(\s*dirfd", source) From f75b3c1c41ba579cf272f10297a3346d15b8d152 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:25:41 +0800 Subject: [PATCH 02/15] =?UTF-8?q?feat(vector):=20=E5=86=85=E7=BD=AE=20flat?= =?UTF-8?q?=20=E7=B4=A2=E5=BC=95=E5=90=8E=E7=AB=AF=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=20hnswlib=20=E7=A1=AC=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dependencies 由 ["hnswlib>=0.8.0"] 改为 []:pip install pyvdisk 不再需要 编译任何东西,这也是"单文件快速上手"的前提。hnswlib 仍是唯一的第三方 import,把它变成可选之后,核心路径回到纯标准库。 新增 pyvdisk/vector_index.py:扁平(精确)索引后端,接口对齐 hnswlib 的 使用形状(init_index/set_ef/add_items/knn_query/save_index/load_index), 距离约定也一致(cosine = 1 - 相似度,l2 = 平方欧氏距离,ip = 1 - 点积), 因此两种后端可以直接互换,不需要在调用点分支。 - VectorDisk._index_backend() 装了 hnswlib 就用它,否则回退内置后端; - 索引文件带 8 字节魔数 PVFLAT01,读方据此判断写入方。文件名保持 index.hnsw 不变(磁盘格式兼容),由魔数而不是文件名决定如何解析; - 两种后端互相可读:hnswlib 写的盘在无 hnswlib 环境下用 flat 后端精确 查询(线性扫描,结果正确,优于拒绝打开),反向亦然; - 重建索引改为一次性序列化后经 VFS 原子改名发布,去掉了临时文件。 代价要说清楚:flat 后端查询是 O(n) 且索引常驻内存,只适合中小集合。 hnswlib 与 fusepy 降级为可选 extra(pyvdisk[vector] / pyvdisk[fuse])。 CI 相应调整:版本矩阵装 [dev,vector] 保住 hnswlib 路径的覆盖(否则它会 悄悄不再被测试),另加一个 no-dependencies job 只装 [dev],断言 hnswlib/ fuse/numpy 都不可导入且核心仍能跑通全套用例。 tests/test_no_dependency_path.py 在 import 层面屏蔽 hnswlib,验证无加速器 时集合仍可增删查、索引可持久化、两种后端结果一致,以及 examples/ quickstart.py 在无依赖环境下真的能跑完。 --- .github/workflows/ci.yml | 25 ++- pyproject.toml | 7 +- pyvdisk/vector_disk.py | 70 +++++--- pyvdisk/vector_index.py | 251 +++++++++++++++++++++++++++++ tests/test_no_dependency_path.py | 263 +++++++++++++++++++++++++++++++ uv.lock | 11 +- 6 files changed, 598 insertions(+), 29 deletions(-) create mode 100644 pyvdisk/vector_index.py create mode 100644 tests/test_no_dependency_path.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cda5eeb..b52969e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,29 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install -e .[dev] + # [vector] keeps the hnswlib path covered now that it is optional: without + # this the accelerator backend would silently stop being tested. + python -m pip install -e .[dev,vector] - name: Tests run: python -m pytest -q --no-header -p no:cacheprovider + + no-dependencies: + # The zero-dependency claim is a promise to users, so it gets its own job: install + # the package alone and prove the core still imports and passes. + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install without extras + run: | + python -m pip install --upgrade pip + python -m pip install -e .[dev] + - name: No third-party runtime dependency may be installed + run: | + python -c "import importlib.util,sys; bad=[n for n in ('hnswlib','fuse','numpy') if importlib.util.find_spec(n)]; sys.exit('installed: '+','.join(bad)) if bad else None" + python -c "import pyvdisk; print('pyvdisk', pyvdisk.__version__, 'imported with the standard library only')" + - name: Tests (accelerator-dependent cases skip) + run: python -m pytest -q --no-header -p no:cacheprovider diff --git a/pyproject.toml b/pyproject.toml index 9079472..669c240 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,12 +11,13 @@ requires-python = ">=3.9" license = { text = "MIT" } authors = [{ name = "PyVDisk contributors" }] keywords = ["virtual-disk", "filesystem", "fuse", "vm", "disk-image", "vector-database", "structured-logging", "time-series"] -# hnswlib 在 Windows 上没有预编译 wheel(PyPI 只有 sdist,要现编 C++),而代码里 -# 向量盘是延迟导入的(vector_disk._hnswlib()),FS/Log/Checkpoint 都不需要它。 -# 因此它属于可选能力而不是核心依赖:不装也能用文件盘,装了才有向量盘。 +# No runtime dependencies: the core is stdlib-only, and the vector disk falls back +# to a built-in flat index when hnswlib is absent. Extras below add the accelerators. dependencies = [] [project.optional-dependencies] +# Approximate nearest-neighbour search for large vector collections. Without it +# VectorDisk still answers exact queries, in linear time. vector = ["hnswlib>=0.8.0"] fuse = ["fusepy"] dev = ["pytest", "setuptools>=61.0", "hnswlib>=0.8.0"] diff --git a/pyvdisk/vector_disk.py b/pyvdisk/vector_disk.py index 264f9ae..7d52ea9 100644 --- a/pyvdisk/vector_disk.py +++ b/pyvdisk/vector_disk.py @@ -1,7 +1,13 @@ -"""向量数据盘:在 PyVDisk 文件系统中持久化多个 HNSW 向量集合。""" +"""向量数据盘:在 PyVDisk 文件系统中持久化多个向量集合。 + +索引后端是可选的:装了 hnswlib 就用 HNSW 图索引(近似、对数级查询), +没装就用内置的扁平索引(精确、线性查询)。两种后端写出的集合都带格式标记, +因此换一台机器、换一个环境打开同一块盘都不会读错。 +""" from __future__ import annotations import hashlib, json, math, os, tempfile, threading from typing import Any, Dict, Iterable, List, Optional +from . import vector_index from .disk import VirtualDisk from .identity import probe_disk, write_identity_to_block0 from .vfs import VFS @@ -13,13 +19,21 @@ class VectorDiskError(Exception): """向量数据盘操作失败。""" -def _hnswlib(): +def _index_backend(): + """返回可用的索引后端:装了 hnswlib 用它,否则用内置扁平索引。 + + 以前缺 hnswlib 会直接抛 ImportError;现在它只是可选的加速器, + 没有它集合依然可用(查询精确,代价是线性扫描)。 + """ try: import hnswlib - except ImportError as exc: - raise ImportError("向量数据盘需要可选依赖 hnswlib;请运行 pip install \"pyvdisk[vector]\"(Windows 上它需要现场编译 C++)") from exc + except ImportError: + return vector_index.backend return hnswlib +def _is_hnswlib(backend) -> bool: + return getattr(backend, "__name__", "") == "hnswlib" + def _json_bytes(value: Any) -> bytes: return json.dumps(value, ensure_ascii=False, separators=(",", ":")).encode("utf-8") @@ -221,25 +235,41 @@ def count(self, collection: str) -> int: self._config(collection); return len(self._records(collection)["items"]) def _rebuild_index(self, name: str, config: Dict[str, Any], records: Dict[str, Any]) -> None: - hnswlib = _hnswlib(); index = hnswlib.Index(space=config["metric"], dim=config["dimension"]) + backend = _index_backend() + index = backend.Index(space=config["metric"], dim=config["dimension"]) index.init_index(max_elements=max(config["max_elements"], 1), ef_construction=config["ef_construction"], M=config["m"]) index.set_ef(config["ef_search"]); values = list(records["items"].values()) if values: index.add_items([v["vector"] for v in values], [v["label"] for v in values]) - fd, host_path = tempfile.mkstemp(suffix=".hnsw"); os.close(fd) - try: - index.save_index(host_path) - with open(host_path, "rb") as stream: - # Publish the rebuilt index as one VFS rename. - target = self._dir(name) + "/index.hnsw" - temporary = target + ".tmp" - self.vfs.write_file(temporary, stream.read()) - self.vfs.rename(temporary, target) - finally: - try: os.unlink(host_path) - except OSError: pass + # The backend tags its own output (the flat index carries a magic header), + # so a later reader knows what wrote the file. + payload = vector_index.serialize_from_backend(index, backend) + # Publish the rebuilt index as one VFS rename. + target = self._dir(name) + "/index.hnsw" + temporary = target + ".tmp" + self.vfs.write_file(temporary, payload) + self.vfs.rename(temporary, target) - def _load_index(self, name: str, config: Dict[str, Any]): - hnswlib = _hnswlib(); data = self.vfs.read_file(self._dir(name) + "/index.hnsw") + def _flat_from_records(self, config: Dict[str, Any], records: Dict[str, Any]): + """精确索引,由记录直接构建(hnswlib 写的盘在无 hnswlib 环境下也能查)。""" + index = vector_index.FlatIndex(space=config["metric"], dim=config["dimension"]) + index.init_index(max_elements=max(config["max_elements"], 1)) + index.set_ef(config["ef_search"]) + for record in records["items"].values(): + index.add_item(int(record["label"]), record["vector"]) + return index + + def _load_index(self, name: str, config: Dict[str, Any], records: Dict[str, Any] = None): + data = self.vfs.read_file(self._dir(name) + "/index.hnsw") + if vector_index.read_kind(data) == vector_index.KIND_FLAT: + return vector_index.deserialize(data) + try: + hnswlib = _index_backend() + if not _is_hnswlib(hnswlib): + raise ImportError("hnswlib unavailable") + except ImportError: + # Written by hnswlib elsewhere and hnswlib is not installed here: + # answer exactly, from the records, instead of failing the query. + return self._flat_from_records(config, records or self._records(name)) fd, host_path = tempfile.mkstemp(suffix=".hnsw") try: with os.fdopen(fd, "wb") as stream: stream.write(data) @@ -258,7 +288,7 @@ def search(self, collection: str, vector: Iterable[float], k: int = 10, by_label = {v["label"]: (item_id, v) for item_id, v in records["items"].items()} allowed = {label for label, (_id, rec) in by_label.items() if _match_filter(rec["metadata"], where)} if not allowed: return [] - index = self._load_index(collection, config); wanted = min(k, len(allowed)) + index = self._load_index(collection, config, records); wanted = min(k, len(allowed)) labels, distances = index.knn_query([query], k=wanted, filter=lambda label: int(label) in allowed) result = [] for label, distance in zip(labels[0], distances[0]): diff --git a/pyvdisk/vector_index.py b/pyvdisk/vector_index.py new file mode 100644 index 0000000..26fddfd --- /dev/null +++ b/pyvdisk/vector_index.py @@ -0,0 +1,251 @@ +"""Vector index backends: hnswlib when it is installed, flat search when it is not. + +``hnswlib`` is an accelerator, not a requirement. It builds a graph index and +answers approximate queries in logarithmic time; without it the package still +has to answer *correct* queries, so this module implements the same surface +``VectorDisk`` uses:: + + Index(space=..., dim=...) -> init_index / set_ef / add_items / + save_index / load_index / knn_query + +Distances follow hnswlib's conventions exactly, so a collection does not change +meaning when the dependency is installed or removed: + +=========== ========================================== +``cosine`` ``1 - cosine similarity`` +``l2`` squared euclidean distance +``ip`` ``1 - inner product`` +=========== ========================================== + +Serialised flat indexes start with :data:`MAGIC`. An hnswlib-written file has no +such header, so :func:`read_kind` can always say which backend wrote a file: a +collection written with hnswlib and opened without it is rebuilt flat instead of +being misread as garbage. + +The flat index is O(n) per query and keeps every vector in memory. That is the +right trade for the quickstart, small collections and CI; ``pip install +pyvdisk[vector]`` is what you want for large ones. +""" + +from __future__ import annotations + +import math +import os +import struct +from typing import Any, Iterable, List, Optional, Sequence, Tuple + +#: Header written in front of a serialised flat index. +MAGIC = b"PVFLAT01" + +#: Backends a collection file can have been written by. +KIND_FLAT = "flat" +KIND_HNSW = "hnsw" + +SUPPORTED_SPACES = ("cosine", "l2", "ip") + + +class FlatIndexError(Exception): + """Raised when a flat index cannot be built, read or written.""" + + +def read_kind(data: bytes) -> str: + """Which backend wrote ``data``: ``"flat"`` for our own files, else ``"hnsw"``.""" + return KIND_FLAT if data[:len(MAGIC)] == MAGIC else KIND_HNSW + + +def _dot(a: Sequence[float], b: Sequence[float]) -> float: + return math.fsum(x * y for x, y in zip(a, b)) + + +def _norm(a: Sequence[float]) -> float: + return math.sqrt(math.fsum(x * x for x in a)) + + +def _unit(vector: Sequence[float]) -> List[float]: + length = _norm(vector) + if length == 0.0: + # hnswlib leaves a zero vector alone rather than dividing by zero. + return list(vector) + return [x / length for x in vector] + + +def distance(space: str, a: Sequence[float], b: Sequence[float]) -> float: + """Distance between two vectors, using hnswlib's convention for ``space``.""" + if space == "cosine": + return 1.0 - _dot(_unit(a), _unit(b)) + if space == "l2": + return math.fsum((x - y) ** 2 for x, y in zip(a, b)) + if space == "ip": + return 1.0 - _dot(a, b) + raise FlatIndexError(f"未知的距离度量: {space}") + + +class FlatIndex: + """Brute-force index with the subset of the hnswlib API that VectorDisk uses.""" + + kind = KIND_FLAT + + def __init__(self, space: str = "cosine", dim: int = 0): + if space not in SUPPORTED_SPACES: + raise FlatIndexError(f"未知的距离度量: {space}") + self.space = space + self.dim = int(dim) + self.ef = 10 + self.max_elements = 0 + self._labels: List[int] = [] + self._vectors: List[List[float]] = [] + self._position = {} + + # ---- hnswlib-compatible surface ------------------------------------- + + def init_index(self, max_elements: int = 0, ef_construction: int = 0, M: int = 0, **_): + self.max_elements = int(max_elements or 0) + + def set_ef(self, ef: int): + self.ef = int(ef) + + def add_items(self, vectors: Iterable[Sequence[float]], labels: Iterable[int], **_): + for vector, label in zip(vectors, labels): + self.add_item(int(label), vector) + + def add_item(self, label: int, vector: Sequence[float]): + values = [float(x) for x in vector] + if self.dim and len(values) != self.dim: + raise FlatIndexError(f"向量维度不匹配: 期望 {self.dim},实际 {len(values)}") + if not self.dim: + self.dim = len(values) + if label in self._position: + self._vectors[self._position[label]] = values + else: + self._position[label] = len(self._labels) + self._labels.append(label) + self._vectors.append(values) + + def knn_query(self, queries: Iterable[Sequence[float]], k: int = 1, filter=None, **_): + """Return ``(labels, distances)`` shaped like hnswlib's numpy arrays.""" + out_labels: List[List[int]] = [] + out_distances: List[List[float]] = [] + for query in queries: + values = [float(x) for x in query] + scored = [] + for label, vector in zip(self._labels, self._vectors): + if filter is not None and not filter(label): + continue + scored.append((distance(self.space, values, vector), label)) + # Ties break on the label so repeated queries return a stable order. + scored.sort(key=lambda pair: (pair[0], pair[1])) + chosen = scored[:max(0, int(k))] + out_labels.append([label for _, label in chosen]) + out_distances.append([value for value, _ in chosen]) + return out_labels, out_distances + + def save_index(self, path: str) -> None: + with open(path, "wb") as stream: + stream.write(serialize(self)) + + def load_index(self, path: str, max_elements: int = 0, **_): + with open(path, "rb") as stream: + loaded = deserialize(stream.read()) + self.space = loaded.space + self.dim = loaded.dim + self._labels = loaded._labels + self._vectors = loaded._vectors + self._position = loaded._position + self.max_elements = int(max_elements or 0) + + # ---- convenience ----------------------------------------------------- + + def __len__(self) -> int: + return len(self._labels) + + @property + def labels(self) -> List[int]: + return list(self._labels) + + def vectors(self) -> List[List[float]]: + return [list(v) for v in self._vectors] + + +def serialize(index: FlatIndex) -> bytes: + """Encode a flat index: header, then labels and float32 vectors.""" + space = index.space.encode("utf-8") + if len(space) > 255: + raise FlatIndexError("度量名过长") + header = struct.pack("<8sBII", MAGIC, len(space), int(index.dim), len(index._labels)) + labels = struct.pack(f"<{len(index._labels)}q", *index._labels) if index._labels else b"" + flat = [value for vector in index._vectors for value in vector] + vectors = struct.pack(f"<{len(flat)}f", *flat) if flat else b"" + return header + space + labels + vectors + + +def deserialize(data: bytes) -> FlatIndex: + """Decode bytes produced by :func:`serialize`.""" + if data[:len(MAGIC)] != MAGIC: + raise FlatIndexError("不是扁索引文件") + if len(data) < 17: + raise FlatIndexError("扁索引头部被截断") + _, space_length, dim, count = struct.unpack("<8sBII", data[:17]) + space = data[17:17 + space_length].decode("utf-8") + offset = 17 + space_length + labels_size = 8 * count + vectors_size = 4 * count * dim + if len(data) < offset + labels_size + vectors_size: + raise FlatIndexError("扁索引数据被截断") + labels = list(struct.unpack(f"<{count}q", data[offset:offset + labels_size])) if count else [] + offset += labels_size + values = list(struct.unpack(f"<{count * dim}f", data[offset:offset + vectors_size])) if count and dim else [] + index = FlatIndex(space, dim) + for position, label in enumerate(labels): + index._labels.append(label) + index._position[label] = position + index._vectors.append(values[position * dim:(position + 1) * dim]) + return index + + +class _FlatBackend: + """Module-shaped backend so ``vector_disk`` can treat both alike.""" + + kind = KIND_FLAT + Index = FlatIndex + MAGIC = MAGIC + + @staticmethod + def is_available() -> bool: + return True + + +#: The object ``vector_disk`` uses when hnswlib is missing. +backend = _FlatBackend() + + +def serialize_from_backend(index: Any, backend_module: Any) -> bytes: + """Serialise ``index`` for ``backend_module``, tagging flat files with MAGIC.""" + if getattr(index, "kind", None) == KIND_FLAT: + return serialize(index) + handle, host_path = _tempfile() + try: + index.save_index(host_path) + with open(host_path, "rb") as stream: + return stream.read() + finally: + _unlink(host_path) + + +def _tempfile() -> Tuple[int, str]: + import tempfile + + return tempfile.mkstemp(suffix=".idx") + + +def _unlink(path: str) -> None: + try: + os.unlink(path) + except OSError: + pass + + +__all__ = [ + "MAGIC", "KIND_FLAT", "KIND_HNSW", "SUPPORTED_SPACES", + "FlatIndex", "FlatIndexError", "backend", + "distance", "read_kind", "serialize", "deserialize", "serialize_from_backend", +] diff --git a/tests/test_no_dependency_path.py b/tests/test_no_dependency_path.py new file mode 100644 index 0000000..412d816 --- /dev/null +++ b/tests/test_no_dependency_path.py @@ -0,0 +1,263 @@ +"""The zero-dependency promise: no hnswlib, no fusepy, no build step. + +Two things make the promise real, and both are tested here: + +* ``pyproject.toml`` declares no runtime dependencies, so ``pip install pyvdisk`` + never tries to compile hnswlib; +* ``VectorDisk`` falls back to the built-in flat index, so a collection still + answers exactly when the accelerator is absent -- and a collection written by + either backend can be read by the other. + +``examples/quickstart.py`` is the user-visible half of the same claim, so it runs +here in a subprocess with ``hnswlib`` blocked: if it ever starts needing the +accelerator, this test fails rather than the user's first five minutes. +""" +from __future__ import annotations + +import re +import subprocess +import sys +import textwrap +from pathlib import Path + +import pytest + +from pyvdisk import VectorDisk, vector_index +from pyvdisk.vector_index import FlatIndex, FlatIndexError + +ROOT = Path(__file__).resolve().parents[1] +QUICKSTART = ROOT / "examples" / "quickstart.py" + +try: # the accelerator may legitimately be absent + import hnswlib # noqa: F401 + HAVE_HNSWLIB = True +except ImportError: # pragma: no cover - depends on the environment + HAVE_HNSWLIB = False + +needs_hnswlib = pytest.mark.skipif(not HAVE_HNSWLIB, reason="hnswlib is not installed here") + + +class _BlockHnswlib: + """Context manager that makes ``import hnswlib`` fail for the block.""" + + def __enter__(self): + import builtins + + self._real = builtins.__import__ + + def blocked(name, *args, **kwargs): + if name == "hnswlib": + raise ImportError("hnswlib blocked for this test") + return self._real(name, *args, **kwargs) + + builtins.__import__ = blocked + return self + + def __exit__(self, *exc): + import builtins + + builtins.__import__ = self._real + + +def _collection(disk): + disk.create_collection("docs", 3, metric="cosine") + disk.upsert_many("docs", [ + {"id": "a", "vector": [1.0, 0.0, 0.0], "metadata": {"kind": "news"}}, + {"id": "b", "vector": [0.0, 1.0, 0.0], "metadata": {"kind": "blog"}}, + {"id": "c", "vector": [0.9, 0.1, 0.0], "metadata": {"kind": "news"}}, + ]) + return disk + + +def _ids(hits): + return [hit["id"] for hit in hits] + + +# ---- the packaging promise ------------------------------------------------ + +def test_declared_runtime_dependencies_are_empty(): + text = (ROOT / "pyproject.toml").read_text(encoding="utf-8") + match = re.search(r"^dependencies\s*=\s*\[(?P.*?)\]", text, re.M | re.S) + assert match, "pyproject.toml has no [project] dependencies field" + assert match.group("body").strip() == "", ( + "the core must stay stdlib-only; extras belong in [project.optional-dependencies]" + ) + extras = text.split("[project.optional-dependencies]", 1)[1] + assert "hnswlib" in extras and "fusepy" in extras, "the accelerators must remain installable" + + +def test_the_quickstart_example_exists_and_is_standard_library_only(): + source = QUICKSTART.read_text(encoding="utf-8") + for line in source.splitlines(): + stripped = line.strip() + if stripped.startswith(("import ", "from ")) and "pyvdisk" not in stripped: + module = stripped.split()[1].split(".")[0] + assert module in { + "__future__", "importlib", "os", "sys", "tempfile", "pathlib", "json", + "time", "hashlib", "shutil", "argparse", + }, f"quickstart must not need {module}" + + +# ---- the flat index ------------------------------------------------------- + +def test_read_kind_identifies_the_writer(): + index = FlatIndex("cosine", 3) + assert vector_index.read_kind(vector_index.serialize(index)) == vector_index.KIND_FLAT + assert vector_index.read_kind(b"\x00\x01hnswlib-bytes") == vector_index.KIND_HNSW + + +def test_flat_index_round_trips_through_its_serialised_form(): + index = FlatIndex("l2", 2) + index.add_items([[0.0, 1.0], [2.0, 2.0]], [7, 9]) + restored = vector_index.deserialize(vector_index.serialize(index)) + assert restored.space == "l2" and restored.dim == 2 + assert restored.labels == [7, 9] + labels, distances = restored.knn_query([[0.0, 1.0]], k=1) + assert labels == [[7]] and distances == [[0.0]] + + +def test_a_truncated_flat_index_is_rejected_rather_than_misread(): + index = FlatIndex("cosine", 3) + index.add_item(1, [1.0, 0.0, 0.0]) + payload = vector_index.serialize(index) + with pytest.raises(FlatIndexError): + vector_index.deserialize(payload[:-2]) + with pytest.raises(FlatIndexError): + vector_index.deserialize(b"not-a-flat-index") + + +def test_flat_index_rejects_an_unknown_metric_and_a_wrong_dimension(): + with pytest.raises(FlatIndexError): + FlatIndex("hamming", 3) + index = FlatIndex("cosine", 3) + with pytest.raises(FlatIndexError): + index.add_item(1, [1.0, 0.0]) + + +def test_flat_index_distances_match_hnswlib_conventions(): + """cosine -> 1 - similarity, l2 -> squared euclidean, ip -> 1 - dot.""" + cosine = FlatIndex("cosine", 2) + cosine.add_items([[1.0, 0.0], [0.0, 1.0]], [1, 2]) + _, distances = cosine.knn_query([[1.0, 0.0]], k=2) + assert distances[0] == [0.0, 1.0] + l2 = FlatIndex("l2", 2) + l2.add_item(1, [0.0, 0.0]) + _, distances = l2.knn_query([[3.0, 4.0]], k=1) + assert distances[0] == [25.0] + ip = FlatIndex("ip", 2) + ip.add_item(1, [2.0, 0.0]) + _, distances = ip.knn_query([[3.0, 0.0]], k=1) + assert distances[0] == [-5.0] + + +# ---- the vector disk without the accelerator ------------------------------ + +def test_the_vector_disk_works_without_hnswlib(tmp_path): + path = str(tmp_path / "vectors.vdisk") + VectorDisk.create(path, 16 << 20) + with _BlockHnswlib(): + with VectorDisk(path) as disk: + _collection(disk) + assert disk.count("docs") == 3 + hits = disk.search("docs", [1.0, 0.0, 0.0], k=3) + assert _ids(hits) == ["a", "c", "b"] + assert hits[0]["distance"] == pytest.approx(0.0, abs=1e-6) + assert _ids(disk.search("docs", [1.0, 0.0, 0.0], k=3, where={"kind": "news"})) == ["a", "c"] + assert disk.get("docs", "a")["metadata"] == {"kind": "news"} + assert disk.delete("docs", "b") is True + assert disk.count("docs") == 2 + assert vector_index.read_kind(disk.vfs.read_file(disk._dir("docs") + "/index.hnsw")) == "flat" + # Reopen with the accelerator still blocked: the flat index persists. + with VectorDisk(path) as disk: + assert disk.count("docs") == 2 + assert _ids(disk.search("docs", [1.0, 0.0, 0.0], k=2)) == ["a", "c"] + + +def test_writes_work_without_hnswlib_after_a_rebuild(tmp_path): + """Upserts and deletes rebuild the index; that path must not need hnswlib either.""" + path = str(tmp_path / "mutate.vdisk") + VectorDisk.create(path, 16 << 20) + with _BlockHnswlib(): + with VectorDisk(path) as disk: + disk.create_collection("docs", 2) + disk.upsert("docs", "a", [1.0, 0.0]) + disk.upsert("docs", "b", [0.0, 1.0]) + disk.upsert("docs", "a", [0.5, 0.5]) # replace + assert disk.count("docs") == 2 + assert disk.delete("docs", "b") is True + assert _ids(disk.search("docs", [1.0, 0.0], k=5)) == ["a"] + + +@needs_hnswlib +def test_both_backends_agree_on_the_same_collection(tmp_path): + flat_path, hnsw_path = str(tmp_path / "flat.vdisk"), str(tmp_path / "hnsw.vdisk") + for path in (flat_path, hnsw_path): + VectorDisk.create(path, 16 << 20) + with _BlockHnswlib(): + with VectorDisk(flat_path) as disk: + _collection(disk) + flat = [(hit["id"], round(hit["distance"], 6)) for hit in disk.search("docs", [1.0, 0.0, 0.0], k=3)] + with VectorDisk(hnsw_path) as disk: + _collection(disk) + hnsw = [(hit["id"], round(hit["distance"], 6)) for hit in disk.search("docs", [1.0, 0.0, 0.0], k=3)] + assert flat == hnsw + + +@needs_hnswlib +def test_an_hnsw_written_collection_is_readable_without_hnswlib(tmp_path): + path = str(tmp_path / "mixed.vdisk") + VectorDisk.create(path, 16 << 20) + with VectorDisk(path) as disk: + _collection(disk) + assert vector_index.read_kind(disk.vfs.read_file(disk._dir("docs") + "/index.hnsw")) == "hnsw" + with _BlockHnswlib(): + with VectorDisk(path) as disk: + # Correct results, linear time: better than refusing to open the disk. + assert _ids(disk.search("docs", [1.0, 0.0, 0.0], k=3)) == ["a", "c", "b"] + + +@needs_hnswlib +def test_a_flat_written_collection_is_readable_with_hnswlib(tmp_path): + path = str(tmp_path / "flat-then-hnsw.vdisk") + VectorDisk.create(path, 16 << 20) + with _BlockHnswlib(): + with VectorDisk(path) as disk: + _collection(disk) + with VectorDisk(path) as disk: + assert _ids(disk.search("docs", [1.0, 0.0, 0.0], k=3)) == ["a", "c", "b"] + + +# ---- the example the user actually runs ----------------------------------- + +def _run_quickstart(workdir: Path, block_hnswlib: bool) -> subprocess.CompletedProcess: + runner = workdir / ("blocked.py" if block_hnswlib else "plain.py") + runner.write_text(textwrap.dedent(f""" + import builtins, runpy, sys + if {block_hnswlib!r}: + real = builtins.__import__ + def blocked(name, *args, **kwargs): + if name == "hnswlib": + raise ImportError("hnswlib blocked for this test") + return real(name, *args, **kwargs) + builtins.__import__ = blocked + sys.argv = ["quickstart.py", {str(workdir / 'out')!r}] + runpy.run_path({str(QUICKSTART)!r}, run_name="__main__") + """), encoding="utf-8") + return subprocess.run([sys.executable, str(runner)], capture_output=True, text=True, + cwd=str(ROOT), timeout=300) + + +def test_the_quickstart_example_runs_without_optional_dependencies(tmp_path): + result = _run_quickstart(tmp_path, block_hnswlib=True) + assert result.returncode == 0, result.stdout + result.stderr + assert "built-in flat (no dependency)" in result.stdout + assert "chain ok = True" in result.stdout + assert "may not escape" in result.stdout, "the refusal demo must still run" + + +def test_the_quickstart_example_also_runs_with_the_accelerator(tmp_path): + if not HAVE_HNSWLIB: + pytest.skip("hnswlib is not installed here") + result = _run_quickstart(tmp_path, block_hnswlib=False) + assert result.returncode == 0, result.stdout + result.stderr + assert "index backend: hnswlib" in result.stdout diff --git a/uv.lock b/uv.lock index 76a8529..8e403c3 100644 --- a/uv.lock +++ b/uv.lock @@ -524,9 +524,7 @@ wheels = [ name = "pyvdisk" version = "0.3.0" source = { editable = "." } -dependencies = [ - { name = "hnswlib" }, -] +dependencies = [] [package.optional-dependencies] dev = [ @@ -537,14 +535,17 @@ dev = [ fuse = [ { name = "fusepy" }, ] +vector = [ + { name = "hnswlib" }, +] [package.metadata] requires-dist = [ { name = "fusepy", marker = "extra == 'fuse'" }, - { name = "hnswlib", specifier = ">=0.8.0" }, + { name = "hnswlib", marker = "extra == 'vector'", specifier = ">=0.8.0" }, { name = "pytest", marker = "extra == 'dev'" }, ] -provides-extras = ["fuse", "dev"] +provides-extras = ["fuse", "dev", "vector"] [[package]] name = "tomli" From f829fa6b07e78f39c8c4594fa5eac04f82bf7f95 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:26:04 +0800 Subject: [PATCH 03/15] =?UTF-8?q?feat(sandbox):=20=E6=96=B0=E5=A2=9E=20Age?= =?UTF-8?q?ntSandbox=20=E9=A1=B6=E5=B1=82=E7=B1=BB=EF=BC=8C=E4=BE=9B=20Age?= =?UTF-8?q?nt=20=E6=A1=86=E6=9E=B6=E7=9B=B4=E6=8E=A5=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把 DataDisk 包成一个可以交给模型的工作区:工具 schema、调用分发、路径 约束、审计一次到位,框架侧只需要 tools() + dispatch() 两个入口。 - create() / open():新建或续用已有镜像; - tools(style=):openai / anthropic / mcp 三种 schema,6 个内置工具 (write_file、read_file、list_files、make_directory、delete_file、 run_script); - dispatch() 永远返回字符串(失败也是字符串),可直接塞回消息列表; call() 返回结构化 ToolResult 供程序使用; - 约束:read_only 时在 capability 层拒绝写(不只是不暴露工具), allow_delete 可单独关掉删除; - 路径空间是镜像不是宿主:.. 直接拒绝而不解析(拒绝行为要能在审计里看到), C:\Windows\x 映射为镜像内 /C:/Windows/x,/.system、/.vectors、/.logs 及其清单文件对读写与列举一律不可见; - 审计:每次调用(含被拒绝的调用)写入哈希链流 agent-audit,记录工具名、 参数、状态、错误类型与能力摘要,可 query/verify/retain; - run_script:盘内 VScript,默认禁止宿主读写,脚本超时与输出/写入字节数 均受限,避免脚本刷爆模型上下文。 修掉两处首次实现里的真实缺陷: 1. 能力授权名写成了沙箱名,而 _check 是按 fs/vector/log/checkpoint 这些 **命名空间**名匹配的,等于所有 fs 操作都会被拒。改为 "*"。 2. 脚本入口原本直接挂载 disk.fs,于是 fs.listdir(sandbox, "/") 能看到 /.system、/.logs,与 Python 侧 list_files 的规则不一致 —— 同一个镜像 两个入口两套规则。新增 _SandboxFS 让脚本侧走同一份路径规则:隐藏项在 读取/写入时拒绝、在 listdir/listdir_with_stat 时过滤、在 walk/glob 时 连目录本身一起剪掉(否则 fs.glob 仍会吐出 /.system)。两种入口现在共用 一个工作区,也共用同一套盲区。 tests/test_agent_sandbox.py 覆盖上述承诺,包括两个入口的根目录一致性、 路径逃逸与容器内部路径的拒绝、只读/禁删模式、审计链校验与篡改检测、 脚本的宿主隔离与输出上限。 --- pyvdisk/__init__.py | 9 + pyvdisk/sandbox.py | 679 ++++++++++++++++++++++++++++++++++++ tests/test_agent_sandbox.py | 253 ++++++++++++++ 3 files changed, 941 insertions(+) create mode 100644 pyvdisk/sandbox.py create mode 100644 tests/test_agent_sandbox.py diff --git a/pyvdisk/__init__.py b/pyvdisk/__init__.py index 624adb0..71478ea 100644 --- a/pyvdisk/__init__.py +++ b/pyvdisk/__init__.py @@ -73,6 +73,9 @@ NamespaceStore, CollectionStore, Event, EventStore, ExecutionContext, RunHandle, ExecutionPlane, ) +from . import compat +from .vector_index import FlatIndex, FlatIndexError +from .sandbox import AgentSandbox, SandboxError, ToolResult __version__ = "0.3.0" @@ -148,6 +151,12 @@ "ExecutionPlane", "ExecutionService", "ExecutionPlaneAdapter", + "compat", + "FlatIndex", + "FlatIndexError", + "AgentSandbox", + "SandboxError", + "ToolResult", "VFS", "VFile", "__version__", diff --git a/pyvdisk/sandbox.py b/pyvdisk/sandbox.py new file mode 100644 index 0000000..c2ace50 --- /dev/null +++ b/pyvdisk/sandbox.py @@ -0,0 +1,679 @@ +"""AgentSandbox: the whole stack behind one object an agent framework can call. + +An agent framework needs three things from a sandbox, and this class is exactly +those three: + +1. **A confined workspace.** ``AgentSandbox`` owns a DataDisk image and hands the + agent a path space inside it. There is no host path in the API, so a model + that invents ``../../etc/passwd`` or ``C:\\Windows`` gets a refusal, not a file. +2. **A tool surface.** :meth:`tools` returns JSON Schemas in the shape OpenAI + function calling, the Anthropic tool API and MCP all accept, and + :meth:`dispatch` routes a model's ``(name, arguments)`` back in. Ten lines of + framework code is the whole integration. +3. **An audit trail.** Every call -- including refused ones -- is appended to a + hash-chained log stream on the same disk, so "what did the agent do" has an + answer that :meth:`verify_audit` can check for tampering. + +The guarantees come from the layers underneath rather than a parallel +implementation: the file verbs go through the capability-scoped view +(:mod:`pyvdisk.infrastructure.capabilities`), the script tool runs on the VScript +runtime with an empty host policy (``host.*`` is unreachable unless you opt in), +and durability is the DataDisk's own transaction log. + + from pyvdisk import AgentSandbox + + with AgentSandbox.create("agent.vdisk") as box: + box.write("/notes.md", "hello") + box.dispatch("list_files", {"path": "/"}) +""" + +from __future__ import annotations + +import hashlib +import io +import json +import time +from dataclasses import dataclass, field +from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple + +from .contracts import CapabilityGrant, ExecutionContext +from .infrastructure.capabilities import scoped +from .infrastructure.disk import DataDisk +from .vscript import Compiler, MountRegistry, Runtime +from .vscript.audit import AuditRecord, DataDiskAuditSink +from .vscript.policy import Policy + +#: Default image size: enough for an agent scratch space, small enough to be fast. +DEFAULT_SIZE = 64 << 20 + +#: Permission strings the capability layer understands for files. +READ, WRITE, DELETE, ADMIN = "read", "write", "delete", "admin" + +#: The audit stream every tool call lands in. +AUDIT_STREAM = "agent-audit" + +#: Container bookkeeping the agent must not read or write. The capability view +#: already guards the three WAL/checkpoint files; these roots go further, because +#: a model that overwrites the manifest or the vector manifest bricks the image it +#: is working in. They are hidden from listings too, so the agent never sees a +#: path it cannot use. +HIDDEN_ROOTS = ("/.system", "/.vectors", "/.logs") + +#: Root-level manifests for those same namespaces (written by ``DataDisk.create``). +HIDDEN_PATHS = ("/.vector_disk.json", "/.log_disk.json") + + +def _hidden(path: str) -> bool: + if path in HIDDEN_PATHS: + return True + return any(path == root or path.startswith(root + "/") for root in HIDDEN_ROOTS) + + +class _SandboxFS: + """The filesystem a VScript program sees: same root, same blind spots. + + The Python verbs go through :meth:`AgentSandbox._visible`; without this the + script door would be a second entrance to the same image with different + rules, and ``fs.listdir(sandbox, "/")`` would hand the model the very paths + ``list_files`` refuses to show it. Paths are translated here and the calls + are forwarded, so the capability-scoped namespace underneath still applies. + """ + + def __init__(self, target: Any, translate: Any): + self._target = target + self._translate = translate + + def __getattr__(self, name: str): + """Everything without a path (``df``, ``fsck``, ...) is passed straight on.""" + return getattr(object.__getattribute__(self, "_target"), name) + + @staticmethod + def _keep(top: str, name: str) -> bool: + return not _hidden(f"{top.rstrip('/')}/{name}") + + def listdir(self, path: str = "/") -> List[str]: + directory = self._translate(path) + return [name for name in self._target.listdir(directory) if self._keep(directory, name)] + + def listdir_with_stat(self, path: str = "/") -> List[Any]: + """Names plus stats, hidden entries dropped. + + Built from ``listdir`` + ``stat`` rather than forwarded: the scoped + namespace the sandbox uses does not expose the bulk variant. + """ + directory = self._translate(path).rstrip("/") or "/" + return [(name, self._target.stat(f"{directory}/{name}" if directory != "/" else f"/{name}")) + for name in self._target.listdir(directory) if self._keep(directory, name)] + + def walk(self, path: str = "/"): + """Walk the visible tree. + + The underlying walk yields a directory even when every child is filtered, + so hidden roots have to be dropped as tops too -- otherwise ``fs.walk`` + (and ``fs.glob``, which is built on it) would still name ``/.system``. + """ + for top, dirs, files in self._target.walk(self._translate(path)): + if _hidden(top): + continue + yield (top, + [name for name in dirs if self._keep(top, name)], + [name for name in files if self._keep(top, name)]) + + def _forward(self, method: str, path: str, *args: Any, **kwargs: Any) -> Any: + return getattr(self._target, method)(self._translate(path), *args, **kwargs) + + def exists(self, path: str = "/") -> bool: + target = self._translate(path) + return False if _hidden(target) else self._target.exists(target) + + def isfile(self, path: str) -> bool: + target = self._translate(path) + return False if _hidden(target) else self._target.isfile(target) + + def isdir(self, path: str) -> bool: + target = self._translate(path) + return False if _hidden(target) else self._target.isdir(target) + + def stat(self, path: str) -> Any: + return self._forward("stat", path) + + def read_file(self, path: str) -> bytes: + return self._forward("read_file", path) + + def write_file(self, path: str, data: Any) -> Any: + return self._forward("write_file", path, data) + + def append_file(self, path: str, data: Any) -> Any: + return self._forward("append_file", path, data) + + def mkdir(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("mkdir", path, *args, **kwargs) + + def makedirs(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("makedirs", path, *args, **kwargs) + + def remove(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("remove", path, *args, **kwargs) + + def rmtree(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("rmtree", path, *args, **kwargs) + + def rename(self, source: str, destination: str, *args: Any, **kwargs: Any) -> Any: + return self._target.rename(self._translate(source), self._translate(destination), *args, **kwargs) + + def move(self, source: str, destination: str, *args: Any, **kwargs: Any) -> Any: + return self._target.move(self._translate(source), self._translate(destination), *args, **kwargs) + + def copy(self, source: str, destination: str, *args: Any, **kwargs: Any) -> Any: + return self._target.copy(self._translate(source), self._translate(destination), *args, **kwargs) + + def link(self, source: str, destination: str, *args: Any, **kwargs: Any) -> Any: + return self._target.link(self._translate(source), self._translate(destination), *args, **kwargs) + + def symlink(self, source: str, destination: str, *args: Any, **kwargs: Any) -> Any: + return self._target.symlink(self._translate(source), self._translate(destination), *args, **kwargs) + + def open(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("open", path, *args, **kwargs) + + def du(self, path: str = "/") -> Any: + return self._forward("du", path) + + def readlink(self, path: str) -> Any: + return self._forward("readlink", path) + + def truncate(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("truncate", path, *args, **kwargs) + + def chmod(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("chmod", path, *args, **kwargs) + + def chown(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("chown", path, *args, **kwargs) + + def utime(self, path: str, *args: Any, **kwargs: Any) -> Any: + return self._forward("utime", path, *args, **kwargs) + + +class SandboxError(Exception): + """The sandbox refused an operation before it reached the disk.""" + + +@dataclass(frozen=True) +class ToolResult: + """Outcome of one tool call, in a shape that is easy to log or assert on.""" + + ok: bool + content: str + tool: str = "" + error: Optional[str] = None + + def __str__(self) -> str: + return self.content + + +#: The tool surface. ``mutates`` decides whether a read-only sandbox offers it. +TOOLS: Tuple[Dict[str, Any], ...] = ( + { + "name": "write_file", + "description": "Create or overwrite a text file inside the sandbox. Parent directories are created.", + "mutates": True, + "parameters": { + "type": "object", + "properties": { + "path": {"type": "string", "description": "Absolute sandbox path, e.g. /report.md"}, + "content": {"type": "string", "description": "File content (UTF-8)"}, + }, + "required": ["path", "content"], + "additionalProperties": False, + }, + }, + { + "name": "read_file", + "description": "Read a text file from the sandbox.", + "mutates": False, + "parameters": { + "type": "object", + "properties": {"path": {"type": "string", "description": "Absolute sandbox path"}}, + "required": ["path"], + "additionalProperties": False, + }, + }, + { + "name": "list_files", + "description": "List the entries of a sandbox directory with their size and type.", + "mutates": False, + "parameters": { + "type": "object", + "properties": { + "path": {"type": "string", "description": "Directory to list (default /)"}, + "recursive": {"type": "boolean", "description": "Walk subdirectories too"}, + }, + "additionalProperties": False, + }, + }, + { + "name": "make_directory", + "description": "Create a directory (and any missing parents) inside the sandbox.", + "mutates": True, + "parameters": { + "type": "object", + "properties": {"path": {"type": "string", "description": "Directory path"}}, + "required": ["path"], + "additionalProperties": False, + }, + }, + { + "name": "delete_file", + "description": "Delete a file, or a directory when recursive is true.", + "mutates": True, + "parameters": { + "type": "object", + "properties": { + "path": {"type": "string", "description": "Path to delete"}, + "recursive": {"type": "boolean", "description": "Allow deleting a non-empty directory"}, + }, + "required": ["path"], + "additionalProperties": False, + }, + }, + { + "name": "run_script", + "description": ( + "Run a VScript program against this sandbox. The disk is bound as the variable " + "'sandbox': fs.write(sandbox, \"/a.txt\", \"hi\"), fs.read_text(sandbox, \"/a.txt\"), " + "fs.listdir(sandbox, \"/\"). Host access is not available. " + "Returns whatever the script printed." + ), + "mutates": True, + "parameters": { + "type": "object", + "properties": { + "source": {"type": "string", "description": "VScript source code"}, + "args": { + "type": "object", + "description": "String arguments exposed to the script via arg(name)", + "additionalProperties": {"type": "string"}, + }, + }, + "required": ["source"], + "additionalProperties": False, + }, + }, +) + +_BY_NAME = {tool["name"]: tool for tool in TOOLS} + + +def _canonical(arguments: Mapping[str, Any]) -> str: + return json.dumps(arguments, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str) + + +def _hash_call(tool: str, arguments: Mapping[str, Any]) -> str: + return hashlib.sha256(f"{tool}\x00{_canonical(arguments)}".encode("utf-8")).hexdigest() + + +class AgentSandbox: + """A confined, audited workspace with an agent-shaped tool interface.""" + + def __init__(self, disk: DataDisk, *, name: str = "sandbox", read_only: bool = False, + allow_delete: bool = True, run_id: Optional[str] = None, + script_timeout: float = 10.0, script_output_bytes: int = 256 * 1024, + script_write_bytes: int = 8 << 20, + host_read_roots: Sequence[str] = (), host_write_roots: Sequence[str] = (), + audit_stream: str = AUDIT_STREAM, audit_max_events: Optional[int] = 10000, + audit: bool = True): + if not getattr(disk, "mounted", False): + disk = disk.mount() + self.disk = disk + self.name = name + self.read_only = bool(read_only) + self.allow_delete = bool(allow_delete) and not self.read_only + self.run_id = run_id or hashlib.sha256(f"{time.time_ns()}:{id(self)}".encode()).hexdigest()[:16] + self.script_timeout = float(script_timeout) + self.script_output_bytes = int(script_output_bytes) + self.script_write_bytes = int(script_write_bytes) + self.host_read_roots = tuple(host_read_roots) + self.host_write_roots = tuple(host_write_roots) + self.audit_stream = audit_stream + self.audit_max_events = audit_max_events + self._calls = 0 + self._failures = 0 + + permissions = {READ} + if not self.read_only: + permissions.add(WRITE) + if self.allow_delete: + permissions.add(DELETE) + self._permissions = frozenset(permissions) + # The verbs go through the capability-scoped view, so a read-only sandbox + # refuses a write at the governance layer even if a caller reaches past + # the tool surface and calls write() directly. + self._context = ExecutionContext( + run_id=self.run_id, + # "*" is how the governance layer spells "every namespace": the grant + # is matched by name against fs/vector/log/checkpoint, so naming it + # after the sandbox would match none of them and refuse everything. + capabilities=(CapabilityGrant(name="*", permissions=self._permissions, scope="/"),), + ) + self._scoped = scoped(disk, self._context) + self._sink = None + if audit: + self._sink = self._open_sink() + + # ---- construction ---------------------------------------------------- + + @classmethod + def create(cls, path: str, *, size_bytes: int = DEFAULT_SIZE, label: str = "agent sandbox", + **options: Any) -> "AgentSandbox": + """Create a new sandbox image and return it, mounted.""" + DataDisk.create(path, size_bytes, label=label) + return cls(DataDisk(path).mount(), **options) + + @classmethod + def open(cls, path: str, **options: Any) -> "AgentSandbox": + """Open an existing sandbox image.""" + return cls(DataDisk(path).mount(), **options) + + def _open_sink(self) -> DataDiskAuditSink: + streams = self.disk.logs.list_streams() + names = {item if isinstance(item, str) else item.get("name") for item in streams} + if self.audit_stream not in names: + self.disk.logs.create_stream(self.audit_stream, max_events=self.audit_max_events) + return DataDiskAuditSink(self.disk, stream=self.audit_stream, chained=True) + + # ---- filesystem verbs ------------------------------------------------ + + def _normalize(self, path: Any) -> str: + """Map anything a model sends onto a path inside the sandbox. + + ``C:\\Windows`` becomes ``/C:/Windows`` -- a directory inside the image, + never the host path it looks like. ``..`` is refused outright rather + than resolved, so the refusal is visible in the audit trail. + """ + if not isinstance(path, str) or not path.strip(): + raise SandboxError("path must be a non-empty string") + if "\x00" in path: + raise SandboxError("path contains NUL") + parts: List[str] = [] + for part in path.replace("\\", "/").split("/"): + if part in ("", "."): + continue + if part == "..": + raise SandboxError("path may not escape the sandbox root") + parts.append(part) + return "/" + "/".join(parts) + + def _visible(self, path: Any) -> str: + """Normalize, then refuse the container's own bookkeeping paths.""" + target = self._normalize(path) + if _hidden(target): + raise SandboxError(f"{target} is container bookkeeping and is not accessible") + return target + + def _parents(self, path: str) -> List[str]: + segments = [p for p in path.strip("/").split("/")[:-1] if p] + out, seen = [], "" + for name in segments: + seen = f"{seen}/{name}" + out.append(seen) + return out + + def write(self, path: str, content: Any) -> int: + """Write ``content`` to ``path``, creating parent directories.""" + target = self._visible(path) + raw = content.encode("utf-8") if isinstance(content, str) else bytes(content) + for parent in self._parents(target): + if not self._scoped.fs.exists(parent): + self._scoped.fs.makedirs(parent) + self._scoped.fs.write_file(target, raw) + return len(raw) + + def read(self, path: str) -> bytes: + """Read the raw bytes at ``path``.""" + return self._scoped.fs.read_file(self._visible(path)) + + def read_text(self, path: str, encoding: str = "utf-8", errors: str = "replace") -> str: + return self.read(path).decode(encoding, errors) + + def list(self, path: str = "/", recursive: bool = False) -> List[Dict[str, Any]]: + """Entries under ``path``, each with its name, type and size.""" + target = self._visible(path) + entries: List[Dict[str, Any]] = [] + + def collect(directory: str) -> None: + for name in self._scoped.fs.listdir(directory): + child = f"{directory.rstrip('/')}/{name}" + if _hidden(child): + continue + stat = self._scoped.fs.stat(child) + entries.append({"path": child, "type": "dir" if stat.is_dir else "file", "size": stat.size}) + if recursive and stat.is_dir: + collect(child) + + collect(target) + return entries + + def delete(self, path: str, recursive: bool = False) -> None: + """Delete a file, or a directory when ``recursive``.""" + target = self._visible(path) + if self._scoped.fs.isdir(target): + if not recursive: + raise SandboxError("path is a directory; pass recursive=true to delete it") + self._scoped.fs.rmtree(target) + else: + self._scoped.fs.remove(target) + + def make_directory(self, path: str) -> str: + target = self._visible(path) + self._scoped.fs.makedirs(target) + return target + + def exists(self, path: str) -> bool: + target = self._normalize(path) + return False if _hidden(target) else self._scoped.fs.exists(target) + + def run(self, source: str, *, args: Optional[Mapping[str, str]] = None, + timeout: Optional[float] = None) -> str: + """Run a VScript program with this sandbox bound as ``sandbox``. + + The host policy is empty unless the sandbox was constructed with host + roots, so ``host.read``/``host.write`` fail even though the language + supports them. + """ + permissions = set(self._permissions) + registry = MountRegistry() + handle = registry.grant(self.name, "fs", _SandboxFS(self._scoped.fs, self._visible), + permissions=permissions, root="/") + policy = Policy( + max_wall_time=self.script_timeout if timeout is None else float(timeout), + max_write_bytes=self.script_write_bytes, + max_output_bytes=self.script_output_bytes, + host_read_roots=list(self.host_read_roots), + host_write_roots=list(self.host_write_roots), + ) + buffer = io.StringIO() + runtime = Runtime(policy=policy, stdout=buffer, mount_registry=registry, + allowed_mounts={self.name: permissions}) + try: + program = Compiler().compile(source, "") + value = runtime.run(program.ast, args=dict(args or {}), bindings={self.name: handle}, source=source) + finally: + registry.close() + text = buffer.getvalue() + if value is not None: + rendered = runtime.stringify(value) + if rendered and rendered != "null": + text = f"{text}{rendered}\n" + return text + + # ---- tool surface ---------------------------------------------------- + + def tools(self, style: str = "openai") -> List[Dict[str, Any]]: + """Tool definitions for the framework's own calling convention. + + ``openai`` and ``anthropic`` share ``{name, description, parameters}``; + ``mcp`` renames the schema key to ``inputSchema``. + """ + if style not in ("openai", "anthropic", "mcp"): + raise SandboxError(f"unknown tool style: {style}") + key = "inputSchema" if style == "mcp" else "parameters" + out = [] + for tool in TOOLS: + if self.read_only and tool["mutates"]: + continue + if tool["name"] == "delete_file" and not self.allow_delete: + continue + out.append({"name": tool["name"], "description": tool["description"], key: tool["parameters"]}) + return out + + def call(self, name: str, arguments: Optional[Mapping[str, Any]] = None) -> ToolResult: + """Run one tool call and audit it, whatever the outcome.""" + arguments = dict(arguments or {}) + started = time.time() + try: + content = self._invoke(name, arguments) + result = ToolResult(True, content, name) + except Exception as exc: # noqa: BLE001 - every failure is reported to the model + message = f"{type(exc).__name__}: {exc}" + result = ToolResult(False, message, name, error=message) + self._record(name, arguments, result, started) + return result + + def dispatch(self, name: str, arguments: Optional[Mapping[str, Any]] = None) -> str: + """What a framework feeds back to the model: always a string.""" + return str(self.call(name, arguments)) + + def _invoke(self, name: str, arguments: Mapping[str, Any]) -> str: + if name not in _BY_NAME: + raise SandboxError(f"unknown tool: {name}") + spec = _BY_NAME[name] + if self.read_only and spec["mutates"]: + raise SandboxError(f"{name} is not available: sandbox is read-only") + if name == "delete_file" and not self.allow_delete: + raise SandboxError("delete_file is not available: deletion is disabled") + missing = [key for key in spec["parameters"].get("required", []) if key not in arguments] + if missing: + raise SandboxError(f"missing required argument(s): {', '.join(missing)}") + if name == "write_file": + written = self.write(arguments["path"], arguments["content"]) + return f"wrote {written} bytes to {self._normalize(arguments['path'])}" + if name == "read_file": + data = self.read(arguments["path"]) + text = data.decode("utf-8", "replace") + return text if len(text) <= 200000 else f"{text[:200000]}\n... [{len(data)} bytes total]" + if name == "list_files": + entries = self.list(arguments.get("path", "/"), bool(arguments.get("recursive", False))) + if not entries: + return f"{self._normalize(arguments.get('path', '/'))}: empty" + lines = [f"{'dir ' if e['type'] == 'dir' else 'file'} {e['size']:>9} {e['path']}" for e in entries] + return "\n".join(lines) + if name == "make_directory": + return f"created {self.make_directory(arguments['path'])}" + if name == "delete_file": + target = self._normalize(arguments["path"]) + self.delete(arguments["path"], bool(arguments.get("recursive", False))) + return f"deleted {target}" + if name == "run_script": + output = self.run(arguments["source"], args=arguments.get("args")) + return output if output else "(script produced no output)" + raise SandboxError(f"tool {name} has no implementation") + + # ---- audit ----------------------------------------------------------- + + def _record(self, tool: str, arguments: Mapping[str, Any], result: ToolResult, started: float) -> None: + self._calls += 1 + if not result.ok: + self._failures += 1 + if self._sink is None: + return + metrics = { + "tool": tool, + "arguments": json.loads(_canonical(arguments)), + "duration_ms": round((time.time() - started) * 1000.0, 3), + "ok": result.ok, + "result_bytes": len(result.content.encode("utf-8")), + } + error = {"type": "SandboxError", "message": result.error} if result.error else None + self._sink.emit(AuditRecord( + run_id=self.run_id, + script_hash=_hash_call(tool, arguments), + policy_hash=self._policy_hash(), + status="success" if result.ok else "failure", + metrics=metrics, + error=error, + started_at=started, + finished_at=time.time(), + capability_summary={"name": self.name, "permissions": sorted(self._permissions)}, + )) + + def _policy_hash(self) -> str: + payload = _canonical({ + "read_only": self.read_only, + "allow_delete": self.allow_delete, + "host_read_roots": list(self.host_read_roots), + "host_write_roots": list(self.host_write_roots), + "script_timeout": self.script_timeout, + }) + return hashlib.sha256(payload.encode("utf-8")).hexdigest() + + def audit(self, **filters: Any) -> List[Dict[str, Any]]: + """Audit rows, oldest first. + + Filters are the sink's own (``run_id``, ``status``, ``since``, ``until``, + ``limit``, ``newest_first``) plus ``tool``, which selects on the tool name + recorded in the row's metrics. + """ + if self._sink is None: + return [] + tool = filters.pop("tool", None) + rows = list(self._sink.query(**filters)) + if tool is not None: + rows = [row for row in rows if (row.get("metrics") or {}).get("tool") == tool] + return rows + + def verify_audit(self) -> Dict[str, Any]: + """Check the hash chain over the audit stream.""" + if self._sink is None: + return {"ok": True, "length": 0, "reason": "audit disabled"} + return self._sink.verify() + + def retain_audit(self) -> Dict[str, Any]: + """Ask the log layer to enforce the stream's retention policy now.""" + if self._sink is None: + return {"kept": 0, "dropped": 0} + return self._sink.retain() + + # ---- lifecycle ------------------------------------------------------- + + @property + def calls(self) -> int: + return self._calls + + @property + def failures(self) -> int: + return self._failures + + def stats(self) -> Dict[str, Any]: + usage = self._scoped.fs.df() + return { + "name": self.name, + "run_id": self.run_id, + "read_only": self.read_only, + "tools": [tool["name"] for tool in self.tools()], + "calls": self._calls, + "failures": self._failures, + "disk": usage, + } + + def close(self) -> None: + self.disk.close() + + def __enter__(self) -> "AgentSandbox": + return self + + def __exit__(self, *exc: Any) -> None: + self.close() + + +__all__ = ["AgentSandbox", "SandboxError", "ToolResult", "TOOLS", "DEFAULT_SIZE", "AUDIT_STREAM"] diff --git a/tests/test_agent_sandbox.py b/tests/test_agent_sandbox.py new file mode 100644 index 0000000..47b367c --- /dev/null +++ b/tests/test_agent_sandbox.py @@ -0,0 +1,253 @@ +"""AgentSandbox: the confinement, the tool surface and the audit trail. + +These are the properties an agent framework is trusting when it hands this object +to a model, so they are tested as promises rather than as implementation: + +* the path space is the image, not the host -- ``..``, ``C:\\Windows`` and the + container's own bookkeeping are refused; +* a read-only sandbox refuses writes at the governance layer, not just by hiding + the tool; +* every call, including every refusal, lands in a hash-chained audit stream; +* ``run_script`` cannot reach the host, and its output is bounded so a script + cannot flood the model's context. +""" +from __future__ import annotations + +import json + +import pytest + +from pyvdisk import DataDisk +from pyvdisk.sandbox import AUDIT_STREAM, TOOLS, AgentSandbox, SandboxError +from pyvdisk.vscript.audit import DataDiskAuditSink +from pyvdisk.vscript.errors import CapabilityError + + +@pytest.fixture +def box(tmp_path): + with AgentSandbox.create(str(tmp_path / "agent.vdisk"), size_bytes=32 << 20) as sandbox: + yield sandbox + + +def test_create_then_reopen_keeps_the_workspace(tmp_path): + path = str(tmp_path / "agent.vdisk") + with AgentSandbox.create(path) as first: + first.dispatch("write_file", {"path": "/notes.md", "content": "kept"}) + run_id = first.run_id + with AgentSandbox.open(path) as second: + assert second.read_text("/notes.md") == "kept" + assert second.run_id != run_id + assert second.verify_audit()["length"] == 1, "the audit stream survives a reopen" + assert second.audit()[0]["run_id"] == run_id + + +def test_the_tool_surface_has_one_definition_per_framework_shape(box): + names = [tool["name"] for tool in box.tools()] + assert names == [tool["name"] for tool in TOOLS] + for style, key in (("openai", "parameters"), ("anthropic", "parameters"), ("mcp", "inputSchema")): + tools = box.tools(style=style) + assert [tool["name"] for tool in tools] == names + assert all(key in tool and "description" in tool for tool in tools) + with pytest.raises(SandboxError): + box.tools(style="langchain") + + +def test_every_advertised_tool_is_dispatchable(box): + assert box.dispatch("write_file", {"path": "/a.txt", "content": "hello"}).startswith("wrote 5 bytes") + assert box.dispatch("read_file", {"path": "/a.txt"}) == "hello" + assert "file" in box.dispatch("list_files", {"path": "/"}) + assert box.dispatch("make_directory", {"path": "/d/e"}) == "created /d/e" + assert box.dispatch("delete_file", {"path": "/a.txt"}) == "deleted /a.txt" + output = box.dispatch("run_script", {"source": 'print("from vscript");'}) + assert "from vscript" in output + assert box.failures == 0, box.audit(status="failure") + + +def test_dispatch_always_returns_a_string(box): + for name, arguments in (("nope", {}), ("write_file", {"path": "/x"}), ("read_file", {"path": "/missing"})): + result = box.dispatch(name, arguments) + assert isinstance(result, str) and result + assert box.failures == 3 + + +def test_paths_cannot_escape_the_sandbox(box): + for path in ("../outside.txt", "/a/../../outside.txt", "..\\outside.txt"): + assert "may not escape" in box.dispatch("write_file", {"path": path, "content": "x"}) + assert not box.exists("/outside.txt") + + +def test_a_windows_looking_path_stays_inside_the_image(box): + """``C:\\Windows\\x`` is a directory in the sandbox, never the host path.""" + box.dispatch("write_file", {"path": r"C:\Windows\evil.txt", "content": "x"}) + assert box.read_text("/C:/Windows/evil.txt") == "x" + + +def test_empty_and_nul_paths_are_refused(box): + for path in ("", " ", "/a\x00b"): + assert not box.call("read_file", {"path": path}).ok + + +def test_container_bookkeeping_is_hidden_and_refused(box): + for path in ("/.system/manifest.json", "/.system/wal.jsonl", "/.vectors", "/.logs", "/.vector_disk.json"): + result = box.call("read_file", {"path": path}) + assert not result.ok and "bookkeeping" in result.content + listing = box.dispatch("list_files", {"path": "/", "recursive": True}) + for hidden in ("/.system", "/.vectors", "/.logs", "/.vector_disk.json", "/.log_disk.json"): + assert hidden not in listing + assert box.exists("/.system/manifest.json") is False + + +def test_a_read_only_sandbox_refuses_writes_and_hides_the_tools(tmp_path): + with AgentSandbox.create(str(tmp_path / "ro.vdisk"), read_only=True) as box: + names = [tool["name"] for tool in box.tools()] + assert "write_file" not in names and "delete_file" not in names and "run_script" not in names + assert names == ["read_file", "list_files"] + assert not box.call("write_file", {"path": "/x", "content": "y"}).ok + # The refusal is enforced by the capability layer, not only by the tool list. + with pytest.raises(PermissionError): + box.write("/direct.txt", "y") + with pytest.raises(CapabilityError): + box.run('import std.fs as fs; fs.write(sandbox, "/x", "y");') + + +def test_deletion_can_be_disabled_without_making_the_sandbox_read_only(tmp_path): + with AgentSandbox.create(str(tmp_path / "nodelete.vdisk"), allow_delete=False) as box: + box.write("/keep.txt", "x") + assert "delete_file" not in [tool["name"] for tool in box.tools()] + assert not box.call("delete_file", {"path": "/keep.txt"}).ok + assert box.exists("/keep.txt") + + +def test_every_call_is_audited_with_its_arguments_and_outcome(box): + box.dispatch("write_file", {"path": "/a.txt", "content": "hello"}) + box.dispatch("read_file", {"path": "/nope.txt"}) + box.dispatch("nope", {}) + rows = box.audit() + assert [row["metrics"]["tool"] for row in rows] == ["write_file", "read_file", "nope"] + assert [row["status"] for row in rows] == ["success", "failure", "failure"] + assert rows[0]["metrics"]["arguments"] == {"path": "/a.txt", "content": "hello"} + assert rows[1]["error"]["type"] == "SandboxError" + assert all(row["run_id"] == box.run_id for row in rows) + assert rows[0]["capability_summary"]["permissions"] == ["delete", "read", "write"] + assert [row["metrics"]["tool"] for row in box.audit(status="failure")] == ["read_file", "nope"] + assert [row["metrics"]["tool"] for row in box.audit(tool="nope")] == ["nope"] + + +def test_the_audit_chain_verifies_and_detects_a_foreign_row(box): + box.dispatch("write_file", {"path": "/a.txt", "content": "x"}) + report = box.verify_audit() + assert report["ok"] is True and report["length"] == 1 + assert box.audit()[0]["prev_hash"] and box.audit()[0]["hash"] + # Append a row that did not go through the sink: the chain must notice. + from pyvdisk.logging_core import LogEvent + box.disk.logs.append(AUDIT_STREAM, LogEvent(1, "INFO", "attacker", DataDiskAuditSink.MESSAGE, + fields={"tool": "forged", "hash": "0" * 64})) + broken = box.verify_audit() + assert broken["ok"] is False + + +def test_retention_keeps_the_chain_verifiable(tmp_path): + """Retention drops rows; the chain anchor must let verify() resume past the gap.""" + path = str(tmp_path / "retain.vdisk") + DataDisk.create(path, 32 << 20) + with DataDisk(path) as disk: + # Small segments so rows can actually age out; the sandbox reuses this stream. + disk.logs.create_stream(AUDIT_STREAM, segment_events=2, max_events=2) + with AgentSandbox.open(path) as box: + for index in range(8): + box.dispatch("write_file", {"path": f"/f{index}.txt", "content": str(index)}) + before = len(box.audit()) + result = box.retain_audit() + assert result["dropped"] >= 1 + assert len(box.audit()) < before + assert box.verify_audit()["ok"] is True + + +def test_scripts_are_confined_to_the_sandbox(box): + script = ( + 'import std.fs as fs;\n' + 'fs.write(sandbox, "/from-script.txt", "written by a script");\n' + 'print("script read:", fs.read_text(sandbox, "/from-script.txt"));\n' + ) + output = box.dispatch("run_script", {"source": script}) + assert "script read: written by a script" in output + assert box.read_text("/from-script.txt") == "written by a script" + + +def test_scripts_see_the_same_root_as_the_python_verbs(box): + """Both doors must agree: no hidden paths leak through the script door.""" + box.write("/report.md", "hi") + listing = box.dispatch("run_script", {"source": 'import std.fs as fs; print(fs.listdir(sandbox, "/"));'}) + assert "report.md" in listing + for hidden in (".system", ".vectors", ".logs", ".vector_disk.json", ".log_disk.json"): + assert hidden not in listing, f"{hidden} leaked through listdir" + walked = box.dispatch("run_script", {"source": 'import std.fs as fs; print(fs.walk(sandbox, "/"));'}) + assert ".system" not in walked and ".logs" not in walked + globbed = box.dispatch("run_script", {"source": 'import std.fs as fs; print(fs.glob(sandbox, "/*"));'}) + assert "/report.md" in globbed and "/.system" not in globbed + + +def test_scripts_cannot_touch_container_bookkeeping(box): + for source in ('import std.fs as fs; print(fs.read_text(sandbox, "/.system/manifest.json"));', + 'import std.fs as fs; fs.write(sandbox, "/.vector_disk.json", "{}");', + 'import std.fs as fs; print(fs.listdir(sandbox, "/.vectors"));', + 'import std.fs as fs; print(fs.exists(sandbox, "/.system/wal.jsonl"));'): + result = box.call("run_script", {"source": source}) + assert not result.ok and "bookkeeping" in result.content, source + + +def test_the_script_and_python_doors_share_one_workspace(box): + """A file written by a script is an ordinary file for every other verb.""" + box.dispatch("run_script", {"source": 'import std.fs as fs; fs.write(sandbox, "/shared.txt", "from script");'}) + assert box.read_text("/shared.txt") == "from script" + box.write("/from-python.txt", "from python") + seen = box.dispatch("run_script", {"source": 'import std.fs as fs; print(fs.read_text(sandbox, "/from-python.txt"));'}) + assert "from python" in seen + + +def test_scripts_cannot_reach_the_host_by_default(box): + for source in ('import std.host as host; print(host.read("/etc/passwd"));', + 'import std.host as host; host.write("/tmp/pyvdisk-escape", "x"); print("wrote");'): + result = box.call("run_script", {"source": source}) + assert not result.ok and "未授权" in result.content + + +def test_host_roots_are_opt_in(tmp_path): + allowed = tmp_path / "shared" + allowed.mkdir() + (allowed / "input.txt").write_text("from the host", encoding="utf-8") + with AgentSandbox.create(str(tmp_path / "host.vdisk"), host_read_roots=[str(allowed)]) as box: + result = box.call("run_script", { + "source": f'import std.host as host; print(host.read("{allowed}/input.txt"));', + }) + assert result.ok and "from the host" in result.content + + +def test_script_output_is_bounded_so_a_script_cannot_flood_the_context(tmp_path): + with AgentSandbox.create(str(tmp_path / "loud.vdisk"), script_output_bytes=512) as box: + result = box.call("run_script", {"source": 'let i = 0; while i < 5000 { print("x".repeat(200)); i = i + 1; }'}) + assert not result.ok + assert len(result.content) < 1000 + + +def test_a_script_timeout_is_a_failed_call_not_a_hang(tmp_path): + with AgentSandbox.create(str(tmp_path / "slow.vdisk")) as box: + result = box.call("run_script", {"source": 'let i = 0; while true { i = i + 1; }', "args": {}}) + assert not result.ok + assert "超时" in result.content or "ResourceLimit" in result.content + + +def test_stats_reports_the_tool_set_and_the_call_counts(box): + box.write("/a.txt", "x") # a direct verb: not a tool call, so not counted + box.call("read_file", {"path": "/missing"}) + stats = box.stats() + assert stats["name"] == "sandbox" + assert stats["calls"] == 1 and stats["failures"] == 1 + assert "run_script" in stats["tools"] + assert stats["disk"]["total_bytes"] > 0 + json.dumps(stats) # must stay JSON-serialisable for logs and dashboards + + +def test_a_sandbox_closes_its_disk(box): + box.close() + assert box.disk.mounted is False From 23606954bb01e19a509e9cfdd8e6ba6738f2ba17 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:26:23 +0800 Subject: [PATCH 04/15] =?UTF-8?q?docs:=20=E6=97=A0=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E4=B8=8A=E6=89=8B=E7=A4=BA=E4=BE=8B=E3=80=81?= =?UTF-8?q?Agent=20=E6=A1=86=E6=9E=B6=E5=AF=B9=E6=8E=A5=20Demo=20=E4=B8=8E?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit examples/quickstart.py:单文件、仅标准库、Windows/Linux 通用,自底向上跑通 块设备与文件系统、事务与检查点、向量检索(有/无 hnswlib 两种后端)、结构化 日志、VScript、AgentSandbox。刻意不依赖 pyvdisk 已安装(未安装时把仓库根加进 sys.path),保证"下载即可运行"。 examples/agent_tools.py:一个可运行的 agent loop,内置脚本化"模型", 不需要 API key 与网络,因此可以进 CI。循环本身与对接真实框架时完全一致, 只把 scripted_model 换成真实客户端即可;示例里包含一次被拒绝的越权读取, 说明拒绝会像普通工具结果一样回灌给模型。 README: - 快速开始补上零依赖说明、quickstart 一行命令、可选 extra 的安装方式; - 新增"对接 Agent 框架(10 行)"小节; - 架构图 Vector 一格改为 "HNSW / flat memory"; - 核心能力补"零外部依赖"一条; - 回归数字 391 → 444(不装 hnswlib 时 440 passed / 4 skipped),并说明 跳过的是对照类用例而非核心路径。 CHANGELOG 记录这三块改动,含 flat 索引的代价(O(n) 查询)与两种后端的互读性。 --- CHANGELOG.md | 12 +++ README.md | 39 ++++++++-- examples/agent_tools.py | 83 ++++++++++++++++++++ examples/quickstart.py | 164 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 examples/agent_tools.py create mode 100644 examples/quickstart.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 353b0fb..b626c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ ## [Unreleased] +### 新增 — 零依赖与跨平台(issue #2) +- **Windows 兼容层**:新增 `pyvdisk/compat.py`,把全部平台原语收敛到一处 —— 定位读写(`os.pread/pwrite` ↔ `lseek`+`read/write` + 互斥)、文件锁(`fcntl.flock` ↔ `msvcrt.locking`)、目录 `fsync`、`uid/gid`、符号链接探测。此前 `pyvdisk/infrastructure/checkpoint.py` 顶层 `import fcntl`,在 Windows 上连导入都会失败。现在除 `compat.py` 外,包内不再直接触碰这些原语,`tests/test_compat.py` 用一条守卫测试固定该约束。 +- **去外部依赖**:`dependencies` 由 `["hnswlib>=0.8.0"]` 改为 `[]`。`VectorDisk` 新增内置 flat 索引后端(`pyvdisk/vector_index.py`),无 hnswlib 时自动回退,查询由 O(log n) 变 O(n) 但结果一致;索引文件带 `PVFLAT01` 魔数标识写入方,**两种后端互相可读**(hnswlib 写的盘无 hnswlib 也能查,反之亦然)。hnswlib / fusepy 降级为可选 extra:`pyvdisk[vector]`、`pyvdisk[fuse]`。 +- **单文件快速上手**:新增 `examples/quickstart.py`(仅标准库,Windows / Linux 通用,无外部依赖),自底向上演示块设备、事务与检查点、向量检索、结构化日志、VScript、AgentSandbox。 + +### 新增 — AgentSandbox(issue #2) +- **`AgentSandbox`**:把 DataDisk 包成可直接交给 Agent 框架的工作区。`create()` / `open()`、`tools(style="openai"|"anthropic"|"mcp")`、`dispatch(name, arguments)`、`call()`(返回结构化 `ToolResult`)、`stats()`。 +- **六个内置工具**:`write_file`、`read_file`、`list_files`、`make_directory`、`delete_file`、`run_script`;`read_only=True` 时按 capability 层拒绝写(不只是隐藏工具),`allow_delete=False` 可单独关掉删除。 +- **路径空间是镜像不是宿主**:`..` 直接拒绝(不解析,便于审计留痕),`C:\Windows\x` 映射为镜像内 `/C:/Windows/x`;`/.system`、`/.vectors`、`/.logs` 及其清单文件对读写与列举一律不可见,脚本入口(`_SandboxFS`)与 Python 入口共用同一套路径规则。 +- **审计**:每次工具调用(含被拒绝的调用)写入哈希链审计流 `agent-audit`,记录工具名、参数、状态、错误类型与能力摘要;`audit()` / `verify_audit()` / `retain_audit()` 可查、可校验、可裁剪。 +- **`run_script`**:盘内 VScript 执行,默认不允许宿主读写(`host_read_roots` / `host_write_roots` 显式开启),脚本超时与输出/写入字节数均受限,避免脚本刷爆模型上下文。 + ### 修复 — ACID 与事务 - **A1** DataDisk 事务不再只覆盖 metadata:FS/Vector/Log 副作用走写前撤销日志(`kind=undo`),`abort()` 可回滚。 - **A2** participant 副作用在崩溃后由持久化的写前补偿日志按逆序补偿,并写入 `compensated` 标记;补偿幂等,重复 mount 结果一致。 diff --git a/README.md b/README.md index 4ed4b52..f244175 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![GitHub](https://img.shields.io/badge/GitHub-PyVDisk-181717?logo=github)](https://github.com/HeDaas-Code/pyvdisk) [![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) -[![Tests](https://img.shields.io/badge/Tests-391%20passed-2ea44f)](#验证) +[![Tests](https://img.shields.io/badge/Tests-444%20passed-2ea44f)](#验证) PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行基础设施项目:DataDisk 负责统一数据与执行基础设施,VScript 负责安全工作流语言、CLI、REPL 与运行时。 @@ -16,7 +16,7 @@ PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行 ## 架构总览 -
Agent / 应用
VScript · Python API · CLI · REPL · HostProxy
ExecutionCapabilityStorage
ExecutionService
DurableQueue
worker · lease · retry · DLQ
RunState · Audit
ScopedDataDisk
FS / Vector / Log / Checkpoint
逐操作权限
DataDisk
单一 .vdisk
WAL · transaction · recovery
FSVectorLog
workspaceHNSW memory
generation · checksum
trace
sequence · replay · ack
VirtualDisk · Volume · lock · fsync · mirror degraded fallback
+
Agent / 应用
VScript · Python API · CLI · REPL · HostProxy
ExecutionCapabilityStorage
ExecutionService
DurableQueue
worker · lease · retry · DLQ
RunState · Audit
ScopedDataDisk
FS / Vector / Log / Checkpoint
逐操作权限
DataDisk
单一 .vdisk
WAL · transaction · recovery
FSVectorLog
workspaceHNSW / flat memory
generation · checksum
trace
sequence · replay · ack
VirtualDisk · Volume · lock · fsync · mirror degraded fallback
## 架构图谱 @@ -84,9 +84,17 @@ graph TD ## 快速开始 +**零依赖**:核心只用标准库,`pip install pyvdisk` 不需要编译任何东西(hnswlib / fusepy 都是可选加速项)。一条命令跑通全栈: + +```bash +python examples/quickstart.py # 单文件、无外部依赖,Windows / Linux 通用 +``` + ```bash python -m pip install -e . -python -m pip install -e ".[dev]" +python -m pip install -e ".[dev]" # 开发依赖 +python -m pip install -e ".[vector]" # 可选:hnswlib 近似最近邻(不装则用内置 flat 索引) +python -m pip install -e ".[fuse]" # 可选:FUSE 挂载 ``` ```python @@ -99,6 +107,25 @@ with DataDisk.create("agent.vdisk", 32 * 1024 * 1024) as disk: disk.log.append("events", level="INFO", logger="demo", message="started") ``` +### 对接 Agent 框架(10 行) + +`AgentSandbox` 把 DataDisk 包成一个"给模型用的工作区":路径被限制在镜像内,工具调用全部落进哈希链审计流。 + +```python +from pyvdisk import AgentSandbox + +box = AgentSandbox.create("agent.vdisk") # 或 AgentSandbox.open(...) 续用已有镜像 +client = OpenAI().chat.completions # 换成任意框架的客户端 + +while True: # 标准 agent loop + reply = client.create(model="gpt-4o", messages=messages, tools=box.tools()) + call = reply.choices[0].message.tool_calls[0] # 模型要调用的工具 + result = box.dispatch(call.function.name, json.loads(call.function.arguments)) + messages += [reply.choices[0].message, {"role": "tool", "tool_call_id": call.id, "content": result}] +``` + +`box.tools()` 支持 `openai` / `anthropic` / `mcp` 三种 schema;`box.dispatch()` 永远返回字符串(失败也是字符串),可以直接塞回消息列表。可运行版本见 [examples/agent_tools.py](examples/agent_tools.py)(内置脚本化"模型",无需 API key)。 + ## VScript VScript 与 PyVDisk 共用 DataDisk、namespace、capability、事务、WAL 和审计模型,支持 Lexer、Parser、解释器、变量、表达式、循环、函数、模块、标准库、事务、rollback、task/await/parallel、cron、触发器、REPL 和盘内脚本。详细规范见 [docs/VSCRIPT_SPEC.md](docs/VSCRIPT_SPEC.md)。 @@ -112,6 +139,7 @@ pyvdisk vscript run-disk tools.vdisk:/.vscript/scripts/job.vds ## 核心能力 +- 零外部依赖:核心仅用标准库,`dependencies = []`;Windows / Linux 同一套代码(`pyvdisk/compat.py` 收敛定位读写、文件锁、目录 fsync、uid/gid 等平台差异)。hnswlib(近似最近邻)与 fusepy(FUSE 挂载)是可选加速项,不装也能跑全栈:`VectorDisk` 自动回退到内置 flat 索引,索引文件带写入方标识,两种后端互相可读。 - Storage Plane:FS、Vector、Log、Checkpoint、Metadata、WAL、VirtualDisk、Volume。 - Execution Plane:ExecutionService、DurableQueue、worker、lease、heartbeat、retry、idempotency、dead-letter、RunState、Audit。 - WAL 检查点:日志结算后整段截断(`wal.ckpt.json` 记录明细),重挂载只重放检查点之后的尾巴;DataDisk 与 VScript 共用同一份 WAL 实现,`vscript run --wal` 是它的真实恢复入口。 @@ -149,5 +177,6 @@ pyvdisk info image.vdisk .venv/bin/python -m pytest -q ``` -当前回归:391 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) -其中 3.11 本地缺 hnswlib 时有 5 例跳过(该版本无法编译 hnswlib),CI 环境正常。 +当前回归:444 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) + +不装 hnswlib 时同一套用例为 440 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 diff --git a/examples/agent_tools.py b/examples/agent_tools.py new file mode 100644 index 0000000..baa6e8d --- /dev/null +++ b/examples/agent_tools.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +"""Wire AgentSandbox into an agent loop -- offline, no API key, no network. + + python examples/agent_tools.py [workdir] + +The "model" here is a scripted list of tool calls, so this runs anywhere. The +loop is exactly the one you write against a real framework: ask the model, run +every tool call it asks for, feed the results back, repeat until it stops asking. +Swap ``scripted_model`` for an [OI]-compatible client and nothing else changes -- +``box.tools()`` and ``box.dispatch()`` are the whole integration surface. + +Note the last scripted call: the model asks to read ``/etc/passwd`` and gets a +refusal, which is fed back like any other tool result. That is the point of +running an agent against a sandbox rather than a directory. +""" +from __future__ import annotations + +import importlib.util +import json +import os +import sys +import tempfile + +if importlib.util.find_spec("pyvdisk") is None: + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from pyvdisk import AgentSandbox # noqa: E402 - the path fix has to run first + +#: What a model would have produced. Each entry is one assistant turn. +SCRIPTED_TURNS = [ + {"tool": "list_files", "arguments": {"path": "/"}}, + {"tool": "write_file", "arguments": { + "path": "/report.md", + "content": "# Findings\n\nThe sandbox works.\n", + }}, + {"tool": "run_script", "arguments": {"source": ( + 'import std.fs as fs;\n' + 'let names = fs.listdir(sandbox, "/");\n' + 'print("files:", names);\n' + 'fs.write(sandbox, "/from-script.txt", "written inside the sandbox");\n' + )}}, + {"tool": "read_file", "arguments": {"path": "/report.md"}}, + {"tool": "read_file", "arguments": {"path": "/etc/passwd"}}, # refused + {"tool": "read_file", "arguments": {"path": "/from-script.txt"}}, +] + + +def scripted_model(messages): + """Stand-in for a chat completion call: returns the next tool call, or None.""" + asked = sum(1 for message in messages if message["role"] == "tool") + return SCRIPTED_TURNS[asked] if asked < len(SCRIPTED_TURNS) else None + + +def main(argv): + work = argv[1] if len(argv) > 1 else tempfile.mkdtemp(prefix="pyvdisk-agent-") + os.makedirs(work, exist_ok=True) + + with AgentSandbox.create(os.path.join(work, "agent.vdisk"), size_bytes=32 << 20) as box: + print("tools offered to the model:", ", ".join(tool["name"] for tool in box.tools())) + print("json schema of one tool:", json.dumps(box.tools()[0], ensure_ascii=False)[:120], "...\n") + + messages = [{"role": "user", "content": "Summarise the workspace and write /report.md"}] + for turn in range(1, 12): + call = scripted_model(messages) + if call is None: + break + result = box.dispatch(call["tool"], call["arguments"]) + messages.append({"role": "tool", "name": call["tool"], "content": result}) + print(f"[{turn}] {call['tool']}({json.dumps(call['arguments'], ensure_ascii=False)[:60]})") + print(" ->", result.replace("\n", "\n ")) + + print("\nfinal /report.md:", repr(box.read_text("/report.md"))) + report = box.verify_audit() + print(f"audit: {report['length']} chained records, chain ok = {report['ok']}") + print("refusals recorded:", + [row["metrics"]["tool"] for row in box.audit(status="failure")]) + print("\nEvery call above is durable, hash-chained and replayable: reopen", + os.path.join(work, "agent.vdisk"), "to see it.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/examples/quickstart.py b/examples/quickstart.py new file mode 100644 index 0000000..837410b --- /dev/null +++ b/examples/quickstart.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 +"""PyVDisk quickstart: one file, standard library only, Windows or Linux. + + python examples/quickstart.py [workdir] + +Nothing here needs hnswlib, fusepy, NumPy or root privileges. The vector disk +falls back to a built-in flat index, FUSE is not used at all, and every artifact +is a plain file in the work directory (a temporary one by default). + +It walks the stack bottom-up: a block device, a filesystem, a transaction, a +vector collection, a log stream, a VScript program, and finally the AgentSandbox +that wraps all of it for an agent framework. +""" +from __future__ import annotations + +import importlib.util +import os +import sys +import tempfile + +# Run straight from a checkout: `python examples/quickstart.py` puts examples/ on +# sys.path, not the repository root. If pyvdisk is not installed, add the root. +if importlib.util.find_spec("pyvdisk") is None: + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from pyvdisk import ( # noqa: E402 - path fix above has to run first + AgentSandbox, + DataDisk, + LogDisk, + VFS, + VectorDisk, + __version__, + compat, +) + + +def section(title: str) -> None: + print(f"\n=== {title} ===") + + +def block_device(work: str) -> str: + """Layer 1: a plain file used as a block device.""" + path = os.path.join(work, "blocks.vdisk") + VFS.create(path, 16 * 1024 * 1024, label="quickstart") + with VFS(path) as vfs: + vfs.makedirs("/docs") + vfs.write_file("/docs/hello.txt", b"hello from a virtual block device") + print("read back:", vfs.read_file("/docs/hello.txt").decode()) + usage = vfs.df() + print("usage:", {key: usage[key] for key in list(usage)[:3]}) + return path + + +def transactions(work: str) -> str: + """Layer 2: a data container with a write-ahead log.""" + path = os.path.join(work, "data.vdisk") + DataDisk.create(path, 32 * 1024 * 1024, label="quickstart data") + with DataDisk(path) as disk: + disk.fs.write_file("/kept.txt", b"committed") + try: + with disk.transaction(): + # Writes inside the block are journalled by the transaction and + # undone when it is left through an exception. + disk.fs.write_file("/rolled-back.txt", b"never visible") + raise RuntimeError("changed my mind") + except RuntimeError as exc: + print("transaction aborted:", exc) + print("kept.txt exists:", disk.fs.exists("/kept.txt")) + print("rolled-back.txt exists:", disk.fs.exists("/rolled-back.txt")) + disk.checkpoints.set("last-run", {"ok": True}) + disk.checkpoints.save() + print("checkpoint:", disk.checkpoints.get("last-run")) + return path + + +def vectors(work: str) -> str: + """Layer 3: a vector collection -- with or without hnswlib.""" + from pyvdisk.vector_disk import _index_backend + + path = os.path.join(work, "vectors.vdisk") + VectorDisk.create(path, 32 * 1024 * 1024, label="embeddings") + backend = getattr(_index_backend(), "__name__", "flat") + with VectorDisk(path) as disk: + disk.create_collection("docs", 3, metric="cosine") + disk.upsert_many("docs", [ + {"id": "intro", "vector": [1.0, 0.0, 0.0], "metadata": {"kind": "guide"}}, + {"id": "api", "vector": [0.9, 0.1, 0.0], "metadata": {"kind": "reference"}}, + {"id": "faq", "vector": [0.0, 1.0, 0.0], "metadata": {"kind": "guide"}}, + ]) + hits = disk.search("docs", [1.0, 0.0, 0.0], k=2) + print("index backend:", "hnswlib" if backend == "hnswlib" else "built-in flat (no dependency)") + print("nearest:", [(hit["id"], round(hit["distance"], 4)) for hit in hits]) + print("filtered:", [hit["id"] for hit in disk.search("docs", [1.0, 0.0, 0.0], k=3, where={"kind": "guide"})]) + return path + + +def logs(work: str) -> str: + """Layer 4: an append-only log with retention.""" + path = os.path.join(work, "logs.vdisk") + LogDisk.create(path, 16 * 1024 * 1024, label="events") + with LogDisk(path) as disk: + disk.create_stream("app", segment_events=2, max_events=100) + for index in range(5): + disk.append("app", level="INFO", logger="quickstart", message=f"event {index}", fields={"i": index}) + print("events:", disk.count("app")) + print("tail:", [event.message for event in disk.tail("app", 2)]) + print("query INFO:", len(disk.query("app", levels=["INFO"]))) + return path + + +def script(work: str) -> None: + """Layer 5: a sandboxed VScript program.""" + from pyvdisk.vscript import Compiler, MountRegistry, Runtime + from pyvdisk.vscript.policy import Policy + + path = os.path.join(work, "script.vdisk") + VFS.create(path, 8 * 1024 * 1024) + with VFS(path) as vfs, MountRegistry() as registry: + handle = registry.grant("store", "fs", vfs, permissions={"read", "write"}, root="/") + source = ( + 'import std.fs as fs;\n' + 'fs.write(store, "/hello.txt", "written by VScript");\n' + 'print("script read:", fs.read_text(store, "/hello.txt"));\n' + ) + runtime = Runtime(policy=Policy(max_wall_time=5.0), stdout=sys.stdout, + mount_registry=registry, allowed_mounts={"store": {"read", "write"}}) + runtime.run(Compiler().compile(source, "").ast, bindings={"store": handle}, source=source) + + +def agent_sandbox(work: str) -> None: + """Layer 6: the object an agent framework talks to.""" + path = os.path.join(work, "agent.vdisk") + with AgentSandbox.create(path, size_bytes=32 * 1024 * 1024) as box: + print("tools:", ", ".join(tool["name"] for tool in box.tools())) + print(box.dispatch("write_file", {"path": "/notes.md", "content": "# findings\n- it works\n"})) + print(box.dispatch("list_files", {"path": "/", "recursive": True})) + print("refused:", box.dispatch("read_file", {"path": "../../etc/passwd"})) + report = box.verify_audit() + print(f"audit: {report['length']} chained records, chain ok = {report['ok']}") + + +def main(argv: list[str]) -> int: + work = argv[1] if len(argv) > 1 else tempfile.mkdtemp(prefix="pyvdisk-quickstart-") + os.makedirs(work, exist_ok=True) + print(f"pyvdisk {__version__} on {sys.platform} (compat: {compat.describe()['implementation']})") + print("work directory:", work) + section("1. block device + filesystem") + block_device(work) + section("2. transactions and checkpoints") + transactions(work) + section("3. vector search") + vectors(work) + section("4. structured logs") + logs(work) + section("5. VScript") + script(work) + section("6. AgentSandbox") + agent_sandbox(work) + print("\nDone. Everything above was plain files in", work) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) From f24e13944a8c997392558119976fb7e72166b19a Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:41:45 +0800 Subject: [PATCH 05/15] =?UTF-8?q?docs(normify):=20=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E5=BA=93=E5=90=8C=E6=AD=A5=E9=9B=B6=E4=BE=9D=E8=B5=96=E3=80=81?= =?UTF-8?q?Windows=20=E5=85=BC=E5=AE=B9=E5=B1=82=E4=B8=8E=20AgentSandbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更 2026-09-24-zero-dep-windows-agentsandbox(已 verified,revision.after = 2c9009b): 新增结构: - pyvdisk.platform(平台适配层,4 个模块):实现选择、定位读写、跨进程文件锁、 持久化与身份。设计上它是"唯一直接触碰平台原语的地方",其余模块经它中转。 - pyvdisk.agent(Agent 工作区,5 个模块):门面、路径约束、工具面、盘内脚本、 工具调用审计。 - pyvdisk.storage.vector.flat-index:无依赖的精确索引后端。 - pyvdisk.examples(2 个模块)与 3 个新测试模块(compat / agent-sandbox / no-dependency)。 同步既有结构:block 的 image/access/io 补上经 platform 的调用箭头;checkpoint、 fuse.meta、vscript.host.guard 同样挂到 platform;vector 的 open/search 更新为 "后端由文件魔数决定、缺 hnswlib 自动回退";api 补上 AgentSandbox/compat/ FlatIndex 三个导出;tests 与 delivery/docs 的计数与介绍对齐当前状态。 渲染数据:根、tests、agent、platform、examples、storage.vector 各层已重排, 其中根层新增"对外接口与 Agent 入口"分组。新模块的 API 键改为 pyvdisk.compat.* 形式,避免与既有的 pyvdisk.api 键空间撞车。 结果:290 模块 / 844 API / 132 箭头 / 41 层渲染数据,0 error,15 warning (多为既有的 leaf-too-coarse 提示,非阻塞)。 --- normify-pyvdisk/api-index.json | 52 +- ...6-09-24-zero-dep-windows-agentsandbox.json | 31 + .../modules/pyvdisk/agent/audit.md | 47 + .../modules/pyvdisk/agent/index.md | 21 + .../modules/pyvdisk/agent/paths.md | 43 + .../modules/pyvdisk/agent/sandbox.md | 75 + .../modules/pyvdisk/agent/script.md | 36 + .../modules/pyvdisk/agent/tools.md | 50 + normify-pyvdisk/modules/pyvdisk/api.md | 44 +- .../modules/pyvdisk/delivery/ci.md | 21 +- .../modules/pyvdisk/delivery/index.md | 6 +- .../modules/pyvdisk/delivery/packaging.md | 12 +- .../modules/pyvdisk/docs/changelog.md | 12 +- normify-pyvdisk/modules/pyvdisk/docs/index.md | 6 +- .../modules/pyvdisk/docs/readme.md | 12 +- .../modules/pyvdisk/examples/agent-tools.md | 25 + .../modules/pyvdisk/examples/index.md | 17 + .../modules/pyvdisk/examples/quickstart.md | 24 + normify-pyvdisk/modules/pyvdisk/index.md | 6 +- .../modules/pyvdisk/platform/dispatch.md | 42 + .../modules/pyvdisk/platform/durability.md | 66 + .../modules/pyvdisk/platform/index.md | 20 + .../modules/pyvdisk/platform/locking.md | 39 + .../modules/pyvdisk/platform/positional.md | 35 + .../modules/pyvdisk/storage/block/access.md | 10 +- .../modules/pyvdisk/storage/block/image.md | 19 +- .../modules/pyvdisk/storage/block/index.md | 8 +- .../modules/pyvdisk/storage/block/io.md | 35 +- .../pyvdisk/storage/checkpoint/index.md | 8 +- .../modules/pyvdisk/storage/checkpoint/io.md | 16 +- .../pyvdisk/storage/checkpoint/open.md | 17 +- .../pyvdisk/storage/checkpoint/triggers.md | 12 +- .../modules/pyvdisk/storage/fuse/data.md | 6 +- .../modules/pyvdisk/storage/fuse/handlers.md | 6 +- .../modules/pyvdisk/storage/fuse/index.md | 6 +- .../modules/pyvdisk/storage/fuse/meta.md | 15 +- .../modules/pyvdisk/storage/fuse/mount.md | 6 +- .../modules/pyvdisk/storage/index.md | 6 +- .../pyvdisk/storage/vector/collections.md | 14 +- .../pyvdisk/storage/vector/flat-index.md | 75 + .../modules/pyvdisk/storage/vector/index.md | 8 +- .../modules/pyvdisk/storage/vector/open.md | 12 +- .../modules/pyvdisk/storage/vector/records.md | 6 +- .../modules/pyvdisk/storage/vector/search.md | 39 +- .../modules/pyvdisk/tests/agent-sandbox.md | 24 + .../modules/pyvdisk/tests/compat.md | 24 + .../modules/pyvdisk/tests/index.md | 8 +- .../modules/pyvdisk/tests/no-dependency.md | 24 + .../modules/pyvdisk/vscript/host/guard.md | 17 +- .../modules/pyvdisk/vscript/host/index.md | 6 +- .../modules/pyvdisk/vscript/host/module.md | 6 +- .../modules/pyvdisk/vscript/index.md | 6 +- normify-pyvdisk/normify.html | 2096 ++++++++++++++--- normify-pyvdisk/outline.md | 52 +- normify-pyvdisk/receipt.json | 32 +- normify-pyvdisk/renders/pyvdisk.json | 22 +- normify-pyvdisk/renders/pyvdisk/agent.json | 42 + normify-pyvdisk/renders/pyvdisk/examples.json | 14 + normify-pyvdisk/renders/pyvdisk/platform.json | 32 + .../renders/pyvdisk/storage/vector.json | 9 +- normify-pyvdisk/renders/pyvdisk/tests.json | 24 +- normify-pyvdisk/tree.json | 2092 +++++++++++++--- 62 files changed, 4724 insertions(+), 872 deletions(-) create mode 100644 normify-pyvdisk/changes/2026-09-24-zero-dep-windows-agentsandbox.json create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/audit.md create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/index.md create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/paths.md create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/sandbox.md create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/script.md create mode 100644 normify-pyvdisk/modules/pyvdisk/agent/tools.md create mode 100644 normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md create mode 100644 normify-pyvdisk/modules/pyvdisk/examples/index.md create mode 100644 normify-pyvdisk/modules/pyvdisk/examples/quickstart.md create mode 100644 normify-pyvdisk/modules/pyvdisk/platform/dispatch.md create mode 100644 normify-pyvdisk/modules/pyvdisk/platform/durability.md create mode 100644 normify-pyvdisk/modules/pyvdisk/platform/index.md create mode 100644 normify-pyvdisk/modules/pyvdisk/platform/locking.md create mode 100644 normify-pyvdisk/modules/pyvdisk/platform/positional.md create mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/flat-index.md create mode 100644 normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md create mode 100644 normify-pyvdisk/modules/pyvdisk/tests/compat.md create mode 100644 normify-pyvdisk/modules/pyvdisk/tests/no-dependency.md create mode 100644 normify-pyvdisk/renders/pyvdisk/agent.json create mode 100644 normify-pyvdisk/renders/pyvdisk/examples.json create mode 100644 normify-pyvdisk/renders/pyvdisk/platform.json diff --git a/normify-pyvdisk/api-index.json b/normify-pyvdisk/api-index.json index cc9d004..04d8c1d 100644 --- a/normify-pyvdisk/api-index.json +++ b/normify-pyvdisk/api-index.json @@ -1,16 +1,23 @@ { "file:.github/workflows/ci.yml": "pyvdisk.delivery.ci", + "file:.github/workflows/ci.yml#no-dependencies": "pyvdisk.delivery.ci", "file:.github/workflows/pylint.yml": "pyvdisk.delivery.lint", "file:CHANGELOG.md": "pyvdisk.docs.changelog", "file:docs/API_GOVERNANCE.md": "pyvdisk.docs.api-governance", "file:docs/ARCHITECTURE.md": "pyvdisk.docs.architecture", "file:docs/CONTRACTS.md": "pyvdisk.docs.contracts", "file:docs/VSCRIPT_SPEC.md": "pyvdisk.docs.vscript-spec", + "file:examples/agent_tools.py:scripted_model": "pyvdisk.examples.agent-tools", + "file:examples/quickstart.py": "pyvdisk.examples.quickstart", "file:MANIFEST.in": "pyvdisk.delivery.packaging", "file:pyproject.toml": "pyvdisk.delivery.packaging", "file:pyvdisk/__main__.py": "pyvdisk.cli.entry", "file:pyvdisk/py.typed": "pyvdisk.delivery.packaging", "file:README.md": "pyvdisk.docs.readme", + "file:tests/test_agent_sandbox.py": "pyvdisk.tests.agent-sandbox", + "file:tests/test_compat.py": "pyvdisk.tests.compat", + "file:tests/test_no_dependency_path.py": "pyvdisk.tests.no-dependency", + "rpc:pyvdisk.AgentSandbox": "pyvdisk.api", "rpc:pyvdisk.CheckpointStore": "pyvdisk.api", "rpc:pyvdisk.cli._add_cred_args": "pyvdisk.cli.format", "rpc:pyvdisk.cli._human_size": "pyvdisk.cli.format", @@ -70,6 +77,20 @@ "rpc:pyvdisk.cli.cmd_vol_status": "pyvdisk.cli.volume", "rpc:pyvdisk.cli.cmd_write": "pyvdisk.cli.file-ops", "rpc:pyvdisk.cli.main": "pyvdisk.cli.main", + "rpc:pyvdisk.compat": "pyvdisk.api", + "rpc:pyvdisk.compat.can_symlink": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.describe": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.fsync_dir": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.implementation": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.lock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.pread": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.pwrite": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.uid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.uid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.unlock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.use_implementation": "pyvdisk.platform.dispatch", "rpc:pyvdisk.contracts.BlockDevice": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#read_block": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#write_block": "pyvdisk.contracts.storage", @@ -151,6 +172,7 @@ "rpc:pyvdisk.execution.ExecutionService#submit": "pyvdisk.execution.service.submit", "rpc:pyvdisk.execution.ExecutionService#worker_count": "pyvdisk.execution.service.setup", "rpc:pyvdisk.ExecutionService": "pyvdisk.api", + "rpc:pyvdisk.FlatIndex": "pyvdisk.api", "rpc:pyvdisk.fs._ceil_div": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._decode_name": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._disk_lock_key": "pyvdisk.storage.fs.locking", @@ -722,6 +744,27 @@ "rpc:pyvdisk.vscript.wal.encode_record": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.RECORD_KINDS": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.WriteAheadLog": "pyvdisk.storage.wal.undo", + "rpc:sandbox:_hidden": "pyvdisk.agent.paths", + "rpc:sandbox:_SandboxFS": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox._normalize": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox._visible": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox.audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.call": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.create": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.delete": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.dispatch": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.exists": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.list": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.make_directory": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.open": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.read": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.retain_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.run": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox.stats": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.tools": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.verify_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.write": "pyvdisk.agent.sandbox", + "rpc:sandbox:TOOLS": "pyvdisk.agent.tools", "rpc:tests/conftest.py": "pyvdisk.tests.fixtures", "rpc:tests/test_agentic_cli.py": "pyvdisk.tests.agentic-cli", "rpc:tests/test_api_governance.py": "pyvdisk.tests.api-governance", @@ -792,5 +835,12 @@ "rpc:tests/test_vscript.py::VScriptTests": "pyvdisk.tests.vscript", "rpc:tests/test_wal_abort_recovery.py": "pyvdisk.tests.wal-recovery", "rpc:tests/test_wal_checkpoint_and_recovery.py": "pyvdisk.tests.wal-checkpoint", - "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation" + "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation", + "rpc:vector_index:deserialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:distance": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.add_item": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.knn_query": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:read_kind": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize_from_backend": "pyvdisk.storage.vector.flat-index" } diff --git a/normify-pyvdisk/changes/2026-09-24-zero-dep-windows-agentsandbox.json b/normify-pyvdisk/changes/2026-09-24-zero-dep-windows-agentsandbox.json new file mode 100644 index 0000000..9009a29 --- /dev/null +++ b/normify-pyvdisk/changes/2026-09-24-zero-dep-windows-agentsandbox.json @@ -0,0 +1,31 @@ +{ + "schema_version": 1, + "id": "2026-09-24-zero-dep-windows-agentsandbox", + "title": { + "en": "Zero dependency, Windows compat layer and AgentSandbox", + "zh": "零依赖 + Windows 兼容层 + AgentSandbox" + }, + "status": "verified", + "intent": { + "en": "Sync the structure DB with the Windows compat layer, the removal of the hnswlib runtime dependency (built-in flat index), and the new AgentSandbox facade, plus the new examples and tests.", + "zh": "同步结构库:新增 Windows 兼容层与零依赖(内置 flat 索引),新增 AgentSandbox 顶层类,并补上新的示例与测试模块。" + }, + "modules": { + "create": [], + "modify": [] + }, + "acceptance": [ + "新增模块(平台适配层、vector flat 索引、AgentSandbox 子树、examples、3 个新测试模块)全部落地且指纹与源码一致", + "受影响模块(block/checkpoint/fuse/host/vector/delivery/docs/api)的介绍与 API 与当前代码一致", + "新增容器模块(platform、agent、examples)都有渲染数据", + "normify_validate 0 error,normify_build 产出回执" + ], + "note": "新增 pyvdisk.platform(4 个原语模块)、pyvdisk.agent(5 个模块,含工具面/路径约束/脚本/审计)、pyvdisk.examples(2 个)、pyvdisk.storage.vector.flat-index 与 3 个测试模块;受影响模块的 source 范围指纹、介绍与 API 已与代码对齐;pyvdisk/tests/delivery/docs 各容器的渲染数据已同步。0 error,15 warning(多为既有的 leaf-too-coarse 提示)。", + "revision": { + "before": null, + "after": "2c9009ba74afb515d301cc96e1946087268479a2" + }, + "created_at": "2026-09-24T11:30:26.105Z", + "updated_at": "2026-09-24T11:41:32.089Z", + "closed_at": "2026-09-24T11:41:32.089Z" +} diff --git a/normify-pyvdisk/modules/pyvdisk/agent/audit.md b/normify-pyvdisk/modules/pyvdisk/agent/audit.md new file mode 100644 index 0000000..0c35daa --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/audit.md @@ -0,0 +1,47 @@ +--- +uid: a000033a +id: pyvdisk.agent.audit +parent: pyvdisk.agent +name: {zh: "工具调用审计", en: "Tool Call Audit"} +description: + zh: > + 每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。"模型是不是读了不该读的路径"这个问题,事后可以从日志里回答。 + en: > + Every call -- including every refusal -- is written to the hash-chained stream agent-audit with its tool name, arguments, status, error type and capability summary. An agent that read a path it should not have is a question the log can answer after the fact. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 584 + end_line: 665 +apis: + - protocol: rpc + path: "sandbox:AgentSandbox.audit" + description: + zh: > + 审计行,由旧到新。过滤条件为 sink 自身支持的若干项,外加 tool——它按行里记录的工具名筛选。 + en: > + Audit rows, oldest first. Filters are the sink's own plus tool, which selects on the tool name recorded in the row. + - protocol: rpc + path: "sandbox:AgentSandbox.verify_audit" + description: + zh: > + 校验整条哈希链;在 sink 之外追加的行会把它断开。 + en: > + Check the hash chain end to end; a row appended outside the sink breaks it. + - protocol: rpc + path: "sandbox:AgentSandbox.retain_audit" + description: + zh: > + 按流上的保留策略裁剪,同时保持哈希链仍可校验。 + en: > + Apply the stream's retention policy while keeping the chain verifiable. + - protocol: rpc + path: "sandbox:AgentSandbox.stats" + description: + zh: > + 调用与失败计数、工具集与磁盘占用,可序列化为 JSON 进日志。 + en: > + Call and failure counters, the tool set and disk usage, JSON-serialisable for logs. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/agent/index.md b/normify-pyvdisk/modules/pyvdisk/agent/index.md new file mode 100644 index 0000000..fcb5054 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/index.md @@ -0,0 +1,21 @@ +--- +uid: a0000335 +id: pyvdisk.agent +parent: pyvdisk +name: {zh: "Agent 工作区", en: "Agent Workspace"} +description: + zh: > + 把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 dispatch()。 + en: > + Wraps a DataDisk into a workspace an agent framework can be handed: tool schemas, call dispatch, path confinement and a hash-chained audit trail. The integration surface is two calls, tools() and dispatch(). +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 198 + end_line: 314 + - path: "pyvdisk/sandbox.py" + line: 387 + end_line: 474 +--- diff --git a/normify-pyvdisk/modules/pyvdisk/agent/paths.md b/normify-pyvdisk/modules/pyvdisk/agent/paths.md new file mode 100644 index 0000000..754c77f --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/paths.md @@ -0,0 +1,43 @@ +--- +uid: a0000337 +id: pyvdisk.agent.paths +parent: pyvdisk.agent +name: {zh: "路径约束", en: "Path Confinement"} +description: + zh: > + 沙箱内"路径意味着什么"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见。 + en: > + The one definition of what a path means inside the sandbox: backslash input is normalised, Windows-looking paths stay inside the image, .. is refused rather than resolved, and the container's own bookkeeping is hidden from reads, writes and listings alike. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 60 + end_line: 195 + - path: "pyvdisk/sandbox.py" + line: 387 + end_line: 420 +apis: + - protocol: rpc + path: "sandbox:AgentSandbox._normalize" + description: + zh: > + 把模型给的路径映射进沙箱命名空间:反斜杠归一化,C:\Windows 变成 /C:/Windows。 + en: > + Map a model-supplied path into the sandbox namespace: backslashes are normalised and C:\Windows becomes /C:/Windows. + - protocol: rpc + path: "sandbox:AgentSandbox._visible" + description: + zh: > + 先归一化,再拒绝容器自身的簿记路径。 + en: > + Normalise, then refuse the container's own bookkeeping paths. + - protocol: rpc + path: "sandbox:_hidden" + description: + zh: > + 路径是否属于 /.system、/.vectors、/.logs,或是根目录下的清单文件。 + en: > + Whether a path is under /.system, /.vectors or /.logs, or is one of the root-level manifests. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/agent/sandbox.md b/normify-pyvdisk/modules/pyvdisk/agent/sandbox.md new file mode 100644 index 0000000..3fe822b --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/sandbox.md @@ -0,0 +1,75 @@ +--- +uid: a0000336 +id: pyvdisk.agent.sandbox +parent: pyvdisk.agent +name: {zh: "沙箱门面", en: "Sandbox Facade"} +description: + zh: > + 门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及 close/上下文管理器生命周期。read_only 由 capability 层强制,而不只是把工具藏起来,所以直接调用动词同样被拒。 + en: > + The facade itself: create/open, the Python verbs (write/read/list/make_directory/delete/exists), the script entry, and the close/context-manager lifecycle. read_only is enforced by the capability layer rather than by hiding tools, so a direct verb is refused too. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 316 + end_line: 474 +apis: + - protocol: rpc + path: "sandbox:AgentSandbox.write" + description: + zh: > + 写入文本或字节,沿途自动建父目录。拒绝容器内部目录,也拒绝任何会越出根目录的路径。 + en: > + Write text or bytes, creating parent directories on the way. Refuses hidden bookkeeping paths and anything that would escape the root. + - protocol: rpc + path: "sandbox:AgentSandbox.read" + description: + zh: > + 读取原始字节;read_text() 返回解码后的字符串。 + en: > + Read raw bytes, then read_text() for a decoded string. + - protocol: rpc + path: "sandbox:AgentSandbox.list" + description: + zh: > + 列出条目及其类型与大小。容器内部路径会被过滤,模型不会看到一个用不了的名字。 + en: > + List entries with type and size. Hidden container paths are filtered out, so the agent never sees a name it cannot use. + - protocol: rpc + path: "sandbox:AgentSandbox.make_directory" + description: + zh: > + 创建目录,自动建父级。 + en: > + Make a directory, creating parents. + - protocol: rpc + path: "sandbox:AgentSandbox.delete" + description: + zh: > + 删除文件;recursive 为真时删整棵目录树。 + en: > + Delete a file, or a directory tree when recursive is set. + - protocol: rpc + path: "sandbox:AgentSandbox.exists" + description: + zh: > + 可见路径是否存在。内部路径一律返回 False。 + en: > + Whether a visible path exists. Hidden paths always answer False. + - protocol: rpc + path: "sandbox:AgentSandbox.create" + description: + zh: > + 新建或打开沙箱背后的镜像,可传 read_only、allow_delete、宿主根目录与审计上限等选项。 + en: > + Open or create the image behind the sandbox, with options such as read_only, allow_delete, host roots and audit limits. + - protocol: rpc + path: "sandbox:AgentSandbox.open" + description: + zh: > + 重新打开已有镜像;工作区与审计记录都保留。 + en: > + Reopen an existing image; the workspace and the audit trail both survive. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/agent/script.md b/normify-pyvdisk/modules/pyvdisk/agent/script.md new file mode 100644 index 0000000..b349706 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/script.md @@ -0,0 +1,36 @@ +--- +uid: a0000339 +id: pyvdisk.agent.script +parent: pyvdisk.agent +name: {zh: "盘内脚本", en: "Sandboxed Scripts"} +description: + zh: > + 盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glob 里滤掉,脚本入口不会变成规则更松的第二个入口。 + en: > + The in-disk VScript entry: a script runs with the sandbox mounted, host access denied by default, and its stdout returned to the model. The adapter in front of the mount filters container bookkeeping out of listdir, walk and glob as well, so the script door is not a second entrance with looser rules. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 72 + end_line: 195 + - path: "pyvdisk/sandbox.py" + line: 476 + end_line: 510 +apis: + - protocol: rpc + path: "sandbox:AgentSandbox.run" + description: + zh: > + 执行 VScript 程序,沙箱绑定为变量 sandbox。未配置宿主根目录时宿主访问一律被拒;墙钟时间、输出与写入字节数都有上限。 + en: > + Run a VScript program with the sandbox bound as the variable sandbox. Host access is refused unless roots were configured; wall time, output and written bytes are all capped. + - protocol: rpc + path: "sandbox:_SandboxFS" + description: + zh: > + 脚本看到的文件系统。每个路径都走与 Python 动词相同的可见性规则,两个入口不可能出现不一致。 + en: > + The filesystem a script sees. Every path is translated through the same visibility rule the Python verbs use, so the two entrances cannot disagree. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/agent/tools.md b/normify-pyvdisk/modules/pyvdisk/agent/tools.md new file mode 100644 index 0000000..b708e3c --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/agent/tools.md @@ -0,0 +1,50 @@ +--- +uid: a0000338 +id: pyvdisk.agent.tools +parent: pyvdisk.agent +name: {zh: "工具面", en: "Tool Surface"} +description: + zh: > + 六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面向各框架约定的 schema 渲染,和在真正碰磁盘之前先校验参数的分发。 + en: > + The six built-in tools: write_file, read_file, list_files, make_directory, delete_file and run_script, plus the schema rendering for each framework convention and the dispatch that validates arguments before anything touches the disk. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d +source: + - path: "pyvdisk/sandbox.py" + line: 198 + end_line: 314 + - path: "pyvdisk/sandbox.py" + line: 512 + end_line: 583 +apis: + - protocol: rpc + path: "sandbox:AgentSandbox.tools" + description: + zh: > + 交给模型的工具定义。openai 与 anthropic 共用 {name, description, parameters};mcp 把 schema 键换成 inputSchema。 + en: > + The tool definitions to hand the model. openai and anthropic share {name, description, parameters}; mcp renames the schema key to inputSchema. + - protocol: rpc + path: "sandbox:AgentSandbox.dispatch" + description: + zh: > + 执行工具并始终返回字符串——拒绝也是字符串,因此可以原样回灌消息列表。 + en: > + Run a named tool and always return a string -- a refusal is a string too, so it goes back into the message list unchanged. + - protocol: rpc + path: "sandbox:AgentSandbox.call" + description: + zh: > + dispatch 的结构化形式:ok、content、tool、error,供需要分支判断的调用方使用。 + en: > + The structured form of dispatch: ok, content, tool and error, for callers that branch on the outcome. + - protocol: rpc + path: "sandbox:TOOLS" + description: + zh: > + 六个内置的文件系统与脚本工具及其 JSON Schema 参数。 + en: > + The six built-in filesystem and script tools, with their JSON Schema parameters. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/api.md b/normify-pyvdisk/modules/pyvdisk/api.md index f6e364e..b906f67 100644 --- a/normify-pyvdisk/modules/pyvdisk/api.md +++ b/normify-pyvdisk/modules/pyvdisk/api.md @@ -6,12 +6,12 @@ tags: [api] name: {zh: "公开门面", en: "Public Facade"} description: zh: > - 公开门面:调用方直接从 pyvdisk 包根导入的存储、执行与契约名称。 + 公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。 en: > - Public facade: the storage, execution and contract names that callers import directly from the pyvdisk package root. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:14:45.848Z" -fingerprint: 1e6d5c306ceb1123c99b098fd82cda1a805d9c5f23aa12f22d64f3bd129a5da7 + Public facade: the storage, execution, agent and contract names that callers import directly from the pyvdisk package root. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 829b9ac86974d0b749ac032ca0809ff290509d8be9218da09a8823562bd84a3b source: - path: "pyvdisk/__init__.py" apis: @@ -71,4 +71,38 @@ apis: 执行平面返回的运行句柄。 en: > Run handle returned by the execution plane. + - protocol: rpc + path: "pyvdisk.AgentSandbox" + description: + zh: > + Agent 工作区门面:Agent 框架只需要这一个导入。 + en: > + The agent workspace facade: the one import an agent framework needs. + - protocol: rpc + path: "pyvdisk.compat" + description: + zh: > + 平台适配层;导出后调用方可以查询当前用的是哪套实现。 + en: > + The platform layer, exported so callers can ask which implementation is live. + - protocol: rpc + path: "pyvdisk.FlatIndex" + description: + zh: > + 无外部依赖的精确向量索引。 + en: > + The dependency-free exact vector index. +deps: + - kind: reference + to: pyvdisk.agent.sandbox + from_api: "rpc:pyvdisk.AgentSandbox" + label: {zh: "转出沙箱门面", en: "re-exports the sandbox"} + - kind: reference + to: pyvdisk.platform + from_api: "rpc:pyvdisk.compat" + label: {zh: "转出平台适配层", en: "re-exports the platform layer"} + - kind: reference + to: pyvdisk.storage.vector.flat-index + from_api: "rpc:pyvdisk.FlatIndex" + label: {zh: "转出扁平索引", en: "re-exports the flat index"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/delivery/ci.md b/normify-pyvdisk/modules/pyvdisk/delivery/ci.md index 9d905b2..9f9a49e 100644 --- a/normify-pyvdisk/modules/pyvdisk/delivery/ci.md +++ b/normify-pyvdisk/modules/pyvdisk/delivery/ci.md @@ -5,14 +5,12 @@ parent: pyvdisk.delivery name: {zh: "测试工作流", en: "Test Workflow"} description: zh: > - CI 工作流:在 push 与 pull request 上安装 dev extras 并在 3.9–3.12 矩阵上运行 pytest,使声明的 requires-python 下限由最老的矩阵任务强制,而不是靠假设。 - + CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 requires-python 下限由最老的矩阵任务强制而不是靠假设。另有独立任务只装基础包并断言加速器确实缺席,零依赖的承诺因此不是自说自话。 en: > - CI workflow: installs the dev extras and runs the pytest suite on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed. - -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.215Z" -fingerprint: b1583a09123f8c3ad3d2e52ae4bc88ff01e6db7a88c3336853b06482634e20eb + CI workflow: installs the dev and vector extras and runs pytest on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed. A second job installs the package without extras and asserts the accelerators are absent, which keeps the zero-dependency claim honest. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 2bf7b99f2ff50585631ea75453ea75cc457a6fe7bece3d39c4fd4b40d5eadc13 source: - path: ".github/workflows/ci.yml" apis: @@ -21,8 +19,13 @@ apis: description: zh: > 主测试工作流:安装依赖并运行 pytest 套件。 - en: > Main test workflow: install and run the pytest suite. - + - protocol: file + path: ".github/workflows/ci.yml#no-dependencies" + description: + zh: > + 零依赖任务:只装 [dev],断言 hnswlib、fusepy、numpy 都不可导入,然后跑整套用例。 + en: > + Zero-dependency job: installs [dev] only, asserts hnswlib, fusepy and numpy are absent, then runs the suite. --- diff --git a/normify-pyvdisk/modules/pyvdisk/delivery/index.md b/normify-pyvdisk/modules/pyvdisk/delivery/index.md index 5b9bcee..1bdfe31 100644 --- a/normify-pyvdisk/modules/pyvdisk/delivery/index.md +++ b/normify-pyvdisk/modules/pyvdisk/delivery/index.md @@ -11,9 +11,9 @@ description: en: > Distribution and continuous integration: packaging metadata, PEP 561 typing marker and the GitHub Actions workflows. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.215Z" -fingerprint: 7b8e690a61c134d576c6f09d81d7bc29a6ab4028d80f74d3320a15c7b43cf8bc +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ffb2fa1aa3e3cc015e3b71a246768d8b6ebbd7ef155a40d3000dafa42f532369 source: - path: "pyproject.toml" - path: ".github/workflows/ci.yml" diff --git a/normify-pyvdisk/modules/pyvdisk/delivery/packaging.md b/normify-pyvdisk/modules/pyvdisk/delivery/packaging.md index abe049c..c123740 100644 --- a/normify-pyvdisk/modules/pyvdisk/delivery/packaging.md +++ b/normify-pyvdisk/modules/pyvdisk/delivery/packaging.md @@ -5,14 +5,12 @@ parent: pyvdisk.delivery name: {zh: "打包元数据", en: "Packaging Metadata"} description: zh: > - 分发元数据:以 hnswlib 为依赖、fuse 与 dev extras、py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。 - + 分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。 en: > - Distribution metadata: cffi-free dependency set with hnswlib, the fuse and dev extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md. - -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.216Z" -fingerprint: eef1180eeb651e5a6edbef6a63bd38eb0f2e3244b7c927f12a61c503b23ac266 + Distribution metadata: no runtime dependencies at all, with hnswlib and fusepy moved to the vector and fuse extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: e83415f6936531ac1130878c36a08b49e1795946d20ecc3bf95a507560e0a608 source: - path: "pyproject.toml" line: 1 diff --git a/normify-pyvdisk/modules/pyvdisk/docs/changelog.md b/normify-pyvdisk/modules/pyvdisk/docs/changelog.md index ea8d37c..1d31b22 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/changelog.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/changelog.md @@ -6,14 +6,12 @@ tags: [docs, changelog] name: {zh: "变更日志", en: "Changelog"} description: zh: > - 变更日志:按 issue #1 的清单编号记录用户可见变更,并列出四条明确留待后续的项目。 - + 用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留"已知未完成"一节,未完成项要看得见,而不是被静默遗忘。 en: > - Changelog: user-visible changes keyed to the issue #1 inventory ids, plus the four deliberately deferred items. - -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.211Z" -fingerprint: ea3f46a9c65b19826cd309658416f1fe840116fa730bfc745a4cf6b95f77858a + User-visible change log, versioned in step with pyproject.toml. Entries are grouped by theme (zero dependency and cross-platform first) and carry the residual-limits section, so unfixed items stay visible instead of being quietly forgotten. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 9648b98246e1e081401981daab12fa29c679efa0b189fb23fcb8542b565e7536 source: - path: "CHANGELOG.md" line: 1 diff --git a/normify-pyvdisk/modules/pyvdisk/docs/index.md b/normify-pyvdisk/modules/pyvdisk/docs/index.md index fc17a53..3967998 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/index.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/index.md @@ -11,9 +11,9 @@ description: en: > Repository documentation layer: architecture, contracts, API governance and the VScript spec; the primary evidence source for this module tree. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T10:00:52.069Z" -fingerprint: 08fd9522bb3a8bd1bc169f548c3c3e441fb6cd89f089c8e4206604371248a807 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7 source: - path: "README.md" - path: "docs/ARCHITECTURE.md" diff --git a/normify-pyvdisk/modules/pyvdisk/docs/readme.md b/normify-pyvdisk/modules/pyvdisk/docs/readme.md index c5658e9..eac261d 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/readme.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/readme.md @@ -5,14 +5,12 @@ parent: pyvdisk.docs name: {zh: "项目总览", en: "Project Overview"} description: zh: > - README 总览:项目定位、快速开始、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。 - + README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。 en: > - README overview: positioning, quick start, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size. - -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T10:00:52.068Z" -fingerprint: fd96eaab9b9f839e266b3f990012c5cc034178b7e0a534eb15be4c397a525f55 + README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef source: - path: "README.md" apis: diff --git a/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md b/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md new file mode 100644 index 0000000..cf5ac51 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md @@ -0,0 +1,25 @@ +--- +uid: a000033d +id: pyvdisk.examples.agent-tools +parent: pyvdisk.examples +tags: [agent, example] +name: {zh: "Agent 对接示例", en: "Agent Loop Demo"} +description: + zh: > + 带脚本化"模型"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。 + en: > + A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1 +source: + - path: "examples/agent_tools.py" +apis: + - protocol: file + path: "examples/agent_tools.py:scripted_model" + description: + zh: > + 聊天补全调用的替身:返回下一条预置的工具调用,"模型"不再调用工具时返回 None。 + en: > + A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/examples/index.md b/normify-pyvdisk/modules/pyvdisk/examples/index.md new file mode 100644 index 0000000..2ea5d4d --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/examples/index.md @@ -0,0 +1,17 @@ +--- +uid: a000033b +id: pyvdisk.examples +parent: pyvdisk +name: {zh: "可运行示例", en: "Runnable Examples"} +description: + zh: > + 可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。 + en: > + Runnable examples that double as the fastest way to see the whole stack work. They are standard-library only and run from a checkout without installing anything, which is also how the zero-dependency claim is tested. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2 +source: + - path: "examples/quickstart.py" + - path: "examples/agent_tools.py" +--- diff --git a/normify-pyvdisk/modules/pyvdisk/examples/quickstart.md b/normify-pyvdisk/modules/pyvdisk/examples/quickstart.md new file mode 100644 index 0000000..d32de24 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/examples/quickstart.md @@ -0,0 +1,24 @@ +--- +uid: a000033c +id: pyvdisk.examples.quickstart +parent: pyvdisk.examples +name: {zh: "快速上手", en: "Quickstart Tour"} +description: + zh: > + 单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏蔽 hnswlib 的子进程里跑它,这正是它能当好"最初五分钟"的原因。 + en: > + One file, standard library only, Windows and Linux. It walks from a raw block device up to AgentSandbox so the layering is visible in one run, and reports which index backend it got. Tests run it in a subprocess with hnswlib blocked, which is what keeps this usable as a first five minutes. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 366abf85eb8b872da8170a251e0d9afc62647e6ff779753eeac8db7c8900e224 +source: + - path: "examples/quickstart.py" +apis: + - protocol: file + path: "examples/quickstart.py" + description: + zh: > + 在一个进程里自底向上跑通整条栈:块设备、事务、向量检索、日志、VScript,最后是沙箱。 + en: > + Run the whole stack bottom-up in one process: block device, transactions, vector search, logs, VScript, then the sandbox. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/index.md b/normify-pyvdisk/modules/pyvdisk/index.md index 267a750..d027f6d 100644 --- a/normify-pyvdisk/modules/pyvdisk/index.md +++ b/normify-pyvdisk/modules/pyvdisk/index.md @@ -7,11 +7,11 @@ tags: [python, agentic, storage, vscript] name: {zh: "PyVDisk", en: "PyVDisk"} description: zh: > - 单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。 + 单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。核心不依赖标准库之外的任何东西,Linux 与 Windows 同一套代码;AgentSandbox 让这个容器可以直接当成 Agent 工作区使用。 en: > - Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language. + Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language. The core depends on nothing outside the standard library and runs on Linux and Windows alike, and AgentSandbox makes the container directly usable as an agent workspace. revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" +updated_at: "2026-09-24T13:45:00Z" fingerprint: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 source: [] --- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md b/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md new file mode 100644 index 0000000..2e08827 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md @@ -0,0 +1,42 @@ +--- +uid: a0000330 +id: pyvdisk.platform.dispatch +parent: pyvdisk.platform +name: {zh: "实现选择", en: "Implementation Dispatch"} +description: + zh: > + 决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。 + + en: > + Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess. + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:40:54.220Z" +fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +source: + - path: "pyvdisk/compat.py" + line: 41 + end_line: 100 +apis: + - protocol: rpc + path: "pyvdisk.compat.implementation" + description: + zh: > + 当前生效的实现:posix 或 windows。 + en: > + The implementation in force: posix or windows. + - protocol: rpc + path: "pyvdisk.compat.use_implementation" + description: + zh: > + 临时强制指定实现;上下文管理器,退出时还原,供测试在 Linux 上执行 Windows 分支。 + en: > + Temporarily force an implementation; a context manager that restores the previous one, used by tests to execute the Windows branches on Linux. + - protocol: rpc + path: "pyvdisk.compat.describe" + description: + zh: > + 当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。 + en: > + Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/durability.md b/normify-pyvdisk/modules/pyvdisk/platform/durability.md new file mode 100644 index 0000000..b1a411e --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/platform/durability.md @@ -0,0 +1,66 @@ +--- +uid: a0000333 +id: pyvdisk.platform.durability +parent: pyvdisk.platform +name: {zh: "持久化与身份", en: "Durability and Identity"} +description: + zh: > + 其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。 + + en: > + The remaining platform differences: flushing a directory after a rename, reporting process identity, probing symlink support, and selecting the implementation in force. Each returns a value the caller can branch on instead of raising, because none of them is fatal on its own. + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:40:47.981Z" +fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +source: + - path: "pyvdisk/compat.py" + line: 202 + end_line: 283 + - path: "pyvdisk/compat.py" + line: 41 + end_line: 100 +apis: + - protocol: rpc + path: "pyvdisk.compat.fsync_dir" + description: + zh: > + 刷盘目录,让改名能抵住崩溃。真的执行了才返回 True;Windows 无法把目录当文件打开,所以返回 False 表示"未执行",而不是假装成功。 + en: > + Flush a directory so a rename survives a crash. Returns True when it actually ran; Windows cannot open a directory as a file, so it returns False to mean not performed rather than claiming success. + - protocol: rpc + path: "pyvdisk.compat.uid" + description: + zh: > + 进程 uid;平台没有该概念时返回 0。 + en: > + Effective uid, or 0 where the platform has no such notion. + - protocol: rpc + path: "pyvdisk.compat.gid" + description: + zh: > + 进程 gid;平台没有该概念时返回 0。 + en: > + Effective gid, or 0 where the platform has no such notion. + - protocol: rpc + path: "pyvdisk.compat.uid_or" + description: + zh: > + 取 uid,无该概念时用传入的缺省值。用它而不是 `uid() or default`:uid 0 是 root,不是"未设置"。 + en: > + uid, or the given fallback. Prefer this over `uid() or default`: uid 0 is root, not unset. + - protocol: rpc + path: "pyvdisk.compat.gid_or" + description: + zh: > + 取 gid,无该概念时用传入的缺省值。 + en: > + gid, or the given fallback. + - protocol: rpc + path: "pyvdisk.compat.can_symlink" + description: + zh: > + 探测指定目录下能否创建符号链接(不抛异常)。Windows 需要开发者模式,调用方据此降级而不是直接失败。 + en: > + Probe whether a symlink can be created in the given directory without raising. Windows needs developer mode, so callers degrade instead of failing. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/index.md b/normify-pyvdisk/modules/pyvdisk/platform/index.md new file mode 100644 index 0000000..482e705 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/platform/index.md @@ -0,0 +1,20 @@ +--- +uid: a000032f +id: pyvdisk.platform +parent: pyvdisk +name: {zh: "平台适配层", en: "Platform Adaptation"} +description: + zh: > + 唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份。 + en: > + The single place that touches operating-system primitives: positional IO, whole-file locking, directory fsync, process identity and symlink support. Every other module goes through it, so Windows differences are handled once instead of at each call site. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f +source: + - path: "pyvdisk/compat.py" + - path: "pyvdisk/disk.py" + - path: "pyvdisk/infrastructure/checkpoint.py" + - path: "pyvdisk/vscript/host.py" + - path: "pyvdisk/fuse_mount.py" +--- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/locking.md b/normify-pyvdisk/modules/pyvdisk/platform/locking.md new file mode 100644 index 0000000..e7b8c79 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/platform/locking.md @@ -0,0 +1,39 @@ +--- +uid: a0000332 +id: pyvdisk.platform.locking +parent: pyvdisk.platform +name: {zh: "跨进程文件锁", en: "Cross-Process Locking"} +description: + zh: > + 跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLCK 轮询:LK_LOCK 约十秒后会报错,而 flock 会一直等下去。 + + en: > + Whole-file write serialisation across threads and processes: fcntl.flock on POSIX, an msvcrt byte range on Windows. The Windows path polls with LK_NBLCK on purpose: LK_LOCK errors out after about ten seconds where flock keeps waiting. + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:41:06.398Z" +fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +source: + - path: "pyvdisk/compat.py" + line: 128 + end_line: 198 + - path: "pyvdisk/compat.py" + line: 55 + - path: "pyvdisk/compat.py" + line: 58 +apis: + - protocol: rpc + path: "pyvdisk.compat.lock" + description: + zh: > + 取得整文件锁。blocking=True 等待,timeout=N 秒后放弃并返回 False,blocking=False 只试一次。返回是否拿到锁。 + en: > + Take the whole-file lock. blocking=True waits, timeout=N seconds gives up and returns False, blocking=False tries once. Returns whether the lock is held. + - protocol: rpc + path: "pyvdisk.compat.unlock" + description: + zh: > + 释放锁。句柄已关闭也能调用,因为卸载路径与出错路径都会走到它。 + en: > + Release the lock. Tolerates an already-closed handle, because unmount and error paths both call it. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/positional.md b/normify-pyvdisk/modules/pyvdisk/platform/positional.md new file mode 100644 index 0000000..c964655 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/platform/positional.md @@ -0,0 +1,35 @@ +--- +uid: a0000331 +id: pyvdisk.platform.positional +parent: pyvdisk.platform +name: {zh: "定位读写", en: "Positioned IO"} +description: + zh: > + 不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。 + + en: > + Atomic positioned reads and writes that neither depend on nor disturb the file cursor. The emulation is not merely a convenience: without the lock, two threads sharing a handle would seek past each other and corrupt blocks. + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:41:00.670Z" +fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +source: + - path: "pyvdisk/compat.py" + line: 102 + end_line: 127 +apis: + - protocol: rpc + path: "pyvdisk.compat.pread" + description: + zh: > + 从 offset 处读取至多 length 字节。POSIX 用 os.pread;模拟实现用进程级互斥锁包住 lseek+read,避免与其它线程的 seek 交错。 + en: > + Positioned read of up to length bytes. POSIX uses os.pread; the emulation holds a process-wide lock across lseek+read so the pair is not interleaved with another thread's seek. + - protocol: rpc + path: "pyvdisk.compat.pwrite" + description: + zh: > + 向 offset 处写入。POSIX 用 os.pwrite;模拟实现用同一把锁串行化 seek+write。 + en: > + Positioned write. POSIX uses os.pwrite; the emulation serialises seek+write under the same lock. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/block/access.md b/normify-pyvdisk/modules/pyvdisk/storage/block/access.md index 81c4738..c5da855 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/block/access.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/block/access.md @@ -10,9 +10,9 @@ description: en: > Block and byte access on an open image: block read/write, raw byte ranges and image resize. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:19:48.423Z" -fingerprint: f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16 source: - path: "pyvdisk/disk.py" line: 143 @@ -68,4 +68,8 @@ deps: to: pyvdisk.storage.block.io from_api: "rpc:pyvdisk.disk.VirtualDisk#read_block" label: {zh: "定位读取", en: "positional read"} + - kind: call + to: pyvdisk.storage.block.io + from_api: "rpc:pyvdisk.disk.VirtualDisk#write_block" + label: {zh: "定位写入", en: "positioned write"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/block/image.md b/normify-pyvdisk/modules/pyvdisk/storage/block/image.md index c389632..1e0ca89 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/block/image.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/block/image.md @@ -5,12 +5,12 @@ parent: pyvdisk.storage.block name: {zh: "镜像生命周期", en: "Image Lifecycle"} description: zh: > - VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。 + VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而不是悄悄退化为空操作。 en: > - VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80 + VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close. The lock is taken from the platform layer, so write serialisation exists on both POSIX and Windows instead of silently degrading to a no-op. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16 source: - path: "pyvdisk/disk.py" line: 60 @@ -34,9 +34,9 @@ apis: path: "pyvdisk.disk.VirtualDisk#open" description: zh: > - 打开镜像,写模式下获取 POSIX 写锁。 + 打开镜像,写锁经由平台适配层获取:POSIX 用 flock,Windows 用 msvcrt 字节区间锁。抢锁失败会关掉句柄报错,而不是无声地无锁继续跑。 en: > - Open the image with optional POSIX write lock acquisition. + Open the image, taking the write lock through the platform layer: flock on POSIX, an msvcrt byte range on Windows. A lock failure closes the handle and raises rather than silently continuing unlocked. - protocol: rpc path: "pyvdisk.disk.VirtualDisk#flush" description: @@ -51,4 +51,9 @@ apis: 释放 advisory 锁并关闭镜像。 en: > Release the advisory lock and close the image. +deps: + - kind: call + to: pyvdisk.platform.locking + from_api: "rpc:pyvdisk.disk.VirtualDisk#open" + label: {zh: "整文件写锁", en: "whole-file write lock"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/block/index.md b/normify-pyvdisk/modules/pyvdisk/storage/block/index.md index 97c1294..e86ed39 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/block/index.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/block/index.md @@ -6,11 +6,13 @@ name: {zh: "块镜像", en: "Block Image"} description: zh: > 块级镜像 IO:把一个 .vdisk 文件当作块设备,使用 os.pread/os.pwrite 与 POSIX advisory 写锁。 + en: > Block-level image IO: one .vdisk file treated as a block device with os.pread/os.pwrite and POSIX advisory write locking. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16 source: - path: "pyvdisk/disk.py" --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/block/io.md b/normify-pyvdisk/modules/pyvdisk/storage/block/io.md index 3271816..9ca3ddd 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/block/io.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/block/io.md @@ -5,12 +5,14 @@ parent: pyvdisk.storage.block name: {zh: "定位 IO 原语", en: "Positional IO"} description: zh: > - 无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用。 + 无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。 + en: > - Unbuffered positional read/write primitives used by every block and byte access on the image. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80 + Unbuffered positional read/write primitives used by every block and byte access on the image, routed through the platform layer so the same code runs on Windows. + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:41:14.329Z" +fingerprint: 88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16 source: - path: "pyvdisk/disk.py" line: 22 @@ -20,14 +22,29 @@ apis: path: "pyvdisk.disk._pread_all" description: zh: > - 定位读取,除 EOF 外保证读满。 + 定位读取,除 EOF 外保证读满。转发给 compat.pread,因此 Windows 上得到的是加锁的 seek+read,而不是 os.pread。 + en: > - Positional read that fills the buffer unless EOF is hit. + Positional read that fills the buffer unless EOF is hit. Delegates to compat.pread, so Windows gets a lock-protected seek+read instead of os.pread. + - protocol: rpc path: "pyvdisk.disk._pwrite_all" description: zh: > - 定位写入,保证写满全部字节。 + 定位写入,保证写满全部字节。转发给 compat.pwrite,在 Windows 上用同一把锁串行化 seek+write。 + en: > - Positional write that guarantees every byte is written. + Positional write that guarantees every byte is written. Delegates to compat.pwrite, which serialises seek+write on Windows. + +deps: + - kind: call + to: pyvdisk.platform.positional + from_api: "rpc:pyvdisk.disk._pread_all" + to_api: "rpc:pyvdisk.compat.pread" + label: {zh: "定位读取", en: "positioned read"} + - kind: call + to: pyvdisk.platform.positional + from_api: "rpc:pyvdisk.disk._pwrite_all" + to_api: "rpc:pyvdisk.compat.pwrite" + label: {zh: "定位写入", en: "positioned write"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/index.md b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/index.md index f77b9a2..3a7c6e9 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/index.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/index.md @@ -6,11 +6,13 @@ name: {zh: "检查点存储", en: "Checkpoint Store"} description: zh: > 检查点存储:以 VFS 路径或宿主目录为背衬的持久键值进度与结果记录,带跨进程锁与原子落盘。 + en: > Checkpoint store: durable key/value progress and result records backed by a VFS path or a host directory, with cross-process locking and atomic saves. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539 source: - path: "pyvdisk/infrastructure/checkpoint.py" --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/io.md b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/io.md index e5a6050..47e4c6a 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/io.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/io.md @@ -6,11 +6,13 @@ name: {zh: "检查点 IO", en: "Checkpoint IO"} description: zh: > 检查点 IO:键值记录映射的加载、读取、暂存与原子保存。 + en: > Checkpoint IO: load, read, stage and atomically save the key/value record map. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539 source: - path: "pyvdisk/infrastructure/checkpoint.py" line: 99 @@ -21,27 +23,35 @@ apis: description: zh: > 从背衬存储加载记录映射。 + en: > Load the record map from the backing store. + - protocol: rpc path: "pyvdisk.infrastructure.checkpoint.CheckpointStore#get" description: zh: > 读取单个检查点值。 + en: > Read one checkpoint value. + - protocol: rpc path: "pyvdisk.infrastructure.checkpoint.CheckpointStore#set" description: zh: > 把单个检查点值写入内存映射。 + en: > Write one checkpoint value into the in-memory map. + - protocol: rpc path: "pyvdisk.infrastructure.checkpoint.CheckpointStore#save" description: zh: > 原子地持久化整个记录映射。 + en: > Atomically persist the whole record map. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/open.md b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/open.md index f2f16d4..804957b 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/open.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/open.md @@ -5,14 +5,14 @@ parent: pyvdisk.storage.checkpoint name: {zh: "检查点存储", en: "Checkpoint Store"} description: zh: > - 检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。 + 检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在锁来自平台适配层。 en: > - Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle. + Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle. This module used to import fcntl at the top level, which made the whole package unimportable on Windows; the lock now comes from the platform layer. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:20:48.308Z" -fingerprint: d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:40:40.830Z" +fingerprint: 9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539 source: - path: "pyvdisk/infrastructure/checkpoint.py" line: 15 @@ -65,8 +65,7 @@ apis: deps: - kind: call - to: pyvdisk.storage.vfs.files - from_api: "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs" - to_api: "rpc:pyvdisk.vfs.VFS#read_file" - label: {zh: "经 VFS 读写", en: "reads via VFS"} + to: pyvdisk.platform.locking + from_api: "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked" + label: {zh: "跨进程锁", en: "cross-process lock"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/triggers.md b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/triggers.md index 7e2d6b3..0e0fd66 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/triggers.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/checkpoint/triggers.md @@ -6,11 +6,13 @@ name: {zh: "触发器检查点", en: "Trigger Checkpoints"} description: zh: > 面向触发器的便利层,为调度器提供持久的事件去重保证。 + en: > Trigger-facing convenience layer that gives the scheduler durable exactly-once event dedup. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539 source: - path: "pyvdisk/infrastructure/checkpoint.py" line: 146 @@ -21,15 +23,19 @@ apis: description: zh: > 记录某触发器已消费某事件 id。 + en: > Record that a trigger already consumed an event id. + - protocol: rpc path: "pyvdisk.infrastructure.checkpoint.CheckpointStore#last_event" description: zh: > 读取某触发器最近成功处理的事件 id。 + en: > Read the last successfully processed event id of a trigger. + deps: - kind: reference to: pyvdisk.vscript.triggers diff --git a/normify-pyvdisk/modules/pyvdisk/storage/fuse/data.md b/normify-pyvdisk/modules/pyvdisk/storage/fuse/data.md index d533474..83663f6 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/fuse/data.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/fuse/data.md @@ -10,9 +10,9 @@ description: en: > FUSE data and namespace mutations: read, write, create, mkdir, rmdir, unlink and rename handlers. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.232Z" -fingerprint: b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76 source: - path: "pyvdisk/fuse_mount.py" line: 85 diff --git a/normify-pyvdisk/modules/pyvdisk/storage/fuse/handlers.md b/normify-pyvdisk/modules/pyvdisk/storage/fuse/handlers.md index d909593..2a3e971 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/fuse/handlers.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/fuse/handlers.md @@ -10,9 +10,9 @@ description: en: > The remaining FUSE handlers: truncate, links, open/release, chmod and the dynamic Operations subclass assembly. readlink resolves without following the final component, so reading a symlink returns its target instead of EINVAL. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.232Z" -fingerprint: b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76 source: - path: "pyvdisk/fuse_mount.py" line: 119 diff --git a/normify-pyvdisk/modules/pyvdisk/storage/fuse/index.md b/normify-pyvdisk/modules/pyvdisk/storage/fuse/index.md index f5f411b..5c0946a 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/fuse/index.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/fuse/index.md @@ -11,9 +11,9 @@ description: en: > Optional FUSE mount that exposes a VFS as a host directory; degrades to a clear ImportError when fusepy is absent. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.231Z" -fingerprint: b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76 source: - path: "pyvdisk/fuse_mount.py" --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/fuse/meta.md b/normify-pyvdisk/modules/pyvdisk/storage/fuse/meta.md index be029e4..8addc31 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/fuse/meta.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/fuse/meta.md @@ -5,14 +5,14 @@ parent: pyvdisk.storage.fuse name: {zh: "FUSE 属性", en: "FUSE Attributes"} description: zh: > - FUSE 可用性检测,以及操作表中属性与目录列举部分。 + stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与"平台没有 uid"无法区分。 en: > - FUSE availability check and the attribute/listing half of the operation table. + Stat-to-fuse mapping and the entry object: type, mode, size, timestamps and ownership. Identity comes from the platform layer, which also fixes a real bug: uid 0 (root) was previously indistinguishable from "no uid available". -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.232Z" -fingerprint: b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T11:37:33.368Z" +fingerprint: c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76 source: - path: "pyvdisk/fuse_mount.py" line: 24 @@ -56,8 +56,7 @@ apis: deps: - kind: call - to: pyvdisk.storage.vfs.stat + to: pyvdisk.platform.durability from_api: "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr" - to_api: "rpc:pyvdisk.vfs.VFS#stat" - label: {zh: "取 stat", en: "stats path"} + label: {zh: "进程身份", en: "process identity"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/fuse/mount.md b/normify-pyvdisk/modules/pyvdisk/storage/fuse/mount.md index 5ac3357..aa0d340 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/fuse/mount.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/fuse/mount.md @@ -10,9 +10,9 @@ description: en: > Public mount entry points, including the patched main loop that tolerates busy mounts and the threaded variant. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.233Z" -fingerprint: b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76 source: - path: "pyvdisk/fuse_mount.py" line: 234 diff --git a/normify-pyvdisk/modules/pyvdisk/storage/index.md b/normify-pyvdisk/modules/pyvdisk/storage/index.md index 11cd4e0..88e8250 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/index.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/index.md @@ -11,9 +11,9 @@ description: en: > Storage plane: block image, disk identity, on-disk filesystem, high-level VFS, multi-disk volumes, vector and log disks, structured logging, simulated drive bay, optional FUSE mount, the unified DataDisk container, WAL and checkpoints. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.225Z" -fingerprint: 3ed800d0914e362e6fa76cf02ccddaa8b41f54ffd8efabaebe018e25619b823f +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 80d794b29e5404773680587fc27ceeac047cd72e0ab8cc13715f9aaa02d75a68 source: - path: "pyvdisk/disk.py" - path: "pyvdisk/identity.py" diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/collections.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/collections.md index fce4d2f..83b0b7f 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/vector/collections.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/collections.md @@ -6,11 +6,13 @@ name: {zh: "集合目录", en: "Collections"} description: zh: > 集合目录:按维度与度量创建、带配置列举,以及连同每集合 HNSW 索引一起删除。 + en: > Collection catalogue: create with dimension and metric, list with configuration, and drop along with the per-collection HNSW index. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0 source: - path: "pyvdisk/vector_disk.py" line: 129 @@ -21,20 +23,26 @@ apis: description: zh: > 以固定维度与度量创建具名集合。 + en: > Create a named collection with a fixed dimension and metric. + - protocol: rpc path: "pyvdisk.vector_disk.VectorDisk#list_collections" description: zh: > 列出集合名称及其配置。 + en: > List the collection names with their configuration. + - protocol: rpc path: "pyvdisk.vector_disk.VectorDisk#drop_collection" description: zh: > 删除集合及其索引文件。 + en: > Drop a collection and its index files. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/flat-index.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/flat-index.md new file mode 100644 index 0000000..603b82b --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/flat-index.md @@ -0,0 +1,75 @@ +--- +uid: a0000334 +id: pyvdisk.storage.vector.flat-index +parent: pyvdisk.storage.vector +tags: [zero-dependency, vector] +name: {zh: "扁平索引后端", en: "Flat Index Backend"} +description: + zh: > + 纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集合,不是大规模下 HNSW 的替代品。 + en: > + A pure-Python exact index that mirrors hnswlib's calling shape, so VectorDisk can fall back to it without branching. Query is O(n) and the vectors stay in memory: correct for small and medium collections, not a replacement for HNSW at scale. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: c2a8e20da7599125065676cf6a3cea638d1a8108df234b9873b098dbfffb547d +source: + - path: "pyvdisk/vector_index.py" + line: 38 + end_line: 47 + - path: "pyvdisk/vector_index.py" + line: 51 + end_line: 83 + - path: "pyvdisk/vector_index.py" + line: 169 + end_line: 251 +apis: + - protocol: rpc + path: "vector_index:distance" + description: + zh: > + 按 hnswlib 的约定计算距离,两种后端在调用点可直接互换:cosine = 1 - 相似度,l2 = 平方欧氏距离,ip = 1 - 点积。 + en: > + Distance in the convention hnswlib uses, so the two backends are interchangeable at the call site: cosine = 1 - similarity, l2 = squared euclidean, ip = 1 - dot product. + - protocol: rpc + path: "vector_index:read_kind" + description: + zh: > + 从索引文件读出写入方标识:是 hnswlib 写的还是 flat 后端写的,不需要解析其余内容。 + en: > + Read the writer's tag from an index file: whether it was written by hnswlib or by the flat backend, without parsing the rest. + - protocol: rpc + path: "vector_index:serialize" + description: + zh: > + 序列化为 flat 格式:8 字节魔数、空间与维度,然后是标签与 float32 向量。 + en: > + Serialise to the flat format: an 8-byte magic, the space and dimension, then labels and float32 vectors. + - protocol: rpc + path: "vector_index:deserialize" + description: + zh: > + 解析 flat 索引;内容被截断或根本不是该格式时报错,而不是当成正确数据读下去。 + en: > + Parse a flat index, rejecting a truncated or foreign payload instead of misreading it. + - protocol: rpc + path: "vector_index:serialize_from_backend" + description: + zh: > + 序列化任一后端的索引:flat 索引直接写自己,hnswlib 索引走它自己的 save_index 落到临时文件,需要负责清理。 + en: > + Serialise an index of either backend: a flat index writes itself, an hnswlib index goes through its own save_index into a temporary file that must be unlinked. + - protocol: rpc + path: "vector_index:FlatIndex.add_item" + description: + zh: > + 写入一条带标签的向量。维度与索引不一致时报错,维度尚未确定的空索引也拒绝写入。 + en: > + Add a labelled vector. Rejects a vector whose dimension disagrees with the index, and refuses a fresh index whose dimension was never set. + - protocol: rpc + path: "vector_index:FlatIndex.knn_query" + description: + zh: > + 精确 k 近邻搜索。距离相同时按标签排序,保证多次运行结果稳定;可选断言用于筛选候选记录。 + en: > + Exact k-nearest search. Ties break on the label so results are stable across runs, and an optional predicate filters the candidate records. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/index.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/index.md index 451758d..d1cceea 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/vector/index.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/index.md @@ -7,11 +7,13 @@ name: {zh: "向量盘", en: "Vector Disk"} description: zh: > 向量盘:基于 HNSW 的具名记录集合,带 generation、checksum、过滤器与相似度检索。 + en: > Vector disk: HNSW-backed collections of named records with generation tracking, checksum, filters and similarity search. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:00:00Z" -fingerprint: f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35 + +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0 source: - path: "pyvdisk/vector_disk.py" --- diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/open.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/open.md index cc308c6..42afd8b 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/vector/open.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/open.md @@ -5,14 +5,12 @@ parent: pyvdisk.storage.vector name: {zh: "向量盘打开", en: "Vector Disk Open"} description: zh: > - VectorDisk 生命周期,以及后续操作共用的 JSON 辅助与集合路径键化。 - + VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。 en: > - VectorDisk lifecycle plus the JSON helpers and collection-path keying used by every later operation. - -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:20:48.309Z" -fingerprint: f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35 + VectorDisk construction and mounting. Nothing here requires hnswlib: a collection opens and answers with the built-in flat index, and the accelerator is picked up only if it happens to be installed. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0 source: - path: "pyvdisk/vector_disk.py" line: 13 diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/records.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/records.md index 6e05485..149055a 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/vector/records.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/records.md @@ -10,9 +10,9 @@ description: en: > Record CRUD: dimension validation, upsert (single and batch), fetch, delete and count. -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:19:13.025Z" -fingerprint: f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0 source: - path: "pyvdisk/vector_disk.py" line: 165 diff --git a/normify-pyvdisk/modules/pyvdisk/storage/vector/search.md b/normify-pyvdisk/modules/pyvdisk/storage/vector/search.md index 3bb2e9a..0b3d444 100644 --- a/normify-pyvdisk/modules/pyvdisk/storage/vector/search.md +++ b/normify-pyvdisk/modules/pyvdisk/storage/vector/search.md @@ -5,14 +5,12 @@ parent: pyvdisk.storage.vector name: {zh: "向量检索", en: "Vector Search"} description: zh: > - HNSW 图上的索引管理与相似度检索,支持元数据过滤。 - + 索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索引。 en: > - Index management and similarity search over the HNSW graph with metadata filtering. - -revision: 6d203c0d5f54ce2e4293edd8054c10a109f8b83d -updated_at: "2026-09-23T07:19:48.423Z" -fingerprint: f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35 + Index construction, loading and query. The backend is chosen at load time from the file's magic tag: hnswlib when installed, the built-in flat index otherwise. Published with a single rename, so a concurrent reader sees either the old index or the new one. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0 source: - path: "pyvdisk/vector_disk.py" line: 223 @@ -22,33 +20,26 @@ apis: path: "pyvdisk.vector_disk.VectorDisk#_rebuild_index" description: zh: > - 从持久记录重建 HNSW 索引。 - + 由记录重建索引,并以一次改名原子发布,读方不会看到写了一半的索引。 en: > - Rebuild the HNSW index from the persisted records. - + Rebuild the index from the records and publish it with one rename, so a reader never sees a half-written index. - protocol: rpc path: "pyvdisk.vector_disk.VectorDisk#_load_index" description: zh: > - 加载盘上索引,缺失时重建。 - + 加载集合索引。由文件魔数决定路径:flat 直接解析,hnswlib 索引经 hnswlib 加载,缺 hnswlib 时回退为按记录重建的精确索引。 en: > - Load the on-disk index or rebuild it when absent. - + Load the collection index. The file's magic decides how: flat parses directly, hnswlib loads through hnswlib, and a missing hnswlib falls back to an exact index over the records. - protocol: rpc path: "pyvdisk.vector_disk.VectorDisk#search" description: zh: > - 相似度检索:k 结果、可选元数据过滤,以及是否返回向量。 - + 最近邻检索,可带元数据过滤。 en: > - Similarity search with k results, an optional metadata filter and include/exclude of vectors. - + Nearest-neighbour search with an optional metadata filter. deps: - - kind: dataflow - to: pyvdisk.storage.vector.records - from_api: "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index" - to_api: "rpc:pyvdisk.vector_disk.VectorDisk#get" - label: {zh: "读取记录", en: "reads records"} + - kind: call + to: pyvdisk.storage.vector.flat-index + from_api: "rpc:pyvdisk.vector_disk.VectorDisk#_load_index" + label: {zh: "后端回退", en: "backend fallback"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md b/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md new file mode 100644 index 0000000..c9f0931 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md @@ -0,0 +1,24 @@ +--- +uid: a000033f +id: pyvdisk.tests.agent-sandbox +parent: pyvdisk.tests +name: {zh: "沙箱测试", en: "Sandbox Tests"} +description: + zh: > + 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及"脚本入口与 Python 入口共用一个根"这条规则。 + en: > + Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290 +source: + - path: "tests/test_agent_sandbox.py" +apis: + - protocol: file + path: "tests/test_agent_sandbox.py" + description: + zh: > + 沙箱的承诺:路径约束、只读、审计链与脚本隔离。 + en: > + Sandbox promises: path confinement, read-only, audit chain and script isolation. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/compat.md b/normify-pyvdisk/modules/pyvdisk/tests/compat.md new file mode 100644 index 0000000..6259ef0 --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/tests/compat.md @@ -0,0 +1,24 @@ +--- +uid: a000033e +id: pyvdisk.tests.compat +parent: pyvdisk.tests +name: {zh: "平台兼容测试", en: "Platform Compat Tests"} +description: + zh: > + 在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。 + en: > + Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: 27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c +source: + - path: "tests/test_compat.py" +apis: + - protocol: file + path: "tests/test_compat.py" + description: + zh: > + 把平台切到模拟实现跑整条用例。 + en: > + Run the whole suite with the platform switched to the emulated implementation. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/index.md b/normify-pyvdisk/modules/pyvdisk/tests/index.md index f2f47f5..0c819b1 100644 --- a/normify-pyvdisk/modules/pyvdisk/tests/index.md +++ b/normify-pyvdisk/modules/pyvdisk/tests/index.md @@ -6,13 +6,11 @@ tags: [tests] name: {zh: "测试套件", en: "Test Suite"} description: zh: > - 测试套件:391 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥与打包。 - + 测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。 en: > - Test suite: 391 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge and packaging. - + Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent. revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.240Z" +updated_at: "2026-09-24T13:45:00Z" fingerprint: b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1 source: - path: "tests/conftest.py" diff --git a/normify-pyvdisk/modules/pyvdisk/tests/no-dependency.md b/normify-pyvdisk/modules/pyvdisk/tests/no-dependency.md new file mode 100644 index 0000000..f6b307f --- /dev/null +++ b/normify-pyvdisk/modules/pyvdisk/tests/no-dependency.md @@ -0,0 +1,24 @@ +--- +uid: a0000340 +id: pyvdisk.tests.no-dependency +parent: pyvdisk.tests +name: {zh: "零依赖测试", en: "Zero Dependency Tests"} +description: + zh: > + 同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端结果一致且能互读对方写的盘;examples/quickstart.py 在屏蔽 hnswlib 的子进程里能跑完,示例不会悄悄地开始依赖它。 + en: > + Three layers of the same claim: pyproject declares no runtime dependencies and keeps the accelerators as extras; VectorDisk answers correctly with hnswlib blocked, and the two backends agree and read each other's files; and examples/quickstart.py runs to completion in a subprocess with hnswlib blocked, so the example cannot quietly start needing it. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:40:00Z" +fingerprint: aca58c61b9b691e1849bc2f3a598cbaa1fd1e5c7db7193c969d3adbeb0c37073 +source: + - path: "tests/test_no_dependency_path.py" +apis: + - protocol: file + path: "tests/test_no_dependency_path.py" + description: + zh: > + 零依赖承诺:从打包、后端与示例三个层面校验。 + en: > + The zero-dependency promise, checked at packaging, backend and example level. +--- diff --git a/normify-pyvdisk/modules/pyvdisk/vscript/host/guard.md b/normify-pyvdisk/modules/pyvdisk/vscript/host/guard.md index 34e0f32..c4bd79a 100644 --- a/normify-pyvdisk/modules/pyvdisk/vscript/host/guard.md +++ b/normify-pyvdisk/modules/pyvdisk/vscript/host/guard.md @@ -5,14 +5,12 @@ parent: pyvdisk.vscript.host name: {zh: "宿主隔离", en: "Host Confinement"} description: zh: > - 宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。该策略现在有真实入口——CLI 注入声明的根目录——host.* 不再因根目录为空而不可用。 - + 宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。 en: > - Host confinement: declares which host directories a script may read and write and refuses everything else. The policy now has a real entry point -- the CLI injects the declared roots -- so host.* is reachable instead of failing with an empty root set. - -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.260Z" -fingerprint: baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2 + Host confinement: declares which host directories a script may read and write and refuses everything else. Writes end with a directory flush so the rename itself is durable; that flush goes through the platform layer, since Windows cannot open a directory as a file. +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a source: - path: "pyvdisk/vscript/host.py" line: 8 @@ -72,4 +70,9 @@ apis: en: > Write host data with an optional no-overwrite guard. +deps: + - kind: call + to: pyvdisk.platform.durability + from_api: "rpc:pyvdisk.vscript.host.HostProxy#write" + label: {zh: "刷盘目录", en: "flush the directory"} --- diff --git a/normify-pyvdisk/modules/pyvdisk/vscript/host/index.md b/normify-pyvdisk/modules/pyvdisk/vscript/host/index.md index 24d4ac6..69dbbc7 100644 --- a/normify-pyvdisk/modules/pyvdisk/vscript/host/index.md +++ b/normify-pyvdisk/modules/pyvdisk/vscript/host/index.md @@ -11,9 +11,9 @@ description: en: > VScript host access: an allowlisted HostProxy that confines script file transfer to declared directory roots. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.260Z" -fingerprint: baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a source: - path: "pyvdisk/vscript/host.py" --- diff --git a/normify-pyvdisk/modules/pyvdisk/vscript/host/module.md b/normify-pyvdisk/modules/pyvdisk/vscript/host/module.md index b909750..11bb804 100644 --- a/normify-pyvdisk/modules/pyvdisk/vscript/host/module.md +++ b/normify-pyvdisk/modules/pyvdisk/vscript/host/module.md @@ -10,9 +10,9 @@ description: en: > The host native module: script-facing read, write and transfer entry points that all funnel through the confinement proxy. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.261Z" -fingerprint: baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a source: - path: "pyvdisk/vscript/host.py" line: 80 diff --git a/normify-pyvdisk/modules/pyvdisk/vscript/index.md b/normify-pyvdisk/modules/pyvdisk/vscript/index.md index 6021089..f3bd639 100644 --- a/normify-pyvdisk/modules/pyvdisk/vscript/index.md +++ b/normify-pyvdisk/modules/pyvdisk/vscript/index.md @@ -11,9 +11,9 @@ description: en: > VScript: a safe workflow language with lexer, parser, tree-walking runtime, capability-confined standard library, policy/budget, audit and scheduling. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T09:58:38.257Z" -fingerprint: c7844269be626ed5058001514ea274cee3b6c62a247f7b5afbeca90ed7c02b66 +revision: 2c9009ba74afb515d301cc96e1946087268479a2 +updated_at: "2026-09-24T13:45:00Z" +fingerprint: 98f6c61340ebda42ddbd0fced95d0ae3c9f008ca45b2b60b7730cb2330c980a6 source: - path: "pyvdisk/vscript/__init__.py" line: 1 diff --git a/normify-pyvdisk/normify.html b/normify-pyvdisk/normify.html index 4529e26..1c28684 100644 --- a/normify-pyvdisk/normify.html +++ b/normify-pyvdisk/normify.html @@ -164,20 +164,20 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T10:00:54.317Z", + "compiled_at": "2026-09-24T11:41:32.016Z", "stats": { "tree_count": 1, - "module_count": 272, - "leaf_count": 234, - "api_count": 794, - "dep_count": 124, + "module_count": 290, + "leaf_count": 249, + "api_count": 844, + "dep_count": 132, "cross_tree_dep_count": 0, "max_depth": 4, - "layout_count": 38, + "layout_count": 41, "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 2, + "change_count": 3, "open_change_count": 1 } }, @@ -199,18 +199,429 @@ "en": "PyVDisk" }, "description": { - "zh": "单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。\n", - "en": "Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language.\n" + "zh": "单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。核心不依赖标准库之外的任何东西,Linux 与 Windows 同一套代码;AgentSandbox 让这个容器可以直接当成 Agent 工作区使用。\n", + "en": "Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language. The core depends on nothing outside the standard library and runs on Linux and Windows alike, and AgentSandbox makes the container directly usable as an agent workspace.\n" }, "source": [], "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", + "updated_at": "2026-09-24T13:45:00Z", "fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "repository": "https://github.com/HeDaas-Code/pyvdisk", "aggregate": { - "descendant_count": 271, + "descendant_count": 289, + "own_api_count": 0, + "inherited_api_count": 844, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent": { + "uid": "a0000335", + "id": "pyvdisk.agent", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "Agent 工作区", + "en": "Agent Workspace" + }, + "description": { + "zh": "把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 dispatch()。\n", + "en": "Wraps a DataDisk into a workspace an agent framework can be handed: tool schemas, call dispatch, path confinement and a hash-chained audit trail. The integration surface is two calls, tools() and dispatch().\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 198, + "end_line": 314 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 387, + "end_line": 474 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "aggregate": { + "descendant_count": 5, "own_api_count": 0, - "inherited_api_count": 794, + "inherited_api_count": 21, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.audit": { + "uid": "a000033a", + "id": "pyvdisk.agent.audit", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "工具调用审计", + "en": "Tool Call Audit" + }, + "description": { + "zh": "每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。\"模型是不是读了不该读的路径\"这个问题,事后可以从日志里回答。\n", + "en": "Every call -- including every refusal -- is written to the hash-chained stream agent-audit with its tool name, arguments, status, error type and capability summary. An agent that read a path it should not have is a question the log can answer after the fact.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 584, + "end_line": 665 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.audit", + "description": { + "zh": "审计行,由旧到新。过滤条件为 sink 自身支持的若干项,外加 tool——它按行里记录的工具名筛选。\n", + "en": "Audit rows, oldest first. Filters are the sink's own plus tool, which selects on the tool name recorded in the row.\n" + }, + "key": "rpc:sandbox:AgentSandbox.audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.verify_audit", + "description": { + "zh": "校验整条哈希链;在 sink 之外追加的行会把它断开。\n", + "en": "Check the hash chain end to end; a row appended outside the sink breaks it.\n" + }, + "key": "rpc:sandbox:AgentSandbox.verify_audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.retain_audit", + "description": { + "zh": "按流上的保留策略裁剪,同时保持哈希链仍可校验。\n", + "en": "Apply the stream's retention policy while keeping the chain verifiable.\n" + }, + "key": "rpc:sandbox:AgentSandbox.retain_audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.stats", + "description": { + "zh": "调用与失败计数、工具集与磁盘占用,可序列化为 JSON 进日志。\n", + "en": "Call and failure counters, the tool set and disk usage, JSON-serialisable for logs.\n" + }, + "key": "rpc:sandbox:AgentSandbox.stats" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 4, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.paths": { + "uid": "a0000337", + "id": "pyvdisk.agent.paths", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "路径约束", + "en": "Path Confinement" + }, + "description": { + "zh": "沙箱内\"路径意味着什么\"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见。\n", + "en": "The one definition of what a path means inside the sandbox: backslash input is normalised, Windows-looking paths stay inside the image, .. is refused rather than resolved, and the container's own bookkeeping is hidden from reads, writes and listings alike.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 60, + "end_line": 195 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 387, + "end_line": 420 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox._normalize", + "description": { + "zh": "把模型给的路径映射进沙箱命名空间:反斜杠归一化,C:\\Windows 变成 /C:/Windows。\n", + "en": "Map a model-supplied path into the sandbox namespace: backslashes are normalised and C:\\Windows becomes /C:/Windows.\n" + }, + "key": "rpc:sandbox:AgentSandbox._normalize" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox._visible", + "description": { + "zh": "先归一化,再拒绝容器自身的簿记路径。\n", + "en": "Normalise, then refuse the container's own bookkeeping paths.\n" + }, + "key": "rpc:sandbox:AgentSandbox._visible" + }, + { + "protocol": "rpc", + "path": "sandbox:_hidden", + "description": { + "zh": "路径是否属于 /.system、/.vectors、/.logs,或是根目录下的清单文件。\n", + "en": "Whether a path is under /.system, /.vectors or /.logs, or is one of the root-level manifests.\n" + }, + "key": "rpc:sandbox:_hidden" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.sandbox": { + "uid": "a0000336", + "id": "pyvdisk.agent.sandbox", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "沙箱门面", + "en": "Sandbox Facade" + }, + "description": { + "zh": "门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及 close/上下文管理器生命周期。read_only 由 capability 层强制,而不只是把工具藏起来,所以直接调用动词同样被拒。\n", + "en": "The facade itself: create/open, the Python verbs (write/read/list/make_directory/delete/exists), the script entry, and the close/context-manager lifecycle. read_only is enforced by the capability layer rather than by hiding tools, so a direct verb is refused too.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 316, + "end_line": 474 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.write", + "description": { + "zh": "写入文本或字节,沿途自动建父目录。拒绝容器内部目录,也拒绝任何会越出根目录的路径。\n", + "en": "Write text or bytes, creating parent directories on the way. Refuses hidden bookkeeping paths and anything that would escape the root.\n" + }, + "key": "rpc:sandbox:AgentSandbox.write" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.read", + "description": { + "zh": "读取原始字节;read_text() 返回解码后的字符串。\n", + "en": "Read raw bytes, then read_text() for a decoded string.\n" + }, + "key": "rpc:sandbox:AgentSandbox.read" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.list", + "description": { + "zh": "列出条目及其类型与大小。容器内部路径会被过滤,模型不会看到一个用不了的名字。\n", + "en": "List entries with type and size. Hidden container paths are filtered out, so the agent never sees a name it cannot use.\n" + }, + "key": "rpc:sandbox:AgentSandbox.list" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.make_directory", + "description": { + "zh": "创建目录,自动建父级。\n", + "en": "Make a directory, creating parents.\n" + }, + "key": "rpc:sandbox:AgentSandbox.make_directory" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.delete", + "description": { + "zh": "删除文件;recursive 为真时删整棵目录树。\n", + "en": "Delete a file, or a directory tree when recursive is set.\n" + }, + "key": "rpc:sandbox:AgentSandbox.delete" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.exists", + "description": { + "zh": "可见路径是否存在。内部路径一律返回 False。\n", + "en": "Whether a visible path exists. Hidden paths always answer False.\n" + }, + "key": "rpc:sandbox:AgentSandbox.exists" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.create", + "description": { + "zh": "新建或打开沙箱背后的镜像,可传 read_only、allow_delete、宿主根目录与审计上限等选项。\n", + "en": "Open or create the image behind the sandbox, with options such as read_only, allow_delete, host roots and audit limits.\n" + }, + "key": "rpc:sandbox:AgentSandbox.create" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.open", + "description": { + "zh": "重新打开已有镜像;工作区与审计记录都保留。\n", + "en": "Reopen an existing image; the workspace and the audit trail both survive.\n" + }, + "key": "rpc:sandbox:AgentSandbox.open" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 8, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.agent.script": { + "uid": "a0000339", + "id": "pyvdisk.agent.script", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "盘内脚本", + "en": "Sandboxed Scripts" + }, + "description": { + "zh": "盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glob 里滤掉,脚本入口不会变成规则更松的第二个入口。\n", + "en": "The in-disk VScript entry: a script runs with the sandbox mounted, host access denied by default, and its stdout returned to the model. The adapter in front of the mount filters container bookkeeping out of listdir, walk and glob as well, so the script door is not a second entrance with looser rules.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 72, + "end_line": 195 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 476, + "end_line": 510 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.run", + "description": { + "zh": "执行 VScript 程序,沙箱绑定为变量 sandbox。未配置宿主根目录时宿主访问一律被拒;墙钟时间、输出与写入字节数都有上限。\n", + "en": "Run a VScript program with the sandbox bound as the variable sandbox. Host access is refused unless roots were configured; wall time, output and written bytes are all capped.\n" + }, + "key": "rpc:sandbox:AgentSandbox.run" + }, + { + "protocol": "rpc", + "path": "sandbox:_SandboxFS", + "description": { + "zh": "脚本看到的文件系统。每个路径都走与 Python 动词相同的可见性规则,两个入口不可能出现不一致。\n", + "en": "The filesystem a script sees. Every path is translated through the same visibility rule the Python verbs use, so the two entrances cannot disagree.\n" + }, + "key": "rpc:sandbox:_SandboxFS" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 2, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.tools": { + "uid": "a0000338", + "id": "pyvdisk.agent.tools", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "工具面", + "en": "Tool Surface" + }, + "description": { + "zh": "六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面向各框架约定的 schema 渲染,和在真正碰磁盘之前先校验参数的分发。\n", + "en": "The six built-in tools: write_file, read_file, list_files, make_directory, delete_file and run_script, plus the schema rendering for each framework convention and the dispatch that validates arguments before anything touches the disk.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 198, + "end_line": 314 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 512, + "end_line": 583 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.tools", + "description": { + "zh": "交给模型的工具定义。openai 与 anthropic 共用 {name, description, parameters};mcp 把 schema 键换成 inputSchema。\n", + "en": "The tool definitions to hand the model. openai and anthropic share {name, description, parameters}; mcp renames the schema key to inputSchema.\n" + }, + "key": "rpc:sandbox:AgentSandbox.tools" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.dispatch", + "description": { + "zh": "执行工具并始终返回字符串——拒绝也是字符串,因此可以原样回灌消息列表。\n", + "en": "Run a named tool and always return a string -- a refusal is a string too, so it goes back into the message list unchanged.\n" + }, + "key": "rpc:sandbox:AgentSandbox.dispatch" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.call", + "description": { + "zh": "dispatch 的结构化形式:ok、content、tool、error,供需要分支判断的调用方使用。\n", + "en": "The structured form of dispatch: ok, content, tool and error, for callers that branch on the outcome.\n" + }, + "key": "rpc:sandbox:AgentSandbox.call" + }, + { + "protocol": "rpc", + "path": "sandbox:TOOLS", + "description": { + "zh": "六个内置的文件系统与脚本工具及其 JSON Schema 参数。\n", + "en": "The six built-in filesystem and script tools, with their JSON Schema parameters.\n" + }, + "key": "rpc:sandbox:TOOLS" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 4, + "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 } @@ -229,17 +640,17 @@ "en": "Public Facade" }, "description": { - "zh": "公开门面:调用方直接从 pyvdisk 包根导入的存储、执行与契约名称。\n", - "en": "Public facade: the storage, execution and contract names that callers import directly from the pyvdisk package root.\n" + "zh": "公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。\n", + "en": "Public facade: the storage, execution, agent and contract names that callers import directly from the pyvdisk package root.\n" }, "source": [ { "path": "pyvdisk/__init__.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:14:45.848Z", - "fingerprint": "1e6d5c306ceb1123c99b098fd82cda1a805d9c5f23aa12f22d64f3bd129a5da7", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "829b9ac86974d0b749ac032ca0809ff290509d8be9218da09a8823562bd84a3b", "apis": [ { "protocol": "rpc", @@ -312,13 +723,72 @@ "en": "Run handle returned by the execution plane.\n" }, "key": "rpc:pyvdisk.RunHandle" + }, + { + "protocol": "rpc", + "path": "pyvdisk.AgentSandbox", + "description": { + "zh": "Agent 工作区门面:Agent 框架只需要这一个导入。\n", + "en": "The agent workspace facade: the one import an agent framework needs.\n" + }, + "key": "rpc:pyvdisk.AgentSandbox" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat", + "description": { + "zh": "平台适配层;导出后调用方可以查询当前用的是哪套实现。\n", + "en": "The platform layer, exported so callers can ask which implementation is live.\n" + }, + "key": "rpc:pyvdisk.compat" + }, + { + "protocol": "rpc", + "path": "pyvdisk.FlatIndex", + "description": { + "zh": "无外部依赖的精确向量索引。\n", + "en": "The dependency-free exact vector index.\n" + }, + "key": "rpc:pyvdisk.FlatIndex" + } + ], + "deps": [ + { + "kind": "reference", + "to": "pyvdisk.agent.sandbox", + "from_api": "rpc:pyvdisk.AgentSandbox", + "label": { + "zh": "转出沙箱门面", + "en": "re-exports the sandbox" + }, + "cross_tree": false + }, + { + "kind": "reference", + "to": "pyvdisk.platform", + "from_api": "rpc:pyvdisk.compat", + "label": { + "zh": "转出平台适配层", + "en": "re-exports the platform layer" + }, + "cross_tree": false + }, + { + "kind": "reference", + "to": "pyvdisk.storage.vector.flat-index", + "from_api": "rpc:pyvdisk.FlatIndex", + "label": { + "zh": "转出扁平索引", + "en": "re-exports the flat index" + }, + "cross_tree": false } ], "aggregate": { "descendant_count": 0, - "own_api_count": 8, + "own_api_count": 11, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 3, "dep_in": 0 } }, @@ -2042,13 +2512,13 @@ "path": ".github/workflows/pylint.yml" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.215Z", - "fingerprint": "7b8e690a61c134d576c6f09d81d7bc29a6ab4028d80f74d3320a15c7b43cf8bc", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ffb2fa1aa3e3cc015e3b71a246768d8b6ebbd7ef155a40d3000dafa42f532369", "aggregate": { "descendant_count": 3, "own_api_count": 0, - "inherited_api_count": 5, + "inherited_api_count": 6, "dep_out": 0, "dep_in": 0 } @@ -2064,17 +2534,17 @@ "en": "Test Workflow" }, "description": { - "zh": "CI 工作流:在 push 与 pull request 上安装 dev extras 并在 3.9–3.12 矩阵上运行 pytest,使声明的 requires-python 下限由最老的矩阵任务强制,而不是靠假设。\n", - "en": "CI workflow: installs the dev extras and runs the pytest suite on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed.\n" + "zh": "CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 requires-python 下限由最老的矩阵任务强制而不是靠假设。另有独立任务只装基础包并断言加速器确实缺席,零依赖的承诺因此不是自说自话。\n", + "en": "CI workflow: installs the dev and vector extras and runs pytest on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed. A second job installs the package without extras and asserts the accelerators are absent, which keeps the zero-dependency claim honest.\n" }, "source": [ { "path": ".github/workflows/ci.yml" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.215Z", - "fingerprint": "b1583a09123f8c3ad3d2e52ae4bc88ff01e6db7a88c3336853b06482634e20eb", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "2bf7b99f2ff50585631ea75453ea75cc457a6fe7bece3d39c4fd4b40d5eadc13", "apis": [ { "protocol": "file", @@ -2084,11 +2554,20 @@ "en": "Main test workflow: install and run the pytest suite.\n" }, "key": "file:.github/workflows/ci.yml" + }, + { + "protocol": "file", + "path": ".github/workflows/ci.yml#no-dependencies", + "description": { + "zh": "零依赖任务:只装 [dev],断言 hnswlib、fusepy、numpy 都不可导入,然后跑整套用例。\n", + "en": "Zero-dependency job: installs [dev] only, asserts hnswlib, fusepy and numpy are absent, then runs the suite.\n" + }, + "key": "file:.github/workflows/ci.yml#no-dependencies" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 1, + "own_api_count": 2, "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 @@ -2146,8 +2625,8 @@ "en": "Packaging Metadata" }, "description": { - "zh": "分发元数据:以 hnswlib 为依赖、fuse 与 dev extras、py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。\n", - "en": "Distribution metadata: cffi-free dependency set with hnswlib, the fuse and dev extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md.\n" + "zh": "分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。\n", + "en": "Distribution metadata: no runtime dependencies at all, with hnswlib and fusepy moved to the vector and fuse extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md.\n" }, "source": [ { @@ -2159,9 +2638,9 @@ "line": 1 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.216Z", - "fingerprint": "eef1180eeb651e5a6edbef6a63bd38eb0f2e3244b7c927f12a61c503b23ac266", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "e83415f6936531ac1130878c36a08b49e1795946d20ecc3bf95a507560e0a608", "apis": [ { "protocol": "file", @@ -2233,9 +2712,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T10:00:52.069Z", - "fingerprint": "08fd9522bb3a8bd1bc169f548c3c3e441fb6cd89f089c8e4206604371248a807", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2341,8 +2820,8 @@ "en": "Changelog" }, "description": { - "zh": "变更日志:按 issue #1 的清单编号记录用户可见变更,并列出四条明确留待后续的项目。\n", - "en": "Changelog: user-visible changes keyed to the issue #1 inventory ids, plus the four deliberately deferred items.\n" + "zh": "用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留\"已知未完成\"一节,未完成项要看得见,而不是被静默遗忘。\n", + "en": "User-visible change log, versioned in step with pyproject.toml. Entries are grouped by theme (zero dependency and cross-platform first) and carry the residual-limits section, so unfixed items stay visible instead of being quietly forgotten.\n" }, "source": [ { @@ -2351,9 +2830,9 @@ "end_line": 47 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.211Z", - "fingerprint": "ea3f46a9c65b19826cd309658416f1fe840116fa730bfc745a4cf6b95f77858a", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9648b98246e1e081401981daab12fa29c679efa0b189fb23fcb8542b565e7536", "apis": [ { "protocol": "file", @@ -2425,17 +2904,17 @@ "en": "Project Overview" }, "description": { - "zh": "README 总览:项目定位、快速开始、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。\n", - "en": "README overview: positioning, quick start, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size.\n" + "zh": "README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。\n", + "en": "README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size.\n" }, "source": [ { "path": "README.md" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T10:00:52.068Z", - "fingerprint": "fd96eaab9b9f839e266b3f990012c5cc034178b7e0a534eb15be4c397a525f55", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef", "apis": [ { "protocol": "file", @@ -2457,48 +2936,167 @@ "zh": "指向架构文档", "en": "points to architecture doc" }, - "cross_tree": false + "cross_tree": false + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 1, + "dep_in": 0 + } + }, + "pyvdisk.docs.vscript-spec": { + "uid": "a0000107", + "id": "pyvdisk.docs.vscript-spec", + "parent": "pyvdisk.docs", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "VScript 规范", + "en": "VScript Spec" + }, + "description": { + "zh": "VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。\n", + "en": "VScript spec: syntax, standard library, interpreter pipeline, capability model, errors and CLI entry points.\n" + }, + "source": [ + { + "path": "docs/VSCRIPT_SPEC.md" + } + ], + "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", + "updated_at": "2026-09-23T07:00:00Z", + "fingerprint": "14929378e2e6fbfb2003b8c1377587db2d92ddae8d754330d724d782016f8dee", + "apis": [ + { + "protocol": "file", + "path": "docs/VSCRIPT_SPEC.md", + "description": { + "zh": "VScript 语言与安全规范。\n", + "en": "VScript language and safety specification.\n" + }, + "key": "file:docs/VSCRIPT_SPEC.md" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.examples": { + "uid": "a000033b", + "id": "pyvdisk.examples", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "可运行示例", + "en": "Runnable Examples" + }, + "description": { + "zh": "可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。\n", + "en": "Runnable examples that double as the fastest way to see the whole stack work. They are standard-library only and run from a checkout without installing anything, which is also how the zero-dependency claim is tested.\n" + }, + "source": [ + { + "path": "examples/quickstart.py" + }, + { + "path": "examples/agent_tools.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2", + "aggregate": { + "descendant_count": 2, + "own_api_count": 0, + "inherited_api_count": 2, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.examples.agent-tools": { + "uid": "a000033d", + "id": "pyvdisk.examples.agent-tools", + "parent": "pyvdisk.examples", + "tree": "pyvdisk", + "depth": 3, + "tags": [ + "agent", + "example" + ], + "name": { + "zh": "Agent 对接示例", + "en": "Agent Loop Demo" + }, + "description": { + "zh": "带脚本化\"模型\"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。\n", + "en": "A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result.\n" + }, + "source": [ + { + "path": "examples/agent_tools.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1", + "apis": [ + { + "protocol": "file", + "path": "examples/agent_tools.py:scripted_model", + "description": { + "zh": "聊天补全调用的替身:返回下一条预置的工具调用,\"模型\"不再调用工具时返回 None。\n", + "en": "A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop.\n" + }, + "key": "file:examples/agent_tools.py:scripted_model" } ], "aggregate": { "descendant_count": 0, "own_api_count": 1, "inherited_api_count": 0, - "dep_out": 1, + "dep_out": 0, "dep_in": 0 } }, - "pyvdisk.docs.vscript-spec": { - "uid": "a0000107", - "id": "pyvdisk.docs.vscript-spec", - "parent": "pyvdisk.docs", + "pyvdisk.examples.quickstart": { + "uid": "a000033c", + "id": "pyvdisk.examples.quickstart", + "parent": "pyvdisk.examples", "tree": "pyvdisk", "depth": 3, "name": { - "zh": "VScript 规范", - "en": "VScript Spec" + "zh": "快速上手", + "en": "Quickstart Tour" }, "description": { - "zh": "VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。\n", - "en": "VScript spec: syntax, standard library, interpreter pipeline, capability model, errors and CLI entry points.\n" + "zh": "单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏蔽 hnswlib 的子进程里跑它,这正是它能当好\"最初五分钟\"的原因。\n", + "en": "One file, standard library only, Windows and Linux. It walks from a raw block device up to AgentSandbox so the layering is visible in one run, and reports which index backend it got. Tests run it in a subprocess with hnswlib blocked, which is what keeps this usable as a first five minutes.\n" }, "source": [ { - "path": "docs/VSCRIPT_SPEC.md" + "path": "examples/quickstart.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "14929378e2e6fbfb2003b8c1377587db2d92ddae8d754330d724d782016f8dee", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "366abf85eb8b872da8170a251e0d9afc62647e6ff779753eeac8db7c8900e224", "apis": [ { "protocol": "file", - "path": "docs/VSCRIPT_SPEC.md", + "path": "examples/quickstart.py", "description": { - "zh": "VScript 语言与安全规范。\n", - "en": "VScript language and safety specification.\n" + "zh": "在一个进程里自底向上跑通整条栈:块设备、事务、向量检索、日志、VScript,最后是沙箱。\n", + "en": "Run the whole stack bottom-up in one process: block device, transactions, vector search, logs, VScript, then the sandbox.\n" }, - "key": "file:docs/VSCRIPT_SPEC.md" + "key": "file:examples/quickstart.py" } ], "aggregate": { @@ -4310,161 +4908,469 @@ "en": "Capability Gate" }, "description": { - "zh": "能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。\n", - "en": "The capability gate: path normalization, scope containment and the guarded delegation helper all scoped namespaces share.\n" + "zh": "能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。\n", + "en": "The capability gate: path normalization, scope containment and the guarded delegation helper all scoped namespaces share.\n" + }, + "source": [ + { + "path": "pyvdisk/infrastructure/capabilities.py", + "line": 7, + "end_line": 49 + } + ], + "revision": "c3881eee5dced2b180cd3b383e5d848026224154", + "updated_at": "2026-09-24T09:58:38.221Z", + "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities._path", + "description": { + "zh": "把能力范围归一到以 / 为根、以斜线为界的路径。\n", + "en": "Normalize a capability scope into a rooted, slash-bounded path.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities._path" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities._inside", + "description": { + "zh": "路径被包含在范围内时为真。\n", + "en": "True when a path is contained in a scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities._inside" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace", + "description": { + "zh": "基础适配器:在委托前把能力检查变为守卫条件。\n", + "en": "Base adapter that turns capability checks into guard clauses before delegating.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "description": { + "zh": "对照执行上下文范围检查单个权限。\n", + "en": "Check one permission against the execution context scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call", + "description": { + "zh": "受保护的委托调用,向下传递所需权限与范围。\n", + "en": "Guarded delegated call that propagates the required permission and scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call" + } + ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.contracts.capability", + "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", + "label": { + "zh": "检查授权", + "en": "checks grants" + }, + "cross_tree": false + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 5, + "inherited_api_count": 0, + "dep_out": 1, + "dep_in": 1 + } + }, + "pyvdisk.governance.scoped": { + "uid": "a0000811", + "id": "pyvdisk.governance.scoped", + "parent": "pyvdisk.governance", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "受限容器", + "en": "Scoped Container" + }, + "description": { + "zh": "检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。\n", + "en": "Checkpoint scoping plus the ScopedDataDisk object and factory that execution passes to untrusted code.\n" + }, + "source": [ + { + "path": "pyvdisk/infrastructure/capabilities.py", + "line": 130, + "end_line": 162 + } + ], + "revision": "c3881eee5dced2b180cd3b383e5d848026224154", + "updated_at": "2026-09-24T09:58:38.221Z", + "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace", + "description": { + "zh": "把每个键限制在能力集内的检查点适配器。\n", + "en": "Checkpoint adapter that scopes each key to the capability set.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk", + "description": { + "zh": "交给不可信调用方的单一对象:DataDisk 及其能力上下文。\n", + "en": "The single object handed to untrusted callers: a DataDisk plus its capability context.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__", + "description": { + "zh": "挂载底层容器并返回受限视图。\n", + "en": "Mount the underlying container and return the scoped view.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__", + "description": { + "zh": "上下文退出时关闭底层容器。\n", + "en": "Close the underlying container on context exit.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.scoped", + "description": { + "zh": "把一个 DataDisk 包装为单次执行上下文视图的便利工厂。\n", + "en": "Convenience factory that wraps a DataDisk for one execution context.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.scoped" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 5, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 2 + } + }, + "pyvdisk.platform": { + "uid": "a000032f", + "id": "pyvdisk.platform", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "平台适配层", + "en": "Platform Adaptation" + }, + "description": { + "zh": "唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份。\n", + "en": "The single place that touches operating-system primitives: positional IO, whole-file locking, directory fsync, process identity and symlink support. Every other module goes through it, so Windows differences are handled once instead of at each call site.\n" + }, + "source": [ + { + "path": "pyvdisk/compat.py" + }, + { + "path": "pyvdisk/disk.py" + }, + { + "path": "pyvdisk/infrastructure/checkpoint.py" + }, + { + "path": "pyvdisk/vscript/host.py" + }, + { + "path": "pyvdisk/fuse_mount.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f", + "aggregate": { + "descendant_count": 4, + "own_api_count": 0, + "inherited_api_count": 13, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.platform.dispatch": { + "uid": "a0000330", + "id": "pyvdisk.platform.dispatch", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "实现选择", + "en": "Implementation Dispatch" + }, + "description": { + "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。\n", + "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess.\n" + }, + "source": [ + { + "path": "pyvdisk/compat.py", + "line": 41, + "end_line": 100 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:54.220Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.compat.implementation", + "description": { + "zh": "当前生效的实现:posix 或 windows。\n", + "en": "The implementation in force: posix or windows.\n" + }, + "key": "rpc:pyvdisk.compat.implementation" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat.use_implementation", + "description": { + "zh": "临时强制指定实现;上下文管理器,退出时还原,供测试在 Linux 上执行 Windows 分支。\n", + "en": "Temporarily force an implementation; a context manager that restores the previous one, used by tests to execute the Windows branches on Linux.\n" + }, + "key": "rpc:pyvdisk.compat.use_implementation" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat.describe", + "description": { + "zh": "当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。\n", + "en": "Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks.\n" + }, + "key": "rpc:pyvdisk.compat.describe" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.platform.durability": { + "uid": "a0000333", + "id": "pyvdisk.platform.durability", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "持久化与身份", + "en": "Durability and Identity" + }, + "description": { + "zh": "其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。\n", + "en": "The remaining platform differences: flushing a directory after a rename, reporting process identity, probing symlink support, and selecting the implementation in force. Each returns a value the caller can branch on instead of raising, because none of them is fatal on its own.\n" }, "source": [ { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 7, - "end_line": 49 + "path": "pyvdisk/compat.py", + "line": 202, + "end_line": 283 + }, + { + "path": "pyvdisk/compat.py", + "line": 41, + "end_line": 100 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:47.981Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._path", + "path": "pyvdisk.compat.fsync_dir", "description": { - "zh": "把能力范围归一到以 / 为根、以斜线为界的路径。\n", - "en": "Normalize a capability scope into a rooted, slash-bounded path.\n" + "zh": "刷盘目录,让改名能抵住崩溃。真的执行了才返回 True;Windows 无法把目录当文件打开,所以返回 False 表示\"未执行\",而不是假装成功。\n", + "en": "Flush a directory so a rename survives a crash. Returns True when it actually ran; Windows cannot open a directory as a file, so it returns False to mean not performed rather than claiming success.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities._path" + "key": "rpc:pyvdisk.compat.fsync_dir" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._inside", + "path": "pyvdisk.compat.uid", "description": { - "zh": "路径被包含在范围内时为真。\n", - "en": "True when a path is contained in a scope.\n" + "zh": "进程 uid;平台没有该概念时返回 0。\n", + "en": "Effective uid, or 0 where the platform has no such notion.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities._inside" + "key": "rpc:pyvdisk.compat.uid" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace", + "path": "pyvdisk.compat.gid", "description": { - "zh": "基础适配器:在委托前把能力检查变为守卫条件。\n", - "en": "Base adapter that turns capability checks into guard clauses before delegating.\n" + "zh": "进程 gid;平台没有该概念时返回 0。\n", + "en": "Effective gid, or 0 where the platform has no such notion.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace" + "key": "rpc:pyvdisk.compat.gid" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "path": "pyvdisk.compat.uid_or", "description": { - "zh": "对照执行上下文范围检查单个权限。\n", - "en": "Check one permission against the execution context scope.\n" + "zh": "取 uid,无该概念时用传入的缺省值。用它而不是 `uid() or default`:uid 0 是 root,不是\"未设置\"。\n", + "en": "uid, or the given fallback. Prefer this over `uid() or default`: uid 0 is root, not unset.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check" + "key": "rpc:pyvdisk.compat.uid_or" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call", + "path": "pyvdisk.compat.gid_or", "description": { - "zh": "受保护的委托调用,向下传递所需权限与范围。\n", - "en": "Guarded delegated call that propagates the required permission and scope.\n" + "zh": "取 gid,无该概念时用传入的缺省值。\n", + "en": "gid, or the given fallback.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call" - } - ], - "deps": [ + "key": "rpc:pyvdisk.compat.gid_or" + }, { - "kind": "call", - "to": "pyvdisk.contracts.capability", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", - "label": { - "zh": "检查授权", - "en": "checks grants" + "protocol": "rpc", + "path": "pyvdisk.compat.can_symlink", + "description": { + "zh": "探测指定目录下能否创建符号链接(不抛异常)。Windows 需要开发者模式,调用方据此降级而不是直接失败。\n", + "en": "Probe whether a symlink can be created in the given directory without raising. Windows needs developer mode, so callers degrade instead of failing.\n" }, - "cross_tree": false + "key": "rpc:pyvdisk.compat.can_symlink" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 5, + "own_api_count": 6, "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 + "dep_out": 0, + "dep_in": 2 } }, - "pyvdisk.governance.scoped": { - "uid": "a0000811", - "id": "pyvdisk.governance.scoped", - "parent": "pyvdisk.governance", + "pyvdisk.platform.locking": { + "uid": "a0000332", + "id": "pyvdisk.platform.locking", + "parent": "pyvdisk.platform", "tree": "pyvdisk", "depth": 3, "name": { - "zh": "受限容器", - "en": "Scoped Container" + "zh": "跨进程文件锁", + "en": "Cross-Process Locking" }, "description": { - "zh": "检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。\n", - "en": "Checkpoint scoping plus the ScopedDataDisk object and factory that execution passes to untrusted code.\n" + "zh": "跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLCK 轮询:LK_LOCK 约十秒后会报错,而 flock 会一直等下去。\n", + "en": "Whole-file write serialisation across threads and processes: fcntl.flock on POSIX, an msvcrt byte range on Windows. The Windows path polls with LK_NBLCK on purpose: LK_LOCK errors out after about ten seconds where flock keeps waiting.\n" }, "source": [ { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 130, - "end_line": 162 + "path": "pyvdisk/compat.py", + "line": 128, + "end_line": 198 + }, + { + "path": "pyvdisk/compat.py", + "line": 55 + }, + { + "path": "pyvdisk/compat.py", + "line": 58 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:06.398Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace", + "path": "pyvdisk.compat.lock", "description": { - "zh": "把每个键限制在能力集内的检查点适配器。\n", - "en": "Checkpoint adapter that scopes each key to the capability set.\n" + "zh": "取得整文件锁。blocking=True 等待,timeout=N 秒后放弃并返回 False,blocking=False 只试一次。返回是否拿到锁。\n", + "en": "Take the whole-file lock. blocking=True waits, timeout=N seconds gives up and returns False, blocking=False tries once. Returns whether the lock is held.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace" + "key": "rpc:pyvdisk.compat.lock" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk", + "path": "pyvdisk.compat.unlock", "description": { - "zh": "交给不可信调用方的单一对象:DataDisk 及其能力上下文。\n", - "en": "The single object handed to untrusted callers: a DataDisk plus its capability context.\n" + "zh": "释放锁。句柄已关闭也能调用,因为卸载路径与出错路径都会走到它。\n", + "en": "Release the lock. Tolerates an already-closed handle, because unmount and error paths both call it.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk" - }, + "key": "rpc:pyvdisk.compat.unlock" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 2, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 2 + } + }, + "pyvdisk.platform.positional": { + "uid": "a0000331", + "id": "pyvdisk.platform.positional", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "定位读写", + "en": "Positioned IO" + }, + "description": { + "zh": "不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。\n", + "en": "Atomic positioned reads and writes that neither depend on nor disturb the file cursor. The emulation is not merely a convenience: without the lock, two threads sharing a handle would seek past each other and corrupt blocks.\n" + }, + "source": [ { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__", - "description": { - "zh": "挂载底层容器并返回受限视图。\n", - "en": "Mount the underlying container and return the scoped view.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__" - }, + "path": "pyvdisk/compat.py", + "line": 102, + "end_line": 127 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:00.670Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__", + "path": "pyvdisk.compat.pread", "description": { - "zh": "上下文退出时关闭底层容器。\n", - "en": "Close the underlying container on context exit.\n" + "zh": "从 offset 处读取至多 length 字节。POSIX 用 os.pread;模拟实现用进程级互斥锁包住 lseek+read,避免与其它线程的 seek 交错。\n", + "en": "Positioned read of up to length bytes. POSIX uses os.pread; the emulation holds a process-wide lock across lseek+read so the pair is not interleaved with another thread's seek.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__" + "key": "rpc:pyvdisk.compat.pread" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.scoped", + "path": "pyvdisk.compat.pwrite", "description": { - "zh": "把一个 DataDisk 包装为单次执行上下文视图的便利工厂。\n", - "en": "Convenience factory that wraps a DataDisk for one execution context.\n" + "zh": "向 offset 处写入。POSIX 用 os.pwrite;模拟实现用同一把锁串行化 seek+write。\n", + "en": "Positioned write. POSIX uses os.pwrite; the emulation serialises seek+write under the same lock.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.scoped" + "key": "rpc:pyvdisk.compat.pwrite" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 5, + "own_api_count": 2, "inherited_api_count": 0, "dep_out": 0, "dep_in": 2 @@ -4531,13 +5437,13 @@ "path": "pyvdisk/infrastructure/checkpoint.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.225Z", - "fingerprint": "3ed800d0914e362e6fa76cf02ccddaa8b41f54ffd8efabaebe018e25619b823f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "80d794b29e5404773680587fc27ceeac047cd72e0ab8cc13715f9aaa02d75a68", "aggregate": { - "descendant_count": 107, + "descendant_count": 108, "own_api_count": 0, - "inherited_api_count": 377, + "inherited_api_count": 384, "dep_out": 0, "dep_in": 0 } @@ -4561,9 +5467,9 @@ "path": "pyvdisk/disk.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "aggregate": { "descendant_count": 3, "own_api_count": 0, @@ -4593,9 +5499,9 @@ "end_line": 188 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", @@ -4653,13 +5559,23 @@ "en": "positional read" }, "cross_tree": false + }, + { + "kind": "call", + "to": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", + "label": { + "zh": "定位写入", + "en": "positioned write" + }, + "cross_tree": false } ], "aggregate": { "descendant_count": 0, "own_api_count": 5, "inherited_api_count": 0, - "dep_out": 1, + "dep_out": 2, "dep_in": 3 } }, @@ -4674,8 +5590,8 @@ "en": "Image Lifecycle" }, "description": { - "zh": "VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。\n", - "en": "VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close.\n" + "zh": "VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而不是悄悄退化为空操作。\n", + "en": "VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close. The lock is taken from the platform layer, so write serialisation exists on both POSIX and Windows instead of silently degrading to a no-op.\n" }, "source": [ { @@ -4684,9 +5600,9 @@ "end_line": 141 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", @@ -4710,8 +5626,8 @@ "protocol": "rpc", "path": "pyvdisk.disk.VirtualDisk#open", "description": { - "zh": "打开镜像,写模式下获取 POSIX 写锁。\n", - "en": "Open the image with optional POSIX write lock acquisition.\n" + "zh": "打开镜像,写锁经由平台适配层获取:POSIX 用 flock,Windows 用 msvcrt 字节区间锁。抢锁失败会关掉句柄报错,而不是无声地无锁继续跑。\n", + "en": "Open the image, taking the write lock through the platform layer: flock on POSIX, an msvcrt byte range on Windows. A lock failure closes the handle and raises rather than silently continuing unlocked.\n" }, "key": "rpc:pyvdisk.disk.VirtualDisk#open" }, @@ -4734,11 +5650,23 @@ "key": "rpc:pyvdisk.disk.VirtualDisk#close" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.locking", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", + "label": { + "zh": "整文件写锁", + "en": "whole-file write lock" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 5, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 1, "dep_in": 2 } }, @@ -4753,8 +5681,8 @@ "en": "Positional IO" }, "description": { - "zh": "无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用。\n", - "en": "Unbuffered positional read/write primitives used by every block and byte access on the image.\n" + "zh": "无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。\n", + "en": "Unbuffered positional read/write primitives used by every block and byte access on the image, routed through the platform layer so the same code runs on Windows.\n" }, "source": [ { @@ -4763,16 +5691,16 @@ "end_line": 57 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:14.329Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", "path": "pyvdisk.disk._pread_all", "description": { - "zh": "定位读取,除 EOF 外保证读满。\n", - "en": "Positional read that fills the buffer unless EOF is hit.\n" + "zh": "定位读取,除 EOF 外保证读满。转发给 compat.pread,因此 Windows 上得到的是加锁的 seek+read,而不是 os.pread。\n", + "en": "Positional read that fills the buffer unless EOF is hit. Delegates to compat.pread, so Windows gets a lock-protected seek+read instead of os.pread.\n" }, "key": "rpc:pyvdisk.disk._pread_all" }, @@ -4780,18 +5708,42 @@ "protocol": "rpc", "path": "pyvdisk.disk._pwrite_all", "description": { - "zh": "定位写入,保证写满全部字节。\n", - "en": "Positional write that guarantees every byte is written.\n" + "zh": "定位写入,保证写满全部字节。转发给 compat.pwrite,在 Windows 上用同一把锁串行化 seek+write。\n", + "en": "Positional write that guarantees every byte is written. Delegates to compat.pwrite, which serialises seek+write on Windows.\n" }, "key": "rpc:pyvdisk.disk._pwrite_all" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.positional", + "from_api": "rpc:pyvdisk.disk._pread_all", + "to_api": "rpc:pyvdisk.compat.pread", + "label": { + "zh": "定位读取", + "en": "positioned read" + }, + "cross_tree": false + }, + { + "kind": "call", + "to": "pyvdisk.platform.positional", + "from_api": "rpc:pyvdisk.disk._pwrite_all", + "to_api": "rpc:pyvdisk.compat.pwrite", + "label": { + "zh": "定位写入", + "en": "positioned write" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 2, "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 + "dep_out": 2, + "dep_in": 2 } }, "pyvdisk.storage.checkpoint": { @@ -4813,9 +5765,9 @@ "path": "pyvdisk/infrastructure/checkpoint.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "aggregate": { "descendant_count": 3, "own_api_count": 0, @@ -4845,9 +5797,9 @@ "end_line": 145 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -4905,8 +5857,8 @@ "en": "Checkpoint Store" }, "description": { - "zh": "检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。\n", - "en": "Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle.\n" + "zh": "检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在锁来自平台适配层。\n", + "en": "Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle. This module used to import fcntl at the top level, which made the whole package unimportable on Windows; the lock now comes from the platform layer.\n" }, "source": [ { @@ -4915,9 +5867,9 @@ "end_line": 98 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.308Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:40.830Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -4968,12 +5920,11 @@ "deps": [ { "kind": "call", - "to": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", + "to": "pyvdisk.platform.locking", + "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", "label": { - "zh": "经 VFS 读写", - "en": "reads via VFS" + "zh": "跨进程锁", + "en": "cross-process lock" }, "cross_tree": false } @@ -5007,9 +5958,9 @@ "end_line": 152 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -7944,9 +8895,9 @@ "path": "pyvdisk/fuse_mount.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.231Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "aggregate": { "descendant_count": 4, "own_api_count": 0, @@ -7976,9 +8927,9 @@ "end_line": 121 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -8086,9 +9037,9 @@ "end_line": 233 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -8173,8 +9124,8 @@ "en": "FUSE Attributes" }, "description": { - "zh": "FUSE 可用性检测,以及操作表中属性与目录列举部分。\n", - "en": "FUSE availability check and the attribute/listing half of the operation table.\n" + "zh": "stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与\"平台没有 uid\"无法区分。\n", + "en": "Stat-to-fuse mapping and the entry object: type, mode, size, timestamps and ownership. Identity comes from the platform layer, which also fixes a real bug: uid 0 (root) was previously indistinguishable from \"no uid available\".\n" }, "source": [ { @@ -8183,9 +9134,9 @@ "end_line": 80 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:37:33.368Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -8227,12 +9178,11 @@ "deps": [ { "kind": "call", - "to": "pyvdisk.storage.vfs.stat", + "to": "pyvdisk.platform.durability", "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "to_api": "rpc:pyvdisk.vfs.VFS#stat", "label": { - "zh": "取 stat", - "en": "stats path" + "zh": "进程身份", + "en": "process identity" }, "cross_tree": false } @@ -8266,9 +9216,9 @@ "end_line": 283 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.233Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -9714,13 +10664,13 @@ "path": "pyvdisk/vector_disk.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "aggregate": { - "descendant_count": 4, + "descendant_count": 5, "own_api_count": 0, - "inherited_api_count": 16, + "inherited_api_count": 23, "dep_out": 0, "dep_in": 0 } @@ -9746,44 +10696,155 @@ "end_line": 163 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#create_collection", + "description": { + "zh": "以固定维度与度量创建具名集合。\n", + "en": "Create a named collection with a fixed dimension and metric.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection" + }, + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#list_collections", + "description": { + "zh": "列出集合名称及其配置。\n", + "en": "List the collection names with their configuration.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#list_collections" + }, + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#drop_collection", + "description": { + "zh": "删除集合及其索引文件。\n", + "en": "Drop a collection and its index files.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.storage.vector.flat-index": { + "uid": "a0000334", + "id": "pyvdisk.storage.vector.flat-index", + "parent": "pyvdisk.storage.vector", + "tree": "pyvdisk", + "depth": 4, + "tags": [ + "zero-dependency", + "vector" + ], + "name": { + "zh": "扁平索引后端", + "en": "Flat Index Backend" + }, + "description": { + "zh": "纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集合,不是大规模下 HNSW 的替代品。\n", + "en": "A pure-Python exact index that mirrors hnswlib's calling shape, so VectorDisk can fall back to it without branching. Query is O(n) and the vectors stay in memory: correct for small and medium collections, not a replacement for HNSW at scale.\n" + }, + "source": [ + { + "path": "pyvdisk/vector_index.py", + "line": 38, + "end_line": 47 + }, + { + "path": "pyvdisk/vector_index.py", + "line": 51, + "end_line": 83 + }, + { + "path": "pyvdisk/vector_index.py", + "line": 169, + "end_line": 251 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "c2a8e20da7599125065676cf6a3cea638d1a8108df234b9873b098dbfffb547d", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#create_collection", + "path": "vector_index:distance", "description": { - "zh": "以固定维度与度量创建具名集合。\n", - "en": "Create a named collection with a fixed dimension and metric.\n" + "zh": "按 hnswlib 的约定计算距离,两种后端在调用点可直接互换:cosine = 1 - 相似度,l2 = 平方欧氏距离,ip = 1 - 点积。\n", + "en": "Distance in the convention hnswlib uses, so the two backends are interchangeable at the call site: cosine = 1 - similarity, l2 = squared euclidean, ip = 1 - dot product.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection" + "key": "rpc:vector_index:distance" }, { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#list_collections", + "path": "vector_index:read_kind", "description": { - "zh": "列出集合名称及其配置。\n", - "en": "List the collection names with their configuration.\n" + "zh": "从索引文件读出写入方标识:是 hnswlib 写的还是 flat 后端写的,不需要解析其余内容。\n", + "en": "Read the writer's tag from an index file: whether it was written by hnswlib or by the flat backend, without parsing the rest.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#list_collections" + "key": "rpc:vector_index:read_kind" }, { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#drop_collection", + "path": "vector_index:serialize", "description": { - "zh": "删除集合及其索引文件。\n", - "en": "Drop a collection and its index files.\n" + "zh": "序列化为 flat 格式:8 字节魔数、空间与维度,然后是标签与 float32 向量。\n", + "en": "Serialise to the flat format: an 8-byte magic, the space and dimension, then labels and float32 vectors.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection" + "key": "rpc:vector_index:serialize" + }, + { + "protocol": "rpc", + "path": "vector_index:deserialize", + "description": { + "zh": "解析 flat 索引;内容被截断或根本不是该格式时报错,而不是当成正确数据读下去。\n", + "en": "Parse a flat index, rejecting a truncated or foreign payload instead of misreading it.\n" + }, + "key": "rpc:vector_index:deserialize" + }, + { + "protocol": "rpc", + "path": "vector_index:serialize_from_backend", + "description": { + "zh": "序列化任一后端的索引:flat 索引直接写自己,hnswlib 索引走它自己的 save_index 落到临时文件,需要负责清理。\n", + "en": "Serialise an index of either backend: a flat index writes itself, an hnswlib index goes through its own save_index into a temporary file that must be unlinked.\n" + }, + "key": "rpc:vector_index:serialize_from_backend" + }, + { + "protocol": "rpc", + "path": "vector_index:FlatIndex.add_item", + "description": { + "zh": "写入一条带标签的向量。维度与索引不一致时报错,维度尚未确定的空索引也拒绝写入。\n", + "en": "Add a labelled vector. Rejects a vector whose dimension disagrees with the index, and refuses a fresh index whose dimension was never set.\n" + }, + "key": "rpc:vector_index:FlatIndex.add_item" + }, + { + "protocol": "rpc", + "path": "vector_index:FlatIndex.knn_query", + "description": { + "zh": "精确 k 近邻搜索。距离相同时按标签排序,保证多次运行结果稳定;可选断言用于筛选候选记录。\n", + "en": "Exact k-nearest search. Ties break on the label so results are stable across runs, and an optional predicate filters the candidate records.\n" + }, + "key": "rpc:vector_index:FlatIndex.knn_query" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 3, + "own_api_count": 7, "inherited_api_count": 0, "dep_out": 0, - "dep_in": 1 + "dep_in": 2 } }, "pyvdisk.storage.vector.open": { @@ -9797,8 +10858,8 @@ "en": "Vector Disk Open" }, "description": { - "zh": "VectorDisk 生命周期,以及后续操作共用的 JSON 辅助与集合路径键化。\n", - "en": "VectorDisk lifecycle plus the JSON helpers and collection-path keying used by every later operation.\n" + "zh": "VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。\n", + "en": "VectorDisk construction and mounting. Nothing here requires hnswlib: a collection opens and answers with the built-in flat index, and the accelerator is picked up only if it happens to be installed.\n" }, "source": [ { @@ -9807,9 +10868,9 @@ "end_line": 127 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", @@ -9899,9 +10960,9 @@ "end_line": 221 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", @@ -9967,7 +11028,7 @@ "own_api_count": 5, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 3 + "dep_in": 2 } }, "pyvdisk.storage.vector.search": { @@ -9981,8 +11042,8 @@ "en": "Vector Search" }, "description": { - "zh": "HNSW 图上的索引管理与相似度检索,支持元数据过滤。\n", - "en": "Index management and similarity search over the HNSW graph with metadata filtering.\n" + "zh": "索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索引。\n", + "en": "Index construction, loading and query. The backend is chosen at load time from the file's magic tag: hnswlib when installed, the built-in flat index otherwise. Published with a single rename, so a concurrent reader sees either the old index or the new one.\n" }, "source": [ { @@ -9991,16 +11052,16 @@ "end_line": 267 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#_rebuild_index", "description": { - "zh": "从持久记录重建 HNSW 索引。\n", - "en": "Rebuild the HNSW index from the persisted records.\n" + "zh": "由记录重建索引,并以一次改名原子发布,读方不会看到写了一半的索引。\n", + "en": "Rebuild the index from the records and publish it with one rename, so a reader never sees a half-written index.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index" }, @@ -10008,8 +11069,8 @@ "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#_load_index", "description": { - "zh": "加载盘上索引,缺失时重建。\n", - "en": "Load the on-disk index or rebuild it when absent.\n" + "zh": "加载集合索引。由文件魔数决定路径:flat 直接解析,hnswlib 索引经 hnswlib 加载,缺 hnswlib 时回退为按记录重建的精确索引。\n", + "en": "Load the collection index. The file's magic decides how: flat parses directly, hnswlib loads through hnswlib, and a missing hnswlib falls back to an exact index over the records.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index" }, @@ -10017,21 +11078,20 @@ "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#search", "description": { - "zh": "相似度检索:k 结果、可选元数据过滤,以及是否返回向量。\n", - "en": "Similarity search with k results, an optional metadata filter and include/exclude of vectors.\n" + "zh": "最近邻检索,可带元数据过滤。\n", + "en": "Nearest-neighbour search with an optional metadata filter.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#search" } ], "deps": [ { - "kind": "dataflow", - "to": "pyvdisk.storage.vector.records", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#get", + "kind": "call", + "to": "pyvdisk.storage.vector.flat-index", + "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", "label": { - "zh": "读取记录", - "en": "reads records" + "zh": "后端回退", + "en": "backend fallback" }, "cross_tree": false } @@ -10340,7 +11400,7 @@ "own_api_count": 3, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 4 + "dep_in": 3 } }, "pyvdisk.storage.vfs.hostio": { @@ -10991,7 +12051,7 @@ "own_api_count": 5, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 1 + "dep_in": 0 } }, "pyvdisk.storage.vfs.vfile": { @@ -12219,8 +13279,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:391 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥与打包。\n", - "en": "Test suite: 391 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge and packaging.\n" + "zh": "测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -12234,12 +13294,53 @@ } ], "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.240Z", + "updated_at": "2026-09-24T13:45:00Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { - "descendant_count": 55, + "descendant_count": 58, "own_api_count": 0, - "inherited_api_count": 71, + "inherited_api_count": 74, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.tests.agent-sandbox": { + "uid": "a000033f", + "id": "pyvdisk.tests.agent-sandbox", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "沙箱测试", + "en": "Sandbox Tests" + }, + "description": { + "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及\"脚本入口与 Python 入口共用一个根\"这条规则。\n", + "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root.\n" + }, + "source": [ + { + "path": "tests/test_agent_sandbox.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290", + "apis": [ + { + "protocol": "file", + "path": "tests/test_agent_sandbox.py", + "description": { + "zh": "沙箱的承诺:路径约束、只读、审计链与脚本隔离。\n", + "en": "Sandbox promises: path confinement, read-only, audit chain and script isolation.\n" + }, + "key": "file:tests/test_agent_sandbox.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 } @@ -12569,6 +13670,47 @@ "dep_in": 0 } }, + "pyvdisk.tests.compat": { + "uid": "a000033e", + "id": "pyvdisk.tests.compat", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "平台兼容测试", + "en": "Platform Compat Tests" + }, + "description": { + "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。\n", + "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite.\n" + }, + "source": [ + { + "path": "tests/test_compat.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c", + "apis": [ + { + "protocol": "file", + "path": "tests/test_compat.py", + "description": { + "zh": "把平台切到模拟实现跑整条用例。\n", + "en": "Run the whole suite with the platform switched to the emulated implementation.\n" + }, + "key": "file:tests/test_compat.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, "pyvdisk.tests.contracts": { "uid": "a0000e0a", "id": "pyvdisk.tests.contracts", @@ -13201,6 +14343,47 @@ "dep_in": 0 } }, + "pyvdisk.tests.no-dependency": { + "uid": "a0000340", + "id": "pyvdisk.tests.no-dependency", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "零依赖测试", + "en": "Zero Dependency Tests" + }, + "description": { + "zh": "同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端结果一致且能互读对方写的盘;examples/quickstart.py 在屏蔽 hnswlib 的子进程里能跑完,示例不会悄悄地开始依赖它。\n", + "en": "Three layers of the same claim: pyproject declares no runtime dependencies and keeps the accelerators as extras; VectorDisk answers correctly with hnswlib blocked, and the two backends agree and read each other's files; and examples/quickstart.py runs to completion in a subprocess with hnswlib blocked, so the example cannot quietly start needing it.\n" + }, + "source": [ + { + "path": "tests/test_no_dependency_path.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "aca58c61b9b691e1849bc2f3a598cbaa1fd1e5c7db7193c969d3adbeb0c37073", + "apis": [ + { + "protocol": "file", + "path": "tests/test_no_dependency_path.py", + "description": { + "zh": "零依赖承诺:从打包、后端与示例三个层面校验。\n", + "en": "The zero-dependency promise, checked at packaging, backend and example level.\n" + }, + "key": "file:tests/test_no_dependency_path.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, "pyvdisk.tests.packaging": { "uid": "a0000e14", "id": "pyvdisk.tests.packaging", @@ -15218,9 +16401,9 @@ "line": 1 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.257Z", - "fingerprint": "c7844269be626ed5058001514ea274cee3b6c62a247f7b5afbeca90ed7c02b66", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "98f6c61340ebda42ddbd0fced95d0ae3c9f008ca45b2b60b7730cb2330c980a6", "aggregate": { "descendant_count": 41, "own_api_count": 0, @@ -16594,9 +17777,9 @@ "path": "pyvdisk/vscript/host.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "aggregate": { "descendant_count": 2, "own_api_count": 0, @@ -16616,8 +17799,8 @@ "en": "Host Confinement" }, "description": { - "zh": "宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。该策略现在有真实入口——CLI 注入声明的根目录——host.* 不再因根目录为空而不可用。\n", - "en": "Host confinement: declares which host directories a script may read and write and refuses everything else. The policy now has a real entry point -- the CLI injects the declared roots -- so host.* is reachable instead of failing with an empty root set.\n" + "zh": "宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。\n", + "en": "Host confinement: declares which host directories a script may read and write and refuses everything else. Writes end with a directory flush so the rename itself is durable; that flush goes through the platform layer, since Windows cannot open a directory as a file.\n" }, "source": [ { @@ -16626,9 +17809,9 @@ "end_line": 79 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "apis": [ { "protocol": "rpc", @@ -16685,11 +17868,23 @@ "key": "rpc:pyvdisk.vscript.host.HostProxy#write" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.durability", + "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", + "label": { + "zh": "刷盘目录", + "en": "flush the directory" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 6, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 1, "dep_in": 2 } }, @@ -16714,9 +17909,9 @@ "end_line": 92 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.261Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "apis": [ { "protocol": "rpc", @@ -18181,17 +19376,24 @@ }, "api_index": { "file:.github/workflows/ci.yml": "pyvdisk.delivery.ci", + "file:.github/workflows/ci.yml#no-dependencies": "pyvdisk.delivery.ci", "file:.github/workflows/pylint.yml": "pyvdisk.delivery.lint", "file:CHANGELOG.md": "pyvdisk.docs.changelog", "file:docs/API_GOVERNANCE.md": "pyvdisk.docs.api-governance", "file:docs/ARCHITECTURE.md": "pyvdisk.docs.architecture", "file:docs/CONTRACTS.md": "pyvdisk.docs.contracts", "file:docs/VSCRIPT_SPEC.md": "pyvdisk.docs.vscript-spec", + "file:examples/agent_tools.py:scripted_model": "pyvdisk.examples.agent-tools", + "file:examples/quickstart.py": "pyvdisk.examples.quickstart", "file:MANIFEST.in": "pyvdisk.delivery.packaging", "file:pyproject.toml": "pyvdisk.delivery.packaging", "file:pyvdisk/__main__.py": "pyvdisk.cli.entry", "file:pyvdisk/py.typed": "pyvdisk.delivery.packaging", "file:README.md": "pyvdisk.docs.readme", + "file:tests/test_agent_sandbox.py": "pyvdisk.tests.agent-sandbox", + "file:tests/test_compat.py": "pyvdisk.tests.compat", + "file:tests/test_no_dependency_path.py": "pyvdisk.tests.no-dependency", + "rpc:pyvdisk.AgentSandbox": "pyvdisk.api", "rpc:pyvdisk.CheckpointStore": "pyvdisk.api", "rpc:pyvdisk.cli._add_cred_args": "pyvdisk.cli.format", "rpc:pyvdisk.cli._human_size": "pyvdisk.cli.format", @@ -18251,6 +19453,20 @@ "rpc:pyvdisk.cli.cmd_vol_status": "pyvdisk.cli.volume", "rpc:pyvdisk.cli.cmd_write": "pyvdisk.cli.file-ops", "rpc:pyvdisk.cli.main": "pyvdisk.cli.main", + "rpc:pyvdisk.compat": "pyvdisk.api", + "rpc:pyvdisk.compat.can_symlink": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.describe": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.fsync_dir": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.implementation": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.lock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.pread": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.pwrite": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.uid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.uid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.unlock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.use_implementation": "pyvdisk.platform.dispatch", "rpc:pyvdisk.contracts.BlockDevice": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#read_block": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#write_block": "pyvdisk.contracts.storage", @@ -18332,6 +19548,7 @@ "rpc:pyvdisk.execution.ExecutionService#submit": "pyvdisk.execution.service.submit", "rpc:pyvdisk.execution.ExecutionService#worker_count": "pyvdisk.execution.service.setup", "rpc:pyvdisk.ExecutionService": "pyvdisk.api", + "rpc:pyvdisk.FlatIndex": "pyvdisk.api", "rpc:pyvdisk.fs._ceil_div": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._decode_name": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._disk_lock_key": "pyvdisk.storage.fs.locking", @@ -18903,6 +20120,27 @@ "rpc:pyvdisk.vscript.wal.encode_record": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.RECORD_KINDS": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.WriteAheadLog": "pyvdisk.storage.wal.undo", + "rpc:sandbox:_hidden": "pyvdisk.agent.paths", + "rpc:sandbox:_SandboxFS": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox._normalize": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox._visible": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox.audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.call": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.create": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.delete": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.dispatch": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.exists": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.list": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.make_directory": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.open": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.read": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.retain_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.run": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox.stats": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.tools": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.verify_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.write": "pyvdisk.agent.sandbox", + "rpc:sandbox:TOOLS": "pyvdisk.agent.tools", "rpc:tests/conftest.py": "pyvdisk.tests.fixtures", "rpc:tests/test_agentic_cli.py": "pyvdisk.tests.agentic-cli", "rpc:tests/test_api_governance.py": "pyvdisk.tests.api-governance", @@ -18973,9 +20211,49 @@ "rpc:tests/test_vscript.py::VScriptTests": "pyvdisk.tests.vscript", "rpc:tests/test_wal_abort_recovery.py": "pyvdisk.tests.wal-recovery", "rpc:tests/test_wal_checkpoint_and_recovery.py": "pyvdisk.tests.wal-checkpoint", - "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation" + "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation", + "rpc:vector_index:deserialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:distance": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.add_item": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.knn_query": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:read_kind": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize_from_backend": "pyvdisk.storage.vector.flat-index" }, "edges": [ + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.AgentSandbox", + "to": "pyvdisk.agent.sandbox", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出沙箱门面", + "en": "re-exports the sandbox" + } + }, + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.compat", + "to": "pyvdisk.platform", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出平台适配层", + "en": "re-exports the platform layer" + } + }, + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.FlatIndex", + "to": "pyvdisk.storage.vector.flat-index", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出扁平索引", + "en": "re-exports the flat index" + } + }, { "from": "pyvdisk.cli.open", "from_api": "rpc:pyvdisk.cli._open_vfs", @@ -19179,16 +20457,61 @@ "en": "positional read" } }, + { + "from": "pyvdisk.storage.block.access", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", + "to": "pyvdisk.storage.block.io", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位写入", + "en": "positioned write" + } + }, + { + "from": "pyvdisk.storage.block.image", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", + "to": "pyvdisk.platform.locking", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "整文件写锁", + "en": "whole-file write lock" + } + }, + { + "from": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk._pread_all", + "to": "pyvdisk.platform.positional", + "to_api": "rpc:pyvdisk.compat.pread", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位读取", + "en": "positioned read" + } + }, + { + "from": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk._pwrite_all", + "to": "pyvdisk.platform.positional", + "to_api": "rpc:pyvdisk.compat.pwrite", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位写入", + "en": "positioned write" + } + }, { "from": "pyvdisk.storage.checkpoint.open", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs", - "to": "pyvdisk.storage.vfs.files", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", + "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", + "to": "pyvdisk.platform.locking", "kind": "call", "cross_tree": false, "label": { - "zh": "经 VFS 读写", - "en": "reads via VFS" + "zh": "跨进程锁", + "en": "cross-process lock" } }, { @@ -19456,13 +20779,12 @@ { "from": "pyvdisk.storage.fuse.meta", "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "to": "pyvdisk.storage.vfs.stat", - "to_api": "rpc:pyvdisk.vfs.VFS#stat", + "to": "pyvdisk.platform.durability", "kind": "call", "cross_tree": false, "label": { - "zh": "取 stat", - "en": "stats path" + "zh": "进程身份", + "en": "process identity" } }, { @@ -19623,14 +20945,13 @@ }, { "from": "pyvdisk.storage.vector.search", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index", - "to": "pyvdisk.storage.vector.records", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#get", - "kind": "dataflow", + "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", + "to": "pyvdisk.storage.vector.flat-index", + "kind": "call", "cross_tree": false, "label": { - "zh": "读取记录", - "en": "reads records" + "zh": "后端回退", + "en": "backend fallback" } }, { @@ -20274,6 +21595,17 @@ "en": "carries source spans" } }, + { + "from": "pyvdisk.vscript.host.guard", + "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", + "to": "pyvdisk.platform.durability", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "刷盘目录", + "en": "flush the directory" + } + }, { "from": "pyvdisk.vscript.host.module", "from_api": "rpc:pyvdisk.vscript.host.create_host_module", @@ -20433,12 +21765,12 @@ "pyvdisk": { "schema_version": 1, "id": "pyvdisk", - "updated_at": "2026-09-23T07:23:36.674Z", + "updated_at": "2026-09-24T11:39:34.471Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;api/compat 是导出面;tests/docs/delivery 是保障与交付。", - "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; api/compat are the exported surface; tests/docs/delivery provide assurance." + "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;接着是对外一组——Agent 工作区与沙箱、导出面、以及沉底的平台适配层;examples/tests/docs/delivery 是示例、保障与交付。", + "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; then the outward-facing group -- the agent workspace and its sandbox, the exported API, and the platform layer everything sits on; examples/docs/tests/delivery provide assurance and delivery." }, "order": [ "pyvdisk.storage", @@ -20447,8 +21779,11 @@ "pyvdisk.vscript", "pyvdisk.cli", "pyvdisk.contracts", + "pyvdisk.agent", "pyvdisk.api", "pyvdisk.compat", + "pyvdisk.platform", + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" @@ -20481,21 +21816,24 @@ { "id": "surface", "title": { - "zh": "对外接口", - "en": "Public Surface" + "zh": "对外接口与 Agent 入口", + "en": "Public Surface and Agent Entry" }, "children": [ + "pyvdisk.agent", "pyvdisk.api", - "pyvdisk.compat" + "pyvdisk.compat", + "pyvdisk.platform" ] }, { "id": "meta", "title": { - "zh": "文档、测试与交付", - "en": "Docs, Tests and Delivery" + "zh": "示例、文档、测试与交付", + "en": "Examples, Docs, Tests and Delivery" }, "children": [ + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" @@ -20503,6 +21841,48 @@ } ] }, + "pyvdisk.agent": { + "schema_version": 1, + "id": "pyvdisk.agent", + "updated_at": "2026-09-24T11:33:31.064Z", + "mode": "groups", + "reading": { + "zh": "从左到右:路径能指向什么,有哪些工具,把两者合起来的门面,最后是调用在哪里执行、留下什么记录。", + "en": "Left to right: what a path may name, what tools exist, the facade that ties them together, then where a call runs and what it leaves behind." + }, + "order": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox", + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ], + "groups": [ + { + "id": "surface", + "title": { + "zh": "模型看到的面", + "en": "What the model sees" + }, + "children": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox" + ] + }, + { + "id": "execution", + "title": { + "zh": "执行与留痕", + "en": "Execution and evidence" + }, + "children": [ + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ] + } + ] + }, "pyvdisk.cli": { "schema_version": 1, "id": "pyvdisk.cli", @@ -20672,6 +22052,20 @@ "pyvdisk.docs.changelog" ] }, + "pyvdisk.examples": { + "schema_version": 1, + "id": "pyvdisk.examples", + "updated_at": "2026-09-24T11:34:32.619Z", + "mode": "grid", + "reading": { + "zh": "两个入口:自底向上跑通整条栈的导览,以及演示框架如何对接的 agent loop。", + "en": "Two entries: the bottom-up tour of the whole stack, and the agent loop that shows how a framework talks to it." + }, + "order": [ + "pyvdisk.examples.quickstart", + "pyvdisk.examples.agent-tools" + ] + }, "pyvdisk.execution": { "schema_version": 1, "id": "pyvdisk.execution", @@ -20788,6 +22182,38 @@ "pyvdisk.governance.scoped" ] }, + "pyvdisk.platform": { + "schema_version": 1, + "id": "pyvdisk.platform", + "updated_at": "2026-09-24T11:34:38.929Z", + "mode": "grid", + "max_columns": 2, + "reading": { + "zh": "先看当前用的是哪套实现,再看其余模块都会经过的四类原语:定位读写、文件锁、持久化与身份。", + "en": "Which implementation is in force, then the four primitive groups every other module goes through: positioned IO, locking, and durability/identity." + }, + "order": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ], + "groups": [ + { + "id": "primitives", + "title": { + "zh": "四类原语", + "en": "Primitives" + }, + "children": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ] + } + ] + }, "pyvdisk.storage": { "schema_version": 1, "id": "pyvdisk.storage", @@ -21151,15 +22577,18 @@ "pyvdisk.storage.vector": { "schema_version": 1, "id": "pyvdisk.storage.vector", - "updated_at": "2026-09-23T07:24:02.752Z", + "updated_at": "2026-09-24T11:32:36.825Z", + "mode": "grid", + "max_columns": 3, "reading": { - "zh": "先挂载向量盘、管理集合,再写入与读取记录,最后在索引上做相似度检索。", - "en": "Mount the vector disk, manage collections, write and read records, then run similarity search over the built index." + "zh": "先看集合簿记与记录,再看索引后端,最后是消费它的检索。", + "en": "Collection bookkeeping and records first, then the index backend, then the search that consumes it." }, "order": [ "pyvdisk.storage.vector.open", "pyvdisk.storage.vector.collections", "pyvdisk.storage.vector.records", + "pyvdisk.storage.vector.flat-index", "pyvdisk.storage.vector.search" ] }, @@ -21273,12 +22702,12 @@ "pyvdisk.tests": { "schema_version": 1, "id": "pyvdisk.tests", - "updated_at": "2026-09-24T09:56:06.550Z", + "updated_at": "2026-09-24T11:39:19.907Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "按所验证的子系统分组:夹具与文件系统持久性(新增 FUSE 桥)、事务/参与者补偿/崩溃矩阵、执行平面、队列与精确一次保证、VScript 语言及其审计轨迹/撤销/cron/触发器、治理与契约,最后是日志盘、CLI 与打包检查。", - "en": "Grouped by the subsystem each module validates: fixtures and filesystem durability (now including the FUSE bridge), transactions, participant compensation and crash matrices, the execution plane, queue and exactly-once guarantees, the VScript language with its audit trail, undo, cron and triggers, governance and contracts, and finally log-disk, CLI and packaging checks." + "zh": "按所验证的子系统分组:夹具、文件系统持久性与平台适配层、事务与崩溃、执行平面、队列与精确一次保证、VScript、治理与沙箱,最后是日志盘、CLI、打包与零依赖检查。", + "en": "Grouped by the subsystem each module validates: fixtures, filesystem durability and the platform layer, transactions and crashes, the execution plane, queue and exactly-once guarantees, VScript, governance and the sandbox, then log-disk, CLI, packaging and the zero-dependency check." }, "order": [ "pyvdisk.tests.fixtures", @@ -21287,6 +22716,7 @@ "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat", "pyvdisk.tests.tx-rollback", "pyvdisk.tests.tx-idempotency", "pyvdisk.tests.crash-matrix", @@ -21313,10 +22743,12 @@ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox", "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ], "groups": [ { @@ -21331,7 +22763,8 @@ "pyvdisk.tests.atomic-save", "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount" + "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat" ] }, { @@ -21396,13 +22829,14 @@ { "id": "gov", "title": { - "zh": "治理与契约", - "en": "Governance and Contracts" + "zh": "治理与沙箱", + "en": "Governance and Sandbox" }, "children": [ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts" + "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox" ] }, { @@ -21415,7 +22849,8 @@ "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ] } ] @@ -21679,12 +23114,12 @@ "changes": [ { "id": "2026-09-24-readme-counts", - "status": "in_progress", + "status": "verified", "title": { "en": "Align the README counts with the rebuilt tree", "zh": "README 计数与重建后的结构库对齐" }, - "updated_at": "2026-09-24T10:00:43.967Z" + "updated_at": "2026-09-24T10:00:54.385Z" }, { "id": "2026-09-24-resync-issue1-fixes", @@ -21694,6 +23129,15 @@ "zh": "结构库同步 issue #1 的修复" }, "updated_at": "2026-09-24T09:59:19.981Z" + }, + { + "id": "2026-09-24-zero-dep-windows-agentsandbox", + "status": "proposed", + "title": { + "en": "Zero dependency, Windows compat layer and AgentSandbox", + "zh": "零依赖 + Windows 兼容层 + AgentSandbox" + }, + "updated_at": "2026-09-24T11:30:26.105Z" } ] } diff --git a/normify-pyvdisk/outline.md b/normify-pyvdisk/outline.md index 935ce1e..6bae71d 100644 --- a/normify-pyvdisk/outline.md +++ b/normify-pyvdisk/outline.md @@ -4,8 +4,14 @@ ## pyvdisk(https://github.com/HeDaas-Code/pyvdisk) -- pyvdisk — PyVDisk / PyVDisk — 单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作… — [模块 272 · API 794] - - pyvdisk.api — 公开门面 / Public Facade — 公开门面:调用方直接从 pyvdisk 包根导入的存储、执行与契约名称。 — [模块 1 · API 8] +- pyvdisk — PyVDisk / PyVDisk — 单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作… — [模块 290 · API 844] + - pyvdisk.agent — Agent 工作区 / Agent Workspace — 把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 d… — [模块 6 · API 21] + - pyvdisk.agent.audit — 工具调用审计 / Tool Call Audit — 每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。"模型是不是读了不该读的路径"这个问题,事… — [模块 1 · API 4] + - pyvdisk.agent.paths — 路径约束 / Path Confinement — 沙箱内"路径意味着什么"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见… — [模块 1 · API 3] + - pyvdisk.agent.sandbox — 沙箱门面 / Sandbox Facade — 门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及… — [模块 1 · API 8] + - pyvdisk.agent.script — 盘内脚本 / Sandboxed Scripts — 盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glo… — [模块 1 · API 2] + - pyvdisk.agent.tools — 工具面 / Tool Surface — 六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面… — [模块 1 · API 4] + - pyvdisk.api — 公开门面 / Public Facade — 公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。 — [模块 1 · API 11] - pyvdisk.cli — 命令行 / Command Line — 命令行界面:参数解析以及文件系统、卷、驱动器、向量、日志与状态检查子命令。 — [模块 15 · API 59] - pyvdisk.cli.admin — 管理子命令 / Admin Subcommands — 管理类子命令:格式化、链接、属性、空间统计、fsck 与扩容。 — [模块 1 · API 8] - pyvdisk.cli.dirs — 目录子命令 / Directory Subcommands — 目录与删除子命令,语义与对应文件系统操作一致。 — [模块 1 · API 4] @@ -32,17 +38,20 @@ - pyvdisk.contracts.plane — 执行平面协议 / Execution Plane — ExecutionPlane 协议:每个执行后端都必须暴露的唯一 submit 入口。 — [模块 1 · API 1] - pyvdisk.contracts.runhandle — 运行句柄 / Run Handle — RunHandle:执行平面返回的可观察、可取消句柄;取消不会覆盖终态。 — [模块 1 · API 5] - pyvdisk.contracts.storage — 存储协议 / Storage Protocols — 结构化存储协议:BlockDevice、NamespaceStore、CollectionStore;既有后端以结构化方式满足它们。 — [模块 1 · API 5] - - pyvdisk.delivery — 打包与持续集成 / Packaging and CI — 分发与持续集成:打包元数据、PEP 561 类型标记与 GitHub Actions 工作流。 — [模块 4 · API 5] - - pyvdisk.delivery.ci — 测试工作流 / Test Workflow — CI 工作流:在 push 与 pull request 上安装 dev extras 并在 3.9–3.12 矩阵上运行 pytest,使声明的 requir… — [模块 1 · API 1] + - pyvdisk.delivery — 打包与持续集成 / Packaging and CI — 分发与持续集成:打包元数据、PEP 561 类型标记与 GitHub Actions 工作流。 — [模块 4 · API 6] + - pyvdisk.delivery.ci — 测试工作流 / Test Workflow — CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 … — [模块 1 · API 2] - pyvdisk.delivery.lint — 静态分析工作流 / Lint Workflow — 独立于单元测试门禁的静态分析流水线:pylint 只保留 error 类,使 Lint 失败不会被误认为测试失败。 — [模块 1 · API 1] - - pyvdisk.delivery.packaging — 打包元数据 / Packaging Metadata — 分发元数据:以 hnswlib 为依赖、fuse 与 dev extras、py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打… — [模块 1 · API 3] + - pyvdisk.delivery.packaging — 打包元数据 / Packaging Metadata — 分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICEN… — [模块 1 · API 3] - pyvdisk.docs — 技术文档 / Technical Docs — 仓库技术文档层:架构设计、契约边界、API 治理与 VScript 语言规范,是模块结构的一手证据来源。 — [模块 7 · API 6] - pyvdisk.docs.api-governance — API 治理 / API Governance — API 治理:公开入口、权限模型、已废弃的旧路径,以及推荐给 Agent 使用的接口面。 — [模块 1 · API 1] - pyvdisk.docs.architecture — 架构设计 / Architecture Design — 架构设计:存储平面、执行平面、单盘 ACID、内部 exactly-once、解释器架构与故障恢复流程。 — [模块 1 · API 1] - - pyvdisk.docs.changelog — 变更日志 / Changelog — 变更日志:按 issue #1 的清单编号记录用户可见变更,并列出四条明确留待后续的项目。 — [模块 1 · API 1] + - pyvdisk.docs.changelog — 变更日志 / Changelog — 用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留"已知未完成"一节,未完成项要看得见,而不是被静… — [模块 1 · API 1] - pyvdisk.docs.contracts — 契约边界 / Contract Boundaries — 各平面的保证边界:存储、执行、事务与内部 exactly-once 承诺什么、不承诺什么;新增 VScript 事务的撤销记账、本地触发器与审计轨迹三节。 — [模块 1 · API 1] - - pyvdisk.docs.readme — 项目总览 / Project Overview — README 总览:项目定位、快速开始、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。 — [模块 1 · API 1] + - pyvdisk.docs.readme — 项目总览 / Project Overview — README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一… — [模块 1 · API 1] - pyvdisk.docs.vscript-spec — VScript 规范 / VScript Spec — VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。 — [模块 1 · API 1] + - pyvdisk.examples — 可运行示例 / Runnable Examples — 可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。 — [模块 3 · API 2] + - pyvdisk.examples.agent-tools — Agent 对接示例 / Agent Loop Demo — 带脚本化"模型"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_m… — [模块 1 · API 1] + - pyvdisk.examples.quickstart — 快速上手 / Quickstart Tour — 单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏… — [模块 1 · API 1] - pyvdisk.execution — 执行平面 / Execution Plane — 执行平面:同步 ExecutionService、持久任务队列、持久化运行状态与操作注册表。 — [模块 22 · API 72] - pyvdisk.execution.operations — 操作注册表 / Operation Registry — 操作注册表:稳定 operation id、负载指纹、持久化结果、可调用对象解析与 VScript 操作描述。 — [模块 7 · API 24] - pyvdisk.execution.operations.callables — 可调用对象注册表 / Callable Registry — 可调用对象注册表,以及把 Python 函数变为可持久重放操作的 RegisteredCallable 包装。 — [模块 1 · API 4] @@ -70,14 +79,19 @@ - pyvdisk.governance.files — 受限文件系统 / Scoped Filesystem — 能力治理的文件系统半边:每个 VFS 方法都必须经过权限与范围检查才能触达。 — [模块 1 · API 8] - pyvdisk.governance.namespace — 能力门禁 / Capability Gate — 能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。 — [模块 1 · API 5] - pyvdisk.governance.scoped — 受限容器 / Scoped Container — 检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。 — [模块 1 · API 5] - - pyvdisk.storage — 存储平面 / Storage Plane — 存储平面:块镜像、磁盘身份、盘上文件系统、高层 VFS、多盘卷、向量盘与日志盘、结构化日志、模拟驱动器、可选 FUSE 挂载、统一 DataDisk 容器、WA… — [模块 108 · API 377] + - pyvdisk.platform — 平台适配层 / Platform Adaptation — 唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份… — [模块 5 · API 13] + - pyvdisk.platform.dispatch — 实现选择 / Implementation Dispatch — 决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linu… — [模块 1 · API 3] + - pyvdisk.platform.durability — 持久化与身份 / Durability and Identity — 其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。 — [模块 1 · API 6] + - pyvdisk.platform.locking — 跨进程文件锁 / Cross-Process Locking — 跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLC… — [模块 1 · API 2] + - pyvdisk.platform.positional — 定位读写 / Positioned IO — 不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。 — [模块 1 · API 2] + - pyvdisk.storage — 存储平面 / Storage Plane — 存储平面:块镜像、磁盘身份、盘上文件系统、高层 VFS、多盘卷、向量盘与日志盘、结构化日志、模拟驱动器、可选 FUSE 挂载、统一 DataDisk 容器、WA… — [模块 109 · API 384] - pyvdisk.storage.block — 块镜像 / Block Image — 块级镜像 IO:把一个 .vdisk 文件当作块设备,使用 os.pread/os.pwrite 与 POSIX advisory 写锁。 — [模块 4 · API 12] - pyvdisk.storage.block.access — 块访问 / Block Access — 已打开镜像上的块级与字节级访问:块读写、裸字节区间与镜像扩缩。 — [模块 1 · API 5] - - pyvdisk.storage.block.image — 镜像生命周期 / Image Lifecycle — VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。 — [模块 1 · API 5] - - pyvdisk.storage.block.io — 定位 IO 原语 / Positional IO — 无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用。 — [模块 1 · API 2] + - pyvdisk.storage.block.image — 镜像生命周期 / Image Lifecycle — VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而… — [模块 1 · API 5] + - pyvdisk.storage.block.io — 定位 IO 原语 / Positional IO — 无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。 — [模块 1 · API 2] - pyvdisk.storage.checkpoint — 检查点存储 / Checkpoint Store — 检查点存储:以 VFS 路径或宿主目录为背衬的持久键值进度与结果记录,带跨进程锁与原子落盘。 — [模块 4 · API 11] - pyvdisk.storage.checkpoint.io — 检查点 IO / Checkpoint IO — 检查点 IO:键值记录映射的加载、读取、暂存与原子保存。 — [模块 1 · API 4] - - pyvdisk.storage.checkpoint.open — 检查点存储 / Checkpoint Store — 检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。 — [模块 1 · API 5] + - pyvdisk.storage.checkpoint.open — 检查点存储 / Checkpoint Store — 检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在… — [模块 1 · API 5] - pyvdisk.storage.checkpoint.triggers — 触发器检查点 / Trigger Checkpoints — 面向触发器的便利层,为调度器提供持久的事件去重保证。 — [模块 1 · API 2] - pyvdisk.storage.datadisk — DataDisk 容器 / DataDisk Container — 统一 DataDisk 容器:一个挂载的 VFS 加上 FS/向量/日志命名空间服务,带撤销日志的元数据事务、WAL 与重挂载恢复。 — [模块 8 · API 39] - pyvdisk.storage.datadisk.api — DataDisk 接口 / DataDisk Interface — 容器生命周期与面向调用方的接口:挂载、manifest、事务、元数据访问与能力受限视图。 — [模块 1 · API 8] @@ -120,7 +134,7 @@ - pyvdisk.storage.fuse — FUSE 挂载 / FUSE Mount — 可选 FUSE 挂载:把 VFS 暴露为宿主目录;缺少 fusepy 时给出清晰的 ImportError。 — [模块 5 · API 20] - pyvdisk.storage.fuse.data — FUSE 数据处理 / FUSE Data Ops — FUSE 数据与命名空间变更:read、write、create、mkdir、rmdir、unlink 与 rename 处理。 — [模块 1 · API 7] - pyvdisk.storage.fuse.handlers — FUSE 链接处理 / FUSE Link Ops — 其余 FUSE 处理:truncate、链接、open/release、chmod,以及动态 Operations 子类装配。readlink 以不追随后一段的… — [模块 1 · API 7] - - pyvdisk.storage.fuse.meta — FUSE 属性 / FUSE Attributes — FUSE 可用性检测,以及操作表中属性与目录列举部分。 — [模块 1 · API 4] + - pyvdisk.storage.fuse.meta — FUSE 属性 / FUSE Attributes — stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与"平台没… — [模块 1 · API 4] - pyvdisk.storage.fuse.mount — FUSE 挂载入口 / FUSE Mount Entry — 公开挂载入口,包含容忍忙挂载的 main 循环补丁与线程化变体。 — [模块 1 · API 2] - pyvdisk.storage.identity — 磁盘身份 / Disk Identity — 磁盘身份:block 0 末尾的 112 字节 VDID 尾标,让每块 .vdisk 不依赖路径即可被识别。 — [模块 5 · API 12] - pyvdisk.storage.identity.format — 身份格式 / Identity Format — 尾标布局常量、.vdisk 后缀规则与身份错误类型。 — [模块 1 · API 3] @@ -143,11 +157,12 @@ - pyvdisk.storage.rwlock — 读写锁 / Read-Write Lock — 可重入、写者优先的读写锁,供同一镜像上并发打开的多个 FS 实例共享。 — [模块 3 · API 9] - pyvdisk.storage.rwlock.core — 锁核心 / Lock Core — 锁核心:每线程重入、写者优先,以及仅限唯一读者时的读锁升级。 — [模块 1 · API 5] - pyvdisk.storage.rwlock.ctx — 锁上下文 / Lock Contexts — 供 FS 锁装饰器与 VFS/FS 公开接口使用的 with 语句辅助类型。 — [模块 1 · API 4] - - pyvdisk.storage.vector — 向量盘 / Vector Disk — 向量盘:基于 HNSW 的具名记录集合,带 generation、checksum、过滤器与相似度检索。 — [模块 5 · API 16] + - pyvdisk.storage.vector — 向量盘 / Vector Disk — 向量盘:基于 HNSW 的具名记录集合,带 generation、checksum、过滤器与相似度检索。 — [模块 6 · API 23] - pyvdisk.storage.vector.collections — 集合目录 / Collections — 集合目录:按维度与度量创建、带配置列举,以及连同每集合 HNSW 索引一起删除。 — [模块 1 · API 3] - - pyvdisk.storage.vector.open — 向量盘打开 / Vector Disk Open — VectorDisk 生命周期,以及后续操作共用的 JSON 辅助与集合路径键化。 — [模块 1 · API 5] + - pyvdisk.storage.vector.flat-index — 扁平索引后端 / Flat Index Backend — 纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集… — [模块 1 · API 7] + - pyvdisk.storage.vector.open — 向量盘打开 / Vector Disk Open — VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。 — [模块 1 · API 5] - pyvdisk.storage.vector.records — 向量记录 / Vector Records — 记录 CRUD:维度校验、单条与批量 upsert、获取、删除与计数。 — [模块 1 · API 5] - - pyvdisk.storage.vector.search — 向量检索 / Vector Search — HNSW 图上的索引管理与相似度检索,支持元数据过滤。 — [模块 1 · API 3] + - pyvdisk.storage.vector.search — 向量检索 / Vector Search — 索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索… — [模块 1 · API 3] - pyvdisk.storage.vfs — 虚拟文件系统 / Virtual File System — FS 之上的高层路径式 VFS:类文件对象、权限检查、宿主导入导出、遍历、空间统计与卷自动识别。 — [模块 17 · API 62] - pyvdisk.storage.vfs.attrs — 元数据变更 / Metadata Writes — VFS 门面上的元数据变更:模式、属主、时间戳、权限检查与截断。 — [模块 1 · API 5] - pyvdisk.storage.vfs.create — 创建盘与卷 / Create Disk or Volume — VFS 门面上的磁盘与卷创建入口。 — [模块 1 · API 2] @@ -178,13 +193,15 @@ - pyvdisk.storage.wal.entries — WAL 记录 / WAL Entries — 事务日志动词与崩溃恢复重放:begin/append/prepare/commit/abort,以及重放所依赖的读取入口。 — [模块 1 · API 8] - pyvdisk.storage.wal.journal — 元数据 WAL / Metadata WAL — DataDisk 事务使用的元数据预写日志:存储后端、行编解码,以及分配序号的追加写入。 — [模块 1 · API 4] - pyvdisk.storage.wal.undo — 宿主撤销 WAL / Host Undo WAL — VScript 侧的 WAL 入口:独立的宿主路径实现已取消——本模块直接复用同一套 WriteAheadLog,并给出撤销记录使用的 kind 集与编解码。 — [模块 1 · API 4] - - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:391 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥与打包。 — [模块 56 · API 71] + - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] + - pyvdisk.tests.agent-sandbox — 沙箱测试 / Sandbox Tests — 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的… — [模块 1 · API 1] - pyvdisk.tests.agentic-cli — 智能体 CLI 用例 / Agentic CLI Tests — 面向智能体使用编写的 CLI 用例:可发现的输出与稳定的退出码。 — [模块 1 · API 1] - pyvdisk.tests.api-governance — API 治理用例 / API Governance Tests — 检查公开能力 API 是否拒绝应当拒绝的调用,而不只验证正常路径。 — [模块 1 · API 1] - pyvdisk.tests.atomic-save — 原子保存用例 / Atomic Save Tests — 验证元数据写入是全有或全无,即事务层所依赖的性质。 — [模块 1 · API 1] - pyvdisk.tests.audit-trail — 审计轨迹用例 / Audit Trail Tests — 审计轨迹用例:哈希链校验(含在真实日志段内篡改记录)、查询筛选与保留策略。 — [模块 1 · API 1] - pyvdisk.tests.cancellation — 取消用例 / Cancellation Tests — 验证协作式取消会让队列与运行状态保持一致,不停留在中间状态。 — [模块 1 · API 1] - pyvdisk.tests.checkpoint — 检查点用例 / Checkpoint Tests — 为队列、运行、操作与审计提供背衬的持久键值存储的单元用例。 — [模块 1 · API 1] + - pyvdisk.tests.compat — 平台兼容测试 / Platform Compat Tests — 在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分… — [模块 1 · API 1] - pyvdisk.tests.contracts — 契约用例 / Contract Tests — 保持抽象契约与具体实现一致的合规性用例。 — [模块 1 · API 1] - pyvdisk.tests.crash-matrix — 崩溃矩阵用例 / Crash Matrix Tests — 最强的持久性用例:在每个阶段中断事务并断言恢复后落在合法状态。 — [模块 1 · API 1] - pyvdisk.tests.e2e — 端到端用例 / End-to-End Tests — 遍历整个基础设施栈的集成用例,含在受限盘上运行脚本。 — [模块 1 · API 1] @@ -197,6 +214,7 @@ - pyvdisk.tests.governance — 治理回归用例 / Governance Regression Tests — 最大的治理测试模块:治理工作新增的受限命名空间的回归覆盖。 — [模块 1 · API 1] - pyvdisk.tests.logdisk-compact — 日志压缩用例 / Log Compaction Tests — 守住压缩绝不可违反的性质:减少存储不得改变可观测的流状态。 — [模块 1 · API 1] - pyvdisk.tests.logdisk-retention — 日志保留用例 / Log Retention Tests — 验证保留策略不会删除消费者尚未确认的事件。 — [模块 1 · API 1] + - pyvdisk.tests.no-dependency — 零依赖测试 / Zero Dependency Tests — 同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端… — [模块 1 · API 1] - pyvdisk.tests.packaging — 打包用例 / Packaging Tests — 验证包可构建安装,且 py.typed 标记与控制台入口完好。 — [模块 1 · API 1] - pyvdisk.tests.participant-compensation — 参与者补偿用例 / Participant Compensation Tests — 参与者补偿用例:持久化写前补偿、进程内 abort 的逆序分发、跨挂载的幂等重复补偿。 — [模块 1 · API 1] - pyvdisk.tests.queue — 队列用例 / Queue Tests — 单进程内持久队列的状态迁移用例。 — [模块 1 · API 1] @@ -254,7 +272,7 @@ - pyvdisk.vscript.frontend.span — 位置与诊断 / Span and Diagnostic — 位置与诊断原语:事情发生在哪里,以及如何向用户报告。 — [模块 1 · API 4] - pyvdisk.vscript.frontend.tokens — 词法单元 / Token Types — 语言的词法单元词表:lexer 能产出的全部关键字、运算符与字面量。 — [模块 1 · API 3] - pyvdisk.vscript.host — 宿主访问 / Host Access — VScript 宿主访问:白名单 HostProxy,把脚本文件传输限制在声明的目录根内。 — [模块 3 · API 7] - - pyvdisk.vscript.host.guard — 宿主隔离 / Host Confinement — 宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。该策略现在有真实入口——CLI 注入声明的根目录——host.* 不再因根目录为空而不可用。 — [模块 1 · API 6] + - pyvdisk.vscript.host.guard — 宿主隔离 / Host Confinement — 宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。 — [模块 1 · API 6] - pyvdisk.vscript.host.module — 宿主模块 / Host Module — host 原生模块:面向脚本的读取、写入与传输入口,全部经隔离代理。 — [模块 1 · API 1] - pyvdisk.vscript.mounts — 挂载注册表 / Mount Registry — 挂载授权:把 CLI 挂载参数转为能力受限句柄并在运行后关闭的注册表。 — [模块 1 · API 6] - pyvdisk.vscript.policy — 策略与预算 / Policy and Budget — VScript 策略与预算:调用深度、循环、IO 与 Host 传输限额,以及脚本可 require 的受保护能力集。 — [模块 3 · API 8] diff --git a/normify-pyvdisk/receipt.json b/normify-pyvdisk/receipt.json index 3565b69..226d9dc 100644 --- a/normify-pyvdisk/receipt.json +++ b/normify-pyvdisk/receipt.json @@ -2,42 +2,42 @@ "schema_version": 1, "ok": true, "project": "normify-pyvdisk", - "compiled_at": "2026-09-24T10:00:54.895Z", + "compiled_at": "2026-09-24T11:41:32.599Z", "stats": { "tree_count": 1, - "module_count": 272, - "leaf_count": 234, - "api_count": 794, - "dep_count": 124, + "module_count": 290, + "leaf_count": 249, + "api_count": 844, + "dep_count": 132, "cross_tree_dep_count": 0, "max_depth": 4, - "layout_count": 38, + "layout_count": 41, "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 2, + "change_count": 3, "open_change_count": 0 }, "warnings": { - "structure/leaf-too-coarse": 8, + "structure/leaf-too-coarse": 14, "evidence/root-no-source": 1 }, "artifacts": { "tree.json": { - "sha256": "fb225f910a9b0e719bce6c335894b2d862c2ad5486e69d017386d0ca6097f652", - "bytes": 769047 + "sha256": "256245e0597d59c43c0a955872b6a0d6f15767ae61e4dcddd1cc425ecff188e7", + "bytes": 831708 }, "outline.md": { - "sha256": "5ecaef82a4f7845a95d87bf091940dd26c8b16047cd895eb7cad938eab24f563", - "bytes": 53255 + "sha256": "75f0105c41d73e9d3b850cf4c79d7cdd61280d8d2c888d8026f16bd2fb6863b3", + "bytes": 58989 }, "api-index.json": { - "sha256": "76fee31bddcdfbc507fe4fa8f18afdb17a0c4cc89fd726af819787d425764399", - "bytes": 59869 + "sha256": "42ba9839a1e2c949f0f2a42b5b0b790b18d8982ce140d4f6767307e055df69f2", + "bytes": 62999 }, "receipt.json": { - "sha256": "af9ade353d66cf2f2beb77c851f48681d1d8beecb2d4a742d4096d7b12d803f0", - "bytes": 963 + "sha256": "888823e1226a2a6a7c4f74c594f4bb934c9c8b1766b865c73d45c22480fccc87", + "bytes": 964 } } } diff --git a/normify-pyvdisk/renders/pyvdisk.json b/normify-pyvdisk/renders/pyvdisk.json index dd924d6..bc400e7 100644 --- a/normify-pyvdisk/renders/pyvdisk.json +++ b/normify-pyvdisk/renders/pyvdisk.json @@ -1,12 +1,12 @@ { "schema_version": 1, "id": "pyvdisk", - "updated_at": "2026-09-23T07:23:36.674Z", + "updated_at": "2026-09-24T11:39:34.471Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;api/compat 是导出面;tests/docs/delivery 是保障与交付。", - "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; api/compat are the exported surface; tests/docs/delivery provide assurance." + "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;接着是对外一组——Agent 工作区与沙箱、导出面、以及沉底的平台适配层;examples/tests/docs/delivery 是示例、保障与交付。", + "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; then the outward-facing group -- the agent workspace and its sandbox, the exported API, and the platform layer everything sits on; examples/docs/tests/delivery provide assurance and delivery." }, "order": [ "pyvdisk.storage", @@ -15,8 +15,11 @@ "pyvdisk.vscript", "pyvdisk.cli", "pyvdisk.contracts", + "pyvdisk.agent", "pyvdisk.api", "pyvdisk.compat", + "pyvdisk.platform", + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" @@ -49,21 +52,24 @@ { "id": "surface", "title": { - "zh": "对外接口", - "en": "Public Surface" + "zh": "对外接口与 Agent 入口", + "en": "Public Surface and Agent Entry" }, "children": [ + "pyvdisk.agent", "pyvdisk.api", - "pyvdisk.compat" + "pyvdisk.compat", + "pyvdisk.platform" ] }, { "id": "meta", "title": { - "zh": "文档、测试与交付", - "en": "Docs, Tests and Delivery" + "zh": "示例、文档、测试与交付", + "en": "Examples, Docs, Tests and Delivery" }, "children": [ + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" diff --git a/normify-pyvdisk/renders/pyvdisk/agent.json b/normify-pyvdisk/renders/pyvdisk/agent.json new file mode 100644 index 0000000..bccdd4c --- /dev/null +++ b/normify-pyvdisk/renders/pyvdisk/agent.json @@ -0,0 +1,42 @@ +{ + "schema_version": 1, + "id": "pyvdisk.agent", + "updated_at": "2026-09-24T11:33:31.064Z", + "mode": "groups", + "reading": { + "zh": "从左到右:路径能指向什么,有哪些工具,把两者合起来的门面,最后是调用在哪里执行、留下什么记录。", + "en": "Left to right: what a path may name, what tools exist, the facade that ties them together, then where a call runs and what it leaves behind." + }, + "order": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox", + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ], + "groups": [ + { + "id": "surface", + "title": { + "zh": "模型看到的面", + "en": "What the model sees" + }, + "children": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox" + ] + }, + { + "id": "execution", + "title": { + "zh": "执行与留痕", + "en": "Execution and evidence" + }, + "children": [ + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ] + } + ] +} diff --git a/normify-pyvdisk/renders/pyvdisk/examples.json b/normify-pyvdisk/renders/pyvdisk/examples.json new file mode 100644 index 0000000..4c4eb71 --- /dev/null +++ b/normify-pyvdisk/renders/pyvdisk/examples.json @@ -0,0 +1,14 @@ +{ + "schema_version": 1, + "id": "pyvdisk.examples", + "updated_at": "2026-09-24T11:34:32.619Z", + "mode": "grid", + "reading": { + "zh": "两个入口:自底向上跑通整条栈的导览,以及演示框架如何对接的 agent loop。", + "en": "Two entries: the bottom-up tour of the whole stack, and the agent loop that shows how a framework talks to it." + }, + "order": [ + "pyvdisk.examples.quickstart", + "pyvdisk.examples.agent-tools" + ] +} diff --git a/normify-pyvdisk/renders/pyvdisk/platform.json b/normify-pyvdisk/renders/pyvdisk/platform.json new file mode 100644 index 0000000..080ac60 --- /dev/null +++ b/normify-pyvdisk/renders/pyvdisk/platform.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "id": "pyvdisk.platform", + "updated_at": "2026-09-24T11:34:38.929Z", + "mode": "grid", + "max_columns": 2, + "reading": { + "zh": "先看当前用的是哪套实现,再看其余模块都会经过的四类原语:定位读写、文件锁、持久化与身份。", + "en": "Which implementation is in force, then the four primitive groups every other module goes through: positioned IO, locking, and durability/identity." + }, + "order": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ], + "groups": [ + { + "id": "primitives", + "title": { + "zh": "四类原语", + "en": "Primitives" + }, + "children": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ] + } + ] +} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/vector.json b/normify-pyvdisk/renders/pyvdisk/storage/vector.json index 81e32c7..97a9ac9 100644 --- a/normify-pyvdisk/renders/pyvdisk/storage/vector.json +++ b/normify-pyvdisk/renders/pyvdisk/storage/vector.json @@ -1,15 +1,18 @@ { "schema_version": 1, "id": "pyvdisk.storage.vector", - "updated_at": "2026-09-23T07:24:02.752Z", + "updated_at": "2026-09-24T11:32:36.825Z", + "mode": "grid", + "max_columns": 3, "reading": { - "zh": "先挂载向量盘、管理集合,再写入与读取记录,最后在索引上做相似度检索。", - "en": "Mount the vector disk, manage collections, write and read records, then run similarity search over the built index." + "zh": "先看集合簿记与记录,再看索引后端,最后是消费它的检索。", + "en": "Collection bookkeeping and records first, then the index backend, then the search that consumes it." }, "order": [ "pyvdisk.storage.vector.open", "pyvdisk.storage.vector.collections", "pyvdisk.storage.vector.records", + "pyvdisk.storage.vector.flat-index", "pyvdisk.storage.vector.search" ] } diff --git a/normify-pyvdisk/renders/pyvdisk/tests.json b/normify-pyvdisk/renders/pyvdisk/tests.json index 7343c60..8ffb7b9 100644 --- a/normify-pyvdisk/renders/pyvdisk/tests.json +++ b/normify-pyvdisk/renders/pyvdisk/tests.json @@ -1,12 +1,12 @@ { "schema_version": 1, "id": "pyvdisk.tests", - "updated_at": "2026-09-24T09:56:06.550Z", + "updated_at": "2026-09-24T11:39:19.907Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "按所验证的子系统分组:夹具与文件系统持久性(新增 FUSE 桥)、事务/参与者补偿/崩溃矩阵、执行平面、队列与精确一次保证、VScript 语言及其审计轨迹/撤销/cron/触发器、治理与契约,最后是日志盘、CLI 与打包检查。", - "en": "Grouped by the subsystem each module validates: fixtures and filesystem durability (now including the FUSE bridge), transactions, participant compensation and crash matrices, the execution plane, queue and exactly-once guarantees, the VScript language with its audit trail, undo, cron and triggers, governance and contracts, and finally log-disk, CLI and packaging checks." + "zh": "按所验证的子系统分组:夹具、文件系统持久性与平台适配层、事务与崩溃、执行平面、队列与精确一次保证、VScript、治理与沙箱,最后是日志盘、CLI、打包与零依赖检查。", + "en": "Grouped by the subsystem each module validates: fixtures, filesystem durability and the platform layer, transactions and crashes, the execution plane, queue and exactly-once guarantees, VScript, governance and the sandbox, then log-disk, CLI, packaging and the zero-dependency check." }, "order": [ "pyvdisk.tests.fixtures", @@ -15,6 +15,7 @@ "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat", "pyvdisk.tests.tx-rollback", "pyvdisk.tests.tx-idempotency", "pyvdisk.tests.crash-matrix", @@ -41,10 +42,12 @@ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox", "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ], "groups": [ { @@ -59,7 +62,8 @@ "pyvdisk.tests.atomic-save", "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount" + "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat" ] }, { @@ -124,13 +128,14 @@ { "id": "gov", "title": { - "zh": "治理与契约", - "en": "Governance and Contracts" + "zh": "治理与沙箱", + "en": "Governance and Sandbox" }, "children": [ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts" + "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox" ] }, { @@ -143,7 +148,8 @@ "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ] } ] diff --git a/normify-pyvdisk/tree.json b/normify-pyvdisk/tree.json index fec1bb3..f8c6d8f 100644 --- a/normify-pyvdisk/tree.json +++ b/normify-pyvdisk/tree.json @@ -9,20 +9,20 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T10:00:54.895Z", + "compiled_at": "2026-09-24T11:41:32.599Z", "stats": { "tree_count": 1, - "module_count": 272, - "leaf_count": 234, - "api_count": 794, - "dep_count": 124, + "module_count": 290, + "leaf_count": 249, + "api_count": 844, + "dep_count": 132, "cross_tree_dep_count": 0, "max_depth": 4, - "layout_count": 38, + "layout_count": 41, "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 2, + "change_count": 3, "open_change_count": 0 } }, @@ -44,18 +44,429 @@ "en": "PyVDisk" }, "description": { - "zh": "单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。\n", - "en": "Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language.\n" + "zh": "单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。核心不依赖标准库之外的任何东西,Linux 与 Windows 同一套代码;AgentSandbox 让这个容器可以直接当成 Agent 工作区使用。\n", + "en": "Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language. The core depends on nothing outside the standard library and runs on Linux and Windows alike, and AgentSandbox makes the container directly usable as an agent workspace.\n" }, "source": [], "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", + "updated_at": "2026-09-24T13:45:00Z", "fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "repository": "https://github.com/HeDaas-Code/pyvdisk", "aggregate": { - "descendant_count": 271, + "descendant_count": 289, + "own_api_count": 0, + "inherited_api_count": 844, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent": { + "uid": "a0000335", + "id": "pyvdisk.agent", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "Agent 工作区", + "en": "Agent Workspace" + }, + "description": { + "zh": "把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 dispatch()。\n", + "en": "Wraps a DataDisk into a workspace an agent framework can be handed: tool schemas, call dispatch, path confinement and a hash-chained audit trail. The integration surface is two calls, tools() and dispatch().\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 198, + "end_line": 314 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 387, + "end_line": 474 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "aggregate": { + "descendant_count": 5, "own_api_count": 0, - "inherited_api_count": 794, + "inherited_api_count": 21, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.audit": { + "uid": "a000033a", + "id": "pyvdisk.agent.audit", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "工具调用审计", + "en": "Tool Call Audit" + }, + "description": { + "zh": "每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。\"模型是不是读了不该读的路径\"这个问题,事后可以从日志里回答。\n", + "en": "Every call -- including every refusal -- is written to the hash-chained stream agent-audit with its tool name, arguments, status, error type and capability summary. An agent that read a path it should not have is a question the log can answer after the fact.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 584, + "end_line": 665 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.audit", + "description": { + "zh": "审计行,由旧到新。过滤条件为 sink 自身支持的若干项,外加 tool——它按行里记录的工具名筛选。\n", + "en": "Audit rows, oldest first. Filters are the sink's own plus tool, which selects on the tool name recorded in the row.\n" + }, + "key": "rpc:sandbox:AgentSandbox.audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.verify_audit", + "description": { + "zh": "校验整条哈希链;在 sink 之外追加的行会把它断开。\n", + "en": "Check the hash chain end to end; a row appended outside the sink breaks it.\n" + }, + "key": "rpc:sandbox:AgentSandbox.verify_audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.retain_audit", + "description": { + "zh": "按流上的保留策略裁剪,同时保持哈希链仍可校验。\n", + "en": "Apply the stream's retention policy while keeping the chain verifiable.\n" + }, + "key": "rpc:sandbox:AgentSandbox.retain_audit" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.stats", + "description": { + "zh": "调用与失败计数、工具集与磁盘占用,可序列化为 JSON 进日志。\n", + "en": "Call and failure counters, the tool set and disk usage, JSON-serialisable for logs.\n" + }, + "key": "rpc:sandbox:AgentSandbox.stats" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 4, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.paths": { + "uid": "a0000337", + "id": "pyvdisk.agent.paths", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "路径约束", + "en": "Path Confinement" + }, + "description": { + "zh": "沙箱内\"路径意味着什么\"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见。\n", + "en": "The one definition of what a path means inside the sandbox: backslash input is normalised, Windows-looking paths stay inside the image, .. is refused rather than resolved, and the container's own bookkeeping is hidden from reads, writes and listings alike.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 60, + "end_line": 195 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 387, + "end_line": 420 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox._normalize", + "description": { + "zh": "把模型给的路径映射进沙箱命名空间:反斜杠归一化,C:\\Windows 变成 /C:/Windows。\n", + "en": "Map a model-supplied path into the sandbox namespace: backslashes are normalised and C:\\Windows becomes /C:/Windows.\n" + }, + "key": "rpc:sandbox:AgentSandbox._normalize" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox._visible", + "description": { + "zh": "先归一化,再拒绝容器自身的簿记路径。\n", + "en": "Normalise, then refuse the container's own bookkeeping paths.\n" + }, + "key": "rpc:sandbox:AgentSandbox._visible" + }, + { + "protocol": "rpc", + "path": "sandbox:_hidden", + "description": { + "zh": "路径是否属于 /.system、/.vectors、/.logs,或是根目录下的清单文件。\n", + "en": "Whether a path is under /.system, /.vectors or /.logs, or is one of the root-level manifests.\n" + }, + "key": "rpc:sandbox:_hidden" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.sandbox": { + "uid": "a0000336", + "id": "pyvdisk.agent.sandbox", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "沙箱门面", + "en": "Sandbox Facade" + }, + "description": { + "zh": "门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及 close/上下文管理器生命周期。read_only 由 capability 层强制,而不只是把工具藏起来,所以直接调用动词同样被拒。\n", + "en": "The facade itself: create/open, the Python verbs (write/read/list/make_directory/delete/exists), the script entry, and the close/context-manager lifecycle. read_only is enforced by the capability layer rather than by hiding tools, so a direct verb is refused too.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 316, + "end_line": 474 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.write", + "description": { + "zh": "写入文本或字节,沿途自动建父目录。拒绝容器内部目录,也拒绝任何会越出根目录的路径。\n", + "en": "Write text or bytes, creating parent directories on the way. Refuses hidden bookkeeping paths and anything that would escape the root.\n" + }, + "key": "rpc:sandbox:AgentSandbox.write" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.read", + "description": { + "zh": "读取原始字节;read_text() 返回解码后的字符串。\n", + "en": "Read raw bytes, then read_text() for a decoded string.\n" + }, + "key": "rpc:sandbox:AgentSandbox.read" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.list", + "description": { + "zh": "列出条目及其类型与大小。容器内部路径会被过滤,模型不会看到一个用不了的名字。\n", + "en": "List entries with type and size. Hidden container paths are filtered out, so the agent never sees a name it cannot use.\n" + }, + "key": "rpc:sandbox:AgentSandbox.list" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.make_directory", + "description": { + "zh": "创建目录,自动建父级。\n", + "en": "Make a directory, creating parents.\n" + }, + "key": "rpc:sandbox:AgentSandbox.make_directory" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.delete", + "description": { + "zh": "删除文件;recursive 为真时删整棵目录树。\n", + "en": "Delete a file, or a directory tree when recursive is set.\n" + }, + "key": "rpc:sandbox:AgentSandbox.delete" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.exists", + "description": { + "zh": "可见路径是否存在。内部路径一律返回 False。\n", + "en": "Whether a visible path exists. Hidden paths always answer False.\n" + }, + "key": "rpc:sandbox:AgentSandbox.exists" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.create", + "description": { + "zh": "新建或打开沙箱背后的镜像,可传 read_only、allow_delete、宿主根目录与审计上限等选项。\n", + "en": "Open or create the image behind the sandbox, with options such as read_only, allow_delete, host roots and audit limits.\n" + }, + "key": "rpc:sandbox:AgentSandbox.create" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.open", + "description": { + "zh": "重新打开已有镜像;工作区与审计记录都保留。\n", + "en": "Reopen an existing image; the workspace and the audit trail both survive.\n" + }, + "key": "rpc:sandbox:AgentSandbox.open" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 8, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.agent.script": { + "uid": "a0000339", + "id": "pyvdisk.agent.script", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "盘内脚本", + "en": "Sandboxed Scripts" + }, + "description": { + "zh": "盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glob 里滤掉,脚本入口不会变成规则更松的第二个入口。\n", + "en": "The in-disk VScript entry: a script runs with the sandbox mounted, host access denied by default, and its stdout returned to the model. The adapter in front of the mount filters container bookkeeping out of listdir, walk and glob as well, so the script door is not a second entrance with looser rules.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 72, + "end_line": 195 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 476, + "end_line": 510 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.run", + "description": { + "zh": "执行 VScript 程序,沙箱绑定为变量 sandbox。未配置宿主根目录时宿主访问一律被拒;墙钟时间、输出与写入字节数都有上限。\n", + "en": "Run a VScript program with the sandbox bound as the variable sandbox. Host access is refused unless roots were configured; wall time, output and written bytes are all capped.\n" + }, + "key": "rpc:sandbox:AgentSandbox.run" + }, + { + "protocol": "rpc", + "path": "sandbox:_SandboxFS", + "description": { + "zh": "脚本看到的文件系统。每个路径都走与 Python 动词相同的可见性规则,两个入口不可能出现不一致。\n", + "en": "The filesystem a script sees. Every path is translated through the same visibility rule the Python verbs use, so the two entrances cannot disagree.\n" + }, + "key": "rpc:sandbox:_SandboxFS" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 2, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.agent.tools": { + "uid": "a0000338", + "id": "pyvdisk.agent.tools", + "parent": "pyvdisk.agent", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "工具面", + "en": "Tool Surface" + }, + "description": { + "zh": "六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面向各框架约定的 schema 渲染,和在真正碰磁盘之前先校验参数的分发。\n", + "en": "The six built-in tools: write_file, read_file, list_files, make_directory, delete_file and run_script, plus the schema rendering for each framework convention and the dispatch that validates arguments before anything touches the disk.\n" + }, + "source": [ + { + "path": "pyvdisk/sandbox.py", + "line": 198, + "end_line": 314 + }, + { + "path": "pyvdisk/sandbox.py", + "line": 512, + "end_line": 583 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", + "apis": [ + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.tools", + "description": { + "zh": "交给模型的工具定义。openai 与 anthropic 共用 {name, description, parameters};mcp 把 schema 键换成 inputSchema。\n", + "en": "The tool definitions to hand the model. openai and anthropic share {name, description, parameters}; mcp renames the schema key to inputSchema.\n" + }, + "key": "rpc:sandbox:AgentSandbox.tools" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.dispatch", + "description": { + "zh": "执行工具并始终返回字符串——拒绝也是字符串,因此可以原样回灌消息列表。\n", + "en": "Run a named tool and always return a string -- a refusal is a string too, so it goes back into the message list unchanged.\n" + }, + "key": "rpc:sandbox:AgentSandbox.dispatch" + }, + { + "protocol": "rpc", + "path": "sandbox:AgentSandbox.call", + "description": { + "zh": "dispatch 的结构化形式:ok、content、tool、error,供需要分支判断的调用方使用。\n", + "en": "The structured form of dispatch: ok, content, tool and error, for callers that branch on the outcome.\n" + }, + "key": "rpc:sandbox:AgentSandbox.call" + }, + { + "protocol": "rpc", + "path": "sandbox:TOOLS", + "description": { + "zh": "六个内置的文件系统与脚本工具及其 JSON Schema 参数。\n", + "en": "The six built-in filesystem and script tools, with their JSON Schema parameters.\n" + }, + "key": "rpc:sandbox:TOOLS" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 4, + "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 } @@ -74,17 +485,17 @@ "en": "Public Facade" }, "description": { - "zh": "公开门面:调用方直接从 pyvdisk 包根导入的存储、执行与契约名称。\n", - "en": "Public facade: the storage, execution and contract names that callers import directly from the pyvdisk package root.\n" + "zh": "公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。\n", + "en": "Public facade: the storage, execution, agent and contract names that callers import directly from the pyvdisk package root.\n" }, "source": [ { "path": "pyvdisk/__init__.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:14:45.848Z", - "fingerprint": "1e6d5c306ceb1123c99b098fd82cda1a805d9c5f23aa12f22d64f3bd129a5da7", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "829b9ac86974d0b749ac032ca0809ff290509d8be9218da09a8823562bd84a3b", "apis": [ { "protocol": "rpc", @@ -157,13 +568,72 @@ "en": "Run handle returned by the execution plane.\n" }, "key": "rpc:pyvdisk.RunHandle" + }, + { + "protocol": "rpc", + "path": "pyvdisk.AgentSandbox", + "description": { + "zh": "Agent 工作区门面:Agent 框架只需要这一个导入。\n", + "en": "The agent workspace facade: the one import an agent framework needs.\n" + }, + "key": "rpc:pyvdisk.AgentSandbox" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat", + "description": { + "zh": "平台适配层;导出后调用方可以查询当前用的是哪套实现。\n", + "en": "The platform layer, exported so callers can ask which implementation is live.\n" + }, + "key": "rpc:pyvdisk.compat" + }, + { + "protocol": "rpc", + "path": "pyvdisk.FlatIndex", + "description": { + "zh": "无外部依赖的精确向量索引。\n", + "en": "The dependency-free exact vector index.\n" + }, + "key": "rpc:pyvdisk.FlatIndex" + } + ], + "deps": [ + { + "kind": "reference", + "to": "pyvdisk.agent.sandbox", + "from_api": "rpc:pyvdisk.AgentSandbox", + "label": { + "zh": "转出沙箱门面", + "en": "re-exports the sandbox" + }, + "cross_tree": false + }, + { + "kind": "reference", + "to": "pyvdisk.platform", + "from_api": "rpc:pyvdisk.compat", + "label": { + "zh": "转出平台适配层", + "en": "re-exports the platform layer" + }, + "cross_tree": false + }, + { + "kind": "reference", + "to": "pyvdisk.storage.vector.flat-index", + "from_api": "rpc:pyvdisk.FlatIndex", + "label": { + "zh": "转出扁平索引", + "en": "re-exports the flat index" + }, + "cross_tree": false } ], "aggregate": { "descendant_count": 0, - "own_api_count": 8, + "own_api_count": 11, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 3, "dep_in": 0 } }, @@ -1887,13 +2357,13 @@ "path": ".github/workflows/pylint.yml" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.215Z", - "fingerprint": "7b8e690a61c134d576c6f09d81d7bc29a6ab4028d80f74d3320a15c7b43cf8bc", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ffb2fa1aa3e3cc015e3b71a246768d8b6ebbd7ef155a40d3000dafa42f532369", "aggregate": { "descendant_count": 3, "own_api_count": 0, - "inherited_api_count": 5, + "inherited_api_count": 6, "dep_out": 0, "dep_in": 0 } @@ -1909,17 +2379,17 @@ "en": "Test Workflow" }, "description": { - "zh": "CI 工作流:在 push 与 pull request 上安装 dev extras 并在 3.9–3.12 矩阵上运行 pytest,使声明的 requires-python 下限由最老的矩阵任务强制,而不是靠假设。\n", - "en": "CI workflow: installs the dev extras and runs the pytest suite on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed.\n" + "zh": "CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 requires-python 下限由最老的矩阵任务强制而不是靠假设。另有独立任务只装基础包并断言加速器确实缺席,零依赖的承诺因此不是自说自话。\n", + "en": "CI workflow: installs the dev and vector extras and runs pytest on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed. A second job installs the package without extras and asserts the accelerators are absent, which keeps the zero-dependency claim honest.\n" }, "source": [ { "path": ".github/workflows/ci.yml" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.215Z", - "fingerprint": "b1583a09123f8c3ad3d2e52ae4bc88ff01e6db7a88c3336853b06482634e20eb", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "2bf7b99f2ff50585631ea75453ea75cc457a6fe7bece3d39c4fd4b40d5eadc13", "apis": [ { "protocol": "file", @@ -1929,11 +2399,20 @@ "en": "Main test workflow: install and run the pytest suite.\n" }, "key": "file:.github/workflows/ci.yml" + }, + { + "protocol": "file", + "path": ".github/workflows/ci.yml#no-dependencies", + "description": { + "zh": "零依赖任务:只装 [dev],断言 hnswlib、fusepy、numpy 都不可导入,然后跑整套用例。\n", + "en": "Zero-dependency job: installs [dev] only, asserts hnswlib, fusepy and numpy are absent, then runs the suite.\n" + }, + "key": "file:.github/workflows/ci.yml#no-dependencies" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 1, + "own_api_count": 2, "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 @@ -1991,8 +2470,8 @@ "en": "Packaging Metadata" }, "description": { - "zh": "分发元数据:以 hnswlib 为依赖、fuse 与 dev extras、py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。\n", - "en": "Distribution metadata: cffi-free dependency set with hnswlib, the fuse and dev extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md.\n" + "zh": "分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。\n", + "en": "Distribution metadata: no runtime dependencies at all, with hnswlib and fusepy moved to the vector and fuse extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md.\n" }, "source": [ { @@ -2004,9 +2483,9 @@ "line": 1 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.216Z", - "fingerprint": "eef1180eeb651e5a6edbef6a63bd38eb0f2e3244b7c927f12a61c503b23ac266", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "e83415f6936531ac1130878c36a08b49e1795946d20ecc3bf95a507560e0a608", "apis": [ { "protocol": "file", @@ -2078,9 +2557,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T10:00:52.069Z", - "fingerprint": "08fd9522bb3a8bd1bc169f548c3c3e441fb6cd89f089c8e4206604371248a807", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2186,8 +2665,8 @@ "en": "Changelog" }, "description": { - "zh": "变更日志:按 issue #1 的清单编号记录用户可见变更,并列出四条明确留待后续的项目。\n", - "en": "Changelog: user-visible changes keyed to the issue #1 inventory ids, plus the four deliberately deferred items.\n" + "zh": "用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留\"已知未完成\"一节,未完成项要看得见,而不是被静默遗忘。\n", + "en": "User-visible change log, versioned in step with pyproject.toml. Entries are grouped by theme (zero dependency and cross-platform first) and carry the residual-limits section, so unfixed items stay visible instead of being quietly forgotten.\n" }, "source": [ { @@ -2196,9 +2675,9 @@ "end_line": 47 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.211Z", - "fingerprint": "ea3f46a9c65b19826cd309658416f1fe840116fa730bfc745a4cf6b95f77858a", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9648b98246e1e081401981daab12fa29c679efa0b189fb23fcb8542b565e7536", "apis": [ { "protocol": "file", @@ -2270,17 +2749,17 @@ "en": "Project Overview" }, "description": { - "zh": "README 总览:项目定位、快速开始、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。\n", - "en": "README overview: positioning, quick start, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size.\n" + "zh": "README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。\n", + "en": "README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size.\n" }, "source": [ { "path": "README.md" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T10:00:52.068Z", - "fingerprint": "fd96eaab9b9f839e266b3f990012c5cc034178b7e0a534eb15be4c397a525f55", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef", "apis": [ { "protocol": "file", @@ -2302,48 +2781,167 @@ "zh": "指向架构文档", "en": "points to architecture doc" }, - "cross_tree": false + "cross_tree": false + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 1, + "dep_in": 0 + } + }, + "pyvdisk.docs.vscript-spec": { + "uid": "a0000107", + "id": "pyvdisk.docs.vscript-spec", + "parent": "pyvdisk.docs", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "VScript 规范", + "en": "VScript Spec" + }, + "description": { + "zh": "VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。\n", + "en": "VScript spec: syntax, standard library, interpreter pipeline, capability model, errors and CLI entry points.\n" + }, + "source": [ + { + "path": "docs/VSCRIPT_SPEC.md" + } + ], + "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", + "updated_at": "2026-09-23T07:00:00Z", + "fingerprint": "14929378e2e6fbfb2003b8c1377587db2d92ddae8d754330d724d782016f8dee", + "apis": [ + { + "protocol": "file", + "path": "docs/VSCRIPT_SPEC.md", + "description": { + "zh": "VScript 语言与安全规范。\n", + "en": "VScript language and safety specification.\n" + }, + "key": "file:docs/VSCRIPT_SPEC.md" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.examples": { + "uid": "a000033b", + "id": "pyvdisk.examples", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "可运行示例", + "en": "Runnable Examples" + }, + "description": { + "zh": "可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。\n", + "en": "Runnable examples that double as the fastest way to see the whole stack work. They are standard-library only and run from a checkout without installing anything, which is also how the zero-dependency claim is tested.\n" + }, + "source": [ + { + "path": "examples/quickstart.py" + }, + { + "path": "examples/agent_tools.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2", + "aggregate": { + "descendant_count": 2, + "own_api_count": 0, + "inherited_api_count": 2, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.examples.agent-tools": { + "uid": "a000033d", + "id": "pyvdisk.examples.agent-tools", + "parent": "pyvdisk.examples", + "tree": "pyvdisk", + "depth": 3, + "tags": [ + "agent", + "example" + ], + "name": { + "zh": "Agent 对接示例", + "en": "Agent Loop Demo" + }, + "description": { + "zh": "带脚本化\"模型\"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。\n", + "en": "A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result.\n" + }, + "source": [ + { + "path": "examples/agent_tools.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1", + "apis": [ + { + "protocol": "file", + "path": "examples/agent_tools.py:scripted_model", + "description": { + "zh": "聊天补全调用的替身:返回下一条预置的工具调用,\"模型\"不再调用工具时返回 None。\n", + "en": "A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop.\n" + }, + "key": "file:examples/agent_tools.py:scripted_model" } ], "aggregate": { "descendant_count": 0, "own_api_count": 1, "inherited_api_count": 0, - "dep_out": 1, + "dep_out": 0, "dep_in": 0 } }, - "pyvdisk.docs.vscript-spec": { - "uid": "a0000107", - "id": "pyvdisk.docs.vscript-spec", - "parent": "pyvdisk.docs", + "pyvdisk.examples.quickstart": { + "uid": "a000033c", + "id": "pyvdisk.examples.quickstart", + "parent": "pyvdisk.examples", "tree": "pyvdisk", "depth": 3, "name": { - "zh": "VScript 规范", - "en": "VScript Spec" + "zh": "快速上手", + "en": "Quickstart Tour" }, "description": { - "zh": "VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。\n", - "en": "VScript spec: syntax, standard library, interpreter pipeline, capability model, errors and CLI entry points.\n" + "zh": "单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏蔽 hnswlib 的子进程里跑它,这正是它能当好\"最初五分钟\"的原因。\n", + "en": "One file, standard library only, Windows and Linux. It walks from a raw block device up to AgentSandbox so the layering is visible in one run, and reports which index backend it got. Tests run it in a subprocess with hnswlib blocked, which is what keeps this usable as a first five minutes.\n" }, "source": [ { - "path": "docs/VSCRIPT_SPEC.md" + "path": "examples/quickstart.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "14929378e2e6fbfb2003b8c1377587db2d92ddae8d754330d724d782016f8dee", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "366abf85eb8b872da8170a251e0d9afc62647e6ff779753eeac8db7c8900e224", "apis": [ { "protocol": "file", - "path": "docs/VSCRIPT_SPEC.md", + "path": "examples/quickstart.py", "description": { - "zh": "VScript 语言与安全规范。\n", - "en": "VScript language and safety specification.\n" + "zh": "在一个进程里自底向上跑通整条栈:块设备、事务、向量检索、日志、VScript,最后是沙箱。\n", + "en": "Run the whole stack bottom-up in one process: block device, transactions, vector search, logs, VScript, then the sandbox.\n" }, - "key": "file:docs/VSCRIPT_SPEC.md" + "key": "file:examples/quickstart.py" } ], "aggregate": { @@ -4155,161 +4753,469 @@ "en": "Capability Gate" }, "description": { - "zh": "能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。\n", - "en": "The capability gate: path normalization, scope containment and the guarded delegation helper all scoped namespaces share.\n" + "zh": "能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。\n", + "en": "The capability gate: path normalization, scope containment and the guarded delegation helper all scoped namespaces share.\n" + }, + "source": [ + { + "path": "pyvdisk/infrastructure/capabilities.py", + "line": 7, + "end_line": 49 + } + ], + "revision": "c3881eee5dced2b180cd3b383e5d848026224154", + "updated_at": "2026-09-24T09:58:38.221Z", + "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities._path", + "description": { + "zh": "把能力范围归一到以 / 为根、以斜线为界的路径。\n", + "en": "Normalize a capability scope into a rooted, slash-bounded path.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities._path" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities._inside", + "description": { + "zh": "路径被包含在范围内时为真。\n", + "en": "True when a path is contained in a scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities._inside" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace", + "description": { + "zh": "基础适配器:在委托前把能力检查变为守卫条件。\n", + "en": "Base adapter that turns capability checks into guard clauses before delegating.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "description": { + "zh": "对照执行上下文范围检查单个权限。\n", + "en": "Check one permission against the execution context scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call", + "description": { + "zh": "受保护的委托调用,向下传递所需权限与范围。\n", + "en": "Guarded delegated call that propagates the required permission and scope.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call" + } + ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.contracts.capability", + "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", + "label": { + "zh": "检查授权", + "en": "checks grants" + }, + "cross_tree": false + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 5, + "inherited_api_count": 0, + "dep_out": 1, + "dep_in": 1 + } + }, + "pyvdisk.governance.scoped": { + "uid": "a0000811", + "id": "pyvdisk.governance.scoped", + "parent": "pyvdisk.governance", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "受限容器", + "en": "Scoped Container" + }, + "description": { + "zh": "检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。\n", + "en": "Checkpoint scoping plus the ScopedDataDisk object and factory that execution passes to untrusted code.\n" + }, + "source": [ + { + "path": "pyvdisk/infrastructure/capabilities.py", + "line": 130, + "end_line": 162 + } + ], + "revision": "c3881eee5dced2b180cd3b383e5d848026224154", + "updated_at": "2026-09-24T09:58:38.221Z", + "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace", + "description": { + "zh": "把每个键限制在能力集内的检查点适配器。\n", + "en": "Checkpoint adapter that scopes each key to the capability set.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk", + "description": { + "zh": "交给不可信调用方的单一对象:DataDisk 及其能力上下文。\n", + "en": "The single object handed to untrusted callers: a DataDisk plus its capability context.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__", + "description": { + "zh": "挂载底层容器并返回受限视图。\n", + "en": "Mount the underlying container and return the scoped view.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__", + "description": { + "zh": "上下文退出时关闭底层容器。\n", + "en": "Close the underlying container on context exit.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__" + }, + { + "protocol": "rpc", + "path": "pyvdisk.infrastructure.capabilities.scoped", + "description": { + "zh": "把一个 DataDisk 包装为单次执行上下文视图的便利工厂。\n", + "en": "Convenience factory that wraps a DataDisk for one execution context.\n" + }, + "key": "rpc:pyvdisk.infrastructure.capabilities.scoped" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 5, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 2 + } + }, + "pyvdisk.platform": { + "uid": "a000032f", + "id": "pyvdisk.platform", + "parent": "pyvdisk", + "tree": "pyvdisk", + "depth": 2, + "name": { + "zh": "平台适配层", + "en": "Platform Adaptation" + }, + "description": { + "zh": "唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份。\n", + "en": "The single place that touches operating-system primitives: positional IO, whole-file locking, directory fsync, process identity and symlink support. Every other module goes through it, so Windows differences are handled once instead of at each call site.\n" + }, + "source": [ + { + "path": "pyvdisk/compat.py" + }, + { + "path": "pyvdisk/disk.py" + }, + { + "path": "pyvdisk/infrastructure/checkpoint.py" + }, + { + "path": "pyvdisk/vscript/host.py" + }, + { + "path": "pyvdisk/fuse_mount.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f", + "aggregate": { + "descendant_count": 4, + "own_api_count": 0, + "inherited_api_count": 13, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.platform.dispatch": { + "uid": "a0000330", + "id": "pyvdisk.platform.dispatch", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "实现选择", + "en": "Implementation Dispatch" + }, + "description": { + "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。\n", + "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess.\n" + }, + "source": [ + { + "path": "pyvdisk/compat.py", + "line": 41, + "end_line": 100 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:54.220Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.compat.implementation", + "description": { + "zh": "当前生效的实现:posix 或 windows。\n", + "en": "The implementation in force: posix or windows.\n" + }, + "key": "rpc:pyvdisk.compat.implementation" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat.use_implementation", + "description": { + "zh": "临时强制指定实现;上下文管理器,退出时还原,供测试在 Linux 上执行 Windows 分支。\n", + "en": "Temporarily force an implementation; a context manager that restores the previous one, used by tests to execute the Windows branches on Linux.\n" + }, + "key": "rpc:pyvdisk.compat.use_implementation" + }, + { + "protocol": "rpc", + "path": "pyvdisk.compat.describe", + "description": { + "zh": "当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。\n", + "en": "Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks.\n" + }, + "key": "rpc:pyvdisk.compat.describe" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.platform.durability": { + "uid": "a0000333", + "id": "pyvdisk.platform.durability", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "持久化与身份", + "en": "Durability and Identity" + }, + "description": { + "zh": "其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。\n", + "en": "The remaining platform differences: flushing a directory after a rename, reporting process identity, probing symlink support, and selecting the implementation in force. Each returns a value the caller can branch on instead of raising, because none of them is fatal on its own.\n" }, "source": [ { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 7, - "end_line": 49 + "path": "pyvdisk/compat.py", + "line": 202, + "end_line": 283 + }, + { + "path": "pyvdisk/compat.py", + "line": 41, + "end_line": 100 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:47.981Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._path", + "path": "pyvdisk.compat.fsync_dir", "description": { - "zh": "把能力范围归一到以 / 为根、以斜线为界的路径。\n", - "en": "Normalize a capability scope into a rooted, slash-bounded path.\n" + "zh": "刷盘目录,让改名能抵住崩溃。真的执行了才返回 True;Windows 无法把目录当文件打开,所以返回 False 表示\"未执行\",而不是假装成功。\n", + "en": "Flush a directory so a rename survives a crash. Returns True when it actually ran; Windows cannot open a directory as a file, so it returns False to mean not performed rather than claiming success.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities._path" + "key": "rpc:pyvdisk.compat.fsync_dir" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._inside", + "path": "pyvdisk.compat.uid", "description": { - "zh": "路径被包含在范围内时为真。\n", - "en": "True when a path is contained in a scope.\n" + "zh": "进程 uid;平台没有该概念时返回 0。\n", + "en": "Effective uid, or 0 where the platform has no such notion.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities._inside" + "key": "rpc:pyvdisk.compat.uid" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace", + "path": "pyvdisk.compat.gid", "description": { - "zh": "基础适配器:在委托前把能力检查变为守卫条件。\n", - "en": "Base adapter that turns capability checks into guard clauses before delegating.\n" + "zh": "进程 gid;平台没有该概念时返回 0。\n", + "en": "Effective gid, or 0 where the platform has no such notion.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace" + "key": "rpc:pyvdisk.compat.gid" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", + "path": "pyvdisk.compat.uid_or", "description": { - "zh": "对照执行上下文范围检查单个权限。\n", - "en": "Check one permission against the execution context scope.\n" + "zh": "取 uid,无该概念时用传入的缺省值。用它而不是 `uid() or default`:uid 0 是 root,不是\"未设置\"。\n", + "en": "uid, or the given fallback. Prefer this over `uid() or default`: uid 0 is root, not unset.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check" + "key": "rpc:pyvdisk.compat.uid_or" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call", + "path": "pyvdisk.compat.gid_or", "description": { - "zh": "受保护的委托调用,向下传递所需权限与范围。\n", - "en": "Guarded delegated call that propagates the required permission and scope.\n" + "zh": "取 gid,无该概念时用传入的缺省值。\n", + "en": "gid, or the given fallback.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call" - } - ], - "deps": [ + "key": "rpc:pyvdisk.compat.gid_or" + }, { - "kind": "call", - "to": "pyvdisk.contracts.capability", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", - "label": { - "zh": "检查授权", - "en": "checks grants" + "protocol": "rpc", + "path": "pyvdisk.compat.can_symlink", + "description": { + "zh": "探测指定目录下能否创建符号链接(不抛异常)。Windows 需要开发者模式,调用方据此降级而不是直接失败。\n", + "en": "Probe whether a symlink can be created in the given directory without raising. Windows needs developer mode, so callers degrade instead of failing.\n" }, - "cross_tree": false + "key": "rpc:pyvdisk.compat.can_symlink" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 5, + "own_api_count": 6, "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 + "dep_out": 0, + "dep_in": 2 } }, - "pyvdisk.governance.scoped": { - "uid": "a0000811", - "id": "pyvdisk.governance.scoped", - "parent": "pyvdisk.governance", + "pyvdisk.platform.locking": { + "uid": "a0000332", + "id": "pyvdisk.platform.locking", + "parent": "pyvdisk.platform", "tree": "pyvdisk", "depth": 3, "name": { - "zh": "受限容器", - "en": "Scoped Container" + "zh": "跨进程文件锁", + "en": "Cross-Process Locking" }, "description": { - "zh": "检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。\n", - "en": "Checkpoint scoping plus the ScopedDataDisk object and factory that execution passes to untrusted code.\n" + "zh": "跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLCK 轮询:LK_LOCK 约十秒后会报错,而 flock 会一直等下去。\n", + "en": "Whole-file write serialisation across threads and processes: fcntl.flock on POSIX, an msvcrt byte range on Windows. The Windows path polls with LK_NBLCK on purpose: LK_LOCK errors out after about ten seconds where flock keeps waiting.\n" }, "source": [ { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 130, - "end_line": 162 + "path": "pyvdisk/compat.py", + "line": 128, + "end_line": 198 + }, + { + "path": "pyvdisk/compat.py", + "line": 55 + }, + { + "path": "pyvdisk/compat.py", + "line": 58 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:06.398Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace", + "path": "pyvdisk.compat.lock", "description": { - "zh": "把每个键限制在能力集内的检查点适配器。\n", - "en": "Checkpoint adapter that scopes each key to the capability set.\n" + "zh": "取得整文件锁。blocking=True 等待,timeout=N 秒后放弃并返回 False,blocking=False 只试一次。返回是否拿到锁。\n", + "en": "Take the whole-file lock. blocking=True waits, timeout=N seconds gives up and returns False, blocking=False tries once. Returns whether the lock is held.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace" + "key": "rpc:pyvdisk.compat.lock" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk", + "path": "pyvdisk.compat.unlock", "description": { - "zh": "交给不可信调用方的单一对象:DataDisk 及其能力上下文。\n", - "en": "The single object handed to untrusted callers: a DataDisk plus its capability context.\n" + "zh": "释放锁。句柄已关闭也能调用,因为卸载路径与出错路径都会走到它。\n", + "en": "Release the lock. Tolerates an already-closed handle, because unmount and error paths both call it.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk" - }, + "key": "rpc:pyvdisk.compat.unlock" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 2, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 2 + } + }, + "pyvdisk.platform.positional": { + "uid": "a0000331", + "id": "pyvdisk.platform.positional", + "parent": "pyvdisk.platform", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "定位读写", + "en": "Positioned IO" + }, + "description": { + "zh": "不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。\n", + "en": "Atomic positioned reads and writes that neither depend on nor disturb the file cursor. The emulation is not merely a convenience: without the lock, two threads sharing a handle would seek past each other and corrupt blocks.\n" + }, + "source": [ { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__", - "description": { - "zh": "挂载底层容器并返回受限视图。\n", - "en": "Mount the underlying container and return the scoped view.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__" - }, + "path": "pyvdisk/compat.py", + "line": 102, + "end_line": 127 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:00.670Z", + "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "apis": [ { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__", + "path": "pyvdisk.compat.pread", "description": { - "zh": "上下文退出时关闭底层容器。\n", - "en": "Close the underlying container on context exit.\n" + "zh": "从 offset 处读取至多 length 字节。POSIX 用 os.pread;模拟实现用进程级互斥锁包住 lseek+read,避免与其它线程的 seek 交错。\n", + "en": "Positioned read of up to length bytes. POSIX uses os.pread; the emulation holds a process-wide lock across lseek+read so the pair is not interleaved with another thread's seek.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__" + "key": "rpc:pyvdisk.compat.pread" }, { "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.scoped", + "path": "pyvdisk.compat.pwrite", "description": { - "zh": "把一个 DataDisk 包装为单次执行上下文视图的便利工厂。\n", - "en": "Convenience factory that wraps a DataDisk for one execution context.\n" + "zh": "向 offset 处写入。POSIX 用 os.pwrite;模拟实现用同一把锁串行化 seek+write。\n", + "en": "Positioned write. POSIX uses os.pwrite; the emulation serialises seek+write under the same lock.\n" }, - "key": "rpc:pyvdisk.infrastructure.capabilities.scoped" + "key": "rpc:pyvdisk.compat.pwrite" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 5, + "own_api_count": 2, "inherited_api_count": 0, "dep_out": 0, "dep_in": 2 @@ -4376,13 +5282,13 @@ "path": "pyvdisk/infrastructure/checkpoint.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.225Z", - "fingerprint": "3ed800d0914e362e6fa76cf02ccddaa8b41f54ffd8efabaebe018e25619b823f", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "80d794b29e5404773680587fc27ceeac047cd72e0ab8cc13715f9aaa02d75a68", "aggregate": { - "descendant_count": 107, + "descendant_count": 108, "own_api_count": 0, - "inherited_api_count": 377, + "inherited_api_count": 384, "dep_out": 0, "dep_in": 0 } @@ -4406,9 +5312,9 @@ "path": "pyvdisk/disk.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "aggregate": { "descendant_count": 3, "own_api_count": 0, @@ -4438,9 +5344,9 @@ "end_line": 188 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", @@ -4498,13 +5404,23 @@ "en": "positional read" }, "cross_tree": false + }, + { + "kind": "call", + "to": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", + "label": { + "zh": "定位写入", + "en": "positioned write" + }, + "cross_tree": false } ], "aggregate": { "descendant_count": 0, "own_api_count": 5, "inherited_api_count": 0, - "dep_out": 1, + "dep_out": 2, "dep_in": 3 } }, @@ -4519,8 +5435,8 @@ "en": "Image Lifecycle" }, "description": { - "zh": "VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。\n", - "en": "VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close.\n" + "zh": "VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而不是悄悄退化为空操作。\n", + "en": "VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close. The lock is taken from the platform layer, so write serialisation exists on both POSIX and Windows instead of silently degrading to a no-op.\n" }, "source": [ { @@ -4529,9 +5445,9 @@ "end_line": 141 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", @@ -4555,8 +5471,8 @@ "protocol": "rpc", "path": "pyvdisk.disk.VirtualDisk#open", "description": { - "zh": "打开镜像,写模式下获取 POSIX 写锁。\n", - "en": "Open the image with optional POSIX write lock acquisition.\n" + "zh": "打开镜像,写锁经由平台适配层获取:POSIX 用 flock,Windows 用 msvcrt 字节区间锁。抢锁失败会关掉句柄报错,而不是无声地无锁继续跑。\n", + "en": "Open the image, taking the write lock through the platform layer: flock on POSIX, an msvcrt byte range on Windows. A lock failure closes the handle and raises rather than silently continuing unlocked.\n" }, "key": "rpc:pyvdisk.disk.VirtualDisk#open" }, @@ -4579,11 +5495,23 @@ "key": "rpc:pyvdisk.disk.VirtualDisk#close" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.locking", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", + "label": { + "zh": "整文件写锁", + "en": "whole-file write lock" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 5, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 1, "dep_in": 2 } }, @@ -4598,8 +5526,8 @@ "en": "Positional IO" }, "description": { - "zh": "无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用。\n", - "en": "Unbuffered positional read/write primitives used by every block and byte access on the image.\n" + "zh": "无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。\n", + "en": "Unbuffered positional read/write primitives used by every block and byte access on the image, routed through the platform layer so the same code runs on Windows.\n" }, "source": [ { @@ -4608,16 +5536,16 @@ "end_line": 57 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3dafc0720e696593d7bf2d99ff7d99856081e9e0c20a734b75f83098f1cfb80", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:41:14.329Z", + "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", "apis": [ { "protocol": "rpc", "path": "pyvdisk.disk._pread_all", "description": { - "zh": "定位读取,除 EOF 外保证读满。\n", - "en": "Positional read that fills the buffer unless EOF is hit.\n" + "zh": "定位读取,除 EOF 外保证读满。转发给 compat.pread,因此 Windows 上得到的是加锁的 seek+read,而不是 os.pread。\n", + "en": "Positional read that fills the buffer unless EOF is hit. Delegates to compat.pread, so Windows gets a lock-protected seek+read instead of os.pread.\n" }, "key": "rpc:pyvdisk.disk._pread_all" }, @@ -4625,18 +5553,42 @@ "protocol": "rpc", "path": "pyvdisk.disk._pwrite_all", "description": { - "zh": "定位写入,保证写满全部字节。\n", - "en": "Positional write that guarantees every byte is written.\n" + "zh": "定位写入,保证写满全部字节。转发给 compat.pwrite,在 Windows 上用同一把锁串行化 seek+write。\n", + "en": "Positional write that guarantees every byte is written. Delegates to compat.pwrite, which serialises seek+write on Windows.\n" }, "key": "rpc:pyvdisk.disk._pwrite_all" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.positional", + "from_api": "rpc:pyvdisk.disk._pread_all", + "to_api": "rpc:pyvdisk.compat.pread", + "label": { + "zh": "定位读取", + "en": "positioned read" + }, + "cross_tree": false + }, + { + "kind": "call", + "to": "pyvdisk.platform.positional", + "from_api": "rpc:pyvdisk.disk._pwrite_all", + "to_api": "rpc:pyvdisk.compat.pwrite", + "label": { + "zh": "定位写入", + "en": "positioned write" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 2, "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 + "dep_out": 2, + "dep_in": 2 } }, "pyvdisk.storage.checkpoint": { @@ -4658,9 +5610,9 @@ "path": "pyvdisk/infrastructure/checkpoint.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "aggregate": { "descendant_count": 3, "own_api_count": 0, @@ -4690,9 +5642,9 @@ "end_line": 145 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -4750,8 +5702,8 @@ "en": "Checkpoint Store" }, "description": { - "zh": "检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。\n", - "en": "Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle.\n" + "zh": "检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在锁来自平台适配层。\n", + "en": "Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle. This module used to import fcntl at the top level, which made the whole package unimportable on Windows; the lock now comes from the platform layer.\n" }, "source": [ { @@ -4760,9 +5712,9 @@ "end_line": 98 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.308Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:40:40.830Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -4813,12 +5765,11 @@ "deps": [ { "kind": "call", - "to": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", + "to": "pyvdisk.platform.locking", + "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", "label": { - "zh": "经 VFS 读写", - "en": "reads via VFS" + "zh": "跨进程锁", + "en": "cross-process lock" }, "cross_tree": false } @@ -4852,9 +5803,9 @@ "end_line": 152 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d96b0e630513ab3bea2172e2d6d091b3f50f62680b86ce05380946d8ce3e3424", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", "apis": [ { "protocol": "rpc", @@ -7789,9 +8740,9 @@ "path": "pyvdisk/fuse_mount.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.231Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "aggregate": { "descendant_count": 4, "own_api_count": 0, @@ -7821,9 +8772,9 @@ "end_line": 121 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -7931,9 +8882,9 @@ "end_line": 233 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -8018,8 +8969,8 @@ "en": "FUSE Attributes" }, "description": { - "zh": "FUSE 可用性检测,以及操作表中属性与目录列举部分。\n", - "en": "FUSE availability check and the attribute/listing half of the operation table.\n" + "zh": "stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与\"平台没有 uid\"无法区分。\n", + "en": "Stat-to-fuse mapping and the entry object: type, mode, size, timestamps and ownership. Identity comes from the platform layer, which also fixes a real bug: uid 0 (root) was previously indistinguishable from \"no uid available\".\n" }, "source": [ { @@ -8028,9 +8979,9 @@ "end_line": 80 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.232Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T11:37:33.368Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -8072,12 +9023,11 @@ "deps": [ { "kind": "call", - "to": "pyvdisk.storage.vfs.stat", + "to": "pyvdisk.platform.durability", "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "to_api": "rpc:pyvdisk.vfs.VFS#stat", "label": { - "zh": "取 stat", - "en": "stats path" + "zh": "进程身份", + "en": "process identity" }, "cross_tree": false } @@ -8111,9 +9061,9 @@ "end_line": 283 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.233Z", - "fingerprint": "b4475de0aa022f77959dd296d825fe99caca40036a8a86be29dcd1e6d6c0cf47", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", "apis": [ { "protocol": "rpc", @@ -9559,13 +10509,13 @@ "path": "pyvdisk/vector_disk.py" } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "aggregate": { - "descendant_count": 4, + "descendant_count": 5, "own_api_count": 0, - "inherited_api_count": 16, + "inherited_api_count": 23, "dep_out": 0, "dep_in": 0 } @@ -9591,44 +10541,155 @@ "end_line": 163 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", + "apis": [ + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#create_collection", + "description": { + "zh": "以固定维度与度量创建具名集合。\n", + "en": "Create a named collection with a fixed dimension and metric.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection" + }, + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#list_collections", + "description": { + "zh": "列出集合名称及其配置。\n", + "en": "List the collection names with their configuration.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#list_collections" + }, + { + "protocol": "rpc", + "path": "pyvdisk.vector_disk.VectorDisk#drop_collection", + "description": { + "zh": "删除集合及其索引文件。\n", + "en": "Drop a collection and its index files.\n" + }, + "key": "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 3, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 1 + } + }, + "pyvdisk.storage.vector.flat-index": { + "uid": "a0000334", + "id": "pyvdisk.storage.vector.flat-index", + "parent": "pyvdisk.storage.vector", + "tree": "pyvdisk", + "depth": 4, + "tags": [ + "zero-dependency", + "vector" + ], + "name": { + "zh": "扁平索引后端", + "en": "Flat Index Backend" + }, + "description": { + "zh": "纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集合,不是大规模下 HNSW 的替代品。\n", + "en": "A pure-Python exact index that mirrors hnswlib's calling shape, so VectorDisk can fall back to it without branching. Query is O(n) and the vectors stay in memory: correct for small and medium collections, not a replacement for HNSW at scale.\n" + }, + "source": [ + { + "path": "pyvdisk/vector_index.py", + "line": 38, + "end_line": 47 + }, + { + "path": "pyvdisk/vector_index.py", + "line": 51, + "end_line": 83 + }, + { + "path": "pyvdisk/vector_index.py", + "line": 169, + "end_line": 251 + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "c2a8e20da7599125065676cf6a3cea638d1a8108df234b9873b098dbfffb547d", "apis": [ { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#create_collection", + "path": "vector_index:distance", "description": { - "zh": "以固定维度与度量创建具名集合。\n", - "en": "Create a named collection with a fixed dimension and metric.\n" + "zh": "按 hnswlib 的约定计算距离,两种后端在调用点可直接互换:cosine = 1 - 相似度,l2 = 平方欧氏距离,ip = 1 - 点积。\n", + "en": "Distance in the convention hnswlib uses, so the two backends are interchangeable at the call site: cosine = 1 - similarity, l2 = squared euclidean, ip = 1 - dot product.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection" + "key": "rpc:vector_index:distance" }, { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#list_collections", + "path": "vector_index:read_kind", "description": { - "zh": "列出集合名称及其配置。\n", - "en": "List the collection names with their configuration.\n" + "zh": "从索引文件读出写入方标识:是 hnswlib 写的还是 flat 后端写的,不需要解析其余内容。\n", + "en": "Read the writer's tag from an index file: whether it was written by hnswlib or by the flat backend, without parsing the rest.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#list_collections" + "key": "rpc:vector_index:read_kind" }, { "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#drop_collection", + "path": "vector_index:serialize", "description": { - "zh": "删除集合及其索引文件。\n", - "en": "Drop a collection and its index files.\n" + "zh": "序列化为 flat 格式:8 字节魔数、空间与维度,然后是标签与 float32 向量。\n", + "en": "Serialise to the flat format: an 8-byte magic, the space and dimension, then labels and float32 vectors.\n" }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection" + "key": "rpc:vector_index:serialize" + }, + { + "protocol": "rpc", + "path": "vector_index:deserialize", + "description": { + "zh": "解析 flat 索引;内容被截断或根本不是该格式时报错,而不是当成正确数据读下去。\n", + "en": "Parse a flat index, rejecting a truncated or foreign payload instead of misreading it.\n" + }, + "key": "rpc:vector_index:deserialize" + }, + { + "protocol": "rpc", + "path": "vector_index:serialize_from_backend", + "description": { + "zh": "序列化任一后端的索引:flat 索引直接写自己,hnswlib 索引走它自己的 save_index 落到临时文件,需要负责清理。\n", + "en": "Serialise an index of either backend: a flat index writes itself, an hnswlib index goes through its own save_index into a temporary file that must be unlinked.\n" + }, + "key": "rpc:vector_index:serialize_from_backend" + }, + { + "protocol": "rpc", + "path": "vector_index:FlatIndex.add_item", + "description": { + "zh": "写入一条带标签的向量。维度与索引不一致时报错,维度尚未确定的空索引也拒绝写入。\n", + "en": "Add a labelled vector. Rejects a vector whose dimension disagrees with the index, and refuses a fresh index whose dimension was never set.\n" + }, + "key": "rpc:vector_index:FlatIndex.add_item" + }, + { + "protocol": "rpc", + "path": "vector_index:FlatIndex.knn_query", + "description": { + "zh": "精确 k 近邻搜索。距离相同时按标签排序,保证多次运行结果稳定;可选断言用于筛选候选记录。\n", + "en": "Exact k-nearest search. Ties break on the label so results are stable across runs, and an optional predicate filters the candidate records.\n" + }, + "key": "rpc:vector_index:FlatIndex.knn_query" } ], "aggregate": { "descendant_count": 0, - "own_api_count": 3, + "own_api_count": 7, "inherited_api_count": 0, "dep_out": 0, - "dep_in": 1 + "dep_in": 2 } }, "pyvdisk.storage.vector.open": { @@ -9642,8 +10703,8 @@ "en": "Vector Disk Open" }, "description": { - "zh": "VectorDisk 生命周期,以及后续操作共用的 JSON 辅助与集合路径键化。\n", - "en": "VectorDisk lifecycle plus the JSON helpers and collection-path keying used by every later operation.\n" + "zh": "VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。\n", + "en": "VectorDisk construction and mounting. Nothing here requires hnswlib: a collection opens and answers with the built-in flat index, and the accelerator is picked up only if it happens to be installed.\n" }, "source": [ { @@ -9652,9 +10713,9 @@ "end_line": 127 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", @@ -9744,9 +10805,9 @@ "end_line": 221 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", @@ -9812,7 +10873,7 @@ "own_api_count": 5, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 3 + "dep_in": 2 } }, "pyvdisk.storage.vector.search": { @@ -9826,8 +10887,8 @@ "en": "Vector Search" }, "description": { - "zh": "HNSW 图上的索引管理与相似度检索,支持元数据过滤。\n", - "en": "Index management and similarity search over the HNSW graph with metadata filtering.\n" + "zh": "索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索引。\n", + "en": "Index construction, loading and query. The backend is chosen at load time from the file's magic tag: hnswlib when installed, the built-in flat index otherwise. Published with a single rename, so a concurrent reader sees either the old index or the new one.\n" }, "source": [ { @@ -9836,16 +10897,16 @@ "end_line": 267 } ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "f3bc6b45a520369279ba039c4bf06fb0bfce7e84df609d7d20d81ad24a85dc35", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", "apis": [ { "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#_rebuild_index", "description": { - "zh": "从持久记录重建 HNSW 索引。\n", - "en": "Rebuild the HNSW index from the persisted records.\n" + "zh": "由记录重建索引,并以一次改名原子发布,读方不会看到写了一半的索引。\n", + "en": "Rebuild the index from the records and publish it with one rename, so a reader never sees a half-written index.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index" }, @@ -9853,8 +10914,8 @@ "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#_load_index", "description": { - "zh": "加载盘上索引,缺失时重建。\n", - "en": "Load the on-disk index or rebuild it when absent.\n" + "zh": "加载集合索引。由文件魔数决定路径:flat 直接解析,hnswlib 索引经 hnswlib 加载,缺 hnswlib 时回退为按记录重建的精确索引。\n", + "en": "Load the collection index. The file's magic decides how: flat parses directly, hnswlib loads through hnswlib, and a missing hnswlib falls back to an exact index over the records.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index" }, @@ -9862,21 +10923,20 @@ "protocol": "rpc", "path": "pyvdisk.vector_disk.VectorDisk#search", "description": { - "zh": "相似度检索:k 结果、可选元数据过滤,以及是否返回向量。\n", - "en": "Similarity search with k results, an optional metadata filter and include/exclude of vectors.\n" + "zh": "最近邻检索,可带元数据过滤。\n", + "en": "Nearest-neighbour search with an optional metadata filter.\n" }, "key": "rpc:pyvdisk.vector_disk.VectorDisk#search" } ], "deps": [ { - "kind": "dataflow", - "to": "pyvdisk.storage.vector.records", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#get", + "kind": "call", + "to": "pyvdisk.storage.vector.flat-index", + "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", "label": { - "zh": "读取记录", - "en": "reads records" + "zh": "后端回退", + "en": "backend fallback" }, "cross_tree": false } @@ -10185,7 +11245,7 @@ "own_api_count": 3, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 4 + "dep_in": 3 } }, "pyvdisk.storage.vfs.hostio": { @@ -10836,7 +11896,7 @@ "own_api_count": 5, "inherited_api_count": 0, "dep_out": 1, - "dep_in": 1 + "dep_in": 0 } }, "pyvdisk.storage.vfs.vfile": { @@ -12064,8 +13124,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:391 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥与打包。\n", - "en": "Test suite: 391 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge and packaging.\n" + "zh": "测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -12079,12 +13139,53 @@ } ], "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.240Z", + "updated_at": "2026-09-24T13:45:00Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { - "descendant_count": 55, + "descendant_count": 58, "own_api_count": 0, - "inherited_api_count": 71, + "inherited_api_count": 74, + "dep_out": 0, + "dep_in": 0 + } + }, + "pyvdisk.tests.agent-sandbox": { + "uid": "a000033f", + "id": "pyvdisk.tests.agent-sandbox", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "沙箱测试", + "en": "Sandbox Tests" + }, + "description": { + "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及\"脚本入口与 Python 入口共用一个根\"这条规则。\n", + "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root.\n" + }, + "source": [ + { + "path": "tests/test_agent_sandbox.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290", + "apis": [ + { + "protocol": "file", + "path": "tests/test_agent_sandbox.py", + "description": { + "zh": "沙箱的承诺:路径约束、只读、审计链与脚本隔离。\n", + "en": "Sandbox promises: path confinement, read-only, audit chain and script isolation.\n" + }, + "key": "file:tests/test_agent_sandbox.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, "dep_out": 0, "dep_in": 0 } @@ -12414,6 +13515,47 @@ "dep_in": 0 } }, + "pyvdisk.tests.compat": { + "uid": "a000033e", + "id": "pyvdisk.tests.compat", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "平台兼容测试", + "en": "Platform Compat Tests" + }, + "description": { + "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。\n", + "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite.\n" + }, + "source": [ + { + "path": "tests/test_compat.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c", + "apis": [ + { + "protocol": "file", + "path": "tests/test_compat.py", + "description": { + "zh": "把平台切到模拟实现跑整条用例。\n", + "en": "Run the whole suite with the platform switched to the emulated implementation.\n" + }, + "key": "file:tests/test_compat.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, "pyvdisk.tests.contracts": { "uid": "a0000e0a", "id": "pyvdisk.tests.contracts", @@ -13046,6 +14188,47 @@ "dep_in": 0 } }, + "pyvdisk.tests.no-dependency": { + "uid": "a0000340", + "id": "pyvdisk.tests.no-dependency", + "parent": "pyvdisk.tests", + "tree": "pyvdisk", + "depth": 3, + "name": { + "zh": "零依赖测试", + "en": "Zero Dependency Tests" + }, + "description": { + "zh": "同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端结果一致且能互读对方写的盘;examples/quickstart.py 在屏蔽 hnswlib 的子进程里能跑完,示例不会悄悄地开始依赖它。\n", + "en": "Three layers of the same claim: pyproject declares no runtime dependencies and keeps the accelerators as extras; VectorDisk answers correctly with hnswlib blocked, and the two backends agree and read each other's files; and examples/quickstart.py runs to completion in a subprocess with hnswlib blocked, so the example cannot quietly start needing it.\n" + }, + "source": [ + { + "path": "tests/test_no_dependency_path.py" + } + ], + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:40:00Z", + "fingerprint": "aca58c61b9b691e1849bc2f3a598cbaa1fd1e5c7db7193c969d3adbeb0c37073", + "apis": [ + { + "protocol": "file", + "path": "tests/test_no_dependency_path.py", + "description": { + "zh": "零依赖承诺:从打包、后端与示例三个层面校验。\n", + "en": "The zero-dependency promise, checked at packaging, backend and example level.\n" + }, + "key": "file:tests/test_no_dependency_path.py" + } + ], + "aggregate": { + "descendant_count": 0, + "own_api_count": 1, + "inherited_api_count": 0, + "dep_out": 0, + "dep_in": 0 + } + }, "pyvdisk.tests.packaging": { "uid": "a0000e14", "id": "pyvdisk.tests.packaging", @@ -15063,9 +16246,9 @@ "line": 1 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.257Z", - "fingerprint": "c7844269be626ed5058001514ea274cee3b6c62a247f7b5afbeca90ed7c02b66", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "98f6c61340ebda42ddbd0fced95d0ae3c9f008ca45b2b60b7730cb2330c980a6", "aggregate": { "descendant_count": 41, "own_api_count": 0, @@ -16439,9 +17622,9 @@ "path": "pyvdisk/vscript/host.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "aggregate": { "descendant_count": 2, "own_api_count": 0, @@ -16461,8 +17644,8 @@ "en": "Host Confinement" }, "description": { - "zh": "宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。该策略现在有真实入口——CLI 注入声明的根目录——host.* 不再因根目录为空而不可用。\n", - "en": "Host confinement: declares which host directories a script may read and write and refuses everything else. The policy now has a real entry point -- the CLI injects the declared roots -- so host.* is reachable instead of failing with an empty root set.\n" + "zh": "宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。\n", + "en": "Host confinement: declares which host directories a script may read and write and refuses everything else. Writes end with a directory flush so the rename itself is durable; that flush goes through the platform layer, since Windows cannot open a directory as a file.\n" }, "source": [ { @@ -16471,9 +17654,9 @@ "end_line": 79 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "apis": [ { "protocol": "rpc", @@ -16530,11 +17713,23 @@ "key": "rpc:pyvdisk.vscript.host.HostProxy#write" } ], + "deps": [ + { + "kind": "call", + "to": "pyvdisk.platform.durability", + "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", + "label": { + "zh": "刷盘目录", + "en": "flush the directory" + }, + "cross_tree": false + } + ], "aggregate": { "descendant_count": 0, "own_api_count": 6, "inherited_api_count": 0, - "dep_out": 0, + "dep_out": 1, "dep_in": 2 } }, @@ -16559,9 +17754,9 @@ "end_line": 92 } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.261Z", - "fingerprint": "baf58ee2c4dbda56cd6c7afb131bba217cd12b97019cd89fbebb5a1a7edad7c2", + "revision": "2c9009ba74afb515d301cc96e1946087268479a2", + "updated_at": "2026-09-24T13:45:00Z", + "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", "apis": [ { "protocol": "rpc", @@ -18026,17 +19221,24 @@ }, "api_index": { "file:.github/workflows/ci.yml": "pyvdisk.delivery.ci", + "file:.github/workflows/ci.yml#no-dependencies": "pyvdisk.delivery.ci", "file:.github/workflows/pylint.yml": "pyvdisk.delivery.lint", "file:CHANGELOG.md": "pyvdisk.docs.changelog", "file:docs/API_GOVERNANCE.md": "pyvdisk.docs.api-governance", "file:docs/ARCHITECTURE.md": "pyvdisk.docs.architecture", "file:docs/CONTRACTS.md": "pyvdisk.docs.contracts", "file:docs/VSCRIPT_SPEC.md": "pyvdisk.docs.vscript-spec", + "file:examples/agent_tools.py:scripted_model": "pyvdisk.examples.agent-tools", + "file:examples/quickstart.py": "pyvdisk.examples.quickstart", "file:MANIFEST.in": "pyvdisk.delivery.packaging", "file:pyproject.toml": "pyvdisk.delivery.packaging", "file:pyvdisk/__main__.py": "pyvdisk.cli.entry", "file:pyvdisk/py.typed": "pyvdisk.delivery.packaging", "file:README.md": "pyvdisk.docs.readme", + "file:tests/test_agent_sandbox.py": "pyvdisk.tests.agent-sandbox", + "file:tests/test_compat.py": "pyvdisk.tests.compat", + "file:tests/test_no_dependency_path.py": "pyvdisk.tests.no-dependency", + "rpc:pyvdisk.AgentSandbox": "pyvdisk.api", "rpc:pyvdisk.CheckpointStore": "pyvdisk.api", "rpc:pyvdisk.cli._add_cred_args": "pyvdisk.cli.format", "rpc:pyvdisk.cli._human_size": "pyvdisk.cli.format", @@ -18096,6 +19298,20 @@ "rpc:pyvdisk.cli.cmd_vol_status": "pyvdisk.cli.volume", "rpc:pyvdisk.cli.cmd_write": "pyvdisk.cli.file-ops", "rpc:pyvdisk.cli.main": "pyvdisk.cli.main", + "rpc:pyvdisk.compat": "pyvdisk.api", + "rpc:pyvdisk.compat.can_symlink": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.describe": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.fsync_dir": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.gid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.implementation": "pyvdisk.platform.dispatch", + "rpc:pyvdisk.compat.lock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.pread": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.pwrite": "pyvdisk.platform.positional", + "rpc:pyvdisk.compat.uid": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.uid_or": "pyvdisk.platform.durability", + "rpc:pyvdisk.compat.unlock": "pyvdisk.platform.locking", + "rpc:pyvdisk.compat.use_implementation": "pyvdisk.platform.dispatch", "rpc:pyvdisk.contracts.BlockDevice": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#read_block": "pyvdisk.contracts.storage", "rpc:pyvdisk.contracts.BlockDevice#write_block": "pyvdisk.contracts.storage", @@ -18177,6 +19393,7 @@ "rpc:pyvdisk.execution.ExecutionService#submit": "pyvdisk.execution.service.submit", "rpc:pyvdisk.execution.ExecutionService#worker_count": "pyvdisk.execution.service.setup", "rpc:pyvdisk.ExecutionService": "pyvdisk.api", + "rpc:pyvdisk.FlatIndex": "pyvdisk.api", "rpc:pyvdisk.fs._ceil_div": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._decode_name": "pyvdisk.storage.fs.names", "rpc:pyvdisk.fs._disk_lock_key": "pyvdisk.storage.fs.locking", @@ -18748,6 +19965,27 @@ "rpc:pyvdisk.vscript.wal.encode_record": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.RECORD_KINDS": "pyvdisk.storage.wal.undo", "rpc:pyvdisk.vscript.wal.WriteAheadLog": "pyvdisk.storage.wal.undo", + "rpc:sandbox:_hidden": "pyvdisk.agent.paths", + "rpc:sandbox:_SandboxFS": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox._normalize": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox._visible": "pyvdisk.agent.paths", + "rpc:sandbox:AgentSandbox.audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.call": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.create": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.delete": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.dispatch": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.exists": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.list": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.make_directory": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.open": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.read": "pyvdisk.agent.sandbox", + "rpc:sandbox:AgentSandbox.retain_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.run": "pyvdisk.agent.script", + "rpc:sandbox:AgentSandbox.stats": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.tools": "pyvdisk.agent.tools", + "rpc:sandbox:AgentSandbox.verify_audit": "pyvdisk.agent.audit", + "rpc:sandbox:AgentSandbox.write": "pyvdisk.agent.sandbox", + "rpc:sandbox:TOOLS": "pyvdisk.agent.tools", "rpc:tests/conftest.py": "pyvdisk.tests.fixtures", "rpc:tests/test_agentic_cli.py": "pyvdisk.tests.agentic-cli", "rpc:tests/test_api_governance.py": "pyvdisk.tests.api-governance", @@ -18818,9 +20056,49 @@ "rpc:tests/test_vscript.py::VScriptTests": "pyvdisk.tests.vscript", "rpc:tests/test_wal_abort_recovery.py": "pyvdisk.tests.wal-recovery", "rpc:tests/test_wal_checkpoint_and_recovery.py": "pyvdisk.tests.wal-checkpoint", - "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation" + "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation", + "rpc:vector_index:deserialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:distance": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.add_item": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:FlatIndex.knn_query": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:read_kind": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize": "pyvdisk.storage.vector.flat-index", + "rpc:vector_index:serialize_from_backend": "pyvdisk.storage.vector.flat-index" }, "edges": [ + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.AgentSandbox", + "to": "pyvdisk.agent.sandbox", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出沙箱门面", + "en": "re-exports the sandbox" + } + }, + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.compat", + "to": "pyvdisk.platform", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出平台适配层", + "en": "re-exports the platform layer" + } + }, + { + "from": "pyvdisk.api", + "from_api": "rpc:pyvdisk.FlatIndex", + "to": "pyvdisk.storage.vector.flat-index", + "kind": "reference", + "cross_tree": false, + "label": { + "zh": "转出扁平索引", + "en": "re-exports the flat index" + } + }, { "from": "pyvdisk.cli.open", "from_api": "rpc:pyvdisk.cli._open_vfs", @@ -19024,16 +20302,61 @@ "en": "positional read" } }, + { + "from": "pyvdisk.storage.block.access", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", + "to": "pyvdisk.storage.block.io", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位写入", + "en": "positioned write" + } + }, + { + "from": "pyvdisk.storage.block.image", + "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", + "to": "pyvdisk.platform.locking", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "整文件写锁", + "en": "whole-file write lock" + } + }, + { + "from": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk._pread_all", + "to": "pyvdisk.platform.positional", + "to_api": "rpc:pyvdisk.compat.pread", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位读取", + "en": "positioned read" + } + }, + { + "from": "pyvdisk.storage.block.io", + "from_api": "rpc:pyvdisk.disk._pwrite_all", + "to": "pyvdisk.platform.positional", + "to_api": "rpc:pyvdisk.compat.pwrite", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "定位写入", + "en": "positioned write" + } + }, { "from": "pyvdisk.storage.checkpoint.open", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs", - "to": "pyvdisk.storage.vfs.files", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", + "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", + "to": "pyvdisk.platform.locking", "kind": "call", "cross_tree": false, "label": { - "zh": "经 VFS 读写", - "en": "reads via VFS" + "zh": "跨进程锁", + "en": "cross-process lock" } }, { @@ -19301,13 +20624,12 @@ { "from": "pyvdisk.storage.fuse.meta", "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "to": "pyvdisk.storage.vfs.stat", - "to_api": "rpc:pyvdisk.vfs.VFS#stat", + "to": "pyvdisk.platform.durability", "kind": "call", "cross_tree": false, "label": { - "zh": "取 stat", - "en": "stats path" + "zh": "进程身份", + "en": "process identity" } }, { @@ -19468,14 +20790,13 @@ }, { "from": "pyvdisk.storage.vector.search", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index", - "to": "pyvdisk.storage.vector.records", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#get", - "kind": "dataflow", + "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", + "to": "pyvdisk.storage.vector.flat-index", + "kind": "call", "cross_tree": false, "label": { - "zh": "读取记录", - "en": "reads records" + "zh": "后端回退", + "en": "backend fallback" } }, { @@ -20119,6 +21440,17 @@ "en": "carries source spans" } }, + { + "from": "pyvdisk.vscript.host.guard", + "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", + "to": "pyvdisk.platform.durability", + "kind": "call", + "cross_tree": false, + "label": { + "zh": "刷盘目录", + "en": "flush the directory" + } + }, { "from": "pyvdisk.vscript.host.module", "from_api": "rpc:pyvdisk.vscript.host.create_host_module", @@ -20278,12 +21610,12 @@ "pyvdisk": { "schema_version": 1, "id": "pyvdisk", - "updated_at": "2026-09-23T07:23:36.674Z", + "updated_at": "2026-09-24T11:39:34.471Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;api/compat 是导出面;tests/docs/delivery 是保障与交付。", - "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; api/compat are the exported surface; tests/docs/delivery provide assurance." + "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;接着是对外一组——Agent 工作区与沙箱、导出面、以及沉底的平台适配层;examples/tests/docs/delivery 是示例、保障与交付。", + "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; then the outward-facing group -- the agent workspace and its sandbox, the exported API, and the platform layer everything sits on; examples/docs/tests/delivery provide assurance and delivery." }, "order": [ "pyvdisk.storage", @@ -20292,8 +21624,11 @@ "pyvdisk.vscript", "pyvdisk.cli", "pyvdisk.contracts", + "pyvdisk.agent", "pyvdisk.api", "pyvdisk.compat", + "pyvdisk.platform", + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" @@ -20326,21 +21661,24 @@ { "id": "surface", "title": { - "zh": "对外接口", - "en": "Public Surface" + "zh": "对外接口与 Agent 入口", + "en": "Public Surface and Agent Entry" }, "children": [ + "pyvdisk.agent", "pyvdisk.api", - "pyvdisk.compat" + "pyvdisk.compat", + "pyvdisk.platform" ] }, { "id": "meta", "title": { - "zh": "文档、测试与交付", - "en": "Docs, Tests and Delivery" + "zh": "示例、文档、测试与交付", + "en": "Examples, Docs, Tests and Delivery" }, "children": [ + "pyvdisk.examples", "pyvdisk.tests", "pyvdisk.docs", "pyvdisk.delivery" @@ -20348,6 +21686,48 @@ } ] }, + "pyvdisk.agent": { + "schema_version": 1, + "id": "pyvdisk.agent", + "updated_at": "2026-09-24T11:33:31.064Z", + "mode": "groups", + "reading": { + "zh": "从左到右:路径能指向什么,有哪些工具,把两者合起来的门面,最后是调用在哪里执行、留下什么记录。", + "en": "Left to right: what a path may name, what tools exist, the facade that ties them together, then where a call runs and what it leaves behind." + }, + "order": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox", + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ], + "groups": [ + { + "id": "surface", + "title": { + "zh": "模型看到的面", + "en": "What the model sees" + }, + "children": [ + "pyvdisk.agent.paths", + "pyvdisk.agent.tools", + "pyvdisk.agent.sandbox" + ] + }, + { + "id": "execution", + "title": { + "zh": "执行与留痕", + "en": "Execution and evidence" + }, + "children": [ + "pyvdisk.agent.script", + "pyvdisk.agent.audit" + ] + } + ] + }, "pyvdisk.cli": { "schema_version": 1, "id": "pyvdisk.cli", @@ -20517,6 +21897,20 @@ "pyvdisk.docs.changelog" ] }, + "pyvdisk.examples": { + "schema_version": 1, + "id": "pyvdisk.examples", + "updated_at": "2026-09-24T11:34:32.619Z", + "mode": "grid", + "reading": { + "zh": "两个入口:自底向上跑通整条栈的导览,以及演示框架如何对接的 agent loop。", + "en": "Two entries: the bottom-up tour of the whole stack, and the agent loop that shows how a framework talks to it." + }, + "order": [ + "pyvdisk.examples.quickstart", + "pyvdisk.examples.agent-tools" + ] + }, "pyvdisk.execution": { "schema_version": 1, "id": "pyvdisk.execution", @@ -20633,6 +22027,38 @@ "pyvdisk.governance.scoped" ] }, + "pyvdisk.platform": { + "schema_version": 1, + "id": "pyvdisk.platform", + "updated_at": "2026-09-24T11:34:38.929Z", + "mode": "grid", + "max_columns": 2, + "reading": { + "zh": "先看当前用的是哪套实现,再看其余模块都会经过的四类原语:定位读写、文件锁、持久化与身份。", + "en": "Which implementation is in force, then the four primitive groups every other module goes through: positioned IO, locking, and durability/identity." + }, + "order": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ], + "groups": [ + { + "id": "primitives", + "title": { + "zh": "四类原语", + "en": "Primitives" + }, + "children": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform.positional", + "pyvdisk.platform.locking", + "pyvdisk.platform.durability" + ] + } + ] + }, "pyvdisk.storage": { "schema_version": 1, "id": "pyvdisk.storage", @@ -20996,15 +22422,18 @@ "pyvdisk.storage.vector": { "schema_version": 1, "id": "pyvdisk.storage.vector", - "updated_at": "2026-09-23T07:24:02.752Z", + "updated_at": "2026-09-24T11:32:36.825Z", + "mode": "grid", + "max_columns": 3, "reading": { - "zh": "先挂载向量盘、管理集合,再写入与读取记录,最后在索引上做相似度检索。", - "en": "Mount the vector disk, manage collections, write and read records, then run similarity search over the built index." + "zh": "先看集合簿记与记录,再看索引后端,最后是消费它的检索。", + "en": "Collection bookkeeping and records first, then the index backend, then the search that consumes it." }, "order": [ "pyvdisk.storage.vector.open", "pyvdisk.storage.vector.collections", "pyvdisk.storage.vector.records", + "pyvdisk.storage.vector.flat-index", "pyvdisk.storage.vector.search" ] }, @@ -21118,12 +22547,12 @@ "pyvdisk.tests": { "schema_version": 1, "id": "pyvdisk.tests", - "updated_at": "2026-09-24T09:56:06.550Z", + "updated_at": "2026-09-24T11:39:19.907Z", "mode": "groups", "max_columns": 4, "reading": { - "zh": "按所验证的子系统分组:夹具与文件系统持久性(新增 FUSE 桥)、事务/参与者补偿/崩溃矩阵、执行平面、队列与精确一次保证、VScript 语言及其审计轨迹/撤销/cron/触发器、治理与契约,最后是日志盘、CLI 与打包检查。", - "en": "Grouped by the subsystem each module validates: fixtures and filesystem durability (now including the FUSE bridge), transactions, participant compensation and crash matrices, the execution plane, queue and exactly-once guarantees, the VScript language with its audit trail, undo, cron and triggers, governance and contracts, and finally log-disk, CLI and packaging checks." + "zh": "按所验证的子系统分组:夹具、文件系统持久性与平台适配层、事务与崩溃、执行平面、队列与精确一次保证、VScript、治理与沙箱,最后是日志盘、CLI、打包与零依赖检查。", + "en": "Grouped by the subsystem each module validates: fixtures, filesystem durability and the platform layer, transactions and crashes, the execution plane, queue and exactly-once guarantees, VScript, governance and the sandbox, then log-disk, CLI, packaging and the zero-dependency check." }, "order": [ "pyvdisk.tests.fixtures", @@ -21132,6 +22561,7 @@ "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat", "pyvdisk.tests.tx-rollback", "pyvdisk.tests.tx-idempotency", "pyvdisk.tests.crash-matrix", @@ -21158,10 +22588,12 @@ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox", "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ], "groups": [ { @@ -21176,7 +22608,8 @@ "pyvdisk.tests.atomic-save", "pyvdisk.tests.submit-conflict", "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount" + "pyvdisk.tests.fuse-mount", + "pyvdisk.tests.compat" ] }, { @@ -21241,13 +22674,14 @@ { "id": "gov", "title": { - "zh": "治理与契约", - "en": "Governance and Contracts" + "zh": "治理与沙箱", + "en": "Governance and Sandbox" }, "children": [ "pyvdisk.tests.governance", "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts" + "pyvdisk.tests.contracts", + "pyvdisk.tests.agent-sandbox" ] }, { @@ -21260,7 +22694,8 @@ "pyvdisk.tests.logdisk-compact", "pyvdisk.tests.logdisk-retention", "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging" + "pyvdisk.tests.packaging", + "pyvdisk.tests.no-dependency" ] } ] @@ -21539,6 +22974,15 @@ "zh": "结构库同步 issue #1 的修复" }, "updated_at": "2026-09-24T09:59:19.981Z" + }, + { + "id": "2026-09-24-zero-dep-windows-agentsandbox", + "status": "verified", + "title": { + "en": "Zero dependency, Windows compat layer and AgentSandbox", + "zh": "零依赖 + Windows 兼容层 + AgentSandbox" + }, + "updated_at": "2026-09-24T11:41:32.089Z" } ] } From 954abf4b554588ba3005a25eeb706b24c37aa71d Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:47:59 +0800 Subject: [PATCH 06/15] =?UTF-8?q?fix(docs):=20=E4=BF=AE=E6=AD=A3=20README?= =?UTF-8?q?=20=E7=9A=84=20Agent=20=E5=AF=B9=E6=8E=A5=20Demo=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E5=85=B6=E7=9C=9F=E8=83=BD=E8=B7=91=E8=B5=B7=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上一版的 10 行 Demo 有三个会让直接复制的人卡住的缺陷: 1. 用了从未定义的 messages 与 json:示例不导入 json,消息列表凭空出现; 2. json.loads(call.function.arguments) 写成了取 call.arguments —— 参数在 call.function 上,照抄必抛 AttributeError; 3. messages += [reply.choices[0].message, ...] 只处理了 tool_calls[0], 模型一轮请求多个工具时会静默丢掉其余调用。 重写为逐条处理 tool_calls、各自用 call.id 回填 tool_call_id,并把 assistant 消息本身也追加进 messages(不追加的话模型看不到自己上一轮请求过什么)。 另外把三个易踩点直接写进正文,而不是只藏在可运行示例里。 examples/agent_tools.py 同步改成与 README 完全一致的循环形状(用 _Message/ _ToolCall 复刻客户端的返回结构),并新增一轮"两个工具同时请求"的用例, 让列表分支真的被执行到。首次运行时它确实暴露了一个真实缺陷:脚本入口挂载 的是原始盘,fs.listdir(sandbox, "/") 能看到 /.system、/.logs(Python 侧 list_files 看不到)。这在前一提交里已由 _SandboxFS 修复,此处同时是所有 工具面测试的回归点。 tests/test_agent_sandbox.py 增加两条守卫,防止 Demo 再次漂移:一条用 ast 解析 README 里的代码块,断言它语法正确、定义了用到的名字、且用的是真实的 API 形状;另一条按 Demo 的写法构造 call 对象,实际跑一遍内部两行。 --- README.md | 28 +++++++++++------ examples/agent_tools.py | 61 +++++++++++++++++++++++++++++-------- tests/test_agent_sandbox.py | 42 +++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index f244175..d67bc5c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![GitHub](https://img.shields.io/badge/GitHub-PyVDisk-181717?logo=github)](https://github.com/HeDaas-Code/pyvdisk) [![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) -[![Tests](https://img.shields.io/badge/Tests-444%20passed-2ea44f)](#验证) +[![Tests](https://img.shields.io/badge/Tests-446%20passed-2ea44f)](#验证) PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行基础设施项目:DataDisk 负责统一数据与执行基础设施,VScript 负责安全工作流语言、CLI、REPL 与运行时。 @@ -112,19 +112,29 @@ with DataDisk.create("agent.vdisk", 32 * 1024 * 1024) as disk: `AgentSandbox` 把 DataDisk 包成一个"给模型用的工作区":路径被限制在镜像内,工具调用全部落进哈希链审计流。 ```python +import json from pyvdisk import AgentSandbox -box = AgentSandbox.create("agent.vdisk") # 或 AgentSandbox.open(...) 续用已有镜像 +box = AgentSandbox.create("agent.vdisk") # 或 AgentSandbox.open(...) 续用已有镜像 client = OpenAI().chat.completions # 换成任意框架的客户端 +messages = [{"role": "user", "content": "把发现写进 /report.md"}] -while True: # 标准 agent loop +while True: reply = client.create(model="gpt-4o", messages=messages, tools=box.tools()) - call = reply.choices[0].message.tool_calls[0] # 模型要调用的工具 - result = box.dispatch(call.function.name, json.loads(call.function.arguments)) - messages += [reply.choices[0].message, {"role": "tool", "tool_call_id": call.id, "content": result}] + message = reply.choices[0].message + messages.append(message) # 不追加则模型看不到自己请求过什么 + if not message.tool_calls: + break # 模型不再调用工具,结束 + for call in message.tool_calls: # 一次可能请求多个工具 + result = box.dispatch(call.function.name, json.loads(call.function.arguments)) + messages.append({"role": "tool", "tool_call_id": call.id, "content": result}) ``` -`box.tools()` 支持 `openai` / `anthropic` / `mcp` 三种 schema;`box.dispatch()` 永远返回字符串(失败也是字符串),可以直接塞回消息列表。可运行版本见 [examples/agent_tools.py](examples/agent_tools.py)(内置脚本化"模型",无需 API key)。 +`box.tools()` 支持 `openai` / `anthropic` / `mcp` 三种 schema;`box.dispatch()` 永远返回字符串(失败也是字符串),可以直接塞回消息列表,**被拒绝的调用也一样**——模型看到的是"越权被拒"这条结果,而不是整个 agent loop 崩掉。 + +三个容易踩的点:`json.loads` 的是 `call.function.arguments`(不是 `call.arguments`);`tool_calls` 是列表,要逐个 `dispatch` 并用各自的 `call.id` 一一对应地回填 `tool_call_id`;每轮都要把 assistant 消息本身也追加进 `messages`。 + +可运行版本见 [examples/agent_tools.py](examples/agent_tools.py)(内置脚本化"模型",无需 API key 与网络,因此也能进 CI)。 ## VScript @@ -177,6 +187,6 @@ pyvdisk info image.vdisk .venv/bin/python -m pytest -q ``` -当前回归:444 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) +当前回归:446 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) -不装 hnswlib 时同一套用例为 440 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 +不装 hnswlib 时同一套用例为 442 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 diff --git a/examples/agent_tools.py b/examples/agent_tools.py index baa6e8d..a1e4f05 100644 --- a/examples/agent_tools.py +++ b/examples/agent_tools.py @@ -26,7 +26,8 @@ from pyvdisk import AgentSandbox # noqa: E402 - the path fix has to run first -#: What a model would have produced. Each entry is one assistant turn. +#: What a model would have produced. Each entry is one assistant turn; an entry +#: with several calls reproduces a model asking for more than one tool at once. SCRIPTED_TURNS = [ {"tool": "list_files", "arguments": {"path": "/"}}, {"tool": "write_file", "arguments": { @@ -41,14 +42,43 @@ )}}, {"tool": "read_file", "arguments": {"path": "/report.md"}}, {"tool": "read_file", "arguments": {"path": "/etc/passwd"}}, # refused - {"tool": "read_file", "arguments": {"path": "/from-script.txt"}}, + # Two tools in one turn: the loop must answer each with its own call id. + {"calls": [ + {"tool": "read_file", "arguments": {"path": "/from-script.txt"}}, + {"tool": "list_files", "arguments": {"path": "/", "recursive": True}}, + ]}, ] +class _Message: + """The assistant message shape the OpenAI client returns.""" + + def __init__(self, calls): + self.tool_calls = [_ToolCall(f"call_{index}", tool, arguments) + for index, (tool, arguments) in enumerate(calls)] + + +class _ToolCall: + def __init__(self, call_id, name, arguments): + self.id = call_id + self.function = type("Function", (), {"name": name, + "arguments": json.dumps(arguments, ensure_ascii=False)})() + + def scripted_model(messages): - """Stand-in for a chat completion call: returns the next tool call, or None.""" - asked = sum(1 for message in messages if message["role"] == "tool") - return SCRIPTED_TURNS[asked] if asked < len(SCRIPTED_TURNS) else None + """Stand-in for one chat completion: returns the next assistant message. + + Returns an empty-tool_calls message once the script runs out, which is how a + real model signals "I am done" -- the loop below treats it identically. + """ + # Assistant turns are objects, tool results are plain dicts; count the latter. + asked = sum(1 for message in messages + if isinstance(message, dict) and message.get("role") == "tool") + turn = SCRIPTED_TURNS[asked] if asked < len(SCRIPTED_TURNS) else None + if turn is None: + return _Message([]) + calls = [(tool["tool"], tool["arguments"]) for tool in turn.get("calls", [turn])] + return _Message(calls) def main(argv): @@ -60,14 +90,21 @@ def main(argv): print("json schema of one tool:", json.dumps(box.tools()[0], ensure_ascii=False)[:120], "...\n") messages = [{"role": "user", "content": "Summarise the workspace and write /report.md"}] - for turn in range(1, 12): - call = scripted_model(messages) - if call is None: + step = 0 + while step < 12: + # Identical to the README demo: ask, append the assistant message, run + # every call it asked for, feed each result back by its own call id. + message = scripted_model(messages) + messages.append(message) + if not message.tool_calls: break - result = box.dispatch(call["tool"], call["arguments"]) - messages.append({"role": "tool", "name": call["tool"], "content": result}) - print(f"[{turn}] {call['tool']}({json.dumps(call['arguments'], ensure_ascii=False)[:60]})") - print(" ->", result.replace("\n", "\n ")) + for call in message.tool_calls: + step += 1 + arguments = json.loads(call.function.arguments) + result = box.dispatch(call.function.name, arguments) + messages.append({"role": "tool", "tool_call_id": call.id, "content": result}) + print(f"[{step}] {call.function.name}({call.function.arguments[:60]})") + print(" ->", result.replace("\n", "\n ")) print("\nfinal /report.md:", repr(box.read_text("/report.md"))) report = box.verify_audit() diff --git a/tests/test_agent_sandbox.py b/tests/test_agent_sandbox.py index 47b367c..dd957cb 100644 --- a/tests/test_agent_sandbox.py +++ b/tests/test_agent_sandbox.py @@ -248,6 +248,48 @@ def test_stats_reports_the_tool_set_and_the_call_counts(box): json.dumps(stats) # must stay JSON-serialisable for logs and dashboards +def test_the_readme_demo_matches_the_real_api(): + """The ten-line README loop must stay executable against the real surface. + + It is the first thing an integrator copies, and it is easy to let drift: the + tool-call arguments live on ``call.function.arguments`` (not ``call.arguments``), + ``tool_calls`` is a list, and every result needs its own ``tool_call_id``. + """ + import ast + from pathlib import Path as _Path + + root = _Path(__file__).resolve().parents[1] + readme = (root / "README.md").read_text(encoding="utf-8") + assert "### 对接 Agent 框架(10 行)" in readme, "the Demo section was renamed or removed" + demo = readme.split("### 对接 Agent 框架(10 行)", 1)[1].split("```python", 1)[1].split("```", 1)[0] + tree = ast.parse(demo) # a syntax error here is a broken copy-paste + + assigned = {target.id for node in ast.walk(tree) if isinstance(node, ast.Assign) + for target in node.targets if isinstance(target, ast.Name)} + for name in ("box", "messages", "client"): + assert name in assigned, f"the demo never defines {name!r}, so it cannot run as pasted" + assert "json" in {alias.name for node in ast.walk(tree) if isinstance(node, ast.Import) + for alias in node.names}, "the demo calls json.loads without importing json" + assert "call.function.arguments" in demo and "call.function.name" in demo + assert "tool_calls" in demo and "tool_call_id" in demo + + +def test_a_tool_call_shaped_like_the_readme_demo_dispatches(tmp_path): + """Run the demo's inner two lines against a real call object.""" + import json as _json + + with AgentSandbox.create(str(tmp_path / "demo.vdisk"), size_bytes=8 << 20) as box: + box.write("/a.txt", "hello") + function = type("Function", (), {"name": "read_file", + "arguments": _json.dumps({"path": "/a.txt"})})() + call = type("Call", (), {"id": "call_1", "function": function})() + result = box.dispatch(call.function.name, _json.loads(call.function.arguments)) + assert result == "hello" + messages = [{"role": "tool", "tool_call_id": call.id, "content": result}] + assert messages[0]["tool_call_id"] == "call_1" + assert box.tools(), "box.tools() is what the demo passes as the tools= argument" + + def test_a_sandbox_closes_its_disk(box): box.close() assert box.disk.mounted is False From 590356c625921dbfff51393ebe38217b80dcf14f Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:48:49 +0800 Subject: [PATCH 07/15] =?UTF-8?q?docs(normify):=20=E5=90=8C=E6=AD=A5=20REA?= =?UTF-8?q?DME=20Agent=20Demo=20=E4=BF=AE=E6=AD=A3=E4=B8=8E=E9=98=B2?= =?UTF-8?q?=E6=BC=82=E7=A7=BB=E5=AE=88=E5=8D=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更 2026-09-24-readme-agent-demo-fix(verified,revision.after = f163400): docs.readme/docs 更新指纹;examples.agent-tools 更新脚本化模型说明(含一轮 多工具调用);tests.agent-sandbox 补上 README 示例守卫的说明;tests 计数 对齐 446。290 模块 / 844 API / 132 箭头,0 error。 --- .../2026-09-24-readme-agent-demo-fix.json | 37 +++++++++++ normify-pyvdisk/modules/pyvdisk/docs/index.md | 6 +- .../modules/pyvdisk/docs/readme.md | 8 ++- .../modules/pyvdisk/examples/agent-tools.md | 18 +++-- .../modules/pyvdisk/examples/index.md | 8 ++- .../modules/pyvdisk/tests/agent-sandbox.md | 14 ++-- .../modules/pyvdisk/tests/index.md | 6 +- normify-pyvdisk/normify.html | 65 +++++++++++-------- normify-pyvdisk/outline.md | 4 +- normify-pyvdisk/receipt.json | 14 ++-- normify-pyvdisk/tree.json | 61 +++++++++-------- 11 files changed, 154 insertions(+), 87 deletions(-) create mode 100644 normify-pyvdisk/changes/2026-09-24-readme-agent-demo-fix.json diff --git a/normify-pyvdisk/changes/2026-09-24-readme-agent-demo-fix.json b/normify-pyvdisk/changes/2026-09-24-readme-agent-demo-fix.json new file mode 100644 index 0000000..265eda4 --- /dev/null +++ b/normify-pyvdisk/changes/2026-09-24-readme-agent-demo-fix.json @@ -0,0 +1,37 @@ +{ + "schema_version": 1, + "id": "2026-09-24-readme-agent-demo-fix", + "title": { + "en": "Fix the README agent demo", + "zh": "修正 README 的 Agent 对接 Demo" + }, + "status": "verified", + "intent": { + "en": "The ten-line README agent demo had three defects that break a copy-paste (undefined names, wrong tool-call attribute, only the first of several tool calls handled). Sync the structure DB after correcting it and adding guards.", + "zh": "README 的 10 行 Agent 对接 Demo 有三处会让直接复制的人卡住的缺陷(名字未定义、工具调用属性取错、一轮多调用只处理第一个)。修正并补上守卫后同步结构库。" + }, + "modules": { + "create": [], + "modify": [ + "pyvdisk.docs.readme", + "pyvdisk.docs", + "pyvdisk.examples.agent-tools", + "pyvdisk.examples", + "pyvdisk.tests.agent-sandbox" + ] + }, + "acceptance": [ + "README 的 Agent 对接 Demo 与 examples/agent_tools.py 的循环形状一致且可直接运行", + "新增守卫测试(ast 解析 README 代码块 + 按 Demo 形状真实 dispatch)已覆盖该承诺", + "受影响模块(docs.readme / examples / tests.agent-sandbox / tests / docs)指纹与介绍与代码一致", + "normify_validate 0 error" + ], + "note": "修正 README Agent Demo 并新增防漂移守卫;docs.readme / docs / examples.agent-tools / tests.agent-sandbox / tests 已同步指纹与介绍。", + "revision": { + "before": null, + "after": "f163400c098f68cbdfb0393a9bf488037d012aaf" + }, + "created_at": "2026-09-24T11:48:12.396Z", + "updated_at": "2026-09-24T11:48:42.331Z", + "closed_at": "2026-09-24T11:48:42.331Z" +} diff --git a/normify-pyvdisk/modules/pyvdisk/docs/index.md b/normify-pyvdisk/modules/pyvdisk/docs/index.md index 3967998..08f2c09 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/index.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/index.md @@ -11,9 +11,9 @@ description: en: > Repository documentation layer: architecture, contracts, API governance and the VScript spec; the primary evidence source for this module tree. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:45:00Z" -fingerprint: 7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7 +revision: f163400c098f68cbdfb0393a9bf488037d012aaf +updated_at: "2026-09-24T11:48:38.686Z" +fingerprint: eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644 source: - path: "README.md" - path: "docs/ARCHITECTURE.md" diff --git a/normify-pyvdisk/modules/pyvdisk/docs/readme.md b/normify-pyvdisk/modules/pyvdisk/docs/readme.md index eac261d..2c93479 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/readme.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/readme.md @@ -6,11 +6,13 @@ name: {zh: "项目总览", en: "Project Overview"} description: zh: > README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。 + en: > README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:45:00Z" -fingerprint: ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef + +revision: f163400c098f68cbdfb0393a9bf488037d012aaf +updated_at: "2026-09-24T11:48:38.684Z" +fingerprint: 21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40 source: - path: "README.md" apis: diff --git a/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md b/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md index cf5ac51..c859a43 100644 --- a/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md +++ b/normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md @@ -6,12 +6,14 @@ tags: [agent, example] name: {zh: "Agent 对接示例", en: "Agent Loop Demo"} description: zh: > - 带脚本化"模型"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。 + 带脚本化"模型"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,以及一轮同时请求两个工具,覆盖拒绝路径与多调用列表路径。 + en: > - A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:40:00Z" -fingerprint: 021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1 + A complete agent loop with a scripted model, shaped exactly like the README demo, so it needs no API key and no network and can run in CI. It includes a refused out-of-root read and a turn that requests two tools at once, covering both the refusal path and the multi-call list path. + +revision: f163400c098f68cbdfb0393a9bf488037d012aaf +updated_at: "2026-09-24T11:48:38.686Z" +fingerprint: 38e6efd2ed3bfcec7954b1a00d09cc90b41ca8906175dcbb023a72fefed9f9b7 source: - path: "examples/agent_tools.py" apis: @@ -19,7 +21,9 @@ apis: path: "examples/agent_tools.py:scripted_model" description: zh: > - 聊天补全调用的替身:返回下一条预置的工具调用,"模型"不再调用工具时返回 None。 + 单次聊天补全调用的替身:返回供循环消费的 assistant 消息;脚本跑完后返回 tool_calls 为空的消息。 + en: > - A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop. + A stand-in for one chat completion call: returns an assistant message whose tool_calls the loop consumes, and an empty tool_calls list when the script runs out. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/examples/index.md b/normify-pyvdisk/modules/pyvdisk/examples/index.md index 2ea5d4d..cfbc89b 100644 --- a/normify-pyvdisk/modules/pyvdisk/examples/index.md +++ b/normify-pyvdisk/modules/pyvdisk/examples/index.md @@ -6,11 +6,13 @@ name: {zh: "可运行示例", en: "Runnable Examples"} description: zh: > 可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。 + en: > Runnable examples that double as the fastest way to see the whole stack work. They are standard-library only and run from a checkout without installing anything, which is also how the zero-dependency claim is tested. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:40:00Z" -fingerprint: 4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2 + +revision: f163400c098f68cbdfb0393a9bf488037d012aaf +updated_at: "2026-09-24T11:48:38.687Z" +fingerprint: d256d8803ce7868b443ddd6cfc00d16a7e42f11938c3056dca32f34eef8b11c9 source: - path: "examples/quickstart.py" - path: "examples/agent_tools.py" diff --git a/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md b/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md index c9f0931..74074b0 100644 --- a/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md +++ b/normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md @@ -5,12 +5,14 @@ parent: pyvdisk.tests name: {zh: "沙箱测试", en: "Sandbox Tests"} description: zh: > - 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及"脚本入口与 Python 入口共用一个根"这条规则。 + 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限、"脚本入口与 Python 入口共用一个根"这条规则,以及防止 README 示例漂移、确保它仍能按真实 API 执行的守卫。 + en: > - Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:40:00Z" -fingerprint: edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290 + Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, the rule that the script door and the Python door share one root, and guards that keep the README demo executing against the real API. + +revision: f163400c098f68cbdfb0393a9bf488037d012aaf +updated_at: "2026-09-24T11:48:38.687Z" +fingerprint: e44e25577e09fe09eef14d1d56de5975ad490fb995cfce45029bb93e2768012e source: - path: "tests/test_agent_sandbox.py" apis: @@ -19,6 +21,8 @@ apis: description: zh: > 沙箱的承诺:路径约束、只读、审计链与脚本隔离。 + en: > Sandbox promises: path confinement, read-only, audit chain and script isolation. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/index.md b/normify-pyvdisk/modules/pyvdisk/tests/index.md index 0c819b1..2491d62 100644 --- a/normify-pyvdisk/modules/pyvdisk/tests/index.md +++ b/normify-pyvdisk/modules/pyvdisk/tests/index.md @@ -6,11 +6,11 @@ tags: [tests] name: {zh: "测试套件", en: "Test Suite"} description: zh: > - 测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。 + 测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。 en: > - Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent. + Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent. revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T13:45:00Z" +updated_at: "2026-09-24T14:10:00Z" fingerprint: b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1 source: - path: "tests/conftest.py" diff --git a/normify-pyvdisk/normify.html b/normify-pyvdisk/normify.html index 1c28684..bec5445 100644 --- a/normify-pyvdisk/normify.html +++ b/normify-pyvdisk/normify.html @@ -164,7 +164,7 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T11:41:32.016Z", + "compiled_at": "2026-09-24T11:48:42.253Z", "stats": { "tree_count": 1, "module_count": 290, @@ -177,7 +177,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 3, + "change_count": 4, "open_change_count": 1 } }, @@ -2712,9 +2712,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.686Z", + "fingerprint": "eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2912,9 +2912,9 @@ "path": "README.md" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.684Z", + "fingerprint": "21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40", "apis": [ { "protocol": "file", @@ -3010,9 +3010,9 @@ "path": "examples/agent_tools.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.687Z", + "fingerprint": "d256d8803ce7868b443ddd6cfc00d16a7e42f11938c3056dca32f34eef8b11c9", "aggregate": { "descendant_count": 2, "own_api_count": 0, @@ -3036,24 +3036,24 @@ "en": "Agent Loop Demo" }, "description": { - "zh": "带脚本化\"模型\"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。\n", - "en": "A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result.\n" + "zh": "带脚本化\"模型\"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,以及一轮同时请求两个工具,覆盖拒绝路径与多调用列表路径。\n", + "en": "A complete agent loop with a scripted model, shaped exactly like the README demo, so it needs no API key and no network and can run in CI. It includes a refused out-of-root read and a turn that requests two tools at once, covering both the refusal path and the multi-call list path.\n" }, "source": [ { "path": "examples/agent_tools.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.686Z", + "fingerprint": "38e6efd2ed3bfcec7954b1a00d09cc90b41ca8906175dcbb023a72fefed9f9b7", "apis": [ { "protocol": "file", "path": "examples/agent_tools.py:scripted_model", "description": { - "zh": "聊天补全调用的替身:返回下一条预置的工具调用,\"模型\"不再调用工具时返回 None。\n", - "en": "A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop.\n" + "zh": "单次聊天补全调用的替身:返回供循环消费的 assistant 消息;脚本跑完后返回 tool_calls 为空的消息。\n", + "en": "A stand-in for one chat completion call: returns an assistant message whose tool_calls the loop consumes, and an empty tool_calls list when the script runs out.\n" }, "key": "file:examples/agent_tools.py:scripted_model" } @@ -13279,8 +13279,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", - "en": "Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" + "zh": "测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -13294,7 +13294,7 @@ } ], "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T13:45:00Z", + "updated_at": "2026-09-24T14:10:00Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { "descendant_count": 58, @@ -13315,17 +13315,17 @@ "en": "Sandbox Tests" }, "description": { - "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及\"脚本入口与 Python 入口共用一个根\"这条规则。\n", - "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root.\n" + "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限、\"脚本入口与 Python 入口共用一个根\"这条规则,以及防止 README 示例漂移、确保它仍能按真实 API 执行的守卫。\n", + "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, the rule that the script door and the Python door share one root, and guards that keep the README demo executing against the real API.\n" }, "source": [ { "path": "tests/test_agent_sandbox.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.687Z", + "fingerprint": "e44e25577e09fe09eef14d1d56de5975ad490fb995cfce45029bb93e2768012e", "apis": [ { "protocol": "file", @@ -23112,6 +23112,15 @@ ] }, "changes": [ + { + "id": "2026-09-24-readme-agent-demo-fix", + "status": "in_progress", + "title": { + "en": "Fix the README agent demo", + "zh": "修正 README 的 Agent 对接 Demo" + }, + "updated_at": "2026-09-24T11:48:12.396Z" + }, { "id": "2026-09-24-readme-counts", "status": "verified", @@ -23132,12 +23141,12 @@ }, { "id": "2026-09-24-zero-dep-windows-agentsandbox", - "status": "proposed", + "status": "verified", "title": { "en": "Zero dependency, Windows compat layer and AgentSandbox", "zh": "零依赖 + Windows 兼容层 + AgentSandbox" }, - "updated_at": "2026-09-24T11:30:26.105Z" + "updated_at": "2026-09-24T11:41:32.089Z" } ] } diff --git a/normify-pyvdisk/outline.md b/normify-pyvdisk/outline.md index 6bae71d..94b13e6 100644 --- a/normify-pyvdisk/outline.md +++ b/normify-pyvdisk/outline.md @@ -50,7 +50,7 @@ - pyvdisk.docs.readme — 项目总览 / Project Overview — README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一… — [模块 1 · API 1] - pyvdisk.docs.vscript-spec — VScript 规范 / VScript Spec — VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。 — [模块 1 · API 1] - pyvdisk.examples — 可运行示例 / Runnable Examples — 可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。 — [模块 3 · API 2] - - pyvdisk.examples.agent-tools — Agent 对接示例 / Agent Loop Demo — 带脚本化"模型"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_m… — [模块 1 · API 1] + - pyvdisk.examples.agent-tools — Agent 对接示例 / Agent Loop Demo — 带脚本化"模型"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,… — [模块 1 · API 1] - pyvdisk.examples.quickstart — 快速上手 / Quickstart Tour — 单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏… — [模块 1 · API 1] - pyvdisk.execution — 执行平面 / Execution Plane — 执行平面:同步 ExecutionService、持久任务队列、持久化运行状态与操作注册表。 — [模块 22 · API 72] - pyvdisk.execution.operations — 操作注册表 / Operation Registry — 操作注册表:稳定 operation id、负载指纹、持久化结果、可调用对象解析与 VScript 操作描述。 — [模块 7 · API 24] @@ -193,7 +193,7 @@ - pyvdisk.storage.wal.entries — WAL 记录 / WAL Entries — 事务日志动词与崩溃恢复重放:begin/append/prepare/commit/abort,以及重放所依赖的读取入口。 — [模块 1 · API 8] - pyvdisk.storage.wal.journal — 元数据 WAL / Metadata WAL — DataDisk 事务使用的元数据预写日志:存储后端、行编解码,以及分配序号的追加写入。 — [模块 1 · API 4] - pyvdisk.storage.wal.undo — 宿主撤销 WAL / Host Undo WAL — VScript 侧的 WAL 入口:独立的宿主路径实现已取消——本模块直接复用同一套 WriteAheadLog,并给出撤销记录使用的 kind 集与编解码。 — [模块 1 · API 4] - - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] + - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] - pyvdisk.tests.agent-sandbox — 沙箱测试 / Sandbox Tests — 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的… — [模块 1 · API 1] - pyvdisk.tests.agentic-cli — 智能体 CLI 用例 / Agentic CLI Tests — 面向智能体使用编写的 CLI 用例:可发现的输出与稳定的退出码。 — [模块 1 · API 1] - pyvdisk.tests.api-governance — API 治理用例 / API Governance Tests — 检查公开能力 API 是否拒绝应当拒绝的调用,而不只验证正常路径。 — [模块 1 · API 1] diff --git a/normify-pyvdisk/receipt.json b/normify-pyvdisk/receipt.json index 226d9dc..0954dea 100644 --- a/normify-pyvdisk/receipt.json +++ b/normify-pyvdisk/receipt.json @@ -2,7 +2,7 @@ "schema_version": 1, "ok": true, "project": "normify-pyvdisk", - "compiled_at": "2026-09-24T11:41:32.599Z", + "compiled_at": "2026-09-24T11:48:42.836Z", "stats": { "tree_count": 1, "module_count": 290, @@ -15,7 +15,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 3, + "change_count": 4, "open_change_count": 0 }, "warnings": { @@ -24,19 +24,19 @@ }, "artifacts": { "tree.json": { - "sha256": "256245e0597d59c43c0a955872b6a0d6f15767ae61e4dcddd1cc425ecff188e7", - "bytes": 831708 + "sha256": "2ec85812c633a314f985ff843562e9feb5c1a9ba78e267d26b4115da786284e3", + "bytes": 832176 }, "outline.md": { - "sha256": "75f0105c41d73e9d3b850cf4c79d7cdd61280d8d2c888d8026f16bd2fb6863b3", - "bytes": 58989 + "sha256": "84959e68fcfce9320bdd3bae70d18973d87fa558d0a0bea716ef5d51a0e1d30e", + "bytes": 58995 }, "api-index.json": { "sha256": "42ba9839a1e2c949f0f2a42b5b0b790b18d8982ce140d4f6767307e055df69f2", "bytes": 62999 }, "receipt.json": { - "sha256": "888823e1226a2a6a7c4f74c594f4bb934c9c8b1766b865c73d45c22480fccc87", + "sha256": "6517e4cb20e1a6adde78aa6a5b9983240e72bad078a1a8914ff38c94acec7e44", "bytes": 964 } } diff --git a/normify-pyvdisk/tree.json b/normify-pyvdisk/tree.json index f8c6d8f..c50aea3 100644 --- a/normify-pyvdisk/tree.json +++ b/normify-pyvdisk/tree.json @@ -9,7 +9,7 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T11:41:32.599Z", + "compiled_at": "2026-09-24T11:48:42.836Z", "stats": { "tree_count": 1, "module_count": 290, @@ -22,7 +22,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 3, + "change_count": 4, "open_change_count": 0 } }, @@ -2557,9 +2557,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "7967b9cf3de163a9defdd8db9f1f6647edc58752751bf6ca540bbeb8155ad7d7", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.686Z", + "fingerprint": "eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2757,9 +2757,9 @@ "path": "README.md" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee385479b03b021e1a6204295602c53737107b4071bdf81038483f4865f230ef", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.684Z", + "fingerprint": "21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40", "apis": [ { "protocol": "file", @@ -2855,9 +2855,9 @@ "path": "examples/agent_tools.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "4ccb5dedebd50551824b10ba22dd7ff4632c7df7b194307e3779d79c0585e4f2", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.687Z", + "fingerprint": "d256d8803ce7868b443ddd6cfc00d16a7e42f11938c3056dca32f34eef8b11c9", "aggregate": { "descendant_count": 2, "own_api_count": 0, @@ -2881,24 +2881,24 @@ "en": "Agent Loop Demo" }, "description": { - "zh": "带脚本化\"模型\"的完整 agent loop,因此不需要 API key 与网络,可以进 CI。循环本身与对接真实客户端时完全一致,只替掉 scripted_model。示例里包含一次越权读取被拒,说明拒绝会像普通工具结果一样回灌。\n", - "en": "A complete agent loop with a scripted model, so it needs no API key and no network and can run in CI. The loop is the one you would write against a real client; only scripted_model is replaced. It includes a refused out-of-root read, showing a denial flows back like any other tool result.\n" + "zh": "带脚本化\"模型\"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,以及一轮同时请求两个工具,覆盖拒绝路径与多调用列表路径。\n", + "en": "A complete agent loop with a scripted model, shaped exactly like the README demo, so it needs no API key and no network and can run in CI. It includes a refused out-of-root read and a turn that requests two tools at once, covering both the refusal path and the multi-call list path.\n" }, "source": [ { "path": "examples/agent_tools.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "021820b569bcab563e878c2d7331874621e55ca5641bac090f379fbf54f5efc1", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.686Z", + "fingerprint": "38e6efd2ed3bfcec7954b1a00d09cc90b41ca8906175dcbb023a72fefed9f9b7", "apis": [ { "protocol": "file", "path": "examples/agent_tools.py:scripted_model", "description": { - "zh": "聊天补全调用的替身:返回下一条预置的工具调用,\"模型\"不再调用工具时返回 None。\n", - "en": "A stand-in for a chat completion call: returns the next scripted tool call, or None when the model would stop.\n" + "zh": "单次聊天补全调用的替身:返回供循环消费的 assistant 消息;脚本跑完后返回 tool_calls 为空的消息。\n", + "en": "A stand-in for one chat completion call: returns an assistant message whose tool_calls the loop consumes, and an empty tool_calls list when the script runs out.\n" }, "key": "file:examples/agent_tools.py:scripted_model" } @@ -13124,8 +13124,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:444 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", - "en": "Test suite: 444 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" + "zh": "测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -13139,7 +13139,7 @@ } ], "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T13:45:00Z", + "updated_at": "2026-09-24T14:10:00Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { "descendant_count": 58, @@ -13160,17 +13160,17 @@ "en": "Sandbox Tests" }, "description": { - "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限,以及\"脚本入口与 Python 入口共用一个根\"这条规则。\n", - "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, and the rule that the script door and the Python door share one root.\n" + "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限、\"脚本入口与 Python 入口共用一个根\"这条规则,以及防止 README 示例漂移、确保它仍能按真实 API 执行的守卫。\n", + "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, the rule that the script door and the Python door share one root, and guards that keep the README demo executing against the real API.\n" }, "source": [ { "path": "tests/test_agent_sandbox.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "edf41d7c5682215a34e651deccb8a108c248aad110293e0dd67c0e56a01c7290", + "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", + "updated_at": "2026-09-24T11:48:38.687Z", + "fingerprint": "e44e25577e09fe09eef14d1d56de5975ad490fb995cfce45029bb93e2768012e", "apis": [ { "protocol": "file", @@ -22957,6 +22957,15 @@ ] }, "changes": [ + { + "id": "2026-09-24-readme-agent-demo-fix", + "status": "verified", + "title": { + "en": "Fix the README agent demo", + "zh": "修正 README 的 Agent 对接 Demo" + }, + "updated_at": "2026-09-24T11:48:42.331Z" + }, { "id": "2026-09-24-readme-counts", "status": "verified", From 107b86e4a0d3946868c77112c2552f2ec032e2ac Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:50:42 +0800 Subject: [PATCH 08/15] =?UTF-8?q?fix(compat):=20describe()=20=E5=BF=85?= =?UTF-8?q?=E9=A1=BB=E6=8F=8F=E8=BF=B0=E7=94=9F=E6=95=88=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在干净的克隆里用系统 Python 复核 Windows 兼容层时发现:强制切到 windows 模拟后, describe() 仍然报告 locking=fcntl.flock、directory_fsync=True、uid_gid=True —— 它描述的是宿主平台,而不是当前生效的实现。拿它做诊断或测试断言的人会得到 恰好相反的结论,而这恰恰是本次改动的核心承诺("Windows 上真的有锁、真的不做 目录 fsync")。 改为按 implementation() 分支:模拟生效时报告 lseek+read/write、msvcrt.locking、 directory_fsync=False、uid_gid=False。 原测试漏掉了这一点,因为它只断言了原生实现的分支;补一条在 windows 模拟下 断言 describe() 全部字段的用例。 --- README.md | 6 +++--- pyvdisk/compat.py | 17 ++++++++++++----- tests/test_compat.py | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d67bc5c..88763a6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![GitHub](https://img.shields.io/badge/GitHub-PyVDisk-181717?logo=github)](https://github.com/HeDaas-Code/pyvdisk) [![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) -[![Tests](https://img.shields.io/badge/Tests-446%20passed-2ea44f)](#验证) +[![Tests](https://img.shields.io/badge/Tests-447%20passed-2ea44f)](#验证) PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行基础设施项目:DataDisk 负责统一数据与执行基础设施,VScript 负责安全工作流语言、CLI、REPL 与运行时。 @@ -187,6 +187,6 @@ pyvdisk info image.vdisk .venv/bin/python -m pytest -q ``` -当前回归:446 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) +当前回归:447 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) -不装 hnswlib 时同一套用例为 442 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 +不装 hnswlib 时同一套用例为 443 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 diff --git a/pyvdisk/compat.py b/pyvdisk/compat.py index ea85bbc..21e43d8 100644 --- a/pyvdisk/compat.py +++ b/pyvdisk/compat.py @@ -87,14 +87,21 @@ def use_implementation(name: str): def describe() -> dict: - """What this platform gives us, for diagnostics and test assertions.""" + """What the implementation in force actually does, for diagnostics. + + This reports the *live* implementation, not the host platform: when the + Windows emulation is forced on Linux, callers must see the emulated + primitives, otherwise ``describe()`` would confirm exactly the wrong thing. + """ + windows = implementation() == "windows" return { "platform": sys.platform, "implementation": implementation(), - "positional_io": "os.pread/os.pwrite" if _HAS_POSITIONAL else "lseek+read/write", - "locking": "fcntl.flock" if _fcntl is not None else ("msvcrt.locking" if _msvcrt is not None else "none"), - "directory_fsync": IS_POSIX, - "uid_gid": hasattr(os, "getuid") and hasattr(os, "getgid"), + "positional_io": ("lseek+read/write" if windows or not _HAS_POSITIONAL + else "os.pread/os.pwrite"), + "locking": ("msvcrt.locking" if windows else ("fcntl.flock" if _fcntl is not None else "none")), + "directory_fsync": IS_POSIX and not windows, + "uid_gid": hasattr(os, "getuid") and hasattr(os, "getgid") and not windows, "symlinks": hasattr(os, "symlink"), } diff --git a/tests/test_compat.py b/tests/test_compat.py index 64565f7..b1647e3 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -80,6 +80,20 @@ def test_describe_reports_the_live_implementation(): assert info["directory_fsync"] is True +def test_describe_follows_the_implementation_not_the_host(windows_emulation): + """A forced implementation must be described as itself. + + Reporting the host's primitives while the emulation is live would confirm + exactly the wrong thing to anyone using describe() for diagnostics. + """ + info = compat.describe() + assert info["implementation"] == "windows" + assert info["positional_io"] == "lseek+read/write" + assert info["locking"] == "msvcrt.locking" + assert info["directory_fsync"] is False, "Windows cannot fsync a directory" + assert info["uid_gid"] is False + + def test_uid_and_gid_are_integers(): assert isinstance(compat.uid(), int) assert isinstance(compat.gid(), int) From d137e5a0bc1141fdc305e6c17fc9675c19bec318 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Thu, 24 Sep 2026 19:51:50 +0800 Subject: [PATCH 09/15] =?UTF-8?q?docs(normify):=20=E5=90=8C=E6=AD=A5=20des?= =?UTF-8?q?cribe()=20=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更 2026-09-24-compat-describe-live-impl(verified,revision.after = 3cb4787): platform 四个模块(dispatch/positional/locking/durability)与 tests.compat、 docs.readme 的指纹已刷新;platform.dispatch 的介绍明确 describe() 描述的是 生效实现而非宿主平台。290 模块 / 844 API / 132 箭头,0 error。 --- .../2026-09-24-compat-describe-live-impl.json | 38 +++++++++ normify-pyvdisk/modules/pyvdisk/docs/index.md | 6 +- .../modules/pyvdisk/docs/readme.md | 6 +- .../modules/pyvdisk/platform/dispatch.md | 20 +++-- .../modules/pyvdisk/platform/durability.md | 18 +++- .../modules/pyvdisk/platform/index.md | 8 +- .../modules/pyvdisk/platform/locking.md | 10 ++- .../modules/pyvdisk/platform/positional.md | 10 ++- .../modules/pyvdisk/tests/compat.md | 14 +-- .../modules/pyvdisk/tests/index.md | 10 ++- normify-pyvdisk/normify.html | 85 ++++++++++--------- normify-pyvdisk/outline.md | 2 +- normify-pyvdisk/receipt.json | 12 +-- normify-pyvdisk/tree.json | 81 ++++++++++-------- 14 files changed, 205 insertions(+), 115 deletions(-) create mode 100644 normify-pyvdisk/changes/2026-09-24-compat-describe-live-impl.json diff --git a/normify-pyvdisk/changes/2026-09-24-compat-describe-live-impl.json b/normify-pyvdisk/changes/2026-09-24-compat-describe-live-impl.json new file mode 100644 index 0000000..ad1449b --- /dev/null +++ b/normify-pyvdisk/changes/2026-09-24-compat-describe-live-impl.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "id": "2026-09-24-compat-describe-live-impl", + "title": { + "en": "describe() reports the live implementation", + "zh": "describe() 报告生效的实现" + }, + "status": "verified", + "intent": { + "en": "describe() reported the host platform's primitives even while the Windows emulation was forced, confirming exactly the opposite of the change's core promise. Fix it and pin it with a test.", + "zh": "describe() 在 Windows 模拟生效时仍报告宿主平台的原语,给出的结论恰好与本次改动的核心承诺相反。修正并用测试固定。" + }, + "modules": { + "create": [], + "modify": [ + "pyvdisk.platform.dispatch", + "pyvdisk.platform", + "pyvdisk.tests.compat", + "pyvdisk.docs.readme", + "pyvdisk.docs", + "pyvdisk.tests" + ] + }, + "acceptance": [ + "describe() 在 windows 模拟生效时报告模拟原语(locking/positional_io/directory_fsync/uid_gid)", + "tests/test_compat.py 有一条在模拟下断言全部字段的用例", + "受影响模块(platform.dispatch / platform / tests.compat / docs.readme / docs / tests)指纹与介绍与代码一致", + "normify_validate 0 error" + ], + "note": "describe() 改为描述生效实现;platform 四个模块、tests.compat、docs/tests 容器已同步指纹。", + "revision": { + "before": null, + "after": "3cb47877135592bd8565726610c54ebd1ecd9fba" + }, + "created_at": "2026-09-24T11:50:54.562Z", + "updated_at": "2026-09-24T11:51:43.517Z", + "closed_at": "2026-09-24T11:51:43.517Z" +} diff --git a/normify-pyvdisk/modules/pyvdisk/docs/index.md b/normify-pyvdisk/modules/pyvdisk/docs/index.md index 08f2c09..042bbc1 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/index.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/index.md @@ -11,9 +11,9 @@ description: en: > Repository documentation layer: architecture, contracts, API governance and the VScript spec; the primary evidence source for this module tree. -revision: f163400c098f68cbdfb0393a9bf488037d012aaf -updated_at: "2026-09-24T11:48:38.686Z" -fingerprint: eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.626Z" +fingerprint: 8d769f91ff4b5ef98a97e401560ea0b464b62e52d7f0300183d14660d5a10460 source: - path: "README.md" - path: "docs/ARCHITECTURE.md" diff --git a/normify-pyvdisk/modules/pyvdisk/docs/readme.md b/normify-pyvdisk/modules/pyvdisk/docs/readme.md index 2c93479..65ce075 100644 --- a/normify-pyvdisk/modules/pyvdisk/docs/readme.md +++ b/normify-pyvdisk/modules/pyvdisk/docs/readme.md @@ -10,9 +10,9 @@ description: en: > README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size. -revision: f163400c098f68cbdfb0393a9bf488037d012aaf -updated_at: "2026-09-24T11:48:38.684Z" -fingerprint: 21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.625Z" +fingerprint: 342ea9fe45178aeef55db55a465024bd6b8b64e68bf3f3fb0441947f7c90aaa4 source: - path: "README.md" apis: diff --git a/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md b/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md index 2e08827..adb601e 100644 --- a/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md +++ b/normify-pyvdisk/modules/pyvdisk/platform/dispatch.md @@ -5,14 +5,14 @@ parent: pyvdisk.platform name: {zh: "实现选择", en: "Implementation Dispatch"} description: zh: > - 决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。 + 决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前生效的实现(包括模拟),调用方不会拿到一份"在说另一个平台"的报告。 en: > - Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess. + Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live -- the emulation included -- so a caller never gets a report about a platform that is not the one running. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T11:40:54.220Z" -fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.621Z" +fingerprint: 00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b source: - path: "pyvdisk/compat.py" line: 41 @@ -23,20 +23,26 @@ apis: description: zh: > 当前生效的实现:posix 或 windows。 + en: > The implementation in force: posix or windows. + - protocol: rpc path: "pyvdisk.compat.use_implementation" description: zh: > 临时强制指定实现;上下文管理器,退出时还原,供测试在 Linux 上执行 Windows 分支。 + en: > Temporarily force an implementation; a context manager that restores the previous one, used by tests to execute the Windows branches on Linux. + - protocol: rpc path: "pyvdisk.compat.describe" description: zh: > - 当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。 + 当前生效的实现实际会做什么:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。描述的是 implementation(),而不是宿主平台。 + en: > - Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks. + What the implementation in force actually does: which primitive backs positional IO, locking, directory fsync, identity and symlinks. Follows implementation(), not the host platform. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/durability.md b/normify-pyvdisk/modules/pyvdisk/platform/durability.md index b1a411e..ace9cf9 100644 --- a/normify-pyvdisk/modules/pyvdisk/platform/durability.md +++ b/normify-pyvdisk/modules/pyvdisk/platform/durability.md @@ -10,9 +10,9 @@ description: en: > The remaining platform differences: flushing a directory after a rename, reporting process identity, probing symlink support, and selecting the implementation in force. Each returns a value the caller can branch on instead of raising, because none of them is fatal on its own. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T11:40:47.981Z" -fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T14:30:00Z" +fingerprint: 00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b source: - path: "pyvdisk/compat.py" line: 202 @@ -26,41 +26,53 @@ apis: description: zh: > 刷盘目录,让改名能抵住崩溃。真的执行了才返回 True;Windows 无法把目录当文件打开,所以返回 False 表示"未执行",而不是假装成功。 + en: > Flush a directory so a rename survives a crash. Returns True when it actually ran; Windows cannot open a directory as a file, so it returns False to mean not performed rather than claiming success. + - protocol: rpc path: "pyvdisk.compat.uid" description: zh: > 进程 uid;平台没有该概念时返回 0。 + en: > Effective uid, or 0 where the platform has no such notion. + - protocol: rpc path: "pyvdisk.compat.gid" description: zh: > 进程 gid;平台没有该概念时返回 0。 + en: > Effective gid, or 0 where the platform has no such notion. + - protocol: rpc path: "pyvdisk.compat.uid_or" description: zh: > 取 uid,无该概念时用传入的缺省值。用它而不是 `uid() or default`:uid 0 是 root,不是"未设置"。 + en: > uid, or the given fallback. Prefer this over `uid() or default`: uid 0 is root, not unset. + - protocol: rpc path: "pyvdisk.compat.gid_or" description: zh: > 取 gid,无该概念时用传入的缺省值。 + en: > gid, or the given fallback. + - protocol: rpc path: "pyvdisk.compat.can_symlink" description: zh: > 探测指定目录下能否创建符号链接(不抛异常)。Windows 需要开发者模式,调用方据此降级而不是直接失败。 + en: > Probe whether a symlink can be created in the given directory without raising. Windows needs developer mode, so callers degrade instead of failing. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/index.md b/normify-pyvdisk/modules/pyvdisk/platform/index.md index 482e705..d9f949c 100644 --- a/normify-pyvdisk/modules/pyvdisk/platform/index.md +++ b/normify-pyvdisk/modules/pyvdisk/platform/index.md @@ -6,11 +6,13 @@ name: {zh: "平台适配层", en: "Platform Adaptation"} description: zh: > 唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份。 + en: > The single place that touches operating-system primitives: positional IO, whole-file locking, directory fsync, process identity and symlink support. Every other module goes through it, so Windows differences are handled once instead of at each call site. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:40:00Z" -fingerprint: 184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f + +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.623Z" +fingerprint: a36d0bc58d4a6da6854f4c155bbc8fca838d7a7ff82d379b18b17490bdb29657 source: - path: "pyvdisk/compat.py" - path: "pyvdisk/disk.py" diff --git a/normify-pyvdisk/modules/pyvdisk/platform/locking.md b/normify-pyvdisk/modules/pyvdisk/platform/locking.md index e7b8c79..86859bb 100644 --- a/normify-pyvdisk/modules/pyvdisk/platform/locking.md +++ b/normify-pyvdisk/modules/pyvdisk/platform/locking.md @@ -10,9 +10,9 @@ description: en: > Whole-file write serialisation across threads and processes: fcntl.flock on POSIX, an msvcrt byte range on Windows. The Windows path polls with LK_NBLCK on purpose: LK_LOCK errors out after about ten seconds where flock keeps waiting. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T11:41:06.398Z" -fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T14:30:00Z" +fingerprint: 00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b source: - path: "pyvdisk/compat.py" line: 128 @@ -27,13 +27,17 @@ apis: description: zh: > 取得整文件锁。blocking=True 等待,timeout=N 秒后放弃并返回 False,blocking=False 只试一次。返回是否拿到锁。 + en: > Take the whole-file lock. blocking=True waits, timeout=N seconds gives up and returns False, blocking=False tries once. Returns whether the lock is held. + - protocol: rpc path: "pyvdisk.compat.unlock" description: zh: > 释放锁。句柄已关闭也能调用,因为卸载路径与出错路径都会走到它。 + en: > Release the lock. Tolerates an already-closed handle, because unmount and error paths both call it. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/platform/positional.md b/normify-pyvdisk/modules/pyvdisk/platform/positional.md index c964655..ee0d6a8 100644 --- a/normify-pyvdisk/modules/pyvdisk/platform/positional.md +++ b/normify-pyvdisk/modules/pyvdisk/platform/positional.md @@ -10,9 +10,9 @@ description: en: > Atomic positioned reads and writes that neither depend on nor disturb the file cursor. The emulation is not merely a convenience: without the lock, two threads sharing a handle would seek past each other and corrupt blocks. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T11:41:00.670Z" -fingerprint: 079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1 +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T14:30:00Z" +fingerprint: 00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b source: - path: "pyvdisk/compat.py" line: 102 @@ -23,13 +23,17 @@ apis: description: zh: > 从 offset 处读取至多 length 字节。POSIX 用 os.pread;模拟实现用进程级互斥锁包住 lseek+read,避免与其它线程的 seek 交错。 + en: > Positioned read of up to length bytes. POSIX uses os.pread; the emulation holds a process-wide lock across lseek+read so the pair is not interleaved with another thread's seek. + - protocol: rpc path: "pyvdisk.compat.pwrite" description: zh: > 向 offset 处写入。POSIX 用 os.pwrite;模拟实现用同一把锁串行化 seek+write。 + en: > Positioned write. POSIX uses os.pwrite; the emulation serialises seek+write under the same lock. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/compat.md b/normify-pyvdisk/modules/pyvdisk/tests/compat.md index 6259ef0..d8e35f6 100644 --- a/normify-pyvdisk/modules/pyvdisk/tests/compat.md +++ b/normify-pyvdisk/modules/pyvdisk/tests/compat.md @@ -5,12 +5,14 @@ parent: pyvdisk.tests name: {zh: "平台兼容测试", en: "Platform Compat Tests"} description: zh: > - 在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。 + 在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作;同时固定 describe() 描述的是生效实现而不是宿主。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。 + en: > - Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite. -revision: 2c9009ba74afb515d301cc96e1946087268479a2 -updated_at: "2026-09-24T13:40:00Z" -fingerprint: 27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c + Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. It also pins describe() to the implementation in force rather than the host. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. + +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.624Z" +fingerprint: 49ec4bf92e42b64486091b5f313fcab34567167b3fdbe9d85ad538e501c2122d source: - path: "tests/test_compat.py" apis: @@ -19,6 +21,8 @@ apis: description: zh: > 把平台切到模拟实现跑整条用例。 + en: > Run the whole suite with the platform switched to the emulated implementation. + --- diff --git a/normify-pyvdisk/modules/pyvdisk/tests/index.md b/normify-pyvdisk/modules/pyvdisk/tests/index.md index 2491d62..7935c60 100644 --- a/normify-pyvdisk/modules/pyvdisk/tests/index.md +++ b/normify-pyvdisk/modules/pyvdisk/tests/index.md @@ -6,11 +6,13 @@ tags: [tests] name: {zh: "测试套件", en: "Test Suite"} description: zh: > - 测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。 + 测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。 + en: > - Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent. -revision: c3881eee5dced2b180cd3b383e5d848026224154 -updated_at: "2026-09-24T14:10:00Z" + Test suite: 447 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent. + +revision: 3cb47877135592bd8565726610c54ebd1ecd9fba +updated_at: "2026-09-24T11:51:39.627Z" fingerprint: b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1 source: - path: "tests/conftest.py" diff --git a/normify-pyvdisk/normify.html b/normify-pyvdisk/normify.html index bec5445..0f9b752 100644 --- a/normify-pyvdisk/normify.html +++ b/normify-pyvdisk/normify.html @@ -164,7 +164,7 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T11:48:42.253Z", + "compiled_at": "2026-09-24T11:51:43.434Z", "stats": { "tree_count": 1, "module_count": 290, @@ -177,7 +177,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 4, + "change_count": 5, "open_change_count": 1 } }, @@ -2712,9 +2712,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.686Z", - "fingerprint": "eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.626Z", + "fingerprint": "8d769f91ff4b5ef98a97e401560ea0b464b62e52d7f0300183d14660d5a10460", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2912,9 +2912,9 @@ "path": "README.md" } ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.684Z", - "fingerprint": "21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.625Z", + "fingerprint": "342ea9fe45178aeef55db55a465024bd6b8b64e68bf3f3fb0441947f7c90aaa4", "apis": [ { "protocol": "file", @@ -5099,9 +5099,9 @@ "path": "pyvdisk/fuse_mount.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.623Z", + "fingerprint": "a36d0bc58d4a6da6854f4c155bbc8fca838d7a7ff82d379b18b17490bdb29657", "aggregate": { "descendant_count": 4, "own_api_count": 0, @@ -5121,8 +5121,8 @@ "en": "Implementation Dispatch" }, "description": { - "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。\n", - "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess.\n" + "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前生效的实现(包括模拟),调用方不会拿到一份\"在说另一个平台\"的报告。\n", + "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live -- the emulation included -- so a caller never gets a report about a platform that is not the one running.\n" }, "source": [ { @@ -5131,9 +5131,9 @@ "end_line": 100 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:40:54.220Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.621Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5157,8 +5157,8 @@ "protocol": "rpc", "path": "pyvdisk.compat.describe", "description": { - "zh": "当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。\n", - "en": "Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks.\n" + "zh": "当前生效的实现实际会做什么:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。描述的是 implementation(),而不是宿主平台。\n", + "en": "What the implementation in force actually does: which primitive backs positional IO, locking, directory fsync, identity and symlinks. Follows implementation(), not the host platform.\n" }, "key": "rpc:pyvdisk.compat.describe" } @@ -5197,9 +5197,9 @@ "end_line": 100 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:40:47.981Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5293,9 +5293,9 @@ "line": 58 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:41:06.398Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5345,9 +5345,9 @@ "end_line": 127 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:41:00.670Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -13279,8 +13279,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", - "en": "Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" + "zh": "测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 447 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -13293,8 +13293,8 @@ "path": "tests/test_vscript.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T14:10:00Z", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.627Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { "descendant_count": 58, @@ -13681,17 +13681,17 @@ "en": "Platform Compat Tests" }, "description": { - "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。\n", - "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite.\n" + "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作;同时固定 describe() 描述的是生效实现而不是宿主。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。\n", + "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. It also pins describe() to the implementation in force rather than the host. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so.\n" }, "source": [ { "path": "tests/test_compat.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.624Z", + "fingerprint": "49ec4bf92e42b64486091b5f313fcab34567167b3fdbe9d85ad538e501c2122d", "apis": [ { "protocol": "file", @@ -23113,13 +23113,22 @@ }, "changes": [ { - "id": "2026-09-24-readme-agent-demo-fix", + "id": "2026-09-24-compat-describe-live-impl", "status": "in_progress", + "title": { + "en": "describe() reports the live implementation", + "zh": "describe() 报告生效的实现" + }, + "updated_at": "2026-09-24T11:50:54.562Z" + }, + { + "id": "2026-09-24-readme-agent-demo-fix", + "status": "verified", "title": { "en": "Fix the README agent demo", "zh": "修正 README 的 Agent 对接 Demo" }, - "updated_at": "2026-09-24T11:48:12.396Z" + "updated_at": "2026-09-24T11:48:42.331Z" }, { "id": "2026-09-24-readme-counts", diff --git a/normify-pyvdisk/outline.md b/normify-pyvdisk/outline.md index 94b13e6..6f05b7d 100644 --- a/normify-pyvdisk/outline.md +++ b/normify-pyvdisk/outline.md @@ -193,7 +193,7 @@ - pyvdisk.storage.wal.entries — WAL 记录 / WAL Entries — 事务日志动词与崩溃恢复重放:begin/append/prepare/commit/abort,以及重放所依赖的读取入口。 — [模块 1 · API 8] - pyvdisk.storage.wal.journal — 元数据 WAL / Metadata WAL — DataDisk 事务使用的元数据预写日志:存储后端、行编解码,以及分配序号的追加写入。 — [模块 1 · API 4] - pyvdisk.storage.wal.undo — 宿主撤销 WAL / Host Undo WAL — VScript 侧的 WAL 入口:独立的宿主路径实现已取消——本模块直接复用同一套 WriteAheadLog,并给出撤销记录使用的 kind 集与编解码。 — [模块 1 · API 4] - - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] + - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] - pyvdisk.tests.agent-sandbox — 沙箱测试 / Sandbox Tests — 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的… — [模块 1 · API 1] - pyvdisk.tests.agentic-cli — 智能体 CLI 用例 / Agentic CLI Tests — 面向智能体使用编写的 CLI 用例:可发现的输出与稳定的退出码。 — [模块 1 · API 1] - pyvdisk.tests.api-governance — API 治理用例 / API Governance Tests — 检查公开能力 API 是否拒绝应当拒绝的调用,而不只验证正常路径。 — [模块 1 · API 1] diff --git a/normify-pyvdisk/receipt.json b/normify-pyvdisk/receipt.json index 0954dea..1fa76ed 100644 --- a/normify-pyvdisk/receipt.json +++ b/normify-pyvdisk/receipt.json @@ -2,7 +2,7 @@ "schema_version": 1, "ok": true, "project": "normify-pyvdisk", - "compiled_at": "2026-09-24T11:48:42.836Z", + "compiled_at": "2026-09-24T11:51:44.100Z", "stats": { "tree_count": 1, "module_count": 290, @@ -15,7 +15,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 4, + "change_count": 5, "open_change_count": 0 }, "warnings": { @@ -24,11 +24,11 @@ }, "artifacts": { "tree.json": { - "sha256": "2ec85812c633a314f985ff843562e9feb5c1a9ba78e267d26b4115da786284e3", - "bytes": 832176 + "sha256": "c166989dfb7459ed702458b273fde1a4135ad707f7ab1ad8743c64705f920dab", + "bytes": 832638 }, "outline.md": { - "sha256": "84959e68fcfce9320bdd3bae70d18973d87fa558d0a0bea716ef5d51a0e1d30e", + "sha256": "fea33e8c6e8b1b7b98c7684729802b8639ca72d16a47c8adae7a20011a8f98cd", "bytes": 58995 }, "api-index.json": { @@ -36,7 +36,7 @@ "bytes": 62999 }, "receipt.json": { - "sha256": "6517e4cb20e1a6adde78aa6a5b9983240e72bad078a1a8914ff38c94acec7e44", + "sha256": "9f630c60ed6c4ff788b9e10259671ad79cc9b42b8f2e116127e206cc347048e6", "bytes": 964 } } diff --git a/normify-pyvdisk/tree.json b/normify-pyvdisk/tree.json index c50aea3..dcfd2e4 100644 --- a/normify-pyvdisk/tree.json +++ b/normify-pyvdisk/tree.json @@ -9,7 +9,7 @@ "repository": "https://github.com/HeDaas-Code/pyvdisk" } ], - "compiled_at": "2026-09-24T11:48:42.836Z", + "compiled_at": "2026-09-24T11:51:44.100Z", "stats": { "tree_count": 1, "module_count": 290, @@ -22,7 +22,7 @@ "planned_count": 0, "deprecated_count": 0, "policy_rule_count": 2, - "change_count": 4, + "change_count": 5, "open_change_count": 0 } }, @@ -2557,9 +2557,9 @@ "path": "docs/VSCRIPT_SPEC.md" } ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.686Z", - "fingerprint": "eb6fa907e54689d8347e966774b0ad07fba9f382d04fba10dacc8c03953c1644", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.626Z", + "fingerprint": "8d769f91ff4b5ef98a97e401560ea0b464b62e52d7f0300183d14660d5a10460", "aggregate": { "descendant_count": 6, "own_api_count": 0, @@ -2757,9 +2757,9 @@ "path": "README.md" } ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.684Z", - "fingerprint": "21502068301a8671d1fae8491b59e2a56e5e63d4a6f43a8250b4f127abba4f40", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.625Z", + "fingerprint": "342ea9fe45178aeef55db55a465024bd6b8b64e68bf3f3fb0441947f7c90aaa4", "apis": [ { "protocol": "file", @@ -4944,9 +4944,9 @@ "path": "pyvdisk/fuse_mount.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "184149afe73afbc06aac483b2bfd4c3def5db0e514b75c6e3b4c2835102d728f", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.623Z", + "fingerprint": "a36d0bc58d4a6da6854f4c155bbc8fca838d7a7ff82d379b18b17490bdb29657", "aggregate": { "descendant_count": 4, "own_api_count": 0, @@ -4966,8 +4966,8 @@ "en": "Implementation Dispatch" }, "description": { - "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前实现,调用方不必猜。\n", - "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live so a caller never has to guess.\n" + "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前生效的实现(包括模拟),调用方不会拿到一份\"在说另一个平台\"的报告。\n", + "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live -- the emulation included -- so a caller never gets a report about a platform that is not the one running.\n" }, "source": [ { @@ -4976,9 +4976,9 @@ "end_line": 100 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:40:54.220Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.621Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5002,8 +5002,8 @@ "protocol": "rpc", "path": "pyvdisk.compat.describe", "description": { - "zh": "当前实现的可读说明:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。\n", - "en": "Human-readable description of the live implementation: which primitive backs positional IO, locking, directory fsync, identity and symlinks.\n" + "zh": "当前生效的实现实际会做什么:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。描述的是 implementation(),而不是宿主平台。\n", + "en": "What the implementation in force actually does: which primitive backs positional IO, locking, directory fsync, identity and symlinks. Follows implementation(), not the host platform.\n" }, "key": "rpc:pyvdisk.compat.describe" } @@ -5042,9 +5042,9 @@ "end_line": 100 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:40:47.981Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5138,9 +5138,9 @@ "line": 58 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:41:06.398Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -5190,9 +5190,9 @@ "end_line": 127 } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:41:00.670Z", - "fingerprint": "079a5edb2e3962afd8293877a634189cbdef72a96e9d5881983523ef5a531fb1", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T14:30:00Z", + "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", "apis": [ { "protocol": "rpc", @@ -13124,8 +13124,8 @@ "en": "Test Suite" }, "description": { - "zh": "测试套件:446 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", - "en": "Test suite: 446 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" + "zh": "测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", + "en": "Test suite: 447 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" }, "source": [ { @@ -13138,8 +13138,8 @@ "path": "tests/test_vscript.py" } ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T14:10:00Z", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.627Z", "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", "aggregate": { "descendant_count": 58, @@ -13526,17 +13526,17 @@ "en": "Platform Compat Tests" }, "description": { - "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。守卫测试会在 compat.py 之外任何模块直接使用 fcntl、msvcrt、os.pread、os.pwrite 时失败。\n", - "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so. A guard test fails if any module outside compat.py reaches for fcntl, msvcrt, os.pread or os.pwrite.\n" + "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作;同时固定 describe() 描述的是生效实现而不是宿主。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。\n", + "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. It also pins describe() to the implementation in force rather than the host. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so.\n" }, "source": [ { "path": "tests/test_compat.py" } ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "27901dc78ca371a0a4fb38f74f89616e6b40b5cf776510c92021ff8155f5970c", + "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", + "updated_at": "2026-09-24T11:51:39.624Z", + "fingerprint": "49ec4bf92e42b64486091b5f313fcab34567167b3fdbe9d85ad538e501c2122d", "apis": [ { "protocol": "file", @@ -22957,6 +22957,15 @@ ] }, "changes": [ + { + "id": "2026-09-24-compat-describe-live-impl", + "status": "verified", + "title": { + "en": "describe() reports the live implementation", + "zh": "describe() 报告生效的实现" + }, + "updated_at": "2026-09-24T11:51:43.517Z" + }, { "id": "2026-09-24-readme-agent-demo-fix", "status": "verified", From 7393b1c45700a662d28e65432a21489957ba6a43 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Mon, 28 Sep 2026 17:08:49 +0800 Subject: [PATCH 10/15] fix(ci): keep hnswlib out of the dev extra so the zero-dependency job can pass The no-dependencies job installs .[dev] and then asserts that neither hnswlib, fuse nor numpy is importable. Having hnswlib in the dev extra made that job fail on CI with 'installed: hnswlib,numpy' -- the job was detecting the accelerator it had just installed itself, not a real leak. The accelerator already has its own 'vector' extra, and the test matrix installs .[dev,vector], so the hnswlib code path stays covered. Splitting the two is what lets the no-dependencies job actually prove the claim it exists to prove. --- pyproject.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 669c240..9232404 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,13 @@ dependencies = [] # VectorDisk still answers exact queries, in linear time. vector = ["hnswlib>=0.8.0"] fuse = ["fusepy"] -dev = ["pytest", "setuptools>=61.0", "hnswlib>=0.8.0"] +# Test tooling only. The accelerator deliberately lives in its own extra: this +# job is what installs the package for every test run, including the +# no-dependencies job, which installs ".[dev]" and then asserts that no +# third-party runtime dependency is present. Keeping pytest and hnswlib apart +# is what lets that job prove the zero-dependency claim instead of failing on +# the accelerator it pulled in itself. +dev = ["pytest", "setuptools>=61.0"] [project.scripts] pyvdisk = "pyvdisk.cli:main" From 3069387cbb2eef144ed448200b3aa2a827b15b99 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Wed, 30 Sep 2026 00:28:54 +0800 Subject: [PATCH 11/15] docs(readme): calibrate the test numbers to CI output rather than local runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verification section claimed "447 passed(本地 3.12;CI 覆盖 ...)" and the badge said 447 passed with no qualifier. Both invited the same misreading: that CI had produced 447. It had not -- this branch's numbers had only ever been measured locally. The branch has now run on CI (all five jobs green), so the numbers can state where they come from. Read out of the job logs: tests (3.9 .. 3.12) -> 447 passed no-dependencies -> 443 passed, 4 skipped Also say which four cases skip and why (they need hnswlib and the built-in flat index present at once to compare the two backends), rather than leaving the reader to guess, and add a zero-dependency badge since that is now a property the CI actually enforces. --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88763a6..19f9790 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![GitHub](https://img.shields.io/badge/GitHub-PyVDisk-181717?logo=github)](https://github.com/HeDaas-Code/pyvdisk) [![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) [![Tests](https://img.shields.io/badge/Tests-447%20passed-2ea44f)](#验证) +[![No%20dependencies](https://img.shields.io/badge/dependencies-none-2ea44f)](#验证) PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行基础设施项目:DataDisk 负责统一数据与执行基础设施,VScript 负责安全工作流语言、CLI、REPL 与运行时。 @@ -187,6 +188,13 @@ pyvdisk info image.vdisk .venv/bin/python -m pytest -q ``` -当前回归:447 passed(本地 3.12;CI 覆盖 3.9 / 3.10 / 3.11 / 3.12 四个版本的同一套用例) +CI 在 `3.9 / 3.10 / 3.11 / 3.12` 四个版本上跑同一套用例,并额外跑一个不装任何第三方包的 +`no-dependencies` job。两个口径的实测结果(均为 CI 输出,非本地推算): -不装 hnswlib 时同一套用例为 443 passed / 4 skipped —— 核心路径不再依赖任何第三方包,跳过的是"两种索引后端结果一致"这类对照用例。 +| 环境 | 结果 | +|---|---| +| `.[dev,vector]`(装了 hnswlib) | **447 passed** | +| `.[dev]`(不装 hnswlib) | **443 passed, 4 skipped** | + +跳过的是"两种索引后端结果一致"这类对照用例 —— 它们需要 hnswlib 与内置 flat 索引同时在场, +没装加速器时无法对照。核心路径在两种环境下都完整执行。 From b5aa584f2d88406bba9e3ea30a36181e4a8814bb Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Wed, 30 Sep 2026 00:57:28 +0800 Subject: [PATCH 12/15] fix(compat): retry only lock-contention errnos, surface everything else _retry() treated every OSError as "someone else holds the lock" and polled at POLL_SECONDS. With blocking=True and no timeout that loop never ends: a stale or bad descriptor (EBADF) or a dead filesystem now spins at 100 Hz forever instead of failing fast. Restrict the retry to errnos that actually mean contention or interruption (EAGAIN/EWOULDBLOCK, EACCES, EINTR, EDEADLOCK) and re-raise the rest from both the blocking and the deadline loop. A non-blocking probe now reports contended (False) only for real contention; any other error raises. Two regression tests pin this: one through the Windows emulation (closed fd + timeout must raise well before the deadline, not return False), one against the native POSIX path (non-blocking probe on a closed fd raises instead of reporting contention). --- pyvdisk/compat.py | 32 ++++++++++++++++++++++++++++++-- tests/test_compat.py | 24 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/pyvdisk/compat.py b/pyvdisk/compat.py index 21e43d8..a096313 100644 --- a/pyvdisk/compat.py +++ b/pyvdisk/compat.py @@ -32,6 +32,7 @@ from __future__ import annotations import contextlib +import errno import os import sys import threading @@ -63,6 +64,25 @@ _POSITIONAL_LOCK = threading.RLock() +#: Errnos that mean "the lock is held by someone else" (or "retry the syscall"): +#: ``flock(LOCK_NB)`` raises EAGAIN/EWOULDBLOCK (and EACCES on some systems), +#: ``msvcrt.locking`` raises EACCES (13) or EDEADLOCK (36), and EINTR means the +#: syscall was interrupted before it could succeed or fail. Anything else is a +#: real error -- a bad descriptor, a dead filesystem -- and must surface +#: immediately instead of burning CPU at POLL_SECONDS forever. +_RETRYABLE_ERRNOS = frozenset({ + errno.EAGAIN, + getattr(errno, "EWOULDBLOCK", errno.EAGAIN), + errno.EACCES, + errno.EINTR, + getattr(errno, "EDEADLOCK", 0), +} - {0}) + + +def _lock_conflict(exc: OSError) -> bool: + """Is this OSError merely "someone else holds the lock" (or EINTR)?""" + return exc.errno in _RETRYABLE_ERRNOS + # Test seams: the emulation is exercised on POSIX by forcing it and injecting a # stand-in for ``msvcrt``. Production code never touches these. _FORCED: str | None = None @@ -140,20 +160,28 @@ def _retry(attempt, *, blocking: bool, timeout: float | None) -> bool: ``LK_LOCK`` gives up after about ten seconds on Windows, so the emulation never uses it: it polls ``LK_NBLCK`` instead and keeps the wait semantics ``flock`` has (wait forever by default, or for ``timeout`` seconds). + + Only lock-contention errnos are retried. Any other OSError (a bad + descriptor, an I/O error) propagates immediately: polling it forever at + 100 Hz would hide the bug and burn a core doing it. """ if blocking and timeout is None: while True: try: attempt() return True - except OSError: + except OSError as exc: + if not _lock_conflict(exc): + raise time.sleep(POLL_SECONDS) deadline = None if timeout is None else time.monotonic() + timeout while True: try: attempt() return True - except OSError: + except OSError as exc: + if not _lock_conflict(exc): + raise if not blocking: return False if deadline is not None and time.monotonic() >= deadline: diff --git a/tests/test_compat.py b/tests/test_compat.py index b1647e3..b20484b 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -187,6 +187,30 @@ def test_unlock_on_a_closed_handle_is_not_an_error(tmp_path): compat.unlock(fd) # must not raise: close() runs on every teardown path +def test_a_real_lock_error_propagates_instead_of_polling(tmp_path, windows_emulation): + """Only lock contention is retried; a bad descriptor must raise at once. + + Under the old catch-all _retry this call polled LK_NBLCK for the whole + timeout and then reported False -- indistinguishable from "contended" -- + and with blocking=True it would have spun forever. + """ + fd = _lock_file(tmp_path) + os.close(fd) + started = time.monotonic() + with pytest.raises(OSError): + compat.lock(fd, timeout=0.2) + assert time.monotonic() - started < 0.2, "a real error must not be retried" + + +def test_native_flock_real_error_is_not_reported_as_contention(tmp_path): + if os.name != "posix": + pytest.skip("the native path is exercised directly only on POSIX") + fd = _lock_file(tmp_path) + os.close(fd) + with pytest.raises(OSError): + compat.lock(fd, blocking=False) # was False before: looked like contention + + def test_fsync_dir_flushes_a_real_directory(tmp_path): if os.name != "posix": pytest.skip("directory fsync is a POSIX facility") From f07baa067c70f3e25ff0b80854a9540d350a52a7 Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Wed, 30 Sep 2026 00:57:38 +0800 Subject: [PATCH 13/15] fix(docs): the example says "OpenAI-compatible", not "[OI]-compatible" Line 9 lost its identifier to whatever pipeline produced the file; restore the intended wording so a reader knows what to swap scripted_model for. --- examples/agent_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/agent_tools.py b/examples/agent_tools.py index a1e4f05..c5ed34d 100644 --- a/examples/agent_tools.py +++ b/examples/agent_tools.py @@ -6,7 +6,7 @@ The "model" here is a scripted list of tool calls, so this runs anywhere. The loop is exactly the one you write against a real framework: ask the model, run every tool call it asks for, feed the results back, repeat until it stops asking. -Swap ``scripted_model`` for an [OI]-compatible client and nothing else changes -- +Swap ``scripted_model`` for an OpenAI-compatible client and nothing else changes -- ``box.tools()`` and ``box.dispatch()`` are the whole integration surface. Note the last scripted call: the model asks to read ``/etc/passwd`` and gets a From 202d9e3ac3e7dc88123ae01363996e9f496d17cf Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Wed, 30 Sep 2026 00:57:38 +0800 Subject: [PATCH 14/15] chore(release): 0.4.0 Drop the [Unreleased] heading onto a dated version. 0.4.0 is the first release carrying the zero-dependency flat index, the compat layer and AgentSandbox; the changelog section was already written for exactly that set. --- CHANGELOG.md | 2 +- pyproject.toml | 2 +- pyvdisk/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b626c99..f1a557a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ 记录用户可见的变更。版本号与 `pyproject.toml` 的 `version` 一致;更早的历史见 git 提交。 本文件从 issue #1(核心缺口复盘)的修复开始维护,条目按该清单的编号标注。 -## [Unreleased] +## [0.4.0] - 2026-09-30 ### 新增 — 零依赖与跨平台(issue #2) - **Windows 兼容层**:新增 `pyvdisk/compat.py`,把全部平台原语收敛到一处 —— 定位读写(`os.pread/pwrite` ↔ `lseek`+`read/write` + 互斥)、文件锁(`fcntl.flock` ↔ `msvcrt.locking`)、目录 `fsync`、`uid/gid`、符号链接探测。此前 `pyvdisk/infrastructure/checkpoint.py` 顶层 `import fcntl`,在 Windows 上连导入都会失败。现在除 `compat.py` 外,包内不再直接触碰这些原语,`tests/test_compat.py` 用一条守卫测试固定该约束。 diff --git a/pyproject.toml b/pyproject.toml index 9232404..0d0e2fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pyvdisk" -version = "0.3.0" +version = "0.4.0" description = "纯 Python 虚拟磁盘、文件系统、向量数据盘与时序日志盘" readme = "README.md" requires-python = ">=3.9" diff --git a/pyvdisk/__init__.py b/pyvdisk/__init__.py index 71478ea..9311ebc 100644 --- a/pyvdisk/__init__.py +++ b/pyvdisk/__init__.py @@ -77,7 +77,7 @@ from .vector_index import FlatIndex, FlatIndexError from .sandbox import AgentSandbox, SandboxError, ToolResult -__version__ = "0.3.0" +__version__ = "0.4.0" __all__ = [ "VirtualDisk", From 1047c82af60cec32a253a25511d98f93e1c701af Mon Sep 17 00:00:00 2001 From: PyVDisk Team Date: Wed, 30 Sep 2026 00:57:48 +0800 Subject: [PATCH 15/15] docs(normify): archive the generated map to the normify branch The 3.4 MB build artifact (272 module pages, renders, tree.json, receipt) has been living inside the code tree, so every docs sync turned routine commits into noise and the tree stopped reading as code. The artifact now lives on its own orphan branch, normify, which holds normify-pyvdisk/ at the same path and nothing else; this branch is the archive location, regenerated only when the map itself is rebuilt. The README links (interactive htmlpreview URL and the artifact table) point there now, so the map stays one click away from the README without occupying the repository's file tree. --- README.md | 16 +- normify-pyvdisk/api-index.json | 846 - .../2026-09-24-compat-describe-live-impl.json | 38 - .../2026-09-24-readme-agent-demo-fix.json | 37 - .../changes/2026-09-24-readme-counts.json | 30 - .../2026-09-24-resync-issue1-fixes.json | 147 - ...6-09-24-zero-dep-windows-agentsandbox.json | 31 - .../modules/pyvdisk/agent/audit.md | 47 - .../modules/pyvdisk/agent/index.md | 21 - .../modules/pyvdisk/agent/paths.md | 43 - .../modules/pyvdisk/agent/sandbox.md | 75 - .../modules/pyvdisk/agent/script.md | 36 - .../modules/pyvdisk/agent/tools.md | 50 - normify-pyvdisk/modules/pyvdisk/api.md | 108 - normify-pyvdisk/modules/pyvdisk/cli/admin.md | 75 - normify-pyvdisk/modules/pyvdisk/cli/dirs.md | 47 - normify-pyvdisk/modules/pyvdisk/cli/drive.md | 40 - normify-pyvdisk/modules/pyvdisk/cli/entry.md | 25 - .../modules/pyvdisk/cli/file-ops.md | 61 - normify-pyvdisk/modules/pyvdisk/cli/format.md | 47 - normify-pyvdisk/modules/pyvdisk/cli/image.md | 47 - normify-pyvdisk/modules/pyvdisk/cli/index.md | 18 - .../modules/pyvdisk/cli/inspect.md | 47 - normify-pyvdisk/modules/pyvdisk/cli/log.md | 75 - normify-pyvdisk/modules/pyvdisk/cli/main.md | 28 - normify-pyvdisk/modules/pyvdisk/cli/open.md | 36 - normify-pyvdisk/modules/pyvdisk/cli/parser.md | 36 - normify-pyvdisk/modules/pyvdisk/cli/vector.md | 75 - normify-pyvdisk/modules/pyvdisk/cli/volume.md | 61 - .../modules/pyvdisk/compat/index.md | 20 - .../modules/pyvdisk/compat/unified.md | 32 - .../modules/pyvdisk/compat/vscript.md | 25 - .../modules/pyvdisk/contracts/capability.md | 47 - .../modules/pyvdisk/contracts/durability.md | 33 - .../modules/pyvdisk/contracts/events.md | 47 - .../modules/pyvdisk/contracts/execution.md | 40 - .../modules/pyvdisk/contracts/index.md | 17 - .../modules/pyvdisk/contracts/plane.md | 26 - .../modules/pyvdisk/contracts/runhandle.md | 54 - .../modules/pyvdisk/contracts/storage.md | 54 - .../modules/pyvdisk/delivery/ci.md | 31 - .../modules/pyvdisk/delivery/index.md | 21 - .../modules/pyvdisk/delivery/lint.md | 28 - .../modules/pyvdisk/delivery/packaging.md | 47 - .../modules/pyvdisk/docs/api-governance.md | 24 - .../modules/pyvdisk/docs/architecture.md | 28 - .../modules/pyvdisk/docs/changelog.md | 29 - .../modules/pyvdisk/docs/contracts.md | 28 - normify-pyvdisk/modules/pyvdisk/docs/index.md | 23 - .../modules/pyvdisk/docs/readme.md | 34 - .../modules/pyvdisk/docs/vscript-spec.md | 24 - .../modules/pyvdisk/examples/agent-tools.md | 29 - .../modules/pyvdisk/examples/index.md | 19 - .../modules/pyvdisk/examples/quickstart.md | 24 - .../modules/pyvdisk/execution/index.md | 20 - .../pyvdisk/execution/operations/callables.md | 47 - .../pyvdisk/execution/operations/describe.md | 47 - .../pyvdisk/execution/operations/errors.md | 40 - .../pyvdisk/execution/operations/index.md | 17 - .../pyvdisk/execution/operations/record.md | 40 - .../pyvdisk/execution/operations/registry.md | 90 - .../pyvdisk/execution/operations/storage.md | 40 - .../modules/pyvdisk/execution/queue/errors.md | 47 - .../modules/pyvdisk/execution/queue/index.md | 17 - .../pyvdisk/execution/queue/lifecycle.md | 75 - .../pyvdisk/execution/queue/recovery.md | 40 - .../modules/pyvdisk/execution/queue/store.md | 81 - .../modules/pyvdisk/execution/queue/task.md | 33 - .../pyvdisk/execution/runstate/index.md | 16 - .../pyvdisk/execution/runstate/model.md | 40 - .../pyvdisk/execution/runstate/store.md | 90 - .../pyvdisk/execution/service/index.md | 16 - .../pyvdisk/execution/service/invoke.md | 68 - .../pyvdisk/execution/service/queue.md | 54 - .../pyvdisk/execution/service/setup.md | 77 - .../pyvdisk/execution/service/submit.md | 54 - .../modules/pyvdisk/governance/data.md | 104 - .../modules/pyvdisk/governance/files.md | 99 - .../modules/pyvdisk/governance/index.md | 19 - .../modules/pyvdisk/governance/namespace.md | 72 - .../modules/pyvdisk/governance/scoped.md | 66 - normify-pyvdisk/modules/pyvdisk/index.md | 17 - .../modules/pyvdisk/platform/dispatch.md | 48 - .../modules/pyvdisk/platform/durability.md | 78 - .../modules/pyvdisk/platform/index.md | 22 - .../modules/pyvdisk/platform/locking.md | 43 - .../modules/pyvdisk/platform/positional.md | 39 - .../modules/pyvdisk/storage/block/access.md | 75 - .../modules/pyvdisk/storage/block/image.md | 59 - .../modules/pyvdisk/storage/block/index.md | 18 - .../modules/pyvdisk/storage/block/io.md | 50 - .../pyvdisk/storage/checkpoint/index.md | 18 - .../modules/pyvdisk/storage/checkpoint/io.md | 57 - .../pyvdisk/storage/checkpoint/open.md | 71 - .../pyvdisk/storage/checkpoint/triggers.md | 43 - .../modules/pyvdisk/storage/datadisk/api.md | 104 - .../modules/pyvdisk/storage/datadisk/codec.md | 66 - .../modules/pyvdisk/storage/datadisk/core.md | 81 - .../modules/pyvdisk/storage/datadisk/index.md | 19 - .../pyvdisk/storage/datadisk/namespace.md | 99 - .../pyvdisk/storage/datadisk/services.md | 50 - .../pyvdisk/storage/datadisk/tx-lifecycle.md | 63 - .../modules/pyvdisk/storage/datadisk/tx.md | 75 - .../pyvdisk/storage/driver/assembled.md | 66 - .../modules/pyvdisk/storage/driver/index.md | 18 - .../pyvdisk/storage/driver/lifecycle.md | 57 - .../modules/pyvdisk/storage/driver/manager.md | 72 - .../pyvdisk/storage/driver/mounting.md | 100 - .../modules/pyvdisk/storage/driver/mounts.md | 75 - .../modules/pyvdisk/storage/fs/attrs.md | 54 - .../modules/pyvdisk/storage/fs/bitmap.md | 40 - .../modules/pyvdisk/storage/fs/block-alloc.md | 33 - .../modules/pyvdisk/storage/fs/create.md | 72 - .../modules/pyvdisk/storage/fs/dir-mutate.md | 40 - .../modules/pyvdisk/storage/fs/dir.md | 40 - .../modules/pyvdisk/storage/fs/fsck.md | 33 - .../modules/pyvdisk/storage/fs/grow.md | 36 - .../modules/pyvdisk/storage/fs/index.md | 17 - .../modules/pyvdisk/storage/fs/inode-io.md | 72 - .../modules/pyvdisk/storage/fs/inode.md | 47 - .../modules/pyvdisk/storage/fs/layout.md | 54 - .../modules/pyvdisk/storage/fs/locking.md | 63 - .../modules/pyvdisk/storage/fs/mkfs.md | 36 - .../modules/pyvdisk/storage/fs/mount.md | 54 - .../modules/pyvdisk/storage/fs/mutate.md | 63 - .../modules/pyvdisk/storage/fs/names.md | 47 - .../modules/pyvdisk/storage/fs/paths.md | 54 - .../modules/pyvdisk/storage/fs/pointers.md | 54 - .../modules/pyvdisk/storage/fs/query.md | 61 - .../modules/pyvdisk/storage/fs/readwrite.md | 63 - .../modules/pyvdisk/storage/fs/stat.md | 47 - .../modules/pyvdisk/storage/fs/superblock.md | 40 - .../modules/pyvdisk/storage/fs/truncate.md | 40 - .../modules/pyvdisk/storage/fuse/data.md | 90 - .../modules/pyvdisk/storage/fuse/handlers.md | 84 - .../modules/pyvdisk/storage/fuse/index.md | 19 - .../modules/pyvdisk/storage/fuse/meta.md | 62 - .../modules/pyvdisk/storage/fuse/mount.md | 45 - .../pyvdisk/storage/identity/format.md | 40 - .../modules/pyvdisk/storage/identity/index.md | 16 - .../modules/pyvdisk/storage/identity/model.md | 47 - .../modules/pyvdisk/storage/identity/probe.md | 54 - .../pyvdisk/storage/identity/trailer.md | 45 - .../modules/pyvdisk/storage/index.md | 32 - .../modules/pyvdisk/storage/log/append.md | 45 - .../modules/pyvdisk/storage/log/filter.md | 48 - .../modules/pyvdisk/storage/log/index.md | 19 - .../modules/pyvdisk/storage/log/open.md | 63 - .../modules/pyvdisk/storage/log/query.md | 90 - .../modules/pyvdisk/storage/log/retention.md | 54 - .../modules/pyvdisk/storage/log/streams.md | 48 - .../modules/pyvdisk/storage/logging/bridge.md | 45 - .../pyvdisk/storage/logging/context.md | 48 - .../modules/pyvdisk/storage/logging/events.md | 57 - .../modules/pyvdisk/storage/logging/index.md | 18 - .../modules/pyvdisk/storage/logging/logger.md | 72 - .../modules/pyvdisk/storage/logging/sinks.md | 63 - .../modules/pyvdisk/storage/rwlock/core.md | 54 - .../modules/pyvdisk/storage/rwlock/ctx.md | 63 - .../modules/pyvdisk/storage/rwlock/index.md | 16 - .../pyvdisk/storage/vector/collections.md | 48 - .../pyvdisk/storage/vector/flat-index.md | 75 - .../modules/pyvdisk/storage/vector/index.md | 19 - .../modules/pyvdisk/storage/vector/open.md | 70 - .../modules/pyvdisk/storage/vector/records.md | 72 - .../modules/pyvdisk/storage/vector/search.md | 45 - .../modules/pyvdisk/storage/vfs/attrs.md | 54 - .../modules/pyvdisk/storage/vfs/create.md | 44 - .../modules/pyvdisk/storage/vfs/dirs.md | 33 - .../modules/pyvdisk/storage/vfs/files.md | 54 - .../modules/pyvdisk/storage/vfs/hostio.md | 47 - .../modules/pyvdisk/storage/vfs/index.md | 16 - .../modules/pyvdisk/storage/vfs/lifetime.md | 63 - .../modules/pyvdisk/storage/vfs/open.md | 54 - .../pyvdisk/storage/vfs/permissions.md | 72 - .../modules/pyvdisk/storage/vfs/query.md | 54 - .../modules/pyvdisk/storage/vfs/remove.md | 47 - .../modules/pyvdisk/storage/vfs/space.md | 71 - .../modules/pyvdisk/storage/vfs/stat.md | 72 - .../modules/pyvdisk/storage/vfs/vfile-ctx.md | 40 - .../modules/pyvdisk/storage/vfs/vfile-io.md | 99 - .../modules/pyvdisk/storage/vfs/vfile.md | 40 - .../modules/pyvdisk/storage/vfs/walk.md | 26 - .../modules/pyvdisk/storage/volume/blocks.md | 48 - .../modules/pyvdisk/storage/volume/bytes.md | 47 - .../modules/pyvdisk/storage/volume/create.md | 44 - .../modules/pyvdisk/storage/volume/index.md | 17 - .../modules/pyvdisk/storage/volume/layout.md | 90 - .../modules/pyvdisk/storage/volume/meta.md | 54 - .../modules/pyvdisk/storage/volume/model.md | 40 - .../modules/pyvdisk/storage/volume/open.md | 63 - .../modules/pyvdisk/storage/volume/repair.md | 54 - .../modules/pyvdisk/storage/wal/entries.md | 93 - .../modules/pyvdisk/storage/wal/index.md | 19 - .../modules/pyvdisk/storage/wal/journal.md | 57 - .../modules/pyvdisk/storage/wal/undo.md | 63 - .../modules/pyvdisk/tests/agent-sandbox.md | 28 - .../modules/pyvdisk/tests/agentic-cli.md | 33 - .../modules/pyvdisk/tests/api-governance.md | 33 - .../modules/pyvdisk/tests/atomic-save.md | 33 - .../modules/pyvdisk/tests/audit-trail.md | 37 - .../modules/pyvdisk/tests/cancellation.md | 33 - .../modules/pyvdisk/tests/checkpoint.md | 33 - .../modules/pyvdisk/tests/compat.md | 28 - .../modules/pyvdisk/tests/contracts.md | 33 - .../modules/pyvdisk/tests/crash-matrix.md | 34 - normify-pyvdisk/modules/pyvdisk/tests/e2e.md | 33 - .../pyvdisk/tests/exactly-once-internal.md | 33 - .../pyvdisk/tests/exactly-once-operation.md | 33 - .../modules/pyvdisk/tests/execution-queue.md | 33 - .../modules/pyvdisk/tests/execution.md | 33 - .../modules/pyvdisk/tests/fixtures.md | 24 - .../modules/pyvdisk/tests/fuse-mount.md | 37 - .../modules/pyvdisk/tests/governance.md | 33 - .../modules/pyvdisk/tests/index.md | 21 - .../modules/pyvdisk/tests/logdisk-compact.md | 33 - .../pyvdisk/tests/logdisk-retention.md | 33 - .../modules/pyvdisk/tests/no-dependency.md | 24 - .../modules/pyvdisk/tests/packaging.md | 28 - .../pyvdisk/tests/participant-compensation.md | 37 - .../modules/pyvdisk/tests/queue-backoff.md | 33 - .../pyvdisk/tests/queue-crossprocess.md | 33 - .../modules/pyvdisk/tests/queue.md | 33 - .../modules/pyvdisk/tests/submit-conflict.md | 33 - .../modules/pyvdisk/tests/tx-idempotency.md | 33 - .../modules/pyvdisk/tests/tx-rollback.md | 33 - .../modules/pyvdisk/tests/vdisk/base.md | 39 - .../modules/pyvdisk/tests/vdisk/cli.md | 30 - .../pyvdisk/tests/vdisk/disk-manager.md | 30 - .../modules/pyvdisk/tests/vdisk/exhaustion.md | 30 - .../modules/pyvdisk/tests/vdisk/identity.md | 30 - .../modules/pyvdisk/tests/vdisk/index.md | 18 - .../modules/pyvdisk/tests/vdisk/io.md | 48 - .../pyvdisk/tests/vdisk/large-files.md | 39 - .../modules/pyvdisk/tests/vdisk/links.md | 48 - .../modules/pyvdisk/tests/vdisk/locking.md | 39 - .../modules/pyvdisk/tests/vdisk/log.md | 30 - .../pyvdisk/tests/vdisk/maintenance.md | 48 - .../modules/pyvdisk/tests/vdisk/names.md | 48 - .../pyvdisk/tests/vdisk/permissions.md | 30 - .../modules/pyvdisk/tests/vdisk/raw-fs.md | 30 - .../modules/pyvdisk/tests/vdisk/vector.md | 30 - .../pyvdisk/tests/vdisk/volume-detect.md | 30 - .../pyvdisk/tests/vdisk/volume-meta.md | 48 - .../pyvdisk/tests/vdisk/volume-mirror.md | 30 - .../modules/pyvdisk/tests/vdisk/volume.md | 48 - .../modules/pyvdisk/tests/vscript-audit.md | 33 - .../modules/pyvdisk/tests/vscript-cron.md | 37 - .../modules/pyvdisk/tests/vscript-host.md | 33 - .../modules/pyvdisk/tests/vscript-optional.md | 33 - .../modules/pyvdisk/tests/vscript-triggers.md | 37 - .../modules/pyvdisk/tests/vscript-undo.md | 37 - .../modules/pyvdisk/tests/vscript.md | 51 - .../modules/pyvdisk/tests/wal-checkpoint.md | 37 - .../modules/pyvdisk/tests/wal-recovery.md | 33 - .../modules/pyvdisk/vscript/audit/clock.md | 39 - .../modules/pyvdisk/vscript/audit/hashing.md | 75 - .../modules/pyvdisk/vscript/audit/index.md | 18 - .../modules/pyvdisk/vscript/audit/query.md | 40 - .../modules/pyvdisk/vscript/audit/record.md | 39 - .../modules/pyvdisk/vscript/audit/sinks.md | 149 - .../modules/pyvdisk/vscript/cli/commands.md | 54 - .../modules/pyvdisk/vscript/cli/index.md | 18 - .../modules/pyvdisk/vscript/cli/parser.md | 30 - .../modules/pyvdisk/vscript/cli/repl.md | 63 - .../modules/pyvdisk/vscript/cron.md | 64 - .../modules/pyvdisk/vscript/frontend/ast.md | 96 - .../pyvdisk/vscript/frontend/errors.md | 98 - .../modules/pyvdisk/vscript/frontend/index.md | 20 - .../modules/pyvdisk/vscript/frontend/lexer.md | 70 - .../pyvdisk/vscript/frontend/parser.md | 48 - .../modules/pyvdisk/vscript/frontend/span.md | 57 - .../pyvdisk/vscript/frontend/tokens.md | 51 - .../modules/pyvdisk/vscript/host/guard.md | 78 - .../modules/pyvdisk/vscript/host/index.md | 19 - .../modules/pyvdisk/vscript/host/module.md | 36 - .../modules/pyvdisk/vscript/index.md | 52 - .../modules/pyvdisk/vscript/mounts.md | 79 - .../modules/pyvdisk/vscript/policy/budget.md | 61 - .../pyvdisk/vscript/policy/capability.md | 33 - .../modules/pyvdisk/vscript/policy/index.md | 16 - .../pyvdisk/vscript/runtime/callables.md | 66 - .../modules/pyvdisk/vscript/runtime/core.md | 86 - .../modules/pyvdisk/vscript/runtime/env.md | 84 - .../pyvdisk/vscript/runtime/expressions.md | 57 - .../modules/pyvdisk/vscript/runtime/index.md | 19 - .../pyvdisk/vscript/runtime/modules.md | 36 - .../pyvdisk/vscript/runtime/statements.md | 36 - .../modules/pyvdisk/vscript/runtime/tx.md | 75 - .../modules/pyvdisk/vscript/stdlib/factory.md | 41 - .../modules/pyvdisk/vscript/stdlib/guards.md | 39 - .../modules/pyvdisk/vscript/stdlib/index.md | 18 - .../modules/pyvdisk/vscript/stdlib/native.md | 81 - .../pyvdisk/vscript/triggers/daemon.md | 59 - .../modules/pyvdisk/vscript/triggers/index.md | 18 - .../pyvdisk/vscript/triggers/registry.md | 57 - .../modules/pyvdisk/vscript/undo.md | 103 - normify-pyvdisk/normify.html | 24761 ---------------- normify-pyvdisk/outline.md | 297 - normify-pyvdisk/policy.yml | 50 - normify-pyvdisk/receipt.json | 43 - normify-pyvdisk/renders/pyvdisk.json | 79 - normify-pyvdisk/renders/pyvdisk/agent.json | 42 - normify-pyvdisk/renders/pyvdisk/cli.json | 79 - normify-pyvdisk/renders/pyvdisk/compat.json | 13 - .../renders/pyvdisk/contracts.json | 46 - normify-pyvdisk/renders/pyvdisk/delivery.json | 14 - normify-pyvdisk/renders/pyvdisk/docs.json | 17 - normify-pyvdisk/renders/pyvdisk/examples.json | 14 - .../renders/pyvdisk/execution.json | 40 - .../renders/pyvdisk/execution/operations.json | 17 - .../renders/pyvdisk/execution/queue.json | 16 - .../renders/pyvdisk/execution/runstate.json | 13 - .../renders/pyvdisk/execution/service.json | 15 - .../renders/pyvdisk/governance.json | 15 - normify-pyvdisk/renders/pyvdisk/platform.json | 32 - normify-pyvdisk/renders/pyvdisk/storage.json | 88 - .../renders/pyvdisk/storage/block.json | 14 - .../renders/pyvdisk/storage/checkpoint.json | 14 - .../renders/pyvdisk/storage/datadisk.json | 55 - .../renders/pyvdisk/storage/driver.json | 16 - .../renders/pyvdisk/storage/fs.json | 97 - .../renders/pyvdisk/storage/fuse.json | 15 - .../renders/pyvdisk/storage/identity.json | 15 - .../renders/pyvdisk/storage/log.json | 17 - .../renders/pyvdisk/storage/logging.json | 16 - .../renders/pyvdisk/storage/rwlock.json | 13 - .../renders/pyvdisk/storage/vector.json | 18 - .../renders/pyvdisk/storage/vfs.json | 74 - .../renders/pyvdisk/storage/volume.json | 19 - .../renders/pyvdisk/storage/wal.json | 14 - normify-pyvdisk/renders/pyvdisk/tests.json | 156 - .../renders/pyvdisk/tests/vdisk.json | 31 - normify-pyvdisk/renders/pyvdisk/vscript.json | 82 - .../renders/pyvdisk/vscript/audit.json | 16 - .../renders/pyvdisk/vscript/cli.json | 14 - .../renders/pyvdisk/vscript/frontend.json | 17 - .../renders/pyvdisk/vscript/host.json | 13 - .../renders/pyvdisk/vscript/policy.json | 13 - .../renders/pyvdisk/vscript/runtime.json | 18 - .../renders/pyvdisk/vscript/stdlib.json | 14 - .../renders/pyvdisk/vscript/triggers.json | 13 - normify-pyvdisk/tree.json | 23006 -------------- 343 files changed, 9 insertions(+), 64182 deletions(-) delete mode 100644 normify-pyvdisk/api-index.json delete mode 100644 normify-pyvdisk/changes/2026-09-24-compat-describe-live-impl.json delete mode 100644 normify-pyvdisk/changes/2026-09-24-readme-agent-demo-fix.json delete mode 100644 normify-pyvdisk/changes/2026-09-24-readme-counts.json delete mode 100644 normify-pyvdisk/changes/2026-09-24-resync-issue1-fixes.json delete mode 100644 normify-pyvdisk/changes/2026-09-24-zero-dep-windows-agentsandbox.json delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/audit.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/paths.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/sandbox.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/script.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/agent/tools.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/api.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/admin.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/dirs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/drive.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/entry.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/file-ops.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/format.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/image.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/inspect.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/log.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/main.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/parser.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/vector.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/cli/volume.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/compat/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/compat/unified.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/compat/vscript.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/capability.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/durability.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/events.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/execution.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/plane.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/runhandle.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/contracts/storage.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/delivery/ci.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/delivery/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/delivery/lint.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/delivery/packaging.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/api-governance.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/architecture.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/changelog.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/contracts.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/readme.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/docs/vscript-spec.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/examples/agent-tools.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/examples/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/examples/quickstart.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/callables.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/describe.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/errors.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/record.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/registry.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/operations/storage.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/errors.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/lifecycle.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/recovery.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/store.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/queue/task.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/runstate/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/runstate/model.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/runstate/store.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/service/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/service/invoke.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/service/queue.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/service/setup.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/execution/service/submit.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/governance/data.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/governance/files.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/governance/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/governance/namespace.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/governance/scoped.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/platform/dispatch.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/platform/durability.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/platform/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/platform/locking.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/platform/positional.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/block/access.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/block/image.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/block/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/block/io.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/checkpoint/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/checkpoint/io.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/checkpoint/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/checkpoint/triggers.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/api.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/codec.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/core.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/namespace.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/services.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/tx-lifecycle.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/datadisk/tx.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/assembled.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/lifecycle.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/manager.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/mounting.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/driver/mounts.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/attrs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/bitmap.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/block-alloc.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/create.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/dir-mutate.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/dir.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/fsck.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/grow.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/inode-io.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/inode.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/layout.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/locking.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/mkfs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/mount.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/mutate.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/names.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/paths.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/pointers.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/query.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/readwrite.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/stat.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/superblock.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fs/truncate.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fuse/data.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fuse/handlers.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fuse/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fuse/meta.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/fuse/mount.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/identity/format.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/identity/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/identity/model.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/identity/probe.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/identity/trailer.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/append.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/filter.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/query.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/retention.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/log/streams.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/bridge.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/context.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/events.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/logger.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/logging/sinks.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/rwlock/core.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/rwlock/ctx.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/rwlock/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/collections.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/flat-index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/records.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vector/search.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/attrs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/create.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/dirs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/files.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/hostio.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/lifetime.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/permissions.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/query.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/remove.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/space.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/stat.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/vfile-ctx.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/vfile-io.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/vfile.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/vfs/walk.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/blocks.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/bytes.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/create.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/layout.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/meta.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/model.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/open.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/volume/repair.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/wal/entries.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/wal/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/wal/journal.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/storage/wal/undo.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/agent-sandbox.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/agentic-cli.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/api-governance.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/atomic-save.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/audit-trail.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/cancellation.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/checkpoint.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/compat.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/contracts.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/crash-matrix.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/e2e.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/exactly-once-internal.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/exactly-once-operation.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/execution-queue.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/execution.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/fixtures.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/fuse-mount.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/governance.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/logdisk-compact.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/logdisk-retention.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/no-dependency.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/packaging.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/participant-compensation.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/queue-backoff.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/queue-crossprocess.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/queue.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/submit-conflict.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/tx-idempotency.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/tx-rollback.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/base.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/cli.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/disk-manager.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/exhaustion.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/identity.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/io.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/large-files.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/links.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/locking.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/log.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/maintenance.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/names.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/permissions.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/raw-fs.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/vector.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/volume-detect.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/volume-meta.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/volume-mirror.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vdisk/volume.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-audit.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-cron.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-host.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-optional.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-triggers.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript-undo.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/vscript.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/wal-checkpoint.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/tests/wal-recovery.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/clock.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/hashing.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/query.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/record.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/audit/sinks.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/cli/commands.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/cli/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/cli/parser.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/cli/repl.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/cron.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/ast.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/errors.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/lexer.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/parser.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/span.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/frontend/tokens.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/host/guard.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/host/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/host/module.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/mounts.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/policy/budget.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/policy/capability.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/policy/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/callables.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/core.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/env.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/expressions.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/modules.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/statements.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/runtime/tx.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/stdlib/factory.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/stdlib/guards.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/stdlib/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/stdlib/native.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/triggers/daemon.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/triggers/index.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/triggers/registry.md delete mode 100644 normify-pyvdisk/modules/pyvdisk/vscript/undo.md delete mode 100644 normify-pyvdisk/normify.html delete mode 100644 normify-pyvdisk/outline.md delete mode 100644 normify-pyvdisk/policy.yml delete mode 100644 normify-pyvdisk/receipt.json delete mode 100644 normify-pyvdisk/renders/pyvdisk.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/agent.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/cli.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/compat.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/contracts.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/delivery.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/docs.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/examples.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/execution.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/execution/operations.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/execution/queue.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/execution/runstate.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/execution/service.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/governance.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/platform.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/block.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/checkpoint.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/datadisk.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/driver.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/fs.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/fuse.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/identity.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/log.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/logging.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/rwlock.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/vector.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/vfs.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/volume.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/storage/wal.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/tests.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/tests/vdisk.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/audit.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/cli.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/frontend.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/host.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/policy.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/runtime.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/stdlib.json delete mode 100644 normify-pyvdisk/renders/pyvdisk/vscript/triggers.json delete mode 100644 normify-pyvdisk/tree.json diff --git a/README.md b/README.md index 19f9790..0ed9da8 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行 ## 架构图谱 -**▶ [打开可交互架构图谱](https://htmlpreview.github.io/?https://github.com/HeDaas-Code/pyvdisk/blob/master/normify-pyvdisk/normify.html)** — 点击模块逐层下钻、悬停查看中英双语介绍、`?lang=en` 切换英文、`#module=` 深链直达具体模块。 +**▶ [打开可交互架构图谱](https://htmlpreview.github.io/?https://github.com/HeDaas-Code/pyvdisk/blob/normify/normify-pyvdisk/normify.html)** — 点击模块逐层下钻、悬停查看中英双语介绍、`?lang=en` 切换英文、`#module=` 深链直达具体模块。 -> GitHub 会过滤 README 中的 ` - - - diff --git a/normify-pyvdisk/outline.md b/normify-pyvdisk/outline.md deleted file mode 100644 index 6f05b7d..0000000 --- a/normify-pyvdisk/outline.md +++ /dev/null @@ -1,297 +0,0 @@ -# normify-pyvdisk · Normify Outline - -> 派生索引(每次 normify_build 重建)。AI 导航入口:先广度后深度。 - -## pyvdisk(https://github.com/HeDaas-Code/pyvdisk) - -- pyvdisk — PyVDisk / PyVDisk — 单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作… — [模块 290 · API 844] - - pyvdisk.agent — Agent 工作区 / Agent Workspace — 把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 d… — [模块 6 · API 21] - - pyvdisk.agent.audit — 工具调用审计 / Tool Call Audit — 每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。"模型是不是读了不该读的路径"这个问题,事… — [模块 1 · API 4] - - pyvdisk.agent.paths — 路径约束 / Path Confinement — 沙箱内"路径意味着什么"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见… — [模块 1 · API 3] - - pyvdisk.agent.sandbox — 沙箱门面 / Sandbox Facade — 门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及… — [模块 1 · API 8] - - pyvdisk.agent.script — 盘内脚本 / Sandboxed Scripts — 盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glo… — [模块 1 · API 2] - - pyvdisk.agent.tools — 工具面 / Tool Surface — 六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面… — [模块 1 · API 4] - - pyvdisk.api — 公开门面 / Public Facade — 公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。 — [模块 1 · API 11] - - pyvdisk.cli — 命令行 / Command Line — 命令行界面:参数解析以及文件系统、卷、驱动器、向量、日志与状态检查子命令。 — [模块 15 · API 59] - - pyvdisk.cli.admin — 管理子命令 / Admin Subcommands — 管理类子命令:格式化、链接、属性、空间统计、fsck 与扩容。 — [模块 1 · API 8] - - pyvdisk.cli.dirs — 目录子命令 / Directory Subcommands — 目录与删除子命令,语义与对应文件系统操作一致。 — [模块 1 · API 4] - - pyvdisk.cli.drive — 驱动器子命令 / Drive Subcommands — 模拟驱动器子命令:scan、mount-all 与卷标管理。 — [模块 1 · API 3] - - pyvdisk.cli.entry — 模块入口 / Module Entry — 让包可直接执行的 4 行模块入口。 — [模块 1 · API 1] - - pyvdisk.cli.file-ops — 文件子命令 / File Subcommands — 整文件子命令:write、append、copy、move 与宿主导入导出。 — [模块 1 · API 6] - - pyvdisk.cli.format — CLI 格式化 / CLI Formatting — 各子命令共用的 CLI 格式化与解析辅助。 — [模块 1 · API 4] - - pyvdisk.cli.image — 镜像子命令 / Image Subcommands — 镜像生命周期与检查子命令:create、info、status 与列举。 — [模块 1 · API 4] - - pyvdisk.cli.inspect — 检查子命令 / Inspection Subcommands — 检查与挂载子命令:stat、tree、mount 与 touch。 — [模块 1 · API 4] - - pyvdisk.cli.log — 日志子命令 / Log Subcommands — 日志盘子命令:流管理、写入、查询、tail、统计、压缩与保留策略。 — [模块 1 · API 8] - - pyvdisk.cli.main — CLI 入口 / CLI Entry Point — CLI 入口:把错误映射为退出码,以及 python -m pyvdisk 钩子。 — [模块 1 · API 1] - - pyvdisk.cli.open — CLI 打开 VFS / CLI VFS Open — 每个文件系统子命令获取已挂载 VFS 的唯一入口。 — [模块 1 · API 1] - - pyvdisk.cli.parser — 参数解析器 / Argument Parser — 参数解析器定义:全部子命令、各自选项与共享的镜像参数组。 — [模块 1 · API 1] - - pyvdisk.cli.vector — 向量子命令 / Vector Subcommands — 向量盘子命令:磁盘与集合管理,以及记录 upsert、检索与获取。 — [模块 1 · API 8] - - pyvdisk.cli.volume — 卷子命令 / Volume Subcommands — 卷子命令:创建、状态与在线镜像维护。 — [模块 1 · API 6] - - pyvdisk.compat — 兼容垫片 / Compatibility Shims — 向后兼容垫片:保留旧的 Unified/Container 名称与遗留 vscript.checkpoint 导入路径。 — [模块 3 · API 3] - - pyvdisk.compat.unified — Unified 别名 / Unified Aliases — 兼容重导出:保留容器化之前的 DataDisk 与 MetadataTransaction 导入路径。 — [模块 1 · API 2] - - pyvdisk.compat.vscript — VScript 检查点垫片 / VScript Checkpoint Shim — 遗留垫片:在存储移入 infrastructure 后仍保留 vscript.checkpoint 模块路径可导入。 — [模块 1 · API 1] - - pyvdisk.contracts — 后端契约 / Backend Contracts — 存储与执行平面的后端中立契约:能力、持久性、块/命名空间/集合/事件存储,以及执行平面协议。 — [模块 8 · API 24] - - pyvdisk.contracts.capability — 能力授权 / Capability Grant — Capability 枚举与 CapabilityGrant:治理层、执行上下文与 VScript 共用的权限词表。 — [模块 1 · API 4] - - pyvdisk.contracts.durability — 持久性 / Durability — 持久性请求词表:后端可以提供强于请求的保证。 — [模块 1 · API 2] - - pyvdisk.contracts.events — 事件契约 / Event Contracts — 事件值类型,以及结构化日志使用的追加/读取事件存储协议。 — [模块 1 · API 4] - - pyvdisk.contracts.execution — 执行上下文 / Execution Context — ExecutionContext:交给单次二层执行的依赖与策略信封。 — [模块 1 · API 3] - - pyvdisk.contracts.plane — 执行平面协议 / Execution Plane — ExecutionPlane 协议:每个执行后端都必须暴露的唯一 submit 入口。 — [模块 1 · API 1] - - pyvdisk.contracts.runhandle — 运行句柄 / Run Handle — RunHandle:执行平面返回的可观察、可取消句柄;取消不会覆盖终态。 — [模块 1 · API 5] - - pyvdisk.contracts.storage — 存储协议 / Storage Protocols — 结构化存储协议:BlockDevice、NamespaceStore、CollectionStore;既有后端以结构化方式满足它们。 — [模块 1 · API 5] - - pyvdisk.delivery — 打包与持续集成 / Packaging and CI — 分发与持续集成:打包元数据、PEP 561 类型标记与 GitHub Actions 工作流。 — [模块 4 · API 6] - - pyvdisk.delivery.ci — 测试工作流 / Test Workflow — CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 … — [模块 1 · API 2] - - pyvdisk.delivery.lint — 静态分析工作流 / Lint Workflow — 独立于单元测试门禁的静态分析流水线:pylint 只保留 error 类,使 Lint 失败不会被误认为测试失败。 — [模块 1 · API 1] - - pyvdisk.delivery.packaging — 打包元数据 / Packaging Metadata — 分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICEN… — [模块 1 · API 3] - - pyvdisk.docs — 技术文档 / Technical Docs — 仓库技术文档层:架构设计、契约边界、API 治理与 VScript 语言规范,是模块结构的一手证据来源。 — [模块 7 · API 6] - - pyvdisk.docs.api-governance — API 治理 / API Governance — API 治理:公开入口、权限模型、已废弃的旧路径,以及推荐给 Agent 使用的接口面。 — [模块 1 · API 1] - - pyvdisk.docs.architecture — 架构设计 / Architecture Design — 架构设计:存储平面、执行平面、单盘 ACID、内部 exactly-once、解释器架构与故障恢复流程。 — [模块 1 · API 1] - - pyvdisk.docs.changelog — 变更日志 / Changelog — 用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留"已知未完成"一节,未完成项要看得见,而不是被静… — [模块 1 · API 1] - - pyvdisk.docs.contracts — 契约边界 / Contract Boundaries — 各平面的保证边界:存储、执行、事务与内部 exactly-once 承诺什么、不承诺什么;新增 VScript 事务的撤销记账、本地触发器与审计轨迹三节。 — [模块 1 · API 1] - - pyvdisk.docs.readme — 项目总览 / Project Overview — README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一… — [模块 1 · API 1] - - pyvdisk.docs.vscript-spec — VScript 规范 / VScript Spec — VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。 — [模块 1 · API 1] - - pyvdisk.examples — 可运行示例 / Runnable Examples — 可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。 — [模块 3 · API 2] - - pyvdisk.examples.agent-tools — Agent 对接示例 / Agent Loop Demo — 带脚本化"模型"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,… — [模块 1 · API 1] - - pyvdisk.examples.quickstart — 快速上手 / Quickstart Tour — 单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏… — [模块 1 · API 1] - - pyvdisk.execution — 执行平面 / Execution Plane — 执行平面:同步 ExecutionService、持久任务队列、持久化运行状态与操作注册表。 — [模块 22 · API 72] - - pyvdisk.execution.operations — 操作注册表 / Operation Registry — 操作注册表:稳定 operation id、负载指纹、持久化结果、可调用对象解析与 VScript 操作描述。 — [模块 7 · API 24] - - pyvdisk.execution.operations.callables — 可调用对象注册表 / Callable Registry — 可调用对象注册表,以及把 Python 函数变为可持久重放操作的 RegisteredCallable 包装。 — [模块 1 · API 4] - - pyvdisk.execution.operations.describe — 操作描述 / Operation Description — 操作描述:把可调用对象、VScript 源码与裸负载归一为可序列化形态并生成稳定 id。 — [模块 1 · API 4] - - pyvdisk.execution.operations.errors — 操作错误 / Operation Errors — 操作注册表错误体系:未知操作与不可序列化操作。 — [模块 1 · API 3] - - pyvdisk.execution.operations.record — 操作记录 / Operation Record — 存储的操作描述及其 JSON 编解码,是稳定 operation id 与幂等性的基础。 — [模块 1 · API 3] - - pyvdisk.execution.operations.registry — 操作注册表 / Operation Registry — 操作注册表门面:存在判定、加载、结果恢复、保存与删除,背衬可为检查点或宿主目录。 — [模块 1 · API 7] - - pyvdisk.execution.operations.storage — 注册表存储 / Registry Storage — 背衬访问与可调用对象解析,注册表的最底层。 — [模块 1 · API 3] - - pyvdisk.execution.queue — 持久任务队列 / Durable Queue — DurableQueue:以检查点为背衬的任务队列,支持 claim、lease、心跳、退避重试、死信、取消与过期回收。 — [模块 6 · API 23] - - pyvdisk.execution.queue.errors — 队列错误 / Queue Errors — 队列错误体系:任务缺失、非法状态迁移与租约丢失。 — [模块 1 · API 4] - - pyvdisk.execution.queue.lifecycle — 任务生命周期 / Task Lifecycle — 任务生命周期:入队、带租约领取、心跳、完成、失败、重试、死信与取消。 — [模块 1 · API 8] - - pyvdisk.execution.queue.recovery — 队列恢复 / Queue Recovery — 可观测性与崩溃恢复:过期租约回收,以及任务查询与列举。 — [模块 1 · API 3] - - pyvdisk.execution.queue.store — 队列存储 / Queue Store — 队列存储层:经检查点存储的状态读写,以及重试退避策略。 — [模块 1 · API 6] - - pyvdisk.execution.queue.task — 队列任务 / Queue Task — 队列状态中存储的任务值对象,含租约与尝试次数记账。 — [模块 1 · API 2] - - pyvdisk.execution.runstate — 运行状态 / Run State Store — RunStateStore:带版本号的运行记录,受保护的状态转换与过期运行回收,经检查点存储持久化。 — [模块 3 · API 10] - - pyvdisk.execution.runstate.model — 运行记录 / Run Record — 运行记录模型,以及受保护状态迁移使用的乐观并发冲突类型。 — [模块 1 · API 3] - - pyvdisk.execution.runstate.store — 运行状态存储 / Run State Store — 运行状态存储:带幂等的创建、受保护状态迁移、列举与过期运行回收。 — [模块 1 · API 7] - - pyvdisk.execution.service — 执行服务 / Execution Service — ExecutionService:以 inline 或可选 worker 方式执行 Python 可调用对象与 VScript 源码,绑定 DataDisk、队… — [模块 5 · API 15] - - pyvdisk.execution.service.invoke — 操作分发 / Operation Dispatch — 操作分发:受限视图构造与两种执行类型,即 Python 可调用对象与 VScript 源码。 — [模块 1 · API 4] - - pyvdisk.execution.service.queue — 队列驱动执行 / Queue-Driven Run — 队列驱动的执行:带去重的操作入队,以及带租约处理的领取-运行循环。 — [模块 1 · API 3] - - pyvdisk.execution.service.setup — 服务初始化 / Service Setup — ExecutionService 构造与 worker 池控制:同步内联执行与后台处理之间的边界。 — [模块 1 · API 5] - - pyvdisk.execution.service.submit — 提交与取消 / Submit and Cancel — ExecutionPlane 协议的实现:submit、阻塞式 run 与取消。 — [模块 1 · API 3] - - pyvdisk.governance — 能力治理 / Capability Governance — 能力治理:路径归一化、受保护命名空间适配器,以及交给不可信调用方的 ScopedDataDisk。 — [模块 5 · API 26] - - pyvdisk.governance.data — 受限数据服务 / Scoped Data Services — 能力治理的向量与日志半边:按集合与流划分范围,区分读、写、追加与 admin 权限。 — [模块 1 · API 8] - - pyvdisk.governance.files — 受限文件系统 / Scoped Filesystem — 能力治理的文件系统半边:每个 VFS 方法都必须经过权限与范围检查才能触达。 — [模块 1 · API 8] - - pyvdisk.governance.namespace — 能力门禁 / Capability Gate — 能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。 — [模块 1 · API 5] - - pyvdisk.governance.scoped — 受限容器 / Scoped Container — 检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。 — [模块 1 · API 5] - - pyvdisk.platform — 平台适配层 / Platform Adaptation — 唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份… — [模块 5 · API 13] - - pyvdisk.platform.dispatch — 实现选择 / Implementation Dispatch — 决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linu… — [模块 1 · API 3] - - pyvdisk.platform.durability — 持久化与身份 / Durability and Identity — 其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。 — [模块 1 · API 6] - - pyvdisk.platform.locking — 跨进程文件锁 / Cross-Process Locking — 跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLC… — [模块 1 · API 2] - - pyvdisk.platform.positional — 定位读写 / Positioned IO — 不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。 — [模块 1 · API 2] - - pyvdisk.storage — 存储平面 / Storage Plane — 存储平面:块镜像、磁盘身份、盘上文件系统、高层 VFS、多盘卷、向量盘与日志盘、结构化日志、模拟驱动器、可选 FUSE 挂载、统一 DataDisk 容器、WA… — [模块 109 · API 384] - - pyvdisk.storage.block — 块镜像 / Block Image — 块级镜像 IO:把一个 .vdisk 文件当作块设备,使用 os.pread/os.pwrite 与 POSIX advisory 写锁。 — [模块 4 · API 12] - - pyvdisk.storage.block.access — 块访问 / Block Access — 已打开镜像上的块级与字节级访问:块读写、裸字节区间与镜像扩缩。 — [模块 1 · API 5] - - pyvdisk.storage.block.image — 镜像生命周期 / Image Lifecycle — VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而… — [模块 1 · API 5] - - pyvdisk.storage.block.io — 定位 IO 原语 / Positional IO — 无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。 — [模块 1 · API 2] - - pyvdisk.storage.checkpoint — 检查点存储 / Checkpoint Store — 检查点存储:以 VFS 路径或宿主目录为背衬的持久键值进度与结果记录,带跨进程锁与原子落盘。 — [模块 4 · API 11] - - pyvdisk.storage.checkpoint.io — 检查点 IO / Checkpoint IO — 检查点 IO:键值记录映射的加载、读取、暂存与原子保存。 — [模块 1 · API 4] - - pyvdisk.storage.checkpoint.open — 检查点存储 / Checkpoint Store — 检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在… — [模块 1 · API 5] - - pyvdisk.storage.checkpoint.triggers — 触发器检查点 / Trigger Checkpoints — 面向触发器的便利层,为调度器提供持久的事件去重保证。 — [模块 1 · API 2] - - pyvdisk.storage.datadisk — DataDisk 容器 / DataDisk Container — 统一 DataDisk 容器:一个挂载的 VFS 加上 FS/向量/日志命名空间服务,带撤销日志的元数据事务、WAL 与重挂载恢复。 — [模块 8 · API 39] - - pyvdisk.storage.datadisk.api — DataDisk 接口 / DataDisk Interface — 容器生命周期与面向调用方的接口:挂载、manifest、事务、元数据访问与能力受限视图。 — [模块 1 · API 8] - - pyvdisk.storage.datadisk.codec — 元数据编解码 / Metadata Codec — DataDisk 的值编码与错误词表,供事务、manifest 与命名空间层共用。 — [模块 1 · API 5] - - pyvdisk.storage.datadisk.core — DataDisk 核心 / DataDisk Core — DataDisk 构造、元数据原子持久化,以及挂载时的 WAL 重放与恢复报告。 — [模块 1 · API 6] - - pyvdisk.storage.datadisk.namespace — 文件系统命名空间 / Filesystem Namespace — 事务性文件系统命名空间:读方法透传给 VFS,而每次变更都登记撤销意图。 — [模块 1 · API 8] - - pyvdisk.storage.datadisk.services — 服务命名空间 / Service Namespaces — 向量与日志命名空间:透传到各自磁盘,同时作为一等事务参与者。 — [模块 1 · API 2] - - pyvdisk.storage.datadisk.tx — 元数据事务 / Metadata Transaction — 元数据事务核心:参与者协议、暂存写入,以及使命名空间变更可回滚的撤销日志。 — [模块 1 · API 6] - - pyvdisk.storage.datadisk.tx-lifecycle — 事务结局 / Transaction Outcome — 事务的完整结局:进入、经 WAL 的持久提交、带撤销的回滚,以及异常驱动的自动回滚。abort 现在先把 intent 落盘,再按逆序在进程内通知每个已登记的 … — [模块 1 · API 4] - - pyvdisk.storage.driver — 模拟驱动器 / Drive Manager — 模拟驱动器:扫描宿主目录、按尾标识别盘、组装卷并按卷标挂载。 — [模块 6 · API 27] - - pyvdisk.storage.driver.assembled — 卷组装 / Volume Assembly — 单个卷的组装结果:找到哪些成员以及必须按何顺序打开。 — [模块 1 · API 5] - - pyvdisk.storage.driver.lifecycle — 卸载与热插拔 / Unmount and Hotplug — 模拟驱动器的卸载、热插拔重扫与诊断汇总。 — [模块 1 · API 4] - - pyvdisk.storage.driver.manager — 磁盘管理器 / Disk Manager — 驱动器扫描与组装:识别宿主目录中的介质及其成员如何聚合成卷。 — [模块 1 · API 5] - - pyvdisk.storage.driver.mounting — 挂载分发 / Mount Dispatch — 挂载分发:每类介质一条路径,以及 CLI 使用的整体挂载与卷标查询。 — [模块 1 · API 7] - - pyvdisk.storage.driver.mounts — 挂载介质 / Mounted Media — 日志盘、向量盘与文件系统介质的统一挂载包装,使驱动器可统一处理。 — [模块 1 · API 6] - - pyvdisk.storage.fs — 文件系统 / Filesystem — 盘上文件系统:超级块、inode 表、位图、间接块指针、目录、路径解析、fsck 与在线扩容。 — [模块 24 · API 82] - - pyvdisk.storage.fs.attrs — 属性与链接 / Attributes and Links — 属性与链接:硬链接、模式、属主、时间戳,以及 VFS 使用的权限检查。 — [模块 1 · API 5] - - pyvdisk.storage.fs.bitmap — 位图分配 / Bitmap Allocation — inode 与数据块分配共用的位图原语。 — [模块 1 · API 3] - - pyvdisk.storage.fs.block-alloc — 块分配器 / Block Allocator — 建立在块位图之上的数据块分配器。 — [模块 1 · API 2] - - pyvdisk.storage.fs.create — 创建节点 / Node Creation — 节点创建:文件、目录、符号链接及其共享构造器。 — [模块 1 · API 5] - - pyvdisk.storage.fs.dir — 目录读取 / Directory Read — 目录读取路径:目录项解码、列举与按名查找。 — [模块 1 · API 3] - - pyvdisk.storage.fs.dir-mutate — 目录写入 / Directory Write — 目录写入路径:槽位查找、目录项插入与删除。 — [模块 1 · API 3] - - pyvdisk.storage.fs.fsck — 一致性检查 / Filesystem Check — 一致性检查器:校验超级块、交叉核对 inode 与块位图、链接数与目录项,并支持修复模式。 — [模块 1 · API 2] - - pyvdisk.storage.fs.grow — 在线扩容 / Online Grow — 在线扩容:扩大底层镜像并重写超级块几何。 — [模块 1 · API 1] - - pyvdisk.storage.fs.inode — Inode / Inode — inode 结构及其二进制编解码与空节点工厂。 — [模块 1 · API 4] - - pyvdisk.storage.fs.inode-io — Inode 表 IO / Inode Table IO — inode 表 IO:128 字节 inode 记录的分配、释放与定位读写。 — [模块 1 · API 5] - - pyvdisk.storage.fs.layout — 盘上布局 / On-Disk Layout — 盘上布局常量:魔数、版本、inode 与目录项几何,以及推导出的文件尺寸上限。 — [模块 1 · API 5] - - pyvdisk.storage.fs.locking — FS 加锁 / FS Locking — 逐方法读写加锁,以及让同一镜像上的多个 FS 实例互斥的跨实例锁注册表。 — [模块 1 · API 4] - - pyvdisk.storage.fs.mkfs — 格式化 / Format — 格式化:构建带保留区的空文件系统,并写入磁盘身份尾标;身份写入不可用时不影响格式化。 — [模块 1 · API 1] - - pyvdisk.storage.fs.mount — 挂载 / Mount — FS 构造、挂载时超级块校验与超级块持久化。 — [模块 1 · API 3] - - pyvdisk.storage.fs.mutate — 删除与重命名 / Delete and Rename — 删除与重命名:unlink、rmdir、节点解绑与目标替换。 — [模块 1 · API 4] - - pyvdisk.storage.fs.names — 名字编解码 / Name Codec — 目录槽位名编解码,以及跨文件系统接口使用的 FSError。 — [模块 1 · API 4] - - pyvdisk.storage.fs.paths — 路径解析 / Path Resolution — 路径解析:分量拆分、带深度上限的符号链接感知查找,以及创建所需的父目录解析。 — [模块 1 · API 3] - - pyvdisk.storage.fs.pointers — 块指针 / Block Pointers — 直接与间接块指针树:解析、扩展与回收 inode 的块映射。 — [模块 1 · API 5] - - pyvdisk.storage.fs.query — 状态与空间查询 / Stat and Space Queries — 只读查询:stat 变体、空闲对象计数,以及 df/du 使用的 statfs 汇总。 — [模块 1 · API 6] - - pyvdisk.storage.fs.readwrite — 文件读写 / File Read and Write — 文件数据路径:定位读取、追加、覆盖与按需分配块的偏移写入。 — [模块 1 · API 4] - - pyvdisk.storage.fs.stat — Stat 视图 / Stat View — stat 结果对象及类型判定,供 VFS、FUSE 与 CLI 使用。 — [模块 1 · API 4] - - pyvdisk.storage.fs.superblock — 超级块 / Superblock — 超级块结构及其二进制编解码;镜像上所有区域偏移的唯一事实来源。 — [模块 1 · API 3] - - pyvdisk.storage.fs.truncate — 截断 / Truncate — 截断操作及其后续的间接块清理。 — [模块 1 · API 3] - - pyvdisk.storage.fuse — FUSE 挂载 / FUSE Mount — 可选 FUSE 挂载:把 VFS 暴露为宿主目录;缺少 fusepy 时给出清晰的 ImportError。 — [模块 5 · API 20] - - pyvdisk.storage.fuse.data — FUSE 数据处理 / FUSE Data Ops — FUSE 数据与命名空间变更:read、write、create、mkdir、rmdir、unlink 与 rename 处理。 — [模块 1 · API 7] - - pyvdisk.storage.fuse.handlers — FUSE 链接处理 / FUSE Link Ops — 其余 FUSE 处理:truncate、链接、open/release、chmod,以及动态 Operations 子类装配。readlink 以不追随后一段的… — [模块 1 · API 7] - - pyvdisk.storage.fuse.meta — FUSE 属性 / FUSE Attributes — stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与"平台没… — [模块 1 · API 4] - - pyvdisk.storage.fuse.mount — FUSE 挂载入口 / FUSE Mount Entry — 公开挂载入口,包含容忍忙挂载的 main 循环补丁与线程化变体。 — [模块 1 · API 2] - - pyvdisk.storage.identity — 磁盘身份 / Disk Identity — 磁盘身份:block 0 末尾的 112 字节 VDID 尾标,让每块 .vdisk 不依赖路径即可被识别。 — [模块 5 · API 12] - - pyvdisk.storage.identity.format — 身份格式 / Identity Format — 尾标布局常量、.vdisk 后缀规则与身份错误类型。 — [模块 1 · API 3] - - pyvdisk.storage.identity.model — 身份模型 / Identity Model — DiskIdentity 值对象及其类型判定与简短展示形式。 — [模块 1 · API 4] - - pyvdisk.storage.identity.probe — 身份探测 / Identity Probe — 身份 IO:写尾标、不挂载即探测盘文件,以及 UUID 生成。 — [模块 1 · API 3] - - pyvdisk.storage.identity.trailer — 尾标编解码 / Trailer Codec — 身份尾标的二进制编解码:定长 112 字节布局的打包与解析。 — [模块 1 · API 2] - - pyvdisk.storage.log — 日志盘 / Log Disk — 日志盘:分段事件流,带序号、游标、ack、replay、保留策略与压缩。 — [模块 7 · API 22] - - pyvdisk.storage.log.append — 日志追加 / Log Append — 事件摄入:单条与批量追加,自动分段。 — [模块 1 · API 2] - - pyvdisk.storage.log.filter — 日志过滤 / Log Filtering — 日志记录值过滤与规范 JSON 编码,供追加与查询共用。 — [模块 1 · API 3] - - pyvdisk.storage.log.open — 日志盘打开 / Log Disk Open — LogDisk 生命周期及日志命名空间下按流的 JSON 辅助。 — [模块 1 · API 4] - - pyvdisk.storage.log.query — 日志查询 / Log Query — 日志盘读取侧:带过滤查询、消费端游标、ack、replay、计数、tail 与实时 follow。 — [模块 1 · API 7] - - pyvdisk.storage.log.retention — 保留与压缩 / Retention and Compaction — 日志盘的存储治理:保留策略执行、压缩与统计。保留如今同时清理被删事件的 event_ids 并校验消费者游标,不再留下指向已裁剪位置的游标。 — [模块 1 · API 3] - - pyvdisk.storage.log.streams — 日志流 / Log Streams — 流目录:带保留策略的创建、列举与删除。 — [模块 1 · API 3] - - pyvdisk.storage.logging — 结构化日志 / Structured Logging — 结构化日志核心:级别归一、LogEvent、上下文绑定、可插拔 sink、UnifiedLogger 与标准库 logging 桥接。 — [模块 6 · API 18] - - pyvdisk.storage.logging.bridge — 日志桥接 / Logging Bridge — 与标准库 logging 模块的桥接,以及模块级日志器工厂。 — [模块 1 · API 2] - - pyvdisk.storage.logging.context — 日志上下文 / Log Context — 基于 contextvar 的环境字段,会合入每个产出的事件。 — [模块 1 · API 3] - - pyvdisk.storage.logging.events — 日志事件 / Log Events — 结构化事件值类型及其级别归一与 JSON 转换。 — [模块 1 · API 4] - - pyvdisk.storage.logging.logger — 统一日志器 / Unified Logger — UnifiedLogger:级别门限、上下文与字段合并、标签绑定与异常捕获。 — [模块 1 · API 5] - - pyvdisk.storage.logging.sinks — 日志 Sink / Log Sinks — sink 协议及其三种实现:内存、流与日志盘持久化。 — [模块 1 · API 4] - - pyvdisk.storage.rwlock — 读写锁 / Read-Write Lock — 可重入、写者优先的读写锁,供同一镜像上并发打开的多个 FS 实例共享。 — [模块 3 · API 9] - - pyvdisk.storage.rwlock.core — 锁核心 / Lock Core — 锁核心:每线程重入、写者优先,以及仅限唯一读者时的读锁升级。 — [模块 1 · API 5] - - pyvdisk.storage.rwlock.ctx — 锁上下文 / Lock Contexts — 供 FS 锁装饰器与 VFS/FS 公开接口使用的 with 语句辅助类型。 — [模块 1 · API 4] - - pyvdisk.storage.vector — 向量盘 / Vector Disk — 向量盘:基于 HNSW 的具名记录集合,带 generation、checksum、过滤器与相似度检索。 — [模块 6 · API 23] - - pyvdisk.storage.vector.collections — 集合目录 / Collections — 集合目录:按维度与度量创建、带配置列举,以及连同每集合 HNSW 索引一起删除。 — [模块 1 · API 3] - - pyvdisk.storage.vector.flat-index — 扁平索引后端 / Flat Index Backend — 纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集… — [模块 1 · API 7] - - pyvdisk.storage.vector.open — 向量盘打开 / Vector Disk Open — VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。 — [模块 1 · API 5] - - pyvdisk.storage.vector.records — 向量记录 / Vector Records — 记录 CRUD:维度校验、单条与批量 upsert、获取、删除与计数。 — [模块 1 · API 5] - - pyvdisk.storage.vector.search — 向量检索 / Vector Search — 索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索… — [模块 1 · API 3] - - pyvdisk.storage.vfs — 虚拟文件系统 / Virtual File System — FS 之上的高层路径式 VFS:类文件对象、权限检查、宿主导入导出、遍历、空间统计与卷自动识别。 — [模块 17 · API 62] - - pyvdisk.storage.vfs.attrs — 元数据变更 / Metadata Writes — VFS 门面上的元数据变更:模式、属主、时间戳、权限检查与截断。 — [模块 1 · API 5] - - pyvdisk.storage.vfs.create — 创建盘与卷 / Create Disk or Volume — VFS 门面上的磁盘与卷创建入口。 — [模块 1 · API 2] - - pyvdisk.storage.vfs.dirs — 目录创建 / Directory Creation — 目录创建辅助,含用于命名空间初始化的递归变体。 — [模块 1 · API 2] - - pyvdisk.storage.vfs.files — 整文件 IO / Whole-File IO — 建立在定位式 FS 文件 API 之上的整文件读、写与追加便利接口。 — [模块 1 · API 3] - - pyvdisk.storage.vfs.hostio — 宿主交换 / Host Interchange — 宿主交换:文件对象打开,以及虚拟与宿主文件系统之间的单文件与递归导入导出。 — [模块 1 · API 4] - - pyvdisk.storage.vfs.lifetime — 挂载生命周期 / Mount Lifecycle — 挂载与关闭生命周期,包含测试与 CLI 广泛使用的 with 协议。 — [模块 1 · API 4] - - pyvdisk.storage.vfs.open — VFS 打开 / VFS Open — VFS 构造与传输选择:单个镜像可按普通盘或多成员卷打开。 — [模块 1 · API 3] - - pyvdisk.storage.vfs.permissions — 权限门禁 / Permission Gate — 每次 VFS 变更前的权限门禁:inode 模式位、路径遍历与父目录检查。 — [模块 1 · API 5] - - pyvdisk.storage.vfs.query — VFS 查询 / VFS Queries — VFS 门面上的存在性、类型判定与目录列举。 — [模块 1 · API 5] - - pyvdisk.storage.vfs.remove — 删除与重命名 / Delete and Rename — 删除与重命名操作,含检查点清理使用的递归目录删除。 — [模块 1 · API 4] - - pyvdisk.storage.vfs.space — 空间与维护 / Space and Maintenance — VFS 门面暴露的诊断与维护能力:空间统计、一致性检查与在线扩容。 — [模块 1 · API 5] - - pyvdisk.storage.vfs.stat — 元数据读取 / Metadata Reads — 暴露给调用方与 FUSE 的元数据读取与链接操作。 — [模块 1 · API 5] - - pyvdisk.storage.vfs.vfile — VFile 对象 / VFile Object — 打开文件对象的 VFile 构造与 inode 自省。 — [模块 1 · API 3] - - pyvdisk.storage.vfs.vfile-ctx — VFile 协议 / VFile Protocol — 打开 VFile 对象的 with 语句与迭代协议。 — [模块 1 · API 3] - - pyvdisk.storage.vfs.vfile-io — VFile 读写 / VFile IO — 打开 VFile 上的定位读写、seek、tell、truncate、flush 与 close。 — [模块 1 · API 8] - - pyvdisk.storage.vfs.walk — 目录遍历 / Directory Walk — 递归目录遍历生成器,供 import_host_tree、du 与 CLI 树视图使用。 — [模块 1 · API 1] - - pyvdisk.storage.volume — 多盘卷 / Multi-Disk Volume — 多盘卷:concat、stripe、mirror 三种模式对外沿用单盘的块 IO 接口,成员元数据存于 block 0。 — [模块 9 · API 31] - - pyvdisk.storage.volume.blocks — 逻辑块 / Logical Blocks — 按模式分发到具体地址映射的逻辑块入口。 — [模块 1 · API 3] - - pyvdisk.storage.volume.bytes — 字节传输 / Byte Transport — 字节级传输、描述符复制与 CLI 使用的状态报告。 — [模块 1 · API 4] - - pyvdisk.storage.volume.create — 卷创建 / Volume Creation — VFS 门面与 CLI 使用的卷创建与打开辅助。 — [模块 1 · API 2] - - pyvdisk.storage.volume.layout — RAID 映射 / RAID Mapping — 分模式地址映射:拼接、条带与镜像,镜像读取支持副本回退。 — [模块 1 · API 7] - - pyvdisk.storage.volume.meta — 卷元数据 / Volume Metadata — 卷元数据模型:写入每个成员的描述符及其内部的成员记录。 — [模块 1 · API 5] - - pyvdisk.storage.volume.model — 卷模型 / Volume Model — 卷模型,以及按模式把成员容量换算为逻辑地址空间的几何计算。 — [模块 1 · API 3] - - pyvdisk.storage.volume.open — 卷打开 / Volume Open — 卷打开路径:成员打开、跨成员一致性校验与关闭/刷新生命周期。 — [模块 1 · API 4] - - pyvdisk.storage.volume.repair — 镜像维护 / Mirror Maintenance — 在线镜像维护:新增、移除与重新同步副本。 — [模块 1 · API 3] - - pyvdisk.storage.wal — 预写日志 / Write-Ahead Log — 预写日志:同一套带检查点与截断的分段 WAL,由 DataDisk 事务与 VScript 事务撤销共用,而不是两份并行实现。 — [模块 4 · API 16] - - pyvdisk.storage.wal.entries — WAL 记录 / WAL Entries — 事务日志动词与崩溃恢复重放:begin/append/prepare/commit/abort,以及重放所依赖的读取入口。 — [模块 1 · API 8] - - pyvdisk.storage.wal.journal — 元数据 WAL / Metadata WAL — DataDisk 事务使用的元数据预写日志:存储后端、行编解码,以及分配序号的追加写入。 — [模块 1 · API 4] - - pyvdisk.storage.wal.undo — 宿主撤销 WAL / Host Undo WAL — VScript 侧的 WAL 入口:独立的宿主路径实现已取消——本模块直接复用同一套 WriteAheadLog,并给出撤销记录使用的 kind 集与编解码。 — [模块 1 · API 4] - - pyvdisk.tests — 测试套件 / Test Suite — 测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有… — [模块 59 · API 74] - - pyvdisk.tests.agent-sandbox — 沙箱测试 / Sandbox Tests — 把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的… — [模块 1 · API 1] - - pyvdisk.tests.agentic-cli — 智能体 CLI 用例 / Agentic CLI Tests — 面向智能体使用编写的 CLI 用例:可发现的输出与稳定的退出码。 — [模块 1 · API 1] - - pyvdisk.tests.api-governance — API 治理用例 / API Governance Tests — 检查公开能力 API 是否拒绝应当拒绝的调用,而不只验证正常路径。 — [模块 1 · API 1] - - pyvdisk.tests.atomic-save — 原子保存用例 / Atomic Save Tests — 验证元数据写入是全有或全无,即事务层所依赖的性质。 — [模块 1 · API 1] - - pyvdisk.tests.audit-trail — 审计轨迹用例 / Audit Trail Tests — 审计轨迹用例:哈希链校验(含在真实日志段内篡改记录)、查询筛选与保留策略。 — [模块 1 · API 1] - - pyvdisk.tests.cancellation — 取消用例 / Cancellation Tests — 验证协作式取消会让队列与运行状态保持一致,不停留在中间状态。 — [模块 1 · API 1] - - pyvdisk.tests.checkpoint — 检查点用例 / Checkpoint Tests — 为队列、运行、操作与审计提供背衬的持久键值存储的单元用例。 — [模块 1 · API 1] - - pyvdisk.tests.compat — 平台兼容测试 / Platform Compat Tests — 在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分… — [模块 1 · API 1] - - pyvdisk.tests.contracts — 契约用例 / Contract Tests — 保持抽象契约与具体实现一致的合规性用例。 — [模块 1 · API 1] - - pyvdisk.tests.crash-matrix — 崩溃矩阵用例 / Crash Matrix Tests — 最强的持久性用例:在每个阶段中断事务并断言恢复后落在合法状态。 — [模块 1 · API 1] - - pyvdisk.tests.e2e — 端到端用例 / End-to-End Tests — 遍历整个基础设施栈的集成用例,含在受限盘上运行脚本。 — [模块 1 · API 1] - - pyvdisk.tests.exactly-once-internal — 内部精确一次用例 / Exactly-Once Internal Tests — 验证重放操作不会重复生效,即精确一次的核心承诺。 — [模块 1 · API 1] - - pyvdisk.tests.exactly-once-operation — 操作精确一次用例 / Exactly-Once Operation Tests — 精确一次契约在操作层的半边,经公开执行接口观察。 — [模块 1 · API 1] - - pyvdisk.tests.execution — 执行用例 / Execution Tests — 执行平面用例:分发、受限视图与结果传递。 — [模块 1 · API 1] - - pyvdisk.tests.execution-queue — 执行队列用例 / Execution Queue Tests — 把执行服务绑定到持久队列及其租约语义的集成用例。 — [模块 1 · API 1] - - pyvdisk.tests.fixtures — 测试夹具 / Test Fixtures — 全套件各测试模块共享的 pytest 夹具定义。 — [模块 1 · API 1] - - pyvdisk.tests.fuse-mount — FUSE 挂载用例 / FUSE Mount Tests — FUSE 桥用例:属性与目录操作、truncate/link/chmod,以及此前对任何符号链接都返回 EINVAL 的 lstat 语义 readlink。 — [模块 1 · API 1] - - pyvdisk.tests.governance — 治理回归用例 / Governance Regression Tests — 最大的治理测试模块:治理工作新增的受限命名空间的回归覆盖。 — [模块 1 · API 1] - - pyvdisk.tests.logdisk-compact — 日志压缩用例 / Log Compaction Tests — 守住压缩绝不可违反的性质:减少存储不得改变可观测的流状态。 — [模块 1 · API 1] - - pyvdisk.tests.logdisk-retention — 日志保留用例 / Log Retention Tests — 验证保留策略不会删除消费者尚未确认的事件。 — [模块 1 · API 1] - - pyvdisk.tests.no-dependency — 零依赖测试 / Zero Dependency Tests — 同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端… — [模块 1 · API 1] - - pyvdisk.tests.packaging — 打包用例 / Packaging Tests — 验证包可构建安装,且 py.typed 标记与控制台入口完好。 — [模块 1 · API 1] - - pyvdisk.tests.participant-compensation — 参与者补偿用例 / Participant Compensation Tests — 参与者补偿用例:持久化写前补偿、进程内 abort 的逆序分发、跨挂载的幂等重复补偿。 — [模块 1 · API 1] - - pyvdisk.tests.queue — 队列用例 / Queue Tests — 单进程内持久队列的状态迁移用例。 — [模块 1 · API 1] - - pyvdisk.tests.queue-backoff — 退避与锁用例 / Backoff and Lock Tests — 对指数退避与串行化队列变更的锁的时序敏感用例。 — [模块 1 · API 1] - - pyvdisk.tests.queue-crossprocess — 跨进程队列用例 / Cross-Process Queue Tests — 证明持久队列的租约与去重保证跨进程边界成立,而非仅限线程。 — [模块 1 · API 1] - - pyvdisk.tests.submit-conflict — 提交冲突用例 / Submit Conflict Tests — 交互用例:提交时的版本冲突不得留下写一半的 VFS 变更。 — [模块 1 · API 1] - - pyvdisk.tests.tx-idempotency — 事务幂等用例 / Transaction Idempotency Tests — 小而关键的用例:同一事务提交两次不会产生副作用。 — [模块 1 · API 1] - - pyvdisk.tests.tx-rollback — 事务回滚用例 / Transaction Rollback Tests — 撤销日志用例:失败事务内的文件系统变更必须被精确还原。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk — VFS 行为规格 / VFS Behaviour Spec — 以真实镜像上的测试类表达的 VFS/FS/卷/锁/CLI/向量/日志行为规格。 — [模块 20 · API 34] - - pyvdisk.tests.vdisk.base — VFS 测试基类 / VFS Test Base — 测试基类与基础路径用例:启动镜像的夹具,以及最小的 VFS 行为。 — [模块 1 · API 2] - - pyvdisk.tests.vdisk.cli — CLI 用例 / CLI Tests — CLI 契约用例:以用户方式调用每个子命令并断言其输出形态。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.disk-manager — 磁盘管理用例 / Disk Manager Tests — 驱动层用例:挂载记账与已挂载文件系统的管理接口。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.exhaustion — 空间耗尽用例 / Space Exhaustion Tests — 空间耗尽行为:分配失败必须上报,不得静默损坏。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.identity — 身份用例 / Identity Tests — 身份用例:让宿主文件可被识别为 pyvdisk 镜像的尾标。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.io — 持久性与 IO 用例 / Persistence and IO Tests — 持久性与 IO 边界用例:重挂载持久性、宿主传输与非法路径错误。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.large-files — 大文件与删除用例 / Large File and Remove Tests — 间接块与目录删除行为,即块记账与 inode 复用最易出错的两处。 — [模块 1 · API 2] - - pyvdisk.tests.vdisk.links — 链接与属性用例 / Link and Attribute Tests — inode 层行为:硬链接、属性修改与稀疏分配。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.locking — 并发用例 / Concurrency Tests — 并发用例:单独验证锁原语,以及真实并发访问下的 VFS。 — [模块 1 · API 2] - - pyvdisk.tests.vdisk.log — 日志盘用例 / Log Disk Tests — 日志盘与日志集成用例,即存储平面用例的末端。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.maintenance — 维护用例 / Maintenance Tests — 维护类用例:一致性检查、就地扩容与空间统计。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.names — 命名空间用例 / Namespace Tests — 命名空间语义:重命名、符号链接与文件对象接口。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.permissions — 权限用例 / Permission Tests — 权限用例:跨 uid 与 gid 组合遵守读、写、执行位。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.raw-fs — 裸文件系统用例 / Raw Filesystem Tests — 直接操作块设备与磁盘布局、绕过 VFS 门面的用例。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.vector — 向量盘用例 / Vector Disk Tests — 向量盘行为,即存储平面同时承载的非文件系统负载。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.volume — 卷模式用例 / Volume Mode Tests — 拼接与条带两种无冗余模式的卷用例。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.volume-detect — 卷检测用例 / Volume Detection Tests — 从设备内容而非配置自动检测卷成员关系。 — [模块 1 · API 1] - - pyvdisk.tests.vdisk.volume-meta — 卷元数据用例 / Volume Metadata Tests — 卷元数据与错误处理,以及卷 CLI 接口。 — [模块 1 · API 3] - - pyvdisk.tests.vdisk.volume-mirror — 镜像卷用例 / Mirror Volume Tests — 镜像模式用例:区别于拼接与条带的冗余契约。 — [模块 1 · API 1] - - pyvdisk.tests.vscript — VScript 用例 / VScript Tests — VScript 语言用例加上针对真实盘的端到端运行,是全套件中最广的单个测试模块。 — [模块 1 · API 3] - - pyvdisk.tests.vscript-audit — 审计用例 / Audit Tests — 对一次运行后审计记录必须包含的内容,以及两种 sink 均持久化它的断言。 — [模块 1 · API 1] - - pyvdisk.tests.vscript-cron — Cron 用例 / Cron Tests — Cron 用例:字段解析、日/星期并集语义、步长与区间写法,以及下次触发时间计算。 — [模块 1 · API 1] - - pyvdisk.tests.vscript-host — 宿主隔离用例 / Host Confinement Tests — 验证 host 模块拒绝根外路径——VScript 所依赖的安全边界。 — [模块 1 · API 1] - - pyvdisk.tests.vscript-optional — 可选链用例 / Optional Chain Tests — 语言边界用例:可选成员访问如何短路而非报错。 — [模块 1 · API 1] - - pyvdisk.tests.vscript-triggers — 触发器用例 / Trigger Tests — 触发器用例:单调水位线排序(此前用随机事件 id 作文本比较会静默丢事件)、注册时空 pattern/stream 的拒绝,以及 poll_once 行为。 — [模块 1 · API 1] - - pyvdisk.tests.vscript-undo — 撤销用例 / Undo Tests — 撤销用例:每个 fs 动词在生效前记账、大正文落盘、restore_tree 与崩溃后遗留快照的清理。 — [模块 1 · API 1] - - pyvdisk.tests.wal-checkpoint — WAL 检查点用例 / WAL Checkpoint Tests — WAL 检查点用例:检查点后的截断、不再全量重放的恢复,以及 DataDisk 与 VScript 共用的同一套实现。 — [模块 1 · API 1] - - pyvdisk.tests.wal-recovery — WAL 恢复用例 / WAL Recovery Tests — 日志重放的专项用例:已回滚事务在恢复后必须不可见。 — [模块 1 · API 1] - - pyvdisk.vscript — VScript 语言 / VScript Language — VScript:安全工作流语言,含词法、语法、树遍历运行时、能力受限标准库、策略/预算、审计与调度。 — [模块 42 · API 143] - - pyvdisk.vscript.audit — VScript 审计 / VScript Audit — VScript 审计:稳定的脚本与策略哈希、带执行平面关联字段的 AuditRecord,以及持久化 sink。 — [模块 6 · API 25] - - pyvdisk.vscript.audit.clock — 运行标识 / Run Identity — 用于填充审计记录的运行标识与耗时测量。 — [模块 1 · API 2] - - pyvdisk.vscript.audit.hashing — 审计哈希 / Audit Hashing — 脚本与策略的确定性哈希,以及审计哈希链:每行都带上前驱哈希,verify 报告第一条不匹配的记录——包括在真实日志段内做的手脚。 — [模块 1 · API 6] - - pyvdisk.vscript.audit.query — 审计查询与保留 / Audit Query and Retention — 审计轨迹的读取侧:按运行/任务/状态/时间筛选记录,并支持显式保留裁剪,使轨迹既可查也可有界,而不是只能追加。 — [模块 1 · API 2] - - pyvdisk.vscript.audit.record — 审计记录 / Audit Record — 解释器、执行服务与 Sink 共用的审计记录形态,含使其可校验(而非仅可追加)的链字段。 — [模块 1 · API 2] - - pyvdisk.vscript.audit.sinks — 审计 Sink / Audit Sinks — 持久审计目的地:检查点存储里的有界保留,或日志盘上的只追加审计流。两者现在都可读:查询筛选、显式保留、哈希链校验,以及供外部锚定的链头。 — [模块 1 · API 13] - - pyvdisk.vscript.cli — VScript 命令行 / VScript CLI — VScript 命令行入口:check、run、run-disk 与交互式 REPL,含挂载授权参数解析。 — [模块 4 · API 8] - - pyvdisk.vscript.cli.commands — VScript 命令 / VScript Commands — VScript 命令接口:参数解析、挂载授权与 check/run 入口,含使 host.* 可用的宿主读/写根目录选项。 — [模块 1 · API 3] - - pyvdisk.vscript.cli.parser — VScript 参数注册 / VScript Parser Hook — 把 VScript 接口挂到 pyvdisk 主 CLI 上的 argparse 注册。 — [模块 1 · API 1] - - pyvdisk.vscript.cli.repl — VScript REPL / VScript REPL — 交互式 VScript REPL:行包装、值格式化、帮助,以及跨输入保持状态的循环。 — [模块 1 · API 4] - - pyvdisk.vscript.cron — Cron 表达式 / Cron Expressions — 定时触发器所需的 cron 支持:字段解析、匹配与下次触发计算。 — [模块 1 · API 5] - - pyvdisk.vscript.frontend — VScript 前端 / VScript Front End — VScript 前端:词法单元、最大匹配 lexer、AST 节点、递归下降语句解析器、Pratt 表达式解析器与带位置诊断。 — [模块 7 · API 30] - - pyvdisk.vscript.frontend.ast — AST 节点 / AST Nodes — AST 节点词表:表达式、语句、声明,以及工作流特有的 transaction、task、parallel 与 await 节点。 — [模块 1 · API 8] - - pyvdisk.vscript.frontend.errors — 错误类型 / Error Types — 错误层次:把语言各阶段映射为可区分、可捕获、可审计的失败。 — [模块 1 · API 8] - - pyvdisk.vscript.frontend.lexer — 词法器 / Lexer — 词法器:注释与空白处理、数字与字符串字面量、运算符与最大匹配。 — [模块 1 · API 5] - - pyvdisk.vscript.frontend.parser — 语法解析器 / Parser — 语法实现:语句、声明、控制流、match 分支与工作流构造。 — [模块 1 · API 2] - - pyvdisk.vscript.frontend.span — 位置与诊断 / Span and Diagnostic — 位置与诊断原语:事情发生在哪里,以及如何向用户报告。 — [模块 1 · API 4] - - pyvdisk.vscript.frontend.tokens — 词法单元 / Token Types — 语言的词法单元词表:lexer 能产出的全部关键字、运算符与字面量。 — [模块 1 · API 3] - - pyvdisk.vscript.host — 宿主访问 / Host Access — VScript 宿主访问:白名单 HostProxy,把脚本文件传输限制在声明的目录根内。 — [模块 3 · API 7] - - pyvdisk.vscript.host.guard — 宿主隔离 / Host Confinement — 宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。 — [模块 1 · API 6] - - pyvdisk.vscript.host.module — 宿主模块 / Host Module — host 原生模块:面向脚本的读取、写入与传输入口,全部经隔离代理。 — [模块 1 · API 1] - - pyvdisk.vscript.mounts — 挂载注册表 / Mount Registry — 挂载授权:把 CLI 挂载参数转为能力受限句柄并在运行后关闭的注册表。 — [模块 1 · API 6] - - pyvdisk.vscript.policy — 策略与预算 / Policy and Budget — VScript 策略与预算:调用深度、循环、IO 与 Host 传输限额,以及脚本可 require 的受保护能力集。 — [模块 3 · API 8] - - pyvdisk.vscript.policy.budget — 策略与预算 / Policy and Budget — 脚本的资源治理:声明式限额与执行计费并强制限额的运行时计数器。 — [模块 1 · API 6] - - pyvdisk.vscript.policy.capability — 脚本能力 / Script Capability — 脚本可见的能力对象及其权限门禁。 — [模块 1 · API 2] - - pyvdisk.vscript.runtime — VScript 运行时 / VScript Runtime — VScript 运行时:树遍历求值器、词法 Env 链、闭包、控制流、确定性 task/parallel、事务与模块加载。 — [模块 8 · API 29] - - pyvdisk.vscript.runtime.callables — 可调用对象与任务 / Callables and Tasks — 可调用对象与任务:参数绑定、对定义作用域的闭包,以及 await 等待的任务句柄。 — [模块 1 · API 5] - - pyvdisk.vscript.runtime.core — 解释器核心 / Interpreter Core — 解释器核心:构造与原生模块安装、带参数的顶层运行、原生模块调用的记账入口,以及语句块执行。 — [模块 1 · API 6] - - pyvdisk.vscript.runtime.env — 作用域与控制流 / Scope and Flow — 作用域与控制流机制:Env 链,以及以异常实现 return、break、continue 的信号。 — [模块 1 · API 7] - - pyvdisk.vscript.runtime.expressions — 表达式求值 / Expression Evaluation — 表达式求值:字面量、运算符、调用、成员与下标访问,以及赋值语义。 — [模块 1 · API 4] - - pyvdisk.vscript.runtime.modules — 模块加载 / Module Loading — 模块加载:在内置原生模块与已配置模块根下解析 import 名称。 — [模块 1 · API 1] - - pyvdisk.vscript.runtime.statements — 语句执行 / Statement Execution — 语句执行:解释器中最大的分发表,覆盖语言的全部语句种类。 — [模块 1 · API 1] - - pyvdisk.vscript.runtime.tx — 脚本事务 / Script Transaction — 脚本事务支持:每个可撤销的 fs 变更在生效前落账,进程内回滚与崩溃恢复走同一个撤销解释器,超过 64 KiB 的快照正文落到事务目录。 — [模块 1 · API 5] - - pyvdisk.vscript.stdlib — VScript 标准库 / VScript Standard Library — VScript 标准库:fs、vector、log、json 的能力受限原生模块,脚本只能通过 Handle 包装访问。 — [模块 4 · API 9] - - pyvdisk.vscript.stdlib.factory — 标准库工厂 / Stdlib Factory — 标准库工厂:文件系统、向量、日志与 json 原生函数,均受能力守卫与字节预算约束。每个会改动的 fs 动词在触碰存储之前先记入撤销账,事务失败时可回滚,而不留… — [模块 1 · API 1] - - pyvdisk.vscript.stdlib.guards — 原生守卫 / Native Guards — 每个原生函数触及资源前调用的两个守卫:类型与权限检查,以及路径范围限定。 — [模块 1 · API 2] - - pyvdisk.vscript.stdlib.native — 原生模块 / Native Modules — 原生模块基础设施与 Handle 包装:让原生资源留在能力检查之后,而非暴露裸 Python 对象。 — [模块 1 · API 6] - - pyvdisk.vscript.triggers — 触发器 / Trigger Registry — VScript 调度:持久触发器注册表,带事件去重与轮询守护进程执行注册脚本。 — [模块 3 · API 7] - - pyvdisk.vscript.triggers.daemon — 调度守护进程 / Scheduler Daemon — 轮询守护进程:每轮评估到期的文件与日志触发器并分发动作,按单调水位线排序事件,不再静默跳过到期事件。 — [模块 1 · API 3] - - pyvdisk.vscript.triggers.registry — 触发器注册表 / Trigger Registry — 触发器的注册与列举。注册即校验输入(空文件 pattern 以前能注册成功、随后把轮询循环打挂),水位线比较改用单调事件序号,而不再拿随机 uuid 作文本比较… — [模块 1 · API 4] - - pyvdisk.vscript.undo — 事务撤销记账 / Transaction Undo Bookkeeping — VScript 事务的撤销记账:每个可撤销的 fs 变更在生效之前就落账,进程内回滚与崩溃恢复共用同一个解释器;超过 64 KiB 的快照正文落到 /.syst… — [模块 1 · API 9] - diff --git a/normify-pyvdisk/policy.yml b/normify-pyvdisk/policy.yml deleted file mode 100644 index ade641c..0000000 --- a/normify-pyvdisk/policy.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Normify 架构规则(policy.yml) -# 在项目设计阶段安装,normify_validate 强制执行;severity: error(默认,阻断)| warning(提示)。 -# 规则类型:forbid-dependency | dependency-direction | acyclic | max-depth | cross-tree | naming -# id 模式:* 单段、** 任意段;例如 dsh-normify.engine.** 匹配引擎下全部模块。 -schema_version: 1 -updated_at: "2026-09-23T06:56:56.092Z" -rules: - # 基础规则 1:依赖图禁止环(含跨树,自环由核心校验拦截) - - id: core-acyclic - type: acyclic - severity: error - includeCrossTree: true - # 基础规则 2:不新增指向已废弃模块的依赖(存量记 warning,便于迁移) - - id: core-no-deprecated-target - type: forbid-dependency - from: ["**"] - to: ["**"] - toState: deprecated - severity: warning - - # ---- 以下为完整规则集的示例,按项目需要取消注释/改写 ---- - # 依赖方向:层顺序 = 允许方向(前 → 后),同层是否允许由 allowSameLayer 控制 - # - id: layer-order - # type: dependency-direction - # severity: error - # allowSameLayer: true - # layers: - # - { name: engine, match: [".engine.**", ".engine"] } - # - { name: surface, match: [".tools.**", ".tools", ".skill.**"] } - # - { name: boot, match: [".bootstrap.**", ".build"] } - # 禁止/只允许某些依赖 - # - id: no-ui-to-core - # type: forbid-dependency - # from: [".ui.**"] - # to: [".engine.**"] - # kind: [call, reference] - # 跨树依赖策略:forbid 禁止 / require-to-api 必须写 to_api / allow 允许 - # - id: cross-tree-api - # type: cross-tree - # mode: require-to-api - # 深度上限(含树名段) - # - id: depth-limit - # type: max-depth - # maxDepth: 10 - # scope: [".ui.**"] - # 命名约束:作用域内每个 id 段必须匹配该正则 - # - id: naming-no-underscore - # type: naming - # pattern: "^[a-z][a-z0-9-]*$" - # scope: [".**"] diff --git a/normify-pyvdisk/receipt.json b/normify-pyvdisk/receipt.json deleted file mode 100644 index 1fa76ed..0000000 --- a/normify-pyvdisk/receipt.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "schema_version": 1, - "ok": true, - "project": "normify-pyvdisk", - "compiled_at": "2026-09-24T11:51:44.100Z", - "stats": { - "tree_count": 1, - "module_count": 290, - "leaf_count": 249, - "api_count": 844, - "dep_count": 132, - "cross_tree_dep_count": 0, - "max_depth": 4, - "layout_count": 41, - "planned_count": 0, - "deprecated_count": 0, - "policy_rule_count": 2, - "change_count": 5, - "open_change_count": 0 - }, - "warnings": { - "structure/leaf-too-coarse": 14, - "evidence/root-no-source": 1 - }, - "artifacts": { - "tree.json": { - "sha256": "c166989dfb7459ed702458b273fde1a4135ad707f7ab1ad8743c64705f920dab", - "bytes": 832638 - }, - "outline.md": { - "sha256": "fea33e8c6e8b1b7b98c7684729802b8639ca72d16a47c8adae7a20011a8f98cd", - "bytes": 58995 - }, - "api-index.json": { - "sha256": "42ba9839a1e2c949f0f2a42b5b0b790b18d8982ce140d4f6767307e055df69f2", - "bytes": 62999 - }, - "receipt.json": { - "sha256": "9f630c60ed6c4ff788b9e10259671ad79cc9b42b8f2e116127e206cc347048e6", - "bytes": 964 - } - } -} diff --git a/normify-pyvdisk/renders/pyvdisk.json b/normify-pyvdisk/renders/pyvdisk.json deleted file mode 100644 index bc400e7..0000000 --- a/normify-pyvdisk/renders/pyvdisk.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk", - "updated_at": "2026-09-24T11:39:34.471Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;接着是对外一组——Agent 工作区与沙箱、导出面、以及沉底的平台适配层;examples/tests/docs/delivery 是示例、保障与交付。", - "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; then the outward-facing group -- the agent workspace and its sandbox, the exported API, and the platform layer everything sits on; examples/docs/tests/delivery provide assurance and delivery." - }, - "order": [ - "pyvdisk.storage", - "pyvdisk.execution", - "pyvdisk.governance", - "pyvdisk.vscript", - "pyvdisk.cli", - "pyvdisk.contracts", - "pyvdisk.agent", - "pyvdisk.api", - "pyvdisk.compat", - "pyvdisk.platform", - "pyvdisk.examples", - "pyvdisk.tests", - "pyvdisk.docs", - "pyvdisk.delivery" - ], - "groups": [ - { - "id": "engine", - "title": { - "zh": "存储与执行引擎", - "en": "Storage and Execution Engine" - }, - "children": [ - "pyvdisk.storage", - "pyvdisk.execution", - "pyvdisk.governance", - "pyvdisk.contracts" - ] - }, - { - "id": "language", - "title": { - "zh": "脚本语言与命令行", - "en": "Script Language and CLI" - }, - "children": [ - "pyvdisk.vscript", - "pyvdisk.cli" - ] - }, - { - "id": "surface", - "title": { - "zh": "对外接口与 Agent 入口", - "en": "Public Surface and Agent Entry" - }, - "children": [ - "pyvdisk.agent", - "pyvdisk.api", - "pyvdisk.compat", - "pyvdisk.platform" - ] - }, - { - "id": "meta", - "title": { - "zh": "示例、文档、测试与交付", - "en": "Examples, Docs, Tests and Delivery" - }, - "children": [ - "pyvdisk.examples", - "pyvdisk.tests", - "pyvdisk.docs", - "pyvdisk.delivery" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/agent.json b/normify-pyvdisk/renders/pyvdisk/agent.json deleted file mode 100644 index bccdd4c..0000000 --- a/normify-pyvdisk/renders/pyvdisk/agent.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.agent", - "updated_at": "2026-09-24T11:33:31.064Z", - "mode": "groups", - "reading": { - "zh": "从左到右:路径能指向什么,有哪些工具,把两者合起来的门面,最后是调用在哪里执行、留下什么记录。", - "en": "Left to right: what a path may name, what tools exist, the facade that ties them together, then where a call runs and what it leaves behind." - }, - "order": [ - "pyvdisk.agent.paths", - "pyvdisk.agent.tools", - "pyvdisk.agent.sandbox", - "pyvdisk.agent.script", - "pyvdisk.agent.audit" - ], - "groups": [ - { - "id": "surface", - "title": { - "zh": "模型看到的面", - "en": "What the model sees" - }, - "children": [ - "pyvdisk.agent.paths", - "pyvdisk.agent.tools", - "pyvdisk.agent.sandbox" - ] - }, - { - "id": "execution", - "title": { - "zh": "执行与留痕", - "en": "Execution and evidence" - }, - "children": [ - "pyvdisk.agent.script", - "pyvdisk.agent.audit" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/cli.json b/normify-pyvdisk/renders/pyvdisk/cli.json deleted file mode 100644 index 933db8e..0000000 --- a/normify-pyvdisk/renders/pyvdisk/cli.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.cli", - "updated_at": "2026-09-23T07:26:44.335Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先是共享的格式化与打开 VFS 辅助,再是文件系统子命令(镜像生命周期、目录、整文件操作、检查、管理),随后是卷/驱动器/向量/日志数据子命令,最后是注册全部命令的解析器、分发入口与 python -m 钩子。", - "en": "Shared formatting and VFS-opening helpers, then the filesystem subcommands (image lifecycle, directories, whole-file operations, inspection, administration), then the volume/drive/vector/log data subcommands, and finally the parser that registers them all, the dispatch entry point and the python -m hook." - }, - "order": [ - "pyvdisk.cli.format", - "pyvdisk.cli.open", - "pyvdisk.cli.image", - "pyvdisk.cli.dirs", - "pyvdisk.cli.file-ops", - "pyvdisk.cli.inspect", - "pyvdisk.cli.admin", - "pyvdisk.cli.volume", - "pyvdisk.cli.drive", - "pyvdisk.cli.vector", - "pyvdisk.cli.log", - "pyvdisk.cli.parser", - "pyvdisk.cli.main", - "pyvdisk.cli.entry" - ], - "groups": [ - { - "id": "helpers", - "title": { - "zh": "共享辅助", - "en": "Shared Helpers" - }, - "children": [ - "pyvdisk.cli.format", - "pyvdisk.cli.open" - ] - }, - { - "id": "fs", - "title": { - "zh": "文件系统子命令", - "en": "Filesystem Subcommands" - }, - "children": [ - "pyvdisk.cli.image", - "pyvdisk.cli.dirs", - "pyvdisk.cli.file-ops", - "pyvdisk.cli.inspect", - "pyvdisk.cli.admin" - ] - }, - { - "id": "data", - "title": { - "zh": "卷与数据子命令", - "en": "Volume and Data Subcommands" - }, - "children": [ - "pyvdisk.cli.volume", - "pyvdisk.cli.drive", - "pyvdisk.cli.vector", - "pyvdisk.cli.log" - ] - }, - { - "id": "entry", - "title": { - "zh": "解析器与入口", - "en": "Parser and Entry Point" - }, - "children": [ - "pyvdisk.cli.parser", - "pyvdisk.cli.main", - "pyvdisk.cli.entry" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/compat.json b/normify-pyvdisk/renders/pyvdisk/compat.json deleted file mode 100644 index c5e2e64..0000000 --- a/normify-pyvdisk/renders/pyvdisk/compat.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.compat", - "updated_at": "2026-09-23T07:26:31.537Z", - "reading": { - "zh": "两条保持可用的遗留导入路径:容器化之前的 Unified 名称,以及旧的 vscript.checkpoint 位置。", - "en": "Two legacy import paths kept working: the pre-container Unified names and the old vscript.checkpoint location." - }, - "order": [ - "pyvdisk.compat.unified", - "pyvdisk.compat.vscript" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/contracts.json b/normify-pyvdisk/renders/pyvdisk/contracts.json deleted file mode 100644 index db5e8d5..0000000 --- a/normify-pyvdisk/renders/pyvdisk/contracts.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.contracts", - "updated_at": "2026-09-23T07:24:03.694Z", - "mode": "groups", - "reading": { - "zh": "先是能力、存储与持久性原语,再是事件、执行与运行句柄协议,以及把它们串起来的 ExecutionPlane。", - "en": "The capability, storage and durability primitives, then the event, execution and run-handle protocols and the ExecutionPlane that ties them together." - }, - "order": [ - "pyvdisk.contracts.capability", - "pyvdisk.contracts.storage", - "pyvdisk.contracts.durability", - "pyvdisk.contracts.events", - "pyvdisk.contracts.execution", - "pyvdisk.contracts.runhandle", - "pyvdisk.contracts.plane" - ], - "groups": [ - { - "id": "primitives", - "title": { - "zh": "基础契约", - "en": "Primitive Contracts" - }, - "children": [ - "pyvdisk.contracts.capability", - "pyvdisk.contracts.storage", - "pyvdisk.contracts.durability" - ] - }, - { - "id": "plane", - "title": { - "zh": "事件与执行契约", - "en": "Event and Execution Contracts" - }, - "children": [ - "pyvdisk.contracts.events", - "pyvdisk.contracts.execution", - "pyvdisk.contracts.runhandle", - "pyvdisk.contracts.plane" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/delivery.json b/normify-pyvdisk/renders/pyvdisk/delivery.json deleted file mode 100644 index a946ad1..0000000 --- a/normify-pyvdisk/renders/pyvdisk/delivery.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.delivery", - "updated_at": "2026-09-23T07:24:04.294Z", - "reading": { - "zh": "先是打包元数据(构建与安装什么),再是守门的 CI 工作流与强制风格的 lint 配置。", - "en": "Packaging metadata first (what gets built and installed), then the CI workflow that gates merges and the lint configuration enforcing style." - }, - "order": [ - "pyvdisk.delivery.packaging", - "pyvdisk.delivery.ci", - "pyvdisk.delivery.lint" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/docs.json b/normify-pyvdisk/renders/pyvdisk/docs.json deleted file mode 100644 index 1060def..0000000 --- a/normify-pyvdisk/renders/pyvdisk/docs.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.docs", - "updated_at": "2026-09-24T09:56:14.155Z", - "reading": { - "zh": "先读 README 建立整体印象,再看架构总览、契约参考、能力治理设计说明与 VScript 语言规范;变更日志记录每个版本改了什么。", - "en": "Start with the README for orientation, then the architecture overview, the contract reference, the capability-governance design note and the VScript language specification; the changelog records what changed release by release." - }, - "order": [ - "pyvdisk.docs.readme", - "pyvdisk.docs.architecture", - "pyvdisk.docs.contracts", - "pyvdisk.docs.api-governance", - "pyvdisk.docs.vscript-spec", - "pyvdisk.docs.changelog" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/examples.json b/normify-pyvdisk/renders/pyvdisk/examples.json deleted file mode 100644 index 4c4eb71..0000000 --- a/normify-pyvdisk/renders/pyvdisk/examples.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.examples", - "updated_at": "2026-09-24T11:34:32.619Z", - "mode": "grid", - "reading": { - "zh": "两个入口:自底向上跑通整条栈的导览,以及演示框架如何对接的 agent loop。", - "en": "Two entries: the bottom-up tour of the whole stack, and the agent loop that shows how a framework talks to it." - }, - "order": [ - "pyvdisk.examples.quickstart", - "pyvdisk.examples.agent-tools" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/execution.json b/normify-pyvdisk/renders/pyvdisk/execution.json deleted file mode 100644 index a636e9d..0000000 --- a/normify-pyvdisk/renders/pyvdisk/execution.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.execution", - "updated_at": "2026-09-23T07:24:03.994Z", - "mode": "groups", - "reading": { - "zh": "先是持久状态:任务队列、带版本的运行记录,以及含可调用对象描述的操作注册表;service 拥有 worker 并向这三者分发执行。", - "en": "Durable state first: the task queue, the versioned run records and the operation registry with its callable descriptions; the service then owns the workers and dispatches into all three." - }, - "order": [ - "pyvdisk.execution.queue", - "pyvdisk.execution.runstate", - "pyvdisk.execution.operations", - "pyvdisk.execution.service" - ], - "groups": [ - { - "id": "durable", - "title": { - "zh": "持久状态", - "en": "Durable State" - }, - "children": [ - "pyvdisk.execution.queue", - "pyvdisk.execution.runstate", - "pyvdisk.execution.operations" - ] - }, - { - "id": "svc", - "title": { - "zh": "执行服务", - "en": "Execution Service" - }, - "children": [ - "pyvdisk.execution.service" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/execution/operations.json b/normify-pyvdisk/renders/pyvdisk/execution/operations.json deleted file mode 100644 index 4a8cebe..0000000 --- a/normify-pyvdisk/renders/pyvdisk/execution/operations.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.execution.operations", - "updated_at": "2026-09-23T07:24:44.073Z", - "reading": { - "zh": "先是错误词表与存储记录,再是可调用对象注册表与给操作稳定 id 的描述逻辑,最后是注册表门面及其背衬访问。", - "en": "Error vocabulary and the stored record first, then the callable registry and operation description that give an operation a stable id, then the registry facade and its backend access." - }, - "order": [ - "pyvdisk.execution.operations.errors", - "pyvdisk.execution.operations.record", - "pyvdisk.execution.operations.callables", - "pyvdisk.execution.operations.describe", - "pyvdisk.execution.operations.registry", - "pyvdisk.execution.operations.storage" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/execution/queue.json b/normify-pyvdisk/renders/pyvdisk/execution/queue.json deleted file mode 100644 index 3fd2848..0000000 --- a/normify-pyvdisk/renders/pyvdisk/execution/queue.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.execution.queue", - "updated_at": "2026-09-23T07:24:44.383Z", - "reading": { - "zh": "先是错误体系与任务值对象,再是状态持久化与重试退避,随后是完整任务生命周期,最后是过期租约回收与列举。", - "en": "Error taxonomy and the task value object, then state persistence with retry backoff, then the full task lifecycle, and finally stale-lease recovery and listing." - }, - "order": [ - "pyvdisk.execution.queue.errors", - "pyvdisk.execution.queue.task", - "pyvdisk.execution.queue.store", - "pyvdisk.execution.queue.lifecycle", - "pyvdisk.execution.queue.recovery" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/execution/runstate.json b/normify-pyvdisk/renders/pyvdisk/execution/runstate.json deleted file mode 100644 index cdfc90c..0000000 --- a/normify-pyvdisk/renders/pyvdisk/execution/runstate.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.execution.runstate", - "updated_at": "2026-09-23T07:24:44.749Z", - "reading": { - "zh": "model 是运行记录及其冲突类型,store 在其上提供带版本的迁移、幂等创建与过期运行回收。", - "en": "model is the run record and its conflict type, store adds versioned transitions, idempotent creation and stale-run recovery." - }, - "order": [ - "pyvdisk.execution.runstate.model", - "pyvdisk.execution.runstate.store" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/execution/service.json b/normify-pyvdisk/renders/pyvdisk/execution/service.json deleted file mode 100644 index 66f464c..0000000 --- a/normify-pyvdisk/renders/pyvdisk/execution/service.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.execution.service", - "updated_at": "2026-09-23T07:24:45.085Z", - "reading": { - "zh": "先是构造与 worker 控制,再是单个操作如何被分发(受限视图加 Python 或 VScript 执行),随后是队列驱动的运行,最后是 submit/run/cancel 接口。", - "en": "Construction and worker control, then how one operation is dispatched (scoped view plus Python or VScript execution), then queue-driven runs, and finally the submit/run/cancel surface." - }, - "order": [ - "pyvdisk.execution.service.setup", - "pyvdisk.execution.service.invoke", - "pyvdisk.execution.service.queue", - "pyvdisk.execution.service.submit" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/governance.json b/normify-pyvdisk/renders/pyvdisk/governance.json deleted file mode 100644 index 57958e7..0000000 --- a/normify-pyvdisk/renders/pyvdisk/governance.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.governance", - "updated_at": "2026-09-23T07:24:45.377Z", - "reading": { - "zh": "先是能力门禁(路径归一、范围包含与受保护委托),再是它保护的文件系统与向量/日志适配器,最后是交给不可信代码的 ScopedDataDisk 对象。", - "en": "The capability gate comes first (path scoping, containment and guarded delegation), then the filesystem and vector/log adapters it protects, and finally the ScopedDataDisk object handed to untrusted code." - }, - "order": [ - "pyvdisk.governance.namespace", - "pyvdisk.governance.files", - "pyvdisk.governance.data", - "pyvdisk.governance.scoped" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/platform.json b/normify-pyvdisk/renders/pyvdisk/platform.json deleted file mode 100644 index 080ac60..0000000 --- a/normify-pyvdisk/renders/pyvdisk/platform.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.platform", - "updated_at": "2026-09-24T11:34:38.929Z", - "mode": "grid", - "max_columns": 2, - "reading": { - "zh": "先看当前用的是哪套实现,再看其余模块都会经过的四类原语:定位读写、文件锁、持久化与身份。", - "en": "Which implementation is in force, then the four primitive groups every other module goes through: positioned IO, locking, and durability/identity." - }, - "order": [ - "pyvdisk.platform.dispatch", - "pyvdisk.platform.positional", - "pyvdisk.platform.locking", - "pyvdisk.platform.durability" - ], - "groups": [ - { - "id": "primitives", - "title": { - "zh": "四类原语", - "en": "Primitives" - }, - "children": [ - "pyvdisk.platform.dispatch", - "pyvdisk.platform.positional", - "pyvdisk.platform.locking", - "pyvdisk.platform.durability" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage.json b/normify-pyvdisk/renders/pyvdisk/storage.json deleted file mode 100644 index b14ccfb..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage", - "updated_at": "2026-09-23T07:23:36.967Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "自下而上:block 是最底的块设备抽象,identity 给它贴身份,fs 在其上实现 inode/目录/块分配,vfs 提供路径式门面,rwlock 负责并发;volume 把多块盘组合成带冗余的卷;vector/log/logging 是块设备上的数据服务;datadisk+wal+checkpoint 组成事务性容器;driver 与 fuse 是挂载与宿主接入。", - "en": "Bottom-up: block is the raw device abstraction, identity labels it, fs implements inodes/directories/block allocation on top, vfs exposes a path-based facade and rwlock handles concurrency; volume combines disks into redundant volumes; vector/log/logging are data services over block devices; datadisk+wal+checkpoint form the transactional container; driver and fuse attach it to hosts." - }, - "order": [ - "pyvdisk.storage.fs", - "pyvdisk.storage.vfs", - "pyvdisk.storage.block", - "pyvdisk.storage.rwlock", - "pyvdisk.storage.identity", - "pyvdisk.storage.volume", - "pyvdisk.storage.vector", - "pyvdisk.storage.log", - "pyvdisk.storage.logging", - "pyvdisk.storage.datadisk", - "pyvdisk.storage.wal", - "pyvdisk.storage.checkpoint", - "pyvdisk.storage.driver", - "pyvdisk.storage.fuse" - ], - "groups": [ - { - "id": "corefs", - "title": { - "zh": "文件系统与块层", - "en": "Filesystem and Block Layer" - }, - "children": [ - "pyvdisk.storage.fs", - "pyvdisk.storage.vfs", - "pyvdisk.storage.block", - "pyvdisk.storage.rwlock", - "pyvdisk.storage.identity" - ] - }, - { - "id": "volumes", - "title": { - "zh": "卷与冗余", - "en": "Volumes and Redundancy" - }, - "children": [ - "pyvdisk.storage.volume" - ] - }, - { - "id": "services", - "title": { - "zh": "数据服务", - "en": "Data Services" - }, - "children": [ - "pyvdisk.storage.vector", - "pyvdisk.storage.log", - "pyvdisk.storage.logging" - ] - }, - { - "id": "containers", - "title": { - "zh": "容器与持久化", - "en": "Container and Durability" - }, - "children": [ - "pyvdisk.storage.datadisk", - "pyvdisk.storage.wal", - "pyvdisk.storage.checkpoint" - ] - }, - { - "id": "access", - "title": { - "zh": "访问入口", - "en": "Access Entry Points" - }, - "children": [ - "pyvdisk.storage.driver", - "pyvdisk.storage.fuse" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/block.json b/normify-pyvdisk/renders/pyvdisk/storage/block.json deleted file mode 100644 index e50ff7f..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/block.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.block", - "updated_at": "2026-09-23T07:23:37.893Z", - "reading": { - "zh": "io 是块级读写原语,image 负责镜像文件的打开与几何,access 是上层看到的设备接口。", - "en": "io holds the raw block read/write primitives, image handles image files and geometry, and access is the device interface seen by upper layers." - }, - "order": [ - "pyvdisk.storage.block.io", - "pyvdisk.storage.block.image", - "pyvdisk.storage.block.access" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/checkpoint.json b/normify-pyvdisk/renders/pyvdisk/storage/checkpoint.json deleted file mode 100644 index a19e2ce..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/checkpoint.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.checkpoint", - "updated_at": "2026-09-23T07:23:38.263Z", - "reading": { - "zh": "open 决定背衬(VFS 或宿主目录)与锁;io 是读写保存;triggers 是给调度器的事件去重层。", - "en": "open chooses the backend (VFS or host directory) and the lock; io reads, writes and saves; triggers is the event-dedup layer used by the scheduler." - }, - "order": [ - "pyvdisk.storage.checkpoint.open", - "pyvdisk.storage.checkpoint.io", - "pyvdisk.storage.checkpoint.triggers" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/datadisk.json b/normify-pyvdisk/renders/pyvdisk/storage/datadisk.json deleted file mode 100644 index ea70bb5..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/datadisk.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.datadisk", - "updated_at": "2026-09-23T07:23:38.616Z", - "mode": "groups", - "reading": { - "zh": "从元数据编解码与事务暂存机制开始,到事务的提交/回滚结局,再看文件系统与向量/日志的事务性命名空间,最后是 DataDisk 容器自身的核心与对外接口。", - "en": "From metadata codec and transaction staging, to commit/rollback outcomes, then the transactional filesystem and vector/log namespaces, and finally the DataDisk container core and its interface." - }, - "order": [ - "pyvdisk.storage.datadisk.codec", - "pyvdisk.storage.datadisk.tx", - "pyvdisk.storage.datadisk.tx-lifecycle", - "pyvdisk.storage.datadisk.namespace", - "pyvdisk.storage.datadisk.services", - "pyvdisk.storage.datadisk.core", - "pyvdisk.storage.datadisk.api" - ], - "groups": [ - { - "id": "txm", - "title": { - "zh": "事务机制", - "en": "Transaction Machinery" - }, - "children": [ - "pyvdisk.storage.datadisk.codec", - "pyvdisk.storage.datadisk.tx", - "pyvdisk.storage.datadisk.tx-lifecycle" - ] - }, - { - "id": "ns", - "title": { - "zh": "事务性命名空间", - "en": "Transactional Namespaces" - }, - "children": [ - "pyvdisk.storage.datadisk.namespace", - "pyvdisk.storage.datadisk.services" - ] - }, - { - "id": "container", - "title": { - "zh": "容器本体", - "en": "The Container" - }, - "children": [ - "pyvdisk.storage.datadisk.core", - "pyvdisk.storage.datadisk.api" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/driver.json b/normify-pyvdisk/renders/pyvdisk/storage/driver.json deleted file mode 100644 index bd7da1f..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/driver.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.driver", - "updated_at": "2026-09-23T07:23:39.653Z", - "reading": { - "zh": "assembled 是挂载结果对象,mounts 是挂载记录,manager 是扫描与台账,mounting 按类型分发挂载,lifecycle 负责卸载与恢复。", - "en": "assembled is the mount result object, mounts holds mount records, manager scans and keeps the ledger, mounting dispatches per disk type, lifecycle unmounts and recovers." - }, - "order": [ - "pyvdisk.storage.driver.assembled", - "pyvdisk.storage.driver.mounts", - "pyvdisk.storage.driver.manager", - "pyvdisk.storage.driver.mounting", - "pyvdisk.storage.driver.lifecycle" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/fs.json b/normify-pyvdisk/renders/pyvdisk/storage/fs.json deleted file mode 100644 index 0e7542f..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/fs.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.fs", - "updated_at": "2026-09-23T07:23:37.275Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先看磁盘布局(超级块、inode 表、位图、多级块指针),再看目录与路径解析,然后是创建/写入/截断等文件操作,最后是加锁、挂载、格式化、fsck 与扩容。", - "en": "Start with the on-disk layout (superblock, inode table, bitmap, multi-level block pointers), then directories and path resolution, then create/write/truncate operations, and finally locking, mount, mkfs, fsck and growth." - }, - "order": [ - "pyvdisk.storage.fs.layout", - "pyvdisk.storage.fs.superblock", - "pyvdisk.storage.fs.inode", - "pyvdisk.storage.fs.inode-io", - "pyvdisk.storage.fs.bitmap", - "pyvdisk.storage.fs.block-alloc", - "pyvdisk.storage.fs.pointers", - "pyvdisk.storage.fs.dir", - "pyvdisk.storage.fs.dir-mutate", - "pyvdisk.storage.fs.names", - "pyvdisk.storage.fs.paths", - "pyvdisk.storage.fs.attrs", - "pyvdisk.storage.fs.stat", - "pyvdisk.storage.fs.query", - "pyvdisk.storage.fs.locking", - "pyvdisk.storage.fs.mount", - "pyvdisk.storage.fs.mkfs", - "pyvdisk.storage.fs.fsck", - "pyvdisk.storage.fs.grow", - "pyvdisk.storage.fs.create", - "pyvdisk.storage.fs.mutate", - "pyvdisk.storage.fs.readwrite", - "pyvdisk.storage.fs.truncate" - ], - "groups": [ - { - "id": "ondisk", - "title": { - "zh": "磁盘布局", - "en": "On-Disk Layout" - }, - "children": [ - "pyvdisk.storage.fs.layout", - "pyvdisk.storage.fs.superblock", - "pyvdisk.storage.fs.inode", - "pyvdisk.storage.fs.inode-io", - "pyvdisk.storage.fs.bitmap", - "pyvdisk.storage.fs.block-alloc", - "pyvdisk.storage.fs.pointers" - ] - }, - { - "id": "namespace", - "title": { - "zh": "目录与命名", - "en": "Directories and Naming" - }, - "children": [ - "pyvdisk.storage.fs.dir", - "pyvdisk.storage.fs.dir-mutate", - "pyvdisk.storage.fs.names", - "pyvdisk.storage.fs.paths", - "pyvdisk.storage.fs.attrs", - "pyvdisk.storage.fs.stat", - "pyvdisk.storage.fs.query" - ] - }, - { - "id": "ops", - "title": { - "zh": "文件操作", - "en": "File Operations" - }, - "children": [ - "pyvdisk.storage.fs.create", - "pyvdisk.storage.fs.mutate", - "pyvdisk.storage.fs.readwrite", - "pyvdisk.storage.fs.truncate" - ] - }, - { - "id": "lifecycle", - "title": { - "zh": "生命周期与维护", - "en": "Lifecycle and Maintenance" - }, - "children": [ - "pyvdisk.storage.fs.locking", - "pyvdisk.storage.fs.mount", - "pyvdisk.storage.fs.mkfs", - "pyvdisk.storage.fs.fsck", - "pyvdisk.storage.fs.grow" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/fuse.json b/normify-pyvdisk/renders/pyvdisk/storage/fuse.json deleted file mode 100644 index 3cf06d2..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/fuse.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.fuse", - "updated_at": "2026-09-23T07:23:39.976Z", - "reading": { - "zh": "meta 与 data 分别实现元数据与数据回调,handlers 覆盖其余 FUSE 操作,mount 负责挂载与参数。", - "en": "meta and data implement the metadata and data callbacks, handlers covers the remaining FUSE operations, and mount performs the mount and argument handling." - }, - "order": [ - "pyvdisk.storage.fuse.meta", - "pyvdisk.storage.fuse.data", - "pyvdisk.storage.fuse.handlers", - "pyvdisk.storage.fuse.mount" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/identity.json b/normify-pyvdisk/renders/pyvdisk/storage/identity.json deleted file mode 100644 index be19a27..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/identity.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.identity", - "updated_at": "2026-09-23T07:23:40.359Z", - "reading": { - "zh": "format 定义尾标的磁盘格式,model 是其内存模型,trailer 负责编码解码,probe 从任意宿主文件识别出 pyvdisk 镜像。", - "en": "format defines the on-disk trailer format, model is its in-memory shape, trailer encodes and decodes it, and probe recognises a pyvdisk image from an arbitrary host file." - }, - "order": [ - "pyvdisk.storage.identity.format", - "pyvdisk.storage.identity.model", - "pyvdisk.storage.identity.trailer", - "pyvdisk.storage.identity.probe" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/log.json b/normify-pyvdisk/renders/pyvdisk/storage/log.json deleted file mode 100644 index 2094625..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/log.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.log", - "updated_at": "2026-09-23T07:24:01.803Z", - "reading": { - "zh": "先打开日志盘并管理流,再追加事件,随后经 query 与其过滤辅助读回,最后执行保留策略。", - "en": "Opens the log disk, manages streams, appends events, then reads them back through query and its filter helper, and finally applies retention." - }, - "order": [ - "pyvdisk.storage.log.open", - "pyvdisk.storage.log.streams", - "pyvdisk.storage.log.append", - "pyvdisk.storage.log.query", - "pyvdisk.storage.log.filter", - "pyvdisk.storage.log.retention" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/logging.json b/normify-pyvdisk/renders/pyvdisk/storage/logging.json deleted file mode 100644 index 1fb46a3..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/logging.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.logging", - "updated_at": "2026-09-23T07:24:02.119Z", - "reading": { - "zh": "先是事件记录,再是持久化它的 sink 与发出事件的 logger,之后是标准库 logging 桥接与上下文传递辅助。", - "en": "Event records first, then the sinks that persist them and the logger that emits, then the stdlib-logging bridge and the context propagation helpers." - }, - "order": [ - "pyvdisk.storage.logging.events", - "pyvdisk.storage.logging.sinks", - "pyvdisk.storage.logging.logger", - "pyvdisk.storage.logging.bridge", - "pyvdisk.storage.logging.context" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/rwlock.json b/normify-pyvdisk/renders/pyvdisk/storage/rwlock.json deleted file mode 100644 index 93f2976..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/rwlock.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.rwlock", - "updated_at": "2026-09-23T07:24:02.413Z", - "reading": { - "zh": "core 是读写锁本体(获取、释放、升级);ctx 把它包装成 with 语句可用的读/写上下文。", - "en": "core is the reader/writer lock itself (acquire, release, upgrade); ctx wraps it into with-statement read and write contexts." - }, - "order": [ - "pyvdisk.storage.rwlock.core", - "pyvdisk.storage.rwlock.ctx" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/vector.json b/normify-pyvdisk/renders/pyvdisk/storage/vector.json deleted file mode 100644 index 97a9ac9..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/vector.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.vector", - "updated_at": "2026-09-24T11:32:36.825Z", - "mode": "grid", - "max_columns": 3, - "reading": { - "zh": "先看集合簿记与记录,再看索引后端,最后是消费它的检索。", - "en": "Collection bookkeeping and records first, then the index backend, then the search that consumes it." - }, - "order": [ - "pyvdisk.storage.vector.open", - "pyvdisk.storage.vector.collections", - "pyvdisk.storage.vector.records", - "pyvdisk.storage.vector.flat-index", - "pyvdisk.storage.vector.search" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/vfs.json b/normify-pyvdisk/renders/pyvdisk/storage/vfs.json deleted file mode 100644 index ba1f447..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/vfs.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.vfs", - "updated_at": "2026-09-23T07:23:37.579Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先看 VFS 如何打开镜像/卷并挂载(含 create),再沿着路径式接口读下去:权限检查、查询、目录、文件、删除、属性、宿主导入导出、遍历与空间;最后是 VFile 文件对象及其读写与上下文。", - "en": "First how the VFS opens an image or volume and mounts it (including create), then the path-based API: permission checks, query, directories, files, removal, attributes, host transfer, walking and space; finally the VFile object with its IO and context." - }, - "order": [ - "pyvdisk.storage.vfs.open", - "pyvdisk.storage.vfs.create", - "pyvdisk.storage.vfs.lifetime", - "pyvdisk.storage.vfs.permissions", - "pyvdisk.storage.vfs.query", - "pyvdisk.storage.vfs.dirs", - "pyvdisk.storage.vfs.files", - "pyvdisk.storage.vfs.remove", - "pyvdisk.storage.vfs.stat", - "pyvdisk.storage.vfs.attrs", - "pyvdisk.storage.vfs.hostio", - "pyvdisk.storage.vfs.walk", - "pyvdisk.storage.vfs.space", - "pyvdisk.storage.vfs.vfile", - "pyvdisk.storage.vfs.vfile-io", - "pyvdisk.storage.vfs.vfile-ctx" - ], - "groups": [ - { - "id": "lifecycle", - "title": { - "zh": "挂载与生命周期", - "en": "Mount and Lifetime" - }, - "children": [ - "pyvdisk.storage.vfs.open", - "pyvdisk.storage.vfs.create", - "pyvdisk.storage.vfs.lifetime" - ] - }, - { - "id": "namespace", - "title": { - "zh": "路径式文件系统接口", - "en": "Path-Based Filesystem API" - }, - "children": [ - "pyvdisk.storage.vfs.permissions", - "pyvdisk.storage.vfs.query", - "pyvdisk.storage.vfs.dirs", - "pyvdisk.storage.vfs.files", - "pyvdisk.storage.vfs.remove", - "pyvdisk.storage.vfs.stat", - "pyvdisk.storage.vfs.attrs", - "pyvdisk.storage.vfs.hostio", - "pyvdisk.storage.vfs.walk", - "pyvdisk.storage.vfs.space" - ] - }, - { - "id": "fileobj", - "title": { - "zh": "文件对象", - "en": "File Objects" - }, - "children": [ - "pyvdisk.storage.vfs.vfile", - "pyvdisk.storage.vfs.vfile-io", - "pyvdisk.storage.vfs.vfile-ctx" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/volume.json b/normify-pyvdisk/renders/pyvdisk/storage/volume.json deleted file mode 100644 index 53c4a50..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/volume.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.volume", - "updated_at": "2026-09-23T07:24:03.065Z", - "reading": { - "zh": "先是卷元数据与其模型,再是打开与创建,随后是把逻辑块映射到成员盘的 layout、使用它的块/字节 IO,最后是镜像修复与重同步。", - "en": "Volume metadata and its model, then open and create, then the layout that maps logical blocks onto members, the block and byte IO that use it, and finally mirror repair and resync." - }, - "order": [ - "pyvdisk.storage.volume.meta", - "pyvdisk.storage.volume.model", - "pyvdisk.storage.volume.open", - "pyvdisk.storage.volume.create", - "pyvdisk.storage.volume.layout", - "pyvdisk.storage.volume.blocks", - "pyvdisk.storage.volume.bytes", - "pyvdisk.storage.volume.repair" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/storage/wal.json b/normify-pyvdisk/renders/pyvdisk/storage/wal.json deleted file mode 100644 index e0a4ce2..0000000 --- a/normify-pyvdisk/renders/pyvdisk/storage/wal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.storage.wal", - "updated_at": "2026-09-23T07:24:03.371Z", - "reading": { - "zh": "journal 是 VFS 背衬的元数据日志,entries 是其事务动词与恢复重放,undo 是记录旧文件内容的宿主文件系统变体。", - "en": "journal is the VFS-backed metadata log, entries are its transaction verbs and recovery replay, and undo is the host-filesystem variant that records previous file bodies." - }, - "order": [ - "pyvdisk.storage.wal.journal", - "pyvdisk.storage.wal.entries", - "pyvdisk.storage.wal.undo" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/tests.json b/normify-pyvdisk/renders/pyvdisk/tests.json deleted file mode 100644 index 8ffb7b9..0000000 --- a/normify-pyvdisk/renders/pyvdisk/tests.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.tests", - "updated_at": "2026-09-24T11:39:19.907Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "按所验证的子系统分组:夹具、文件系统持久性与平台适配层、事务与崩溃、执行平面、队列与精确一次保证、VScript、治理与沙箱,最后是日志盘、CLI、打包与零依赖检查。", - "en": "Grouped by the subsystem each module validates: fixtures, filesystem durability and the platform layer, transactions and crashes, the execution plane, queue and exactly-once guarantees, VScript, governance and the sandbox, then log-disk, CLI, packaging and the zero-dependency check." - }, - "order": [ - "pyvdisk.tests.fixtures", - "pyvdisk.tests.vdisk", - "pyvdisk.tests.atomic-save", - "pyvdisk.tests.submit-conflict", - "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount", - "pyvdisk.tests.compat", - "pyvdisk.tests.tx-rollback", - "pyvdisk.tests.tx-idempotency", - "pyvdisk.tests.crash-matrix", - "pyvdisk.tests.checkpoint", - "pyvdisk.tests.participant-compensation", - "pyvdisk.tests.wal-checkpoint", - "pyvdisk.tests.execution", - "pyvdisk.tests.execution-queue", - "pyvdisk.tests.cancellation", - "pyvdisk.tests.e2e", - "pyvdisk.tests.queue", - "pyvdisk.tests.queue-backoff", - "pyvdisk.tests.queue-crossprocess", - "pyvdisk.tests.exactly-once-internal", - "pyvdisk.tests.exactly-once-operation", - "pyvdisk.tests.vscript", - "pyvdisk.tests.vscript-audit", - "pyvdisk.tests.audit-trail", - "pyvdisk.tests.vscript-host", - "pyvdisk.tests.vscript-optional", - "pyvdisk.tests.vscript-undo", - "pyvdisk.tests.vscript-cron", - "pyvdisk.tests.vscript-triggers", - "pyvdisk.tests.governance", - "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts", - "pyvdisk.tests.agent-sandbox", - "pyvdisk.tests.logdisk-compact", - "pyvdisk.tests.logdisk-retention", - "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging", - "pyvdisk.tests.no-dependency" - ], - "groups": [ - { - "id": "fs", - "title": { - "zh": "文件系统与持久性", - "en": "Filesystem and Durability" - }, - "children": [ - "pyvdisk.tests.fixtures", - "pyvdisk.tests.vdisk", - "pyvdisk.tests.atomic-save", - "pyvdisk.tests.submit-conflict", - "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount", - "pyvdisk.tests.compat" - ] - }, - { - "id": "tx", - "title": { - "zh": "事务与崩溃", - "en": "Transaction and Crash" - }, - "children": [ - "pyvdisk.tests.tx-rollback", - "pyvdisk.tests.tx-idempotency", - "pyvdisk.tests.crash-matrix", - "pyvdisk.tests.checkpoint", - "pyvdisk.tests.participant-compensation", - "pyvdisk.tests.wal-checkpoint" - ] - }, - { - "id": "exec", - "title": { - "zh": "执行平面", - "en": "Execution Plane" - }, - "children": [ - "pyvdisk.tests.execution", - "pyvdisk.tests.execution-queue", - "pyvdisk.tests.cancellation", - "pyvdisk.tests.e2e" - ] - }, - { - "id": "queue", - "title": { - "zh": "队列与精确一次", - "en": "Queue and Exactly-Once" - }, - "children": [ - "pyvdisk.tests.queue", - "pyvdisk.tests.queue-backoff", - "pyvdisk.tests.queue-crossprocess", - "pyvdisk.tests.exactly-once-internal", - "pyvdisk.tests.exactly-once-operation" - ] - }, - { - "id": "vscript", - "title": { - "zh": "VScript", - "en": "VScript" - }, - "children": [ - "pyvdisk.tests.vscript", - "pyvdisk.tests.vscript-audit", - "pyvdisk.tests.audit-trail", - "pyvdisk.tests.vscript-host", - "pyvdisk.tests.vscript-optional", - "pyvdisk.tests.vscript-undo", - "pyvdisk.tests.vscript-cron", - "pyvdisk.tests.vscript-triggers" - ] - }, - { - "id": "gov", - "title": { - "zh": "治理与沙箱", - "en": "Governance and Sandbox" - }, - "children": [ - "pyvdisk.tests.governance", - "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts", - "pyvdisk.tests.agent-sandbox" - ] - }, - { - "id": "misc", - "title": { - "zh": "日志盘、CLI 与打包", - "en": "Log Disk, CLI and Packaging" - }, - "children": [ - "pyvdisk.tests.logdisk-compact", - "pyvdisk.tests.logdisk-retention", - "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging", - "pyvdisk.tests.no-dependency" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/tests/vdisk.json b/normify-pyvdisk/renders/pyvdisk/tests/vdisk.json deleted file mode 100644 index 1078a2a..0000000 --- a/normify-pyvdisk/renders/pyvdisk/tests/vdisk.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.tests.vdisk", - "updated_at": "2026-09-23T07:24:46.362Z", - "max_columns": 4, - "reading": { - "zh": "这份 1650 行的存储测试模块按类顺序阅读:基础路径与大文件、命名与 IO、链接与属性、维护、裸设备访问、空间耗尽、四组卷模式、身份、磁盘管理器、并发、权限、向量盘、日志盘,最后是 CLI 契约。", - "en": "The single 1650-line storage test module, read in class order: basic paths and large files, naming and IO, links and attributes, maintenance, raw device access, space exhaustion, the four volume-mode groups, identity, the disk manager, concurrency, permissions, vector disk, log disk and finally the CLI contract." - }, - "order": [ - "pyvdisk.tests.vdisk.base", - "pyvdisk.tests.vdisk.large-files", - "pyvdisk.tests.vdisk.names", - "pyvdisk.tests.vdisk.io", - "pyvdisk.tests.vdisk.links", - "pyvdisk.tests.vdisk.maintenance", - "pyvdisk.tests.vdisk.raw-fs", - "pyvdisk.tests.vdisk.exhaustion", - "pyvdisk.tests.vdisk.volume", - "pyvdisk.tests.vdisk.volume-mirror", - "pyvdisk.tests.vdisk.volume-meta", - "pyvdisk.tests.vdisk.volume-detect", - "pyvdisk.tests.vdisk.identity", - "pyvdisk.tests.vdisk.disk-manager", - "pyvdisk.tests.vdisk.locking", - "pyvdisk.tests.vdisk.permissions", - "pyvdisk.tests.vdisk.vector", - "pyvdisk.tests.vdisk.log", - "pyvdisk.tests.vdisk.cli" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript.json b/normify-pyvdisk/renders/pyvdisk/vscript.json deleted file mode 100644 index 062f312..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript", - "updated_at": "2026-09-24T09:55:44.889Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "跟随一个脚本穿过系统:前端完成词法与语法分析,策略与挂载/宿主层决定它能触及什么,标准库与运行时执行它,撤销记账让每处可撤销改动都能回滚,审计记录结果,触发器与 cron 安排后续运行,CLI 是用户的启动方式。", - "en": "Follow a script through the system: the front end lexes and parses, the policy and mount/host layers decide what it may touch, the stdlib and runtime execute it, the undo module keeps every reversible change rollback-able, audit records the outcome, triggers and cron schedule further runs, and the CLI is how a user starts one." - }, - "order": [ - "pyvdisk.vscript.frontend", - "pyvdisk.vscript.policy", - "pyvdisk.vscript.mounts", - "pyvdisk.vscript.host", - "pyvdisk.vscript.stdlib", - "pyvdisk.vscript.runtime", - "pyvdisk.vscript.undo", - "pyvdisk.vscript.audit", - "pyvdisk.vscript.triggers", - "pyvdisk.vscript.cron", - "pyvdisk.vscript.cli" - ], - "groups": [ - { - "id": "frontend", - "title": { - "zh": "语言前端", - "en": "Language Front End" - }, - "children": [ - "pyvdisk.vscript.frontend" - ] - }, - { - "id": "security", - "title": { - "zh": "沙箱与能力", - "en": "Sandbox and Capabilities" - }, - "children": [ - "pyvdisk.vscript.policy", - "pyvdisk.vscript.mounts", - "pyvdisk.vscript.host" - ] - }, - { - "id": "runtime", - "title": { - "zh": "运行时与审计", - "en": "Runtime and Audit" - }, - "children": [ - "pyvdisk.vscript.stdlib", - "pyvdisk.vscript.runtime", - "pyvdisk.vscript.undo", - "pyvdisk.vscript.audit" - ] - }, - { - "id": "events", - "title": { - "zh": "触发器与调度", - "en": "Triggers and Scheduling" - }, - "children": [ - "pyvdisk.vscript.triggers", - "pyvdisk.vscript.cron" - ] - }, - { - "id": "entry", - "title": { - "zh": "命令行", - "en": "CLI" - }, - "children": [ - "pyvdisk.vscript.cli" - ] - } - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/audit.json b/normify-pyvdisk/renders/pyvdisk/vscript/audit.json deleted file mode 100644 index cbd42b1..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/audit.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.audit", - "updated_at": "2026-09-24T09:55:53.156Z", - "reading": { - "zh": "先是脚本与策略的内容哈希,再是由它们构成的记录形态、查询与保留辅助、负责持久化与校验的 sink,以及填充记录的 run id 与计时辅助。", - "en": "Content hashes of script and policy, then the record shape built from them, the query/retention helpers, the sinks that persist and verify records, and the run-id and timing helpers that fill them in." - }, - "order": [ - "pyvdisk.vscript.audit.hashing", - "pyvdisk.vscript.audit.record", - "pyvdisk.vscript.audit.query", - "pyvdisk.vscript.audit.sinks", - "pyvdisk.vscript.audit.clock" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/cli.json b/normify-pyvdisk/renders/pyvdisk/vscript/cli.json deleted file mode 100644 index 228e20e..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/cli.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.cli", - "updated_at": "2026-09-23T07:25:08.831Z", - "reading": { - "zh": "先是把本接口挂到主 CLI 的解析器钩子,再是含挂载授权的 check/run 命令,最后是交互式 REPL。", - "en": "The parser hook that grafts this surface onto the main CLI, the check/run commands with mount authorization, and the interactive REPL." - }, - "order": [ - "pyvdisk.vscript.cli.parser", - "pyvdisk.vscript.cli.commands", - "pyvdisk.vscript.cli.repl" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/frontend.json b/normify-pyvdisk/renders/pyvdisk/vscript/frontend.json deleted file mode 100644 index 9286afc..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/frontend.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.frontend", - "updated_at": "2026-09-23T07:25:09.231Z", - "reading": { - "zh": "按编译流水线顺序阅读:词法单元词表、词法器、AST 节点、语法解析器,以及前四者用于报告的的位置/诊断与错误类型。", - "en": "The compilation pipeline in order: token vocabulary, lexer, AST nodes, parser, and the span/diagnostic and error types the first four report through." - }, - "order": [ - "pyvdisk.vscript.frontend.tokens", - "pyvdisk.vscript.frontend.lexer", - "pyvdisk.vscript.frontend.ast", - "pyvdisk.vscript.frontend.parser", - "pyvdisk.vscript.frontend.span", - "pyvdisk.vscript.frontend.errors" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/host.json b/normify-pyvdisk/renders/pyvdisk/vscript/host.json deleted file mode 100644 index dc1864e..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/host.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.host", - "updated_at": "2026-09-23T07:25:09.568Z", - "reading": { - "zh": "guard 是读写根白名单的强制执行;module 是面向脚本的读取、写入与传输入口,全部经它限权。", - "en": "guard is the allowlisted read/write root enforcement; module is the script-facing read/write/transfer entry points that all funnel through it." - }, - "order": [ - "pyvdisk.vscript.host.guard", - "pyvdisk.vscript.host.module" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/policy.json b/normify-pyvdisk/renders/pyvdisk/vscript/policy.json deleted file mode 100644 index 1f16608..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/policy.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.policy", - "updated_at": "2026-09-23T07:25:09.885Z", - "reading": { - "zh": "budget 是声明式限额与强制限额的运行时计数器;capability 是脚本必须满足的逐句柄权限集。", - "en": "budget is the declarative limits plus the runtime counter that enforces them; capability is the per-handle permission set a script must satisfy." - }, - "order": [ - "pyvdisk.vscript.policy.budget", - "pyvdisk.vscript.policy.capability" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/runtime.json b/normify-pyvdisk/renders/pyvdisk/vscript/runtime.json deleted file mode 100644 index 1649aa8..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/runtime.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.runtime", - "updated_at": "2026-09-23T07:25:10.297Z", - "reading": { - "zh": "先是作用域与控制流,再是可调用对象与任务,随后是解释器核心及其两张分发表(语句与表达式)、模块加载,最后是带撤销日志的脚本事务。", - "en": "Scopes and control flow, then callables and tasks, then the interpreter core and its two dispatch tables (statements and expressions), module loading, and finally script transactions with their undo journal." - }, - "order": [ - "pyvdisk.vscript.runtime.env", - "pyvdisk.vscript.runtime.callables", - "pyvdisk.vscript.runtime.core", - "pyvdisk.vscript.runtime.statements", - "pyvdisk.vscript.runtime.expressions", - "pyvdisk.vscript.runtime.modules", - "pyvdisk.vscript.runtime.tx" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/stdlib.json b/normify-pyvdisk/renders/pyvdisk/vscript/stdlib.json deleted file mode 100644 index 05b015b..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/stdlib.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.stdlib", - "updated_at": "2026-09-23T07:25:10.640Z", - "reading": { - "zh": "先是原生模块与 Handle 基础设施,再是每个原生函数都会调用的两个守卫,最后是组装 fs、vector、log 与 json 模块的工厂。", - "en": "Native module and Handle plumbing first, then the two guard helpers every native calls, and finally the factory that assembles the fs, vector, log and json modules." - }, - "order": [ - "pyvdisk.vscript.stdlib.native", - "pyvdisk.vscript.stdlib.guards", - "pyvdisk.vscript.stdlib.factory" - ] -} diff --git a/normify-pyvdisk/renders/pyvdisk/vscript/triggers.json b/normify-pyvdisk/renders/pyvdisk/vscript/triggers.json deleted file mode 100644 index 3496119..0000000 --- a/normify-pyvdisk/renders/pyvdisk/vscript/triggers.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "schema_version": 1, - "id": "pyvdisk.vscript.triggers", - "updated_at": "2026-09-23T07:25:11.546Z", - "reading": { - "zh": "registry 声明并持久化应当触发什么;daemon 轮询文件与日志事件、经检查点去重并调用处理函数。", - "en": "registry declares and persists what should fire; daemon polls file and log events, dedups them through checkpoints and invokes handlers." - }, - "order": [ - "pyvdisk.vscript.triggers.registry", - "pyvdisk.vscript.triggers.daemon" - ] -} diff --git a/normify-pyvdisk/tree.json b/normify-pyvdisk/tree.json deleted file mode 100644 index dcfd2e4..0000000 --- a/normify-pyvdisk/tree.json +++ /dev/null @@ -1,23006 +0,0 @@ -{ - "schema_version": 1, - "project": { - "name": "normify-pyvdisk", - "trees": [ - { - "tree_id": "pyvdisk", - "root_uid": "9185f699", - "repository": "https://github.com/HeDaas-Code/pyvdisk" - } - ], - "compiled_at": "2026-09-24T11:51:44.100Z", - "stats": { - "tree_count": 1, - "module_count": 290, - "leaf_count": 249, - "api_count": 844, - "dep_count": 132, - "cross_tree_dep_count": 0, - "max_depth": 4, - "layout_count": 41, - "planned_count": 0, - "deprecated_count": 0, - "policy_rule_count": 2, - "change_count": 5, - "open_change_count": 0 - } - }, - "modules": { - "pyvdisk": { - "uid": "9185f699", - "id": "pyvdisk", - "parent": null, - "tree": "pyvdisk", - "depth": 1, - "tags": [ - "python", - "agentic", - "storage", - "vscript" - ], - "name": { - "zh": "PyVDisk", - "en": "PyVDisk" - }, - "description": { - "zh": "单机 Agentic 数据与执行基础设施:一个 .vdisk 容器承载文件系统、向量记忆、事件轨迹、检查点、WAL 与运行状态,并内置 VScript 安全工作流语言。核心不依赖标准库之外的任何东西,Linux 与 Windows 同一套代码;AgentSandbox 让这个容器可以直接当成 Agent 工作区使用。\n", - "en": "Single-machine agentic data and execution infrastructure: one .vdisk container carries FS, vector memory, event trace, checkpoints, WAL and run state, plus the VScript safe workflow language. The core depends on nothing outside the standard library and runs on Linux and Windows alike, and AgentSandbox makes the container directly usable as an agent workspace.\n" - }, - "source": [], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "repository": "https://github.com/HeDaas-Code/pyvdisk", - "aggregate": { - "descendant_count": 289, - "own_api_count": 0, - "inherited_api_count": 844, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.agent": { - "uid": "a0000335", - "id": "pyvdisk.agent", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "name": { - "zh": "Agent 工作区", - "en": "Agent Workspace" - }, - "description": { - "zh": "把 DataDisk 包成可以直接交给 Agent 框架的工作区:工具 schema、调用分发、路径约束与哈希链审计。对接面只有两个调用:tools() 与 dispatch()。\n", - "en": "Wraps a DataDisk into a workspace an agent framework can be handed: tool schemas, call dispatch, path confinement and a hash-chained audit trail. The integration surface is two calls, tools() and dispatch().\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 198, - "end_line": 314 - }, - { - "path": "pyvdisk/sandbox.py", - "line": 387, - "end_line": 474 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 21, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.agent.audit": { - "uid": "a000033a", - "id": "pyvdisk.agent.audit", - "parent": "pyvdisk.agent", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "工具调用审计", - "en": "Tool Call Audit" - }, - "description": { - "zh": "每次调用——包括每次被拒的调用——都写入哈希链流 agent-audit,记录工具名、参数、状态、错误类型与能力摘要。\"模型是不是读了不该读的路径\"这个问题,事后可以从日志里回答。\n", - "en": "Every call -- including every refusal -- is written to the hash-chained stream agent-audit with its tool name, arguments, status, error type and capability summary. An agent that read a path it should not have is a question the log can answer after the fact.\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 584, - "end_line": 665 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "apis": [ - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.audit", - "description": { - "zh": "审计行,由旧到新。过滤条件为 sink 自身支持的若干项,外加 tool——它按行里记录的工具名筛选。\n", - "en": "Audit rows, oldest first. Filters are the sink's own plus tool, which selects on the tool name recorded in the row.\n" - }, - "key": "rpc:sandbox:AgentSandbox.audit" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.verify_audit", - "description": { - "zh": "校验整条哈希链;在 sink 之外追加的行会把它断开。\n", - "en": "Check the hash chain end to end; a row appended outside the sink breaks it.\n" - }, - "key": "rpc:sandbox:AgentSandbox.verify_audit" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.retain_audit", - "description": { - "zh": "按流上的保留策略裁剪,同时保持哈希链仍可校验。\n", - "en": "Apply the stream's retention policy while keeping the chain verifiable.\n" - }, - "key": "rpc:sandbox:AgentSandbox.retain_audit" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.stats", - "description": { - "zh": "调用与失败计数、工具集与磁盘占用,可序列化为 JSON 进日志。\n", - "en": "Call and failure counters, the tool set and disk usage, JSON-serialisable for logs.\n" - }, - "key": "rpc:sandbox:AgentSandbox.stats" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.agent.paths": { - "uid": "a0000337", - "id": "pyvdisk.agent.paths", - "parent": "pyvdisk.agent", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "路径约束", - "en": "Path Confinement" - }, - "description": { - "zh": "沙箱内\"路径意味着什么\"的唯一一份定义。反斜杠输入被归一化,Windows 样式的路径留在镜像内部,.. 是拒绝而不是解析,容器自身的簿记对读写与列举一律不可见。\n", - "en": "The one definition of what a path means inside the sandbox: backslash input is normalised, Windows-looking paths stay inside the image, .. is refused rather than resolved, and the container's own bookkeeping is hidden from reads, writes and listings alike.\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 60, - "end_line": 195 - }, - { - "path": "pyvdisk/sandbox.py", - "line": 387, - "end_line": 420 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "apis": [ - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox._normalize", - "description": { - "zh": "把模型给的路径映射进沙箱命名空间:反斜杠归一化,C:\\Windows 变成 /C:/Windows。\n", - "en": "Map a model-supplied path into the sandbox namespace: backslashes are normalised and C:\\Windows becomes /C:/Windows.\n" - }, - "key": "rpc:sandbox:AgentSandbox._normalize" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox._visible", - "description": { - "zh": "先归一化,再拒绝容器自身的簿记路径。\n", - "en": "Normalise, then refuse the container's own bookkeeping paths.\n" - }, - "key": "rpc:sandbox:AgentSandbox._visible" - }, - { - "protocol": "rpc", - "path": "sandbox:_hidden", - "description": { - "zh": "路径是否属于 /.system、/.vectors、/.logs,或是根目录下的清单文件。\n", - "en": "Whether a path is under /.system, /.vectors or /.logs, or is one of the root-level manifests.\n" - }, - "key": "rpc:sandbox:_hidden" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.agent.sandbox": { - "uid": "a0000336", - "id": "pyvdisk.agent.sandbox", - "parent": "pyvdisk.agent", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "沙箱门面", - "en": "Sandbox Facade" - }, - "description": { - "zh": "门面本体:create/open、Python 动词(write/read/list/make_directory/delete/exists)、脚本入口,以及 close/上下文管理器生命周期。read_only 由 capability 层强制,而不只是把工具藏起来,所以直接调用动词同样被拒。\n", - "en": "The facade itself: create/open, the Python verbs (write/read/list/make_directory/delete/exists), the script entry, and the close/context-manager lifecycle. read_only is enforced by the capability layer rather than by hiding tools, so a direct verb is refused too.\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 316, - "end_line": 474 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "apis": [ - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.write", - "description": { - "zh": "写入文本或字节,沿途自动建父目录。拒绝容器内部目录,也拒绝任何会越出根目录的路径。\n", - "en": "Write text or bytes, creating parent directories on the way. Refuses hidden bookkeeping paths and anything that would escape the root.\n" - }, - "key": "rpc:sandbox:AgentSandbox.write" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.read", - "description": { - "zh": "读取原始字节;read_text() 返回解码后的字符串。\n", - "en": "Read raw bytes, then read_text() for a decoded string.\n" - }, - "key": "rpc:sandbox:AgentSandbox.read" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.list", - "description": { - "zh": "列出条目及其类型与大小。容器内部路径会被过滤,模型不会看到一个用不了的名字。\n", - "en": "List entries with type and size. Hidden container paths are filtered out, so the agent never sees a name it cannot use.\n" - }, - "key": "rpc:sandbox:AgentSandbox.list" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.make_directory", - "description": { - "zh": "创建目录,自动建父级。\n", - "en": "Make a directory, creating parents.\n" - }, - "key": "rpc:sandbox:AgentSandbox.make_directory" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.delete", - "description": { - "zh": "删除文件;recursive 为真时删整棵目录树。\n", - "en": "Delete a file, or a directory tree when recursive is set.\n" - }, - "key": "rpc:sandbox:AgentSandbox.delete" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.exists", - "description": { - "zh": "可见路径是否存在。内部路径一律返回 False。\n", - "en": "Whether a visible path exists. Hidden paths always answer False.\n" - }, - "key": "rpc:sandbox:AgentSandbox.exists" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.create", - "description": { - "zh": "新建或打开沙箱背后的镜像,可传 read_only、allow_delete、宿主根目录与审计上限等选项。\n", - "en": "Open or create the image behind the sandbox, with options such as read_only, allow_delete, host roots and audit limits.\n" - }, - "key": "rpc:sandbox:AgentSandbox.create" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.open", - "description": { - "zh": "重新打开已有镜像;工作区与审计记录都保留。\n", - "en": "Reopen an existing image; the workspace and the audit trail both survive.\n" - }, - "key": "rpc:sandbox:AgentSandbox.open" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.agent.script": { - "uid": "a0000339", - "id": "pyvdisk.agent.script", - "parent": "pyvdisk.agent", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "盘内脚本", - "en": "Sandboxed Scripts" - }, - "description": { - "zh": "盘内 VScript 入口:脚本带着沙箱挂载运行,默认禁止宿主访问,stdout 返回给模型。挂载前面的适配器同样把容器簿记从 listdir、walk、glob 里滤掉,脚本入口不会变成规则更松的第二个入口。\n", - "en": "The in-disk VScript entry: a script runs with the sandbox mounted, host access denied by default, and its stdout returned to the model. The adapter in front of the mount filters container bookkeeping out of listdir, walk and glob as well, so the script door is not a second entrance with looser rules.\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 72, - "end_line": 195 - }, - { - "path": "pyvdisk/sandbox.py", - "line": 476, - "end_line": 510 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "apis": [ - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.run", - "description": { - "zh": "执行 VScript 程序,沙箱绑定为变量 sandbox。未配置宿主根目录时宿主访问一律被拒;墙钟时间、输出与写入字节数都有上限。\n", - "en": "Run a VScript program with the sandbox bound as the variable sandbox. Host access is refused unless roots were configured; wall time, output and written bytes are all capped.\n" - }, - "key": "rpc:sandbox:AgentSandbox.run" - }, - { - "protocol": "rpc", - "path": "sandbox:_SandboxFS", - "description": { - "zh": "脚本看到的文件系统。每个路径都走与 Python 动词相同的可见性规则,两个入口不可能出现不一致。\n", - "en": "The filesystem a script sees. Every path is translated through the same visibility rule the Python verbs use, so the two entrances cannot disagree.\n" - }, - "key": "rpc:sandbox:_SandboxFS" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.agent.tools": { - "uid": "a0000338", - "id": "pyvdisk.agent.tools", - "parent": "pyvdisk.agent", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "工具面", - "en": "Tool Surface" - }, - "description": { - "zh": "六个内置工具:write_file、read_file、list_files、make_directory、delete_file、run_script,以及面向各框架约定的 schema 渲染,和在真正碰磁盘之前先校验参数的分发。\n", - "en": "The six built-in tools: write_file, read_file, list_files, make_directory, delete_file and run_script, plus the schema rendering for each framework convention and the dispatch that validates arguments before anything touches the disk.\n" - }, - "source": [ - { - "path": "pyvdisk/sandbox.py", - "line": 198, - "end_line": 314 - }, - { - "path": "pyvdisk/sandbox.py", - "line": 512, - "end_line": 583 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "16f85eddeab0b3086fcfd918528a3d307ffcfbfa3cf7f030223ac20f360a198d", - "apis": [ - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.tools", - "description": { - "zh": "交给模型的工具定义。openai 与 anthropic 共用 {name, description, parameters};mcp 把 schema 键换成 inputSchema。\n", - "en": "The tool definitions to hand the model. openai and anthropic share {name, description, parameters}; mcp renames the schema key to inputSchema.\n" - }, - "key": "rpc:sandbox:AgentSandbox.tools" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.dispatch", - "description": { - "zh": "执行工具并始终返回字符串——拒绝也是字符串,因此可以原样回灌消息列表。\n", - "en": "Run a named tool and always return a string -- a refusal is a string too, so it goes back into the message list unchanged.\n" - }, - "key": "rpc:sandbox:AgentSandbox.dispatch" - }, - { - "protocol": "rpc", - "path": "sandbox:AgentSandbox.call", - "description": { - "zh": "dispatch 的结构化形式:ok、content、tool、error,供需要分支判断的调用方使用。\n", - "en": "The structured form of dispatch: ok, content, tool and error, for callers that branch on the outcome.\n" - }, - "key": "rpc:sandbox:AgentSandbox.call" - }, - { - "protocol": "rpc", - "path": "sandbox:TOOLS", - "description": { - "zh": "六个内置的文件系统与脚本工具及其 JSON Schema 参数。\n", - "en": "The six built-in filesystem and script tools, with their JSON Schema parameters.\n" - }, - "key": "rpc:sandbox:TOOLS" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.api": { - "uid": "a0000322", - "id": "pyvdisk.api", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "api" - ], - "name": { - "zh": "公开门面", - "en": "Public Facade" - }, - "description": { - "zh": "公开门面:调用方直接从 pyvdisk 包根导入的存储、执行、Agent 与契约名称。\n", - "en": "Public facade: the storage, execution, agent and contract names that callers import directly from the pyvdisk package root.\n" - }, - "source": [ - { - "path": "pyvdisk/__init__.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "829b9ac86974d0b749ac032ca0809ff290509d8be9218da09a8823562bd84a3b", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.VirtualDisk", - "description": { - "zh": "宿主 .vdisk 文件之上的块设备。\n", - "en": "Block device over a host .vdisk file.\n" - }, - "key": "rpc:pyvdisk.VirtualDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.VFS", - "description": { - "zh": "高层路径式虚拟文件系统门面。\n", - "en": "High-level path-based virtual filesystem facade.\n" - }, - "key": "rpc:pyvdisk.VFS" - }, - { - "protocol": "rpc", - "path": "pyvdisk.DataDisk", - "description": { - "zh": "在包根导出的统一 DataDisk 容器。\n", - "en": "Unified DataDisk container exported at the package root.\n" - }, - "key": "rpc:pyvdisk.DataDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.ExecutionService", - "description": { - "zh": "在包根导出的执行平面实现。\n", - "en": "Execution plane implementation exported at the package root.\n" - }, - "key": "rpc:pyvdisk.ExecutionService" - }, - { - "protocol": "rpc", - "path": "pyvdisk.DurableQueue", - "description": { - "zh": "在包根导出的持久任务队列。\n", - "en": "Durable task queue exported at the package root.\n" - }, - "key": "rpc:pyvdisk.DurableQueue" - }, - { - "protocol": "rpc", - "path": "pyvdisk.CheckpointStore", - "description": { - "zh": "在包根导出的检查点键值存储。\n", - "en": "Checkpoint-backed key/value store exported at the package root.\n" - }, - "key": "rpc:pyvdisk.CheckpointStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.VectorDisk", - "description": { - "zh": "在包根导出的向量盘。\n", - "en": "Vector disk exported at the package root.\n" - }, - "key": "rpc:pyvdisk.VectorDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.RunHandle", - "description": { - "zh": "执行平面返回的运行句柄。\n", - "en": "Run handle returned by the execution plane.\n" - }, - "key": "rpc:pyvdisk.RunHandle" - }, - { - "protocol": "rpc", - "path": "pyvdisk.AgentSandbox", - "description": { - "zh": "Agent 工作区门面:Agent 框架只需要这一个导入。\n", - "en": "The agent workspace facade: the one import an agent framework needs.\n" - }, - "key": "rpc:pyvdisk.AgentSandbox" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat", - "description": { - "zh": "平台适配层;导出后调用方可以查询当前用的是哪套实现。\n", - "en": "The platform layer, exported so callers can ask which implementation is live.\n" - }, - "key": "rpc:pyvdisk.compat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.FlatIndex", - "description": { - "zh": "无外部依赖的精确向量索引。\n", - "en": "The dependency-free exact vector index.\n" - }, - "key": "rpc:pyvdisk.FlatIndex" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.agent.sandbox", - "from_api": "rpc:pyvdisk.AgentSandbox", - "label": { - "zh": "转出沙箱门面", - "en": "re-exports the sandbox" - }, - "cross_tree": false - }, - { - "kind": "reference", - "to": "pyvdisk.platform", - "from_api": "rpc:pyvdisk.compat", - "label": { - "zh": "转出平台适配层", - "en": "re-exports the platform layer" - }, - "cross_tree": false - }, - { - "kind": "reference", - "to": "pyvdisk.storage.vector.flat-index", - "from_api": "rpc:pyvdisk.FlatIndex", - "label": { - "zh": "转出扁平索引", - "en": "re-exports the flat index" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 11, - "inherited_api_count": 0, - "dep_out": 3, - "dep_in": 0 - } - }, - "pyvdisk.cli": { - "uid": "a000031f", - "id": "pyvdisk.cli", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "cli" - ], - "name": { - "zh": "命令行", - "en": "Command Line" - }, - "description": { - "zh": "命令行界面:参数解析以及文件系统、卷、驱动器、向量、日志与状态检查子命令。\n", - "en": "Command line interface: argument parsing plus filesystem, volume, drive, vector, log and inspection subcommands.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py" - }, - { - "path": "pyvdisk/__main__.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1d8a742c452a9efbcb8f6f9055b1d84192c6434b3512e71a65479f0fdbb2a2be", - "aggregate": { - "descendant_count": 14, - "own_api_count": 0, - "inherited_api_count": 59, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.admin": { - "uid": "a0000c0a", - "id": "pyvdisk.cli.admin", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "管理子命令", - "en": "Admin Subcommands" - }, - "description": { - "zh": "管理类子命令:格式化、链接、属性、空间统计、fsck 与扩容。\n", - "en": "Administrative subcommands: format, links, attributes, space accounting, fsck and resize.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 306, - "end_line": 407 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_format", - "description": { - "zh": "格式化镜像,可选强制重建。\n", - "en": "Format an image, optionally forcing re-creation.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_format" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_ln", - "description": { - "zh": "创建硬链接或符号链接。\n", - "en": "Create a hard or symbolic link.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_ln" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_chmod", - "description": { - "zh": "修改模式位。\n", - "en": "Change mode bits.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_chmod" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_chown", - "description": { - "zh": "修改属主。\n", - "en": "Change ownership.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_chown" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_df", - "description": { - "zh": "打印文件系统空间使用。\n", - "en": "Print filesystem space usage.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_df" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_du", - "description": { - "zh": "打印子树的递归占用。\n", - "en": "Print recursive disk usage of a subtree.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_du" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_fsck", - "description": { - "zh": "运行一致性检查,可选修复。\n", - "en": "Run a consistency check, optionally repairing.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_fsck" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_resize", - "description": { - "zh": "就地扩容镜像。\n", - "en": "Grow an image in place.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_resize" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.dirs": { - "uid": "a0000c07", - "id": "pyvdisk.cli.dirs", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "目录子命令", - "en": "Directory Subcommands" - }, - "description": { - "zh": "目录与删除子命令,语义与对应文件系统操作一致。\n", - "en": "Directory and deletion subcommands, with the same semantics as their filesystem counterparts.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 153, - "end_line": 188 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_mkdir", - "description": { - "zh": "创建单个目录。\n", - "en": "Create one directory.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_mkdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_rmdir", - "description": { - "zh": "删除空目录。\n", - "en": "Remove an empty directory.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_rmdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_rm", - "description": { - "zh": "删除文件或目录树。\n", - "en": "Remove a file or directory tree.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_rm" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_cat", - "description": { - "zh": "把文件内容输出到标准输出。\n", - "en": "Print a file to standard output.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_cat" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.drive": { - "uid": "a0000c0c", - "id": "pyvdisk.cli.drive", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "驱动器子命令", - "en": "Drive Subcommands" - }, - "description": { - "zh": "模拟驱动器子命令:scan、mount-all 与卷标管理。\n", - "en": "Simulated drive bay subcommands: scan, mount-all and label management.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 493, - "end_line": 572 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_scan", - "description": { - "zh": "扫描宿主目录并报告其中发现的介质。\n", - "en": "Scan a host directory and report the media found there.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_scan" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_mount_all", - "description": { - "zh": "按卷标挂载全部检测到的盘与卷。\n", - "en": "Mount every detected disk and volume by label.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_mount_all" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_label", - "description": { - "zh": "在身份尾标中重置磁盘卷标。\n", - "en": "Reassign a disk label in its identity trailer.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_label" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.entry": { - "uid": "a0000f03", - "id": "pyvdisk.cli.entry", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "cli" - ], - "name": { - "zh": "模块入口", - "en": "Module Entry" - }, - "description": { - "zh": "让包可直接执行的 4 行模块入口。\n", - "en": "The four-line module entry point making the package directly executable.\n" - }, - "source": [ - { - "path": "pyvdisk/__main__.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "db66f6dfd7da8e7b715ebafb64ada9834869a86cda0750e8a1c37d574c2a3bbe", - "apis": [ - { - "protocol": "file", - "path": "pyvdisk/__main__.py", - "description": { - "zh": "以 python -m pyvdisk 调用时运行 CLI 的模块入口。\n", - "en": "Module entry point that runs the CLI when invoked as python -m pyvdisk.\n" - }, - "key": "file:pyvdisk/__main__.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.file-ops": { - "uid": "a0000c08", - "id": "pyvdisk.cli.file-ops", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "文件子命令", - "en": "File Subcommands" - }, - "description": { - "zh": "整文件子命令:write、append、copy、move 与宿主导入导出。\n", - "en": "Whole-file subcommands: write, append, copy, move and host import/export.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 189, - "end_line": 254 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_write", - "description": { - "zh": "向文件写入数据,内容可内联或来自文件。\n", - "en": "Write data into a file, accepting inline or file-sourced content.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_write" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_append", - "description": { - "zh": "向文件追加数据。\n", - "en": "Append data to a file.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_append" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_cp", - "description": { - "zh": "在 VFS 内部复制。\n", - "en": "Copy inside the VFS.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_cp" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_mv", - "description": { - "zh": "在 VFS 内部移动或重命名。\n", - "en": "Move or rename inside the VFS.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_mv" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_import", - "description": { - "zh": "导入宿主文件或目录树。\n", - "en": "Import a host file or tree.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_import" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_export", - "description": { - "zh": "把 VFS 路径导出到宿主。\n", - "en": "Export a VFS path to the host.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_export" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.format": { - "uid": "a0000c04", - "id": "pyvdisk.cli.format", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "CLI 格式化", - "en": "CLI Formatting" - }, - "description": { - "zh": "各子命令共用的 CLI 格式化与解析辅助。\n", - "en": "CLI formatting and parsing helpers shared by every subcommand.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 24, - "end_line": 64 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli._parse_size", - "description": { - "zh": "把带单位后缀的尺寸字符串解析为字节数。\n", - "en": "Parse size strings with unit suffixes into bytes.\n" - }, - "key": "rpc:pyvdisk.cli._parse_size" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli._type_str", - "description": { - "zh": "把 inode 类型号渲染为 ls 风格字符。\n", - "en": "Render an inode type number as its ls-style letter.\n" - }, - "key": "rpc:pyvdisk.cli._type_str" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli._human_size", - "description": { - "zh": "把字节数格式化为人类可读。\n", - "en": "Format a byte count for humans.\n" - }, - "key": "rpc:pyvdisk.cli._human_size" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli._add_cred_args", - "description": { - "zh": "为子解析器添加 uid/gid 凭据选项。\n", - "en": "Add uid/gid credential options to a subparser.\n" - }, - "key": "rpc:pyvdisk.cli._add_cred_args" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.image": { - "uid": "a0000c06", - "id": "pyvdisk.cli.image", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "镜像子命令", - "en": "Image Subcommands" - }, - "description": { - "zh": "镜像生命周期与检查子命令:create、info、status 与列举。\n", - "en": "Image lifecycle and inspection subcommands: create, info, status and listing.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 77, - "end_line": 152 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_create", - "description": { - "zh": "按命令行参数创建新的磁盘镜像或卷。\n", - "en": "Create a new disk image or volume from CLI arguments.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_info", - "description": { - "zh": "打印磁盘身份、几何与剩余空间信息。\n", - "en": "Print disk identity, geometry and free-space information.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_info" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_status", - "description": { - "zh": "打印紧凑的磁盘状态汇总。\n", - "en": "Print a compact disk status summary.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_status" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_ls", - "description": { - "zh": "以 ls 风格输出列举目录。\n", - "en": "List a directory with ls-style output.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_ls" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.inspect": { - "uid": "a0000c09", - "id": "pyvdisk.cli.inspect", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "检查子命令", - "en": "Inspection Subcommands" - }, - "description": { - "zh": "检查与挂载子命令:stat、tree、mount 与 touch。\n", - "en": "Inspection and mounting subcommands: stat, tree, mount and touch.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 255, - "end_line": 305 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_stat", - "description": { - "zh": "打印路径的详细 stat 记录。\n", - "en": "Print a detailed stat record for a path.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_stat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_tree", - "description": { - "zh": "打印路径的目录树。\n", - "en": "Print the directory tree of a path.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_tree" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_mount", - "description": { - "zh": "把磁盘镜像挂载到宿主目录,可选经 FUSE。\n", - "en": "Mount a disk image at a host directory, optionally through FUSE.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_touch", - "description": { - "zh": "创建空文件。\n", - "en": "Create an empty file.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_touch" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.log": { - "uid": "a0000c0e", - "id": "pyvdisk.cli.log", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "日志子命令", - "en": "Log Subcommands" - }, - "description": { - "zh": "日志盘子命令:流管理、写入、查询、tail、统计、压缩与保留策略。\n", - "en": "Log-disk subcommands: stream management, emission, query, tail, statistics, compaction and retention.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 626, - "end_line": 674 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_create", - "description": { - "zh": "创建日志盘。\n", - "en": "Create a log disk.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_stream", - "description": { - "zh": "创建、列举或删除日志流。\n", - "en": "Create, list or drop a log stream.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_stream" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_emit", - "description": { - "zh": "向流追加事件。\n", - "en": "Append an event to a stream.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_emit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_query", - "description": { - "zh": "带过滤条件查询流。\n", - "en": "Query a stream with filters.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_query" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_tail", - "description": { - "zh": "打印流的最近事件。\n", - "en": "Print the most recent events of a stream.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_tail" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_stats", - "description": { - "zh": "打印每流统计。\n", - "en": "Print per-stream statistics.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_stats" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_compact", - "description": { - "zh": "压缩流。\n", - "en": "Compact a stream.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_compact" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_log_retention", - "description": { - "zh": "对流派生保留策略。\n", - "en": "Enforce retention on a stream.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_log_retention" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.main": { - "uid": "a0000c10", - "id": "pyvdisk.cli.main", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "CLI 入口", - "en": "CLI Entry Point" - }, - "description": { - "zh": "CLI 入口:把错误映射为退出码,以及 python -m pyvdisk 钩子。\n", - "en": "The CLI entry point: error mapping to exit codes, and the python -m pyvdisk hook.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 950, - "end_line": 966 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:26:30.912Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.main", - "description": { - "zh": "解析参数、分发子命令并把错误转为退出码。\n", - "en": "Parse arguments, dispatch the subcommand and translate errors into exit codes.\n" - }, - "key": "rpc:pyvdisk.cli.main" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.cli.open": { - "uid": "a0000c05", - "id": "pyvdisk.cli.open", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "CLI 打开 VFS", - "en": "CLI VFS Open" - }, - "description": { - "zh": "每个文件系统子命令获取已挂载 VFS 的唯一入口。\n", - "en": "The single entry point every filesystem subcommand uses to obtain a mounted VFS.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 65, - "end_line": 75 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.024Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli._open_vfs", - "description": { - "zh": "按命令行参数打开 VFS,处理凭据与卷成员。\n", - "en": "Open the VFS named by CLI arguments, resolving credentials and volume membership.\n" - }, - "key": "rpc:pyvdisk.cli._open_vfs" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.open", - "from_api": "rpc:pyvdisk.cli._open_vfs", - "to_api": "rpc:pyvdisk.vfs.VFS", - "label": { - "zh": "打开 VFS", - "en": "opens VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.cli.parser": { - "uid": "a0000c0f", - "id": "pyvdisk.cli.parser", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "参数解析器", - "en": "Argument Parser" - }, - "description": { - "zh": "参数解析器定义:全部子命令、各自选项与共享的镜像参数组。\n", - "en": "The argument parser definition: every subcommand, its options and the shared image argument group.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 675, - "end_line": 949 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.build_parser", - "description": { - "zh": "构建完整 argparse 树,含嵌套镜像参数与 vscript 钩子。\n", - "en": "Build the full argparse tree, including nested image arguments and the vscript hook.\n" - }, - "key": "rpc:pyvdisk.cli.build_parser" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.cli.parser", - "from_api": "rpc:pyvdisk.cli.build_parser", - "to_api": "rpc:pyvdisk.vscript.cli.add_parser", - "label": { - "zh": "添加 vscript 子解析器", - "en": "adds vscript parser" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.cli.vector": { - "uid": "a0000c0d", - "id": "pyvdisk.cli.vector", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "向量子命令", - "en": "Vector Subcommands" - }, - "description": { - "zh": "向量盘子命令:磁盘与集合管理,以及记录 upsert、检索与获取。\n", - "en": "Vector-disk subcommands: disk and collection management plus record upsert, search and retrieval.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 573, - "end_line": 625 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli._json_arg", - "description": { - "zh": "解析内联 JSON 参数。\n", - "en": "Decode an inline JSON argument.\n" - }, - "key": "rpc:pyvdisk.cli._json_arg" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_create", - "description": { - "zh": "创建向量盘。\n", - "en": "Create a vector disk.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_collection", - "description": { - "zh": "创建、列举或删除集合。\n", - "en": "Create, list or drop a collection.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_collection" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_upsert", - "description": { - "zh": "向集合 upsert 记录。\n", - "en": "Upsert records into a collection.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_upsert" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_search", - "description": { - "zh": "执行相似度检索。\n", - "en": "Run a similarity search.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_search" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_get", - "description": { - "zh": "按 id 获取记录。\n", - "en": "Fetch a record by id.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_delete", - "description": { - "zh": "按 id 删除记录。\n", - "en": "Delete a record by id.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_delete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vec_list", - "description": { - "zh": "列出向量盘的集合。\n", - "en": "List the collections of a vector disk.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vec_list" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.cli.volume": { - "uid": "a0000c0b", - "id": "pyvdisk.cli.volume", - "parent": "pyvdisk.cli", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "卷子命令", - "en": "Volume Subcommands" - }, - "description": { - "zh": "卷子命令:创建、状态与在线镜像维护。\n", - "en": "Volume subcommands covering creation, status and online mirror maintenance.\n" - }, - "source": [ - { - "path": "pyvdisk/cli.py", - "line": 408, - "end_line": 492 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "93bfec8924577ecc9e2568629fdaedff8a73379a5d29cd81a40928f400d3ad11", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_create", - "description": { - "zh": "创建多盘卷。\n", - "en": "Create a multi-disk volume.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_status", - "description": { - "zh": "打印卷模式、成员与健康状况。\n", - "en": "Print volume mode, members and health.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_status" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_format", - "description": { - "zh": "格式化已有卷。\n", - "en": "Format an existing volume.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_format" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_add", - "description": { - "zh": "在线新增镜像成员。\n", - "en": "Add a mirror member online.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_add" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_remove", - "description": { - "zh": "在线移除镜像成员。\n", - "en": "Remove a mirror member online.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_remove" - }, - { - "protocol": "rpc", - "path": "pyvdisk.cli.cmd_vol_resync", - "description": { - "zh": "重新同步镜像成员。\n", - "en": "Resynchronize mirror members.\n" - }, - "key": "rpc:pyvdisk.cli.cmd_vol_resync" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.compat": { - "uid": "a0000323", - "id": "pyvdisk.compat", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "deprecated" - ], - "name": { - "zh": "兼容垫片", - "en": "Compatibility Shims" - }, - "description": { - "zh": "向后兼容垫片:保留旧的 Unified/Container 名称与遗留 vscript.checkpoint 导入路径。\n", - "en": "Backward-compatibility shims that keep old Unified/Container names and the legacy vscript.checkpoint import path working.\n" - }, - "source": [ - { - "path": "pyvdisk/unified.py" - }, - { - "path": "pyvdisk/vscript/checkpoint.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:25:52.858Z", - "fingerprint": "6f7e62522b92762cdebef84ead8584d62ebb049484266259a4bb81ab6486fa94", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 3, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.compat.unified": { - "uid": "a0000f01", - "id": "pyvdisk.compat.unified", - "parent": "pyvdisk.compat", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "compat" - ], - "name": { - "zh": "Unified 别名", - "en": "Unified Aliases" - }, - "description": { - "zh": "兼容重导出:保留容器化之前的 DataDisk 与 MetadataTransaction 导入路径。\n", - "en": "Compatibility re-exports that keep the pre-container DataDisk and MetadataTransaction import paths working.\n" - }, - "source": [ - { - "path": "pyvdisk/unified.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7bd0da8459e2672fd8efee93a3734b6ed45da3af20763bc82dabc158f892e87d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.unified.DataDisk", - "description": { - "zh": "保留旧 Unified 容器名称可导入的兼容别名。\n", - "en": "Legacy alias keeping the old Unified container name importable.\n" - }, - "key": "rpc:pyvdisk.unified.DataDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.unified.MetadataTransaction", - "description": { - "zh": "元数据事务类型的兼容别名。\n", - "en": "Legacy alias for the metadata transaction type.\n" - }, - "key": "rpc:pyvdisk.unified.MetadataTransaction" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.compat.vscript": { - "uid": "a0000f02", - "id": "pyvdisk.compat.vscript", - "parent": "pyvdisk.compat", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "compat" - ], - "name": { - "zh": "VScript 检查点垫片", - "en": "VScript Checkpoint Shim" - }, - "description": { - "zh": "遗留垫片:在存储移入 infrastructure 后仍保留 vscript.checkpoint 模块路径可导入。\n", - "en": "Legacy shim that keeps the vscript.checkpoint module path importable after the store moved into infrastructure.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/checkpoint.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "ed01dfc21949e087c9a325e41118c960083b90243e8ab58b85a860de7cd2a8e0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.checkpoint.CheckpointStore", - "description": { - "zh": "为旧调用方重导出的遗留检查点导入路径。\n", - "en": "Legacy checkpoint import path re-exported for older callers.\n" - }, - "key": "rpc:pyvdisk.vscript.checkpoint.CheckpointStore" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.contracts": { - "uid": "a000010c", - "id": "pyvdisk.contracts", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "contract", - "protocol" - ], - "name": { - "zh": "后端契约", - "en": "Backend Contracts" - }, - "description": { - "zh": "存储与执行平面的后端中立契约:能力、持久性、块/命名空间/集合/事件存储,以及执行平面协议。\n", - "en": "Backend-neutral contracts for the storage and execution planes: capability, durability, block/namespace/collection/event stores and the execution plane protocol.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "aggregate": { - "descendant_count": 7, - "own_api_count": 0, - "inherited_api_count": 24, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.contracts.capability": { - "uid": "a000010d", - "id": "pyvdisk.contracts.capability", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "能力授权", - "en": "Capability Grant" - }, - "description": { - "zh": "Capability 枚举与 CapabilityGrant:治理层、执行上下文与 VScript 共用的权限词表。\n", - "en": "Capability enum and CapabilityGrant: the permission vocabulary shared by governance, execution contexts and VScript.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 16, - "end_line": 37 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.Capability", - "description": { - "zh": "能力权限枚举:read、write、append、admin。\n", - "en": "Capability permission enum: read, write, append, admin.\n" - }, - "key": "rpc:pyvdisk.contracts.Capability" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.CapabilityGrant", - "description": { - "zh": "单次执行持有的具名、可限定范围的授权。\n", - "en": "Named, optionally scoped grant held by one execution.\n" - }, - "key": "rpc:pyvdisk.contracts.CapabilityGrant" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.CapabilityGrant#allows", - "description": { - "zh": "判断某权限在给定范围下是否被允许。\n", - "en": "Check whether a permission is allowed inside an optional scope.\n" - }, - "key": "rpc:pyvdisk.contracts.CapabilityGrant#allows" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.CapabilityGrant#require", - "description": { - "zh": "缺少任一权限时抛出 PermissionError。\n", - "en": "Raise PermissionError unless every listed permission is granted.\n" - }, - "key": "rpc:pyvdisk.contracts.CapabilityGrant#require" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.contracts.durability": { - "uid": "a000010e", - "id": "pyvdisk.contracts.durability", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "持久性", - "en": "Durability" - }, - "description": { - "zh": "持久性请求词表:后端可以提供强于请求的保证。\n", - "en": "Durability request vocabulary: a backend may provide a stronger guarantee than requested.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 40, - "end_line": 57 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.DurabilityMode", - "description": { - "zh": "持久性级别枚举:memory、flushed、synced、replicated。\n", - "en": "Durability level enum: memory, flushed, synced, replicated.\n" - }, - "key": "rpc:pyvdisk.contracts.DurabilityMode" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.Durability", - "description": { - "zh": "带副本数的持久性请求及其校验。\n", - "en": "Requested durability with a replica count and validation.\n" - }, - "key": "rpc:pyvdisk.contracts.Durability" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.contracts.events": { - "uid": "a0000110", - "id": "pyvdisk.contracts.events", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "事件契约", - "en": "Event Contracts" - }, - "description": { - "zh": "事件值类型,以及结构化日志使用的追加/读取事件存储协议。\n", - "en": "Event value type and the append/read event-store protocol used by the structured log.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 86, - "end_line": 96 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.Event", - "description": { - "zh": "不可变事件:流名、负载、event_id 与时间戳。\n", - "en": "Immutable event with stream, payload, event_id and timestamp.\n" - }, - "key": "rpc:pyvdisk.contracts.Event" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.EventStore", - "description": { - "zh": "事件流的追加与读取协议。\n", - "en": "Append/read event stream protocol.\n" - }, - "key": "rpc:pyvdisk.contracts.EventStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.EventStore#append", - "description": { - "zh": "追加一个事件并返回其持久 event id。\n", - "en": "Append one event and return its durable event id.\n" - }, - "key": "rpc:pyvdisk.contracts.EventStore#append" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.EventStore#read", - "description": { - "zh": "从游标之后按可选上限读取某流的事件。\n", - "en": "Read events from a stream after a cursor with an optional limit.\n" - }, - "key": "rpc:pyvdisk.contracts.EventStore#read" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.contracts.execution": { - "uid": "a0000111", - "id": "pyvdisk.contracts.execution", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "执行上下文", - "en": "Execution Context" - }, - "description": { - "zh": "ExecutionContext:交给单次二层执行的依赖与策略信封。\n", - "en": "ExecutionContext: the dependency and policy envelope handed to one layer-2 execution.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 99, - "end_line": 114 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.ExecutionContext", - "description": { - "zh": "执行依赖与策略:run_id、能力授权、持久性、存储句柄与截止时间。\n", - "en": "Execution dependencies and policy: run_id, capability grants, durability, stores, deadline.\n" - }, - "key": "rpc:pyvdisk.contracts.ExecutionContext" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.ExecutionContext#require", - "description": { - "zh": "没有任何授权允许该权限时抛出 PermissionError。\n", - "en": "Raise PermissionError unless some grant allows the permission.\n" - }, - "key": "rpc:pyvdisk.contracts.ExecutionContext#require" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.ExecutionContext#expired", - "description": { - "zh": "判断执行截止时间是否已过。\n", - "en": "Report whether the execution deadline has passed.\n" - }, - "key": "rpc:pyvdisk.contracts.ExecutionContext#expired" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.contracts.plane": { - "uid": "a0000113", - "id": "pyvdisk.contracts.plane", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "执行平面协议", - "en": "Execution Plane" - }, - "description": { - "zh": "ExecutionPlane 协议:每个执行后端都必须暴露的唯一 submit 入口。\n", - "en": "ExecutionPlane protocol: the single submit entry point every execution backend must expose.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 158, - "end_line": 162 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.ExecutionPlane#submit", - "description": { - "zh": "带执行上下文提交操作并返回 RunHandle。\n", - "en": "Submit an operation with an execution context and return a RunHandle.\n" - }, - "key": "rpc:pyvdisk.contracts.ExecutionPlane#submit" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.contracts.runhandle": { - "uid": "a0000112", - "id": "pyvdisk.contracts.runhandle", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "运行句柄", - "en": "Run Handle" - }, - "description": { - "zh": "RunHandle:执行平面返回的可观察、可取消句柄;取消不会覆盖终态。\n", - "en": "RunHandle: the observable, cancellable handle returned by the execution plane; cancellation never overwrites a terminal state.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 117, - "end_line": 155 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.RunHandle", - "description": { - "zh": "可观察句柄:run_id、状态、结果与错误。\n", - "en": "Observable handle carrying run_id, status, result and error.\n" - }, - "key": "rpc:pyvdisk.contracts.RunHandle" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.RunHandle#complete", - "description": { - "zh": "将运行标记为成功(已取消则忽略)。\n", - "en": "Mark the run succeeded unless it was already cancelled.\n" - }, - "key": "rpc:pyvdisk.contracts.RunHandle#complete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.RunHandle#fail", - "description": { - "zh": "将运行标记为失败(已取消则忽略)。\n", - "en": "Mark the run failed unless it was already cancelled.\n" - }, - "key": "rpc:pyvdisk.contracts.RunHandle#fail" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.RunHandle#cancel", - "description": { - "zh": "协作式取消尚未完成的运行。\n", - "en": "Cooperatively cancel a not-yet-finished run.\n" - }, - "key": "rpc:pyvdisk.contracts.RunHandle#cancel" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.RunHandle#wait", - "description": { - "zh": "阻塞直到运行结束,并重新抛出其错误。\n", - "en": "Block until the run finishes, re-raising its error.\n" - }, - "key": "rpc:pyvdisk.contracts.RunHandle#wait" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.contracts.storage": { - "uid": "a000010f", - "id": "pyvdisk.contracts.storage", - "parent": "pyvdisk.contracts", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "存储协议", - "en": "Storage Protocols" - }, - "description": { - "zh": "结构化存储协议:BlockDevice、NamespaceStore、CollectionStore;既有后端以结构化方式满足它们。\n", - "en": "Structural storage protocols: BlockDevice, NamespaceStore and CollectionStore; existing backends satisfy them structurally.\n" - }, - "source": [ - { - "path": "pyvdisk/contracts.py", - "line": 60, - "end_line": 83 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7094a1dd45da0c9a7ac8d898a6f97d47ae87d10d3f32818f4e2dfa6c7b5eab40", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.contracts.BlockDevice", - "description": { - "zh": "面向一层存储后端的定长块 IO 协议。\n", - "en": "Fixed-size block IO protocol for layer-1 storage backends.\n" - }, - "key": "rpc:pyvdisk.contracts.BlockDevice" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.NamespaceStore", - "description": { - "zh": "以路径为键的元数据命名空间协议:get、put、delete、list。\n", - "en": "Path-keyed metadata namespace protocol: get, put, delete, list.\n" - }, - "key": "rpc:pyvdisk.contracts.NamespaceStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.CollectionStore", - "description": { - "zh": "具名集合协议:create、drop、put、get、scan。\n", - "en": "Named collection protocol: create, drop, put, get, scan.\n" - }, - "key": "rpc:pyvdisk.contracts.CollectionStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.BlockDevice#read_block", - "description": { - "zh": "按下标读取一个定长块。\n", - "en": "Read one fixed-size block by index.\n" - }, - "key": "rpc:pyvdisk.contracts.BlockDevice#read_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.contracts.BlockDevice#write_block", - "description": { - "zh": "在指定持久性下写入一个块。\n", - "en": "Write one block under a requested durability.\n" - }, - "key": "rpc:pyvdisk.contracts.BlockDevice#write_block" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.delivery": { - "uid": "a0000108", - "id": "pyvdisk.delivery", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "packaging", - "ci" - ], - "name": { - "zh": "打包与持续集成", - "en": "Packaging and CI" - }, - "description": { - "zh": "分发与持续集成:打包元数据、PEP 561 类型标记与 GitHub Actions 工作流。\n", - "en": "Distribution and continuous integration: packaging metadata, PEP 561 typing marker and the GitHub Actions workflows.\n" - }, - "source": [ - { - "path": "pyproject.toml" - }, - { - "path": ".github/workflows/ci.yml" - }, - { - "path": ".github/workflows/pylint.yml" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ffb2fa1aa3e3cc015e3b71a246768d8b6ebbd7ef155a40d3000dafa42f532369", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 6, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.delivery.ci": { - "uid": "a000010a", - "id": "pyvdisk.delivery.ci", - "parent": "pyvdisk.delivery", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "测试工作流", - "en": "Test Workflow" - }, - "description": { - "zh": "CI 工作流:安装 dev 与 vector extras,在 push 与 pull request 上跨 3.9–3.12 矩阵跑 pytest,让声明的 requires-python 下限由最老的矩阵任务强制而不是靠假设。另有独立任务只装基础包并断言加速器确实缺席,零依赖的承诺因此不是自说自话。\n", - "en": "CI workflow: installs the dev and vector extras and runs pytest on push and pull request across the 3.9-3.12 matrix, so the declared requires-python floor is enforced by the oldest job rather than assumed. A second job installs the package without extras and asserts the accelerators are absent, which keeps the zero-dependency claim honest.\n" - }, - "source": [ - { - "path": ".github/workflows/ci.yml" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "2bf7b99f2ff50585631ea75453ea75cc457a6fe7bece3d39c4fd4b40d5eadc13", - "apis": [ - { - "protocol": "file", - "path": ".github/workflows/ci.yml", - "description": { - "zh": "主测试工作流:安装依赖并运行 pytest 套件。\n", - "en": "Main test workflow: install and run the pytest suite.\n" - }, - "key": "file:.github/workflows/ci.yml" - }, - { - "protocol": "file", - "path": ".github/workflows/ci.yml#no-dependencies", - "description": { - "zh": "零依赖任务:只装 [dev],断言 hnswlib、fusepy、numpy 都不可导入,然后跑整套用例。\n", - "en": "Zero-dependency job: installs [dev] only, asserts hnswlib, fusepy and numpy are absent, then runs the suite.\n" - }, - "key": "file:.github/workflows/ci.yml#no-dependencies" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.delivery.lint": { - "uid": "a000010b", - "id": "pyvdisk.delivery.lint", - "parent": "pyvdisk.delivery", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "静态分析工作流", - "en": "Lint Workflow" - }, - "description": { - "zh": "独立于单元测试门禁的静态分析流水线:pylint 只保留 error 类,使 Lint 失败不会被误认为测试失败。\n", - "en": "Static analysis pipeline, independent of the unit-test gate: pylint with the error class only, so a lint failure can never be mistaken for a test failure.\n" - }, - "source": [ - { - "path": ".github/workflows/pylint.yml" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.216Z", - "fingerprint": "b8b7a5b39cc8e23ea498ca698d6446ab567057a9fe91d2088fb0b05d8f95e2ac", - "apis": [ - { - "protocol": "file", - "path": ".github/workflows/pylint.yml", - "description": { - "zh": "静态分析工作流:对包运行 pylint。\n", - "en": "Static-analysis workflow: run pylint over the package.\n" - }, - "key": "file:.github/workflows/pylint.yml" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.delivery.packaging": { - "uid": "a0000109", - "id": "pyvdisk.delivery.packaging", - "parent": "pyvdisk.delivery", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "打包元数据", - "en": "Packaging Metadata" - }, - "description": { - "zh": "分发元数据:运行时依赖为空,hnswlib 与 fusepy 下沉到 vector、fuse 两个 extra,外加 py.typed 标记,以及把 LICENSE 与 CHANGELOG.md 一并打包的 sdist 清单。\n", - "en": "Distribution metadata: no runtime dependencies at all, with hnswlib and fusepy moved to the vector and fuse extras, the py.typed marker, and the sdist manifest that ships LICENSE plus CHANGELOG.md.\n" - }, - "source": [ - { - "path": "pyproject.toml", - "line": 1 - }, - { - "path": "MANIFEST.in", - "line": 1 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "e83415f6936531ac1130878c36a08b49e1795946d20ecc3bf95a507560e0a608", - "apis": [ - { - "protocol": "file", - "path": "pyproject.toml", - "description": { - "zh": "打包元数据:包名、版本、依赖、extras 与 pytest 配置。\n", - "en": "Packaging metadata: name, version, dependencies, extras and the pytest configuration.\n" - }, - "key": "file:pyproject.toml" - }, - { - "protocol": "file", - "path": "pyvdisk/py.typed", - "description": { - "zh": "PEP 561 类型标记,使类型检查器认可本包有类型。\n", - "en": "PEP 561 marker so type checkers see the package as typed.\n" - }, - "key": "file:pyvdisk/py.typed" - }, - { - "protocol": "file", - "path": "MANIFEST.in", - "description": { - "zh": "sdist 清单:把 LICENSE 与 CHANGELOG.md 一并打包,setuptools 不会自动带上它们。\n", - "en": "sdist manifest: ships LICENSE and CHANGELOG.md, which setuptools does not include by itself.\n" - }, - "key": "file:MANIFEST.in" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.docs": { - "uid": "a0000102", - "id": "pyvdisk.docs", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "docs" - ], - "name": { - "zh": "技术文档", - "en": "Technical Docs" - }, - "description": { - "zh": "仓库技术文档层:架构设计、契约边界、API 治理与 VScript 语言规范,是模块结构的一手证据来源。\n", - "en": "Repository documentation layer: architecture, contracts, API governance and the VScript spec; the primary evidence source for this module tree.\n" - }, - "source": [ - { - "path": "README.md" - }, - { - "path": "docs/ARCHITECTURE.md" - }, - { - "path": "docs/CONTRACTS.md" - }, - { - "path": "docs/API_GOVERNANCE.md" - }, - { - "path": "docs/VSCRIPT_SPEC.md" - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.626Z", - "fingerprint": "8d769f91ff4b5ef98a97e401560ea0b464b62e52d7f0300183d14660d5a10460", - "aggregate": { - "descendant_count": 6, - "own_api_count": 0, - "inherited_api_count": 6, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.docs.api-governance": { - "uid": "a0000106", - "id": "pyvdisk.docs.api-governance", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "API 治理", - "en": "API Governance" - }, - "description": { - "zh": "API 治理:公开入口、权限模型、已废弃的旧路径,以及推荐给 Agent 使用的接口面。\n", - "en": "API governance: public entry points, permission model, deprecated legacy paths and the recommended agent-facing surface.\n" - }, - "source": [ - { - "path": "docs/API_GOVERNANCE.md" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "d81bb08b805e5d98279d49f4397e3cb3f6b00a80e87fda2ebad975ec4e64e133", - "apis": [ - { - "protocol": "file", - "path": "docs/API_GOVERNANCE.md", - "description": { - "zh": "API 治理与使用策略文档。\n", - "en": "API governance and usage-policy document.\n" - }, - "key": "file:docs/API_GOVERNANCE.md" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.docs.architecture": { - "uid": "a0000104", - "id": "pyvdisk.docs.architecture", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "架构设计", - "en": "Architecture Design" - }, - "description": { - "zh": "架构设计:存储平面、执行平面、单盘 ACID、内部 exactly-once、解释器架构与故障恢复流程。\n", - "en": "Architecture design: storage plane, execution plane, single-disk ACID, exactly-once, interpreter architecture and recovery flow.\n" - }, - "source": [ - { - "path": "docs/ARCHITECTURE.md" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.218Z", - "fingerprint": "040f8007c5e897dd23e12dacf31ff33c8f79d95afb231e115b8a2f919b1bdde0", - "apis": [ - { - "protocol": "file", - "path": "docs/ARCHITECTURE.md", - "description": { - "zh": "详细架构设计文档。\n", - "en": "Detailed architecture design document.\n" - }, - "key": "file:docs/ARCHITECTURE.md" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.docs.changelog": { - "uid": "156bc3a8", - "id": "pyvdisk.docs.changelog", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "docs", - "changelog" - ], - "name": { - "zh": "变更日志", - "en": "Changelog" - }, - "description": { - "zh": "用户可见变更日志,版本号与 pyproject.toml 保持一致。条目按主题分组(零依赖与跨平台在前),并保留\"已知未完成\"一节,未完成项要看得见,而不是被静默遗忘。\n", - "en": "User-visible change log, versioned in step with pyproject.toml. Entries are grouped by theme (zero dependency and cross-platform first) and carry the residual-limits section, so unfixed items stay visible instead of being quietly forgotten.\n" - }, - "source": [ - { - "path": "CHANGELOG.md", - "line": 1, - "end_line": 47 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "9648b98246e1e081401981daab12fa29c679efa0b189fb23fcb8542b565e7536", - "apis": [ - { - "protocol": "file", - "path": "CHANGELOG.md", - "description": { - "zh": "0.3.0 起的变更日志,含 issue #1 的修复清单与明确留待后续的条目。\n", - "en": "Changelog from 0.3.0 onward, including the issue #1 fix inventory and the items deliberately left open.\n" - }, - "key": "file:CHANGELOG.md" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.docs.contracts": { - "uid": "a0000105", - "id": "pyvdisk.docs.contracts", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "契约边界", - "en": "Contract Boundaries" - }, - "description": { - "zh": "各平面的保证边界:存储、执行、事务与内部 exactly-once 承诺什么、不承诺什么;新增 VScript 事务的撤销记账、本地触发器与审计轨迹三节。\n", - "en": "Per-plane guarantee boundaries: what storage, execution, transactions and internal exactly-once promise and what they do not, now including the VScript transaction undo accounting, the local triggers and the audit trail.\n" - }, - "source": [ - { - "path": "docs/CONTRACTS.md" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.218Z", - "fingerprint": "da48634bd787c62c762739c1f35a5c0ed86c7c8aa9e5a08ee5e9d350aeb9eed4", - "apis": [ - { - "protocol": "file", - "path": "docs/CONTRACTS.md", - "description": { - "zh": "存储/执行/ACID/exactly-once 契约文档。\n", - "en": "Storage/execution/ACID/exactly-once contract document.\n" - }, - "key": "file:docs/CONTRACTS.md" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.docs.readme": { - "uid": "a0000103", - "id": "pyvdisk.docs.readme", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "项目总览", - "en": "Project Overview" - }, - "description": { - "zh": "README 总览:定位、零依赖快速开始、十行 Agent 框架对接 Demo、核心能力、CLI 用法与验证方式;徽章与声明的 Python 下限及当前用例数一致。\n", - "en": "README overview: positioning, zero-dependency quick start, a ten-line agent-framework demo, core capabilities, CLI usage and how it is verified, with badges that match the declared Python floor and the current suite size.\n" - }, - "source": [ - { - "path": "README.md" - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.625Z", - "fingerprint": "342ea9fe45178aeef55db55a465024bd6b8b64e68bf3f3fb0441947f7c90aaa4", - "apis": [ - { - "protocol": "file", - "path": "README.md", - "description": { - "zh": "项目总览文档。\n", - "en": "Project overview document.\n" - }, - "key": "file:README.md" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.docs.architecture", - "from_api": "file:README.md", - "to_api": "file:docs/ARCHITECTURE.md", - "label": { - "zh": "指向架构文档", - "en": "points to architecture doc" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.docs.vscript-spec": { - "uid": "a0000107", - "id": "pyvdisk.docs.vscript-spec", - "parent": "pyvdisk.docs", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 规范", - "en": "VScript Spec" - }, - "description": { - "zh": "VScript 规范:语法、标准库、解释器流水线、能力模型、错误体系与 CLI 入口。\n", - "en": "VScript spec: syntax, standard library, interpreter pipeline, capability model, errors and CLI entry points.\n" - }, - "source": [ - { - "path": "docs/VSCRIPT_SPEC.md" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "14929378e2e6fbfb2003b8c1377587db2d92ddae8d754330d724d782016f8dee", - "apis": [ - { - "protocol": "file", - "path": "docs/VSCRIPT_SPEC.md", - "description": { - "zh": "VScript 语言与安全规范。\n", - "en": "VScript language and safety specification.\n" - }, - "key": "file:docs/VSCRIPT_SPEC.md" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.examples": { - "uid": "a000033b", - "id": "pyvdisk.examples", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "name": { - "zh": "可运行示例", - "en": "Runnable Examples" - }, - "description": { - "zh": "可运行的示例,同时也是最快看懂整条栈怎么跑起来的方式。仅用标准库,从源码目录直接运行无需安装——零依赖的承诺也是靠它们被测试的。\n", - "en": "Runnable examples that double as the fastest way to see the whole stack work. They are standard-library only and run from a checkout without installing anything, which is also how the zero-dependency claim is tested.\n" - }, - "source": [ - { - "path": "examples/quickstart.py" - }, - { - "path": "examples/agent_tools.py" - } - ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.687Z", - "fingerprint": "d256d8803ce7868b443ddd6cfc00d16a7e42f11938c3056dca32f34eef8b11c9", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 2, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.examples.agent-tools": { - "uid": "a000033d", - "id": "pyvdisk.examples.agent-tools", - "parent": "pyvdisk.examples", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "agent", - "example" - ], - "name": { - "zh": "Agent 对接示例", - "en": "Agent Loop Demo" - }, - "description": { - "zh": "带脚本化\"模型\"的完整 agent loop,形状与 README 示例完全一致,因此不需要 API key 与网络,可以进 CI。示例里包含一次越权读取被拒,以及一轮同时请求两个工具,覆盖拒绝路径与多调用列表路径。\n", - "en": "A complete agent loop with a scripted model, shaped exactly like the README demo, so it needs no API key and no network and can run in CI. It includes a refused out-of-root read and a turn that requests two tools at once, covering both the refusal path and the multi-call list path.\n" - }, - "source": [ - { - "path": "examples/agent_tools.py" - } - ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.686Z", - "fingerprint": "38e6efd2ed3bfcec7954b1a00d09cc90b41ca8906175dcbb023a72fefed9f9b7", - "apis": [ - { - "protocol": "file", - "path": "examples/agent_tools.py:scripted_model", - "description": { - "zh": "单次聊天补全调用的替身:返回供循环消费的 assistant 消息;脚本跑完后返回 tool_calls 为空的消息。\n", - "en": "A stand-in for one chat completion call: returns an assistant message whose tool_calls the loop consumes, and an empty tool_calls list when the script runs out.\n" - }, - "key": "file:examples/agent_tools.py:scripted_model" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.examples.quickstart": { - "uid": "a000033c", - "id": "pyvdisk.examples.quickstart", - "parent": "pyvdisk.examples", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "快速上手", - "en": "Quickstart Tour" - }, - "description": { - "zh": "单文件、仅标准库、Windows 与 Linux 通用。从裸块设备一路走到 AgentSandbox,跑一遍就能看清分层,并如实报告用的是哪个索引后端。测试在屏蔽 hnswlib 的子进程里跑它,这正是它能当好\"最初五分钟\"的原因。\n", - "en": "One file, standard library only, Windows and Linux. It walks from a raw block device up to AgentSandbox so the layering is visible in one run, and reports which index backend it got. Tests run it in a subprocess with hnswlib blocked, which is what keeps this usable as a first five minutes.\n" - }, - "source": [ - { - "path": "examples/quickstart.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "366abf85eb8b872da8170a251e0d9afc62647e6ff779753eeac8db7c8900e224", - "apis": [ - { - "protocol": "file", - "path": "examples/quickstart.py", - "description": { - "zh": "在一个进程里自底向上跑通整条栈:块设备、事务、向量检索、日志、VScript,最后是沙箱。\n", - "en": "Run the whole stack bottom-up in one process: block device, transactions, vector search, logs, VScript, then the sandbox.\n" - }, - "key": "file:examples/quickstart.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution": { - "uid": "a0000310", - "id": "pyvdisk.execution", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "execution" - ], - "name": { - "zh": "执行平面", - "en": "Execution Plane" - }, - "description": { - "zh": "执行平面:同步 ExecutionService、持久任务队列、持久化运行状态与操作注册表。\n", - "en": "Execution plane: the synchronous ExecutionService, the durable task queue, persisted run state and the operation registry.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py" - }, - { - "path": "pyvdisk/infrastructure/queue.py" - }, - { - "path": "pyvdisk/infrastructure/run_state.py" - }, - { - "path": "pyvdisk/infrastructure/operations.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "7066bef5c1baa719c1a7faa2194b5c6531a11bf35cbbd739fb0fee99ceebc1e6", - "aggregate": { - "descendant_count": 21, - "own_api_count": 0, - "inherited_api_count": 72, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations": { - "uid": "a0000314", - "id": "pyvdisk.execution.operations", - "parent": "pyvdisk.execution", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "idempotency" - ], - "name": { - "zh": "操作注册表", - "en": "Operation Registry" - }, - "description": { - "zh": "操作注册表:稳定 operation id、负载指纹、持久化结果、可调用对象解析与 VScript 操作描述。\n", - "en": "Operation registry: stable operation ids, payload fingerprints, persisted results, callable resolution and VScript operation description.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "aggregate": { - "descendant_count": 6, - "own_api_count": 0, - "inherited_api_count": 24, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations.callables": { - "uid": "a000090e", - "id": "pyvdisk.execution.operations.callables", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "可调用对象注册表", - "en": "Callable Registry" - }, - "description": { - "zh": "可调用对象注册表,以及把 Python 函数变为可持久重放操作的 RegisteredCallable 包装。\n", - "en": "Callable registry and the RegisteredCallable wrapper that makes a Python function a durable, replayable operation.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 74, - "end_line": 126 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.register_callable", - "description": { - "zh": "以稳定名称注册可调用对象以便后续解析。\n", - "en": "Register a callable under a stable name for later resolution.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.register_callable" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.registered_callables", - "description": { - "zh": "返回名称到可调用对象的注册表快照。\n", - "en": "Return the registry snapshot of name to callable.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.registered_callables" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations._clear_callables", - "description": { - "zh": "清空进程级可调用对象注册表。\n", - "en": "Clear the process-wide callable registry.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations._clear_callables" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.RegisteredCallable", - "description": { - "zh": "可调用对象及预绑定参数,可按名解析并可重放。\n", - "en": "A callable plus pre-bound arguments, resolvable by name and replayable.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.RegisteredCallable" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations.describe": { - "uid": "a000090f", - "id": "pyvdisk.execution.operations.describe", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "操作描述", - "en": "Operation Description" - }, - "description": { - "zh": "操作描述:把可调用对象、VScript 源码与裸负载归一为可序列化形态并生成稳定 id。\n", - "en": "Operation description: normalizes callables, VScript sources and raw payloads into a serializable shape with a stable id.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 127, - "end_line": 166 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations._describe_callable", - "description": { - "zh": "把 Python 可调用对象描述为类型、名称、参数与关键字参数。\n", - "en": "Describe a Python callable as kind, name, args and kwargs.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations._describe_callable" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations._describe_vscript", - "description": { - "zh": "把 VScript 值或源码描述为操作负载。\n", - "en": "Describe a VScript value or source as an operation payload.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations._describe_vscript" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations._describe_payload", - "description": { - "zh": "补全操作负载描述的默认值。\n", - "en": "Fill in defaults of an operation payload description.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations._describe_payload" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.describe_operation", - "description": { - "zh": "描述任意受支持操作类型的公开入口。\n", - "en": "Public entry point that describes any supported operation kind.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.describe_operation" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations.errors": { - "uid": "a000090c", - "id": "pyvdisk.execution.operations.errors", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "操作错误", - "en": "Operation Errors" - }, - "description": { - "zh": "操作注册表错误体系:未知操作与不可序列化操作。\n", - "en": "Operation registry error taxonomy covering unknown and unserializable operations.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 40, - "end_line": 52 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationError", - "description": { - "zh": "操作注册表的错误基类。\n", - "en": "Base error for the operation registry.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationNotFound", - "description": { - "zh": "operation id 未知时抛出。\n", - "en": "Raised when an operation id is unknown.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationNotFound" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.UnserializableOperation", - "description": { - "zh": "操作负载无法序列化时抛出。\n", - "en": "Raised when an operation payload cannot be serialized.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.UnserializableOperation" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations.record": { - "uid": "a000090d", - "id": "pyvdisk.execution.operations.record", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "操作记录", - "en": "Operation Record" - }, - "description": { - "zh": "存储的操作描述及其 JSON 编解码,是稳定 operation id 与幂等性的基础。\n", - "en": "The stored operation description and its JSON codec, the basis of stable operation ids and idempotency.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 53, - "end_line": 73 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRecord", - "description": { - "zh": "持久化操作记录:id、类型、负载指纹与主体。\n", - "en": "Persisted operation record: id, kind, payload fingerprint and body.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRecord" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRecord#to_json", - "description": { - "zh": "把记录渲染为可存储形式。\n", - "en": "Render the record for storage.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRecord#to_json" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRecord#from_json", - "description": { - "zh": "从存储重建记录。\n", - "en": "Rebuild a record from storage.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRecord#from_json" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.operations.registry": { - "uid": "a0000910", - "id": "pyvdisk.execution.operations.registry", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "操作注册表", - "en": "Operation Registry" - }, - "description": { - "zh": "操作注册表门面:存在判定、加载、结果恢复、保存与删除,背衬可为检查点或宿主目录。\n", - "en": "Operation registry facade: existence, load, result recovery, save and forget, over a checkpoint or host backend.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 167, - "end_line": 248 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.308Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry", - "description": { - "zh": "存储、加载与重放操作记录的注册表。\n", - "en": "Registry that stores, loads and replays operation records.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#backend", - "description": { - "zh": "报告注册表使用的背衬存储。\n", - "en": "Report which backing store the registry uses.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#backend" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#has", - "description": { - "zh": "判断某 operation id 是否已登记。\n", - "en": "Test whether an operation id is registered.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#has" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#load", - "description": { - "zh": "按 id 加载操作记录。\n", - "en": "Load an operation record by id.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#load" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#recover", - "description": { - "zh": "返回该操作此前持久化的结果。\n", - "en": "Return the previously persisted result of an operation.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#recover" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#save", - "description": { - "zh": "持久化操作描述并返回其记录。\n", - "en": "Persist an operation description and return its record.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#save" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#forget", - "description": { - "zh": "删除操作记录。\n", - "en": "Forget an operation record.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#forget" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.open", - "from_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#save", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "label": { - "zh": "经检查点持久化", - "en": "persists via checkpoint" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.execution.operations.storage": { - "uid": "a0000911", - "id": "pyvdisk.execution.operations.storage", - "parent": "pyvdisk.execution.operations", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "注册表存储", - "en": "Registry Storage" - }, - "description": { - "zh": "背衬访问与可调用对象解析,注册表的最底层。\n", - "en": "Backend access and callable resolution, the lowest layer of the registry.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/operations.py", - "line": 249, - "end_line": 324 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "6c6d5973baffc84ba17358dc47248de3da2b046dae72d88f9ff96ee9d5fc3bd4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#_raw_get", - "description": { - "zh": "从背衬读取裸操作值。\n", - "en": "Read a raw operation value from the backend.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_raw_get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#_raw_put", - "description": { - "zh": "向背衬写入裸操作值。\n", - "en": "Write a raw operation value to the backend.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_raw_put" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.operations.OperationRegistry#_resolve_callable", - "description": { - "zh": "把已注册的可调用对象名解析回 Python 可调用对象。\n", - "en": "Resolve a registered callable name back to a Python callable.\n" - }, - "key": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_resolve_callable" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.queue": { - "uid": "a0000312", - "id": "pyvdisk.execution.queue", - "parent": "pyvdisk.execution", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "queue", - "lease" - ], - "name": { - "zh": "持久任务队列", - "en": "Durable Queue" - }, - "description": { - "zh": "DurableQueue:以检查点为背衬的任务队列,支持 claim、lease、心跳、退避重试、死信、取消与过期回收。\n", - "en": "DurableQueue: checkpoint-backed task queue with claim, lease, heartbeat, retry with backoff, dead-letter, cancellation and stale-run recovery.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 23, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.queue.errors": { - "uid": "a0000905", - "id": "pyvdisk.execution.queue.errors", - "parent": "pyvdisk.execution.queue", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "队列错误", - "en": "Queue Errors" - }, - "description": { - "zh": "队列错误体系:任务缺失、非法状态迁移与租约丢失。\n", - "en": "Queue error taxonomy: missing tasks, invalid transitions and lost leases.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py", - "line": 19, - "end_line": 35 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.QueueError", - "description": { - "zh": "队列操作的错误基类。\n", - "en": "Base error for queue operations.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.QueueError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.TaskNotFound", - "description": { - "zh": "任务 id 未知时抛出。\n", - "en": "Raised when a task id is unknown.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.TaskNotFound" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.InvalidTaskState", - "description": { - "zh": "操作与任务当前状态不符时抛出。\n", - "en": "Raised when an operation is invalid for the task's current status.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.InvalidTaskState" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.LeaseLost", - "description": { - "zh": "租约过期且任务被回收时抛出。\n", - "en": "Raised when a lease expired and the task was reclaimed.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.LeaseLost" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.queue.lifecycle": { - "uid": "a0000908", - "id": "pyvdisk.execution.queue.lifecycle", - "parent": "pyvdisk.execution.queue", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "任务生命周期", - "en": "Task Lifecycle" - }, - "description": { - "zh": "任务生命周期:入队、带租约领取、心跳、完成、失败、重试、死信与取消。\n", - "en": "Task lifecycle: enqueue, claim with lease, heartbeat, complete, fail, retry, dead-letter and cancel.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py", - "line": 128, - "end_line": 230 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#enqueue", - "description": { - "zh": "入队负载,并按幂等键去重。\n", - "en": "Enqueue a payload, deduplicating by idempotency key.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#enqueue" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#claim", - "description": { - "zh": "领取就绪任务并发放租约。\n", - "en": "Claim a ready task and issue a lease.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#heartbeat", - "description": { - "zh": "延长运行中任务的租约。\n", - "en": "Extend the lease of a running task.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#heartbeat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#complete", - "description": { - "zh": "将任务标记为完成,可选带结果。\n", - "en": "Mark a task completed with an optional result.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#complete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#fail", - "description": { - "zh": "将任务标记为失败,可选安排重试。\n", - "en": "Mark a task failed, optionally scheduling a retry.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#fail" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#retry", - "description": { - "zh": "立即重新入队失败或死信任务。\n", - "en": "Requeue a failed or dead-lettered task immediately.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#retry" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#dead_letter", - "description": { - "zh": "把任务移入死信状态。\n", - "en": "Move a task to the dead-letter state.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#dead_letter" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#cancel", - "description": { - "zh": "取消待处理或运行中的任务。\n", - "en": "Cancel a pending or running task.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#cancel" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.execution.queue.recovery": { - "uid": "a0000909", - "id": "pyvdisk.execution.queue.recovery", - "parent": "pyvdisk.execution.queue", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "队列恢复", - "en": "Queue Recovery" - }, - "description": { - "zh": "可观测性与崩溃恢复:过期租约回收,以及任务查询与列举。\n", - "en": "Observability and crash recovery: stale-lease reclamation plus task lookup and listing.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py", - "line": 231, - "end_line": 260 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#recover_stale", - "description": { - "zh": "回收租约过期的任务,重新入队或转死信。\n", - "en": "Reclaim tasks whose lease expired and requeue or dead-letter them.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#recover_stale" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#get", - "description": { - "zh": "按 id 取单个任务。\n", - "en": "Fetch one task by id.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#list", - "description": { - "zh": "列出任务,可按状态过滤。\n", - "en": "List tasks, optionally filtered by status.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#list" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.queue.store": { - "uid": "a0000907", - "id": "pyvdisk.execution.queue.store", - "parent": "pyvdisk.execution.queue", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "队列存储", - "en": "Queue Store" - }, - "description": { - "zh": "队列存储层:经检查点存储的状态读写,以及重试退避策略。\n", - "en": "Queue storage layer: state load/save through a checkpoint store and the retry backoff policy.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py", - "line": 58, - "end_line": 127 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:22:04.608Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue", - "description": { - "zh": "以检查点为背衬的持久任务队列。\n", - "en": "Checkpoint-backed durable task queue.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#_state", - "description": { - "zh": "读取整个队列状态。\n", - "en": "Read the whole queue state.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_state" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#_save", - "description": { - "zh": "持久化整个队列状态。\n", - "en": "Persist the whole queue state.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_save" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#_backoff_seconds", - "description": { - "zh": "计算某个尝试次数的指数退避延迟。\n", - "en": "Compute the exponential backoff delay for an attempt number.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_backoff_seconds" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#_stamp_next_attempt", - "description": { - "zh": "设置任务的下次可领取时间。\n", - "en": "Set the next eligible attempt time on a task.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_stamp_next_attempt" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.DurableQueue#_task", - "description": { - "zh": "从状态中取单条任务记录。\n", - "en": "Fetch one task record from the state.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_task" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.io", - "from_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_save", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save", - "label": { - "zh": "持久化状态", - "en": "persists state" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 3 - } - }, - "pyvdisk.execution.queue.task": { - "uid": "a0000906", - "id": "pyvdisk.execution.queue.task", - "parent": "pyvdisk.execution.queue", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "队列任务", - "en": "Queue Task" - }, - "description": { - "zh": "队列状态中存储的任务值对象,含租约与尝试次数记账。\n", - "en": "The task value object stored in the queue state, including lease and attempt bookkeeping.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/queue.py", - "line": 36, - "end_line": 57 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1bf87a430e905414842b7c7b482ebffbec2d6d60adc1617411d91f32d3fcd18d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.QueueTask", - "description": { - "zh": "任务记录:id、负载、状态、尝试次数、租约、结果与错误。\n", - "en": "Task record: id, payload, status, attempts, lease, result and error.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.QueueTask" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.queue.QueueTask#from_dict", - "description": { - "zh": "从持久字典重建任务。\n", - "en": "Rebuild a task from its persisted dictionary.\n" - }, - "key": "rpc:pyvdisk.infrastructure.queue.QueueTask#from_dict" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.runstate": { - "uid": "a0000313", - "id": "pyvdisk.execution.runstate", - "parent": "pyvdisk.execution", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "运行状态", - "en": "Run State Store" - }, - "description": { - "zh": "RunStateStore:带版本号的运行记录,受保护的状态转换与过期运行回收,经检查点存储持久化。\n", - "en": "RunStateStore: versioned run records with guarded transitions and stale-running recovery, persisted through a checkpoint store.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/run_state.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "38952ffc815f8771c14753783c0e3da128b6877309ee722d94fe8fb43aa54b97", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 10, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.runstate.model": { - "uid": "a000090a", - "id": "pyvdisk.execution.runstate.model", - "parent": "pyvdisk.execution.runstate", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "运行记录", - "en": "Run Record" - }, - "description": { - "zh": "运行记录模型,以及受保护状态迁移使用的乐观并发冲突类型。\n", - "en": "Run record model and the optimistic-concurrency conflict type used by guarded transitions.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/run_state.py", - "line": 7, - "end_line": 26 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "38952ffc815f8771c14753783c0e3da128b6877309ee722d94fe8fb43aa54b97", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateConflict", - "description": { - "zh": "版本保护的运行状态迁移被拒时抛出。\n", - "en": "Raised when a version-guarded run transition is rejected.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateConflict" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunRecord", - "description": { - "zh": "运行记录:id、状态、版本、幂等键与结果/错误引用。\n", - "en": "Run record: id, status, version, idempotency key and result or error reference.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunRecord" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunRecord#__post_init__", - "description": { - "zh": "一致地初始化记录版本与状态。\n", - "en": "Initialize the record version and status consistently.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunRecord#__post_init__" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.runstate.store": { - "uid": "a000090b", - "id": "pyvdisk.execution.runstate.store", - "parent": "pyvdisk.execution.runstate", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "运行状态存储", - "en": "Run State Store" - }, - "description": { - "zh": "运行状态存储:带幂等的创建、受保护状态迁移、列举与过期运行回收。\n", - "en": "Run state store: create with idempotency, guarded transitions, listing and stale-run recovery.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/run_state.py", - "line": 27, - "end_line": 87 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:22:04.608Z", - "fingerprint": "38952ffc815f8771c14753783c0e3da128b6877309ee722d94fe8fb43aa54b97", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore", - "description": { - "zh": "经检查点存储持久化的带版本运行状态。\n", - "en": "Versioned run state persisted through a checkpoint store.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#from_data_disk", - "description": { - "zh": "从 DataDisk 元数据命名空间构建存储。\n", - "en": "Build the store from a DataDisk metadata namespace.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#from_data_disk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#get", - "description": { - "zh": "获取单条运行记录。\n", - "en": "Fetch one run record.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#list", - "description": { - "zh": "列出运行记录,可按状态过滤。\n", - "en": "List run records, optionally filtered by status.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#list" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#create", - "description": { - "zh": "创建运行记录,并按幂等键去重。\n", - "en": "Create a run record, deduplicating by idempotency key.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#transition", - "description": { - "zh": "执行受版本保护的状态迁移。\n", - "en": "Apply a version-guarded status transition.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#transition" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.run_state.RunStateStore#recover_stale", - "description": { - "zh": "回收停留在中间状态超过最大时长的运行。\n", - "en": "Reclaim runs stuck in a transient status beyond a maximum age.\n" - }, - "key": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#recover_stale" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.open", - "from_api": "rpc:pyvdisk.infrastructure.run_state.RunStateStore", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "label": { - "zh": "持久化运行", - "en": "persists runs" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.execution.service": { - "uid": "a0000311", - "id": "pyvdisk.execution.service", - "parent": "pyvdisk.execution", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "执行服务", - "en": "Execution Service" - }, - "description": { - "zh": "ExecutionService:以 inline 或可选 worker 方式执行 Python 可调用对象与 VScript 源码,绑定 DataDisk、队列、运行状态与审计 sink。\n", - "en": "ExecutionService: inline and optional worker execution of Python callables and VScript sources, bound to a DataDisk, queue, run state and audit sink.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "4152ec61e453494829e848f89f2834faa980e43e4bb670d7b0814b68d3187b61", - "aggregate": { - "descendant_count": 4, - "own_api_count": 0, - "inherited_api_count": 15, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.execution.service.invoke": { - "uid": "a0000902", - "id": "pyvdisk.execution.service.invoke", - "parent": "pyvdisk.execution.service", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "操作分发", - "en": "Operation Dispatch" - }, - "description": { - "zh": "操作分发:受限视图构造与两种执行类型,即 Python 可调用对象与 VScript 源码。\n", - "en": "Operation dispatch: scoped view construction and the two execution kinds, Python callables and VScript sources.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py", - "line": 116, - "end_line": 167 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:22:04.609Z", - "fingerprint": "4152ec61e453494829e848f89f2834faa980e43e4bb670d7b0814b68d3187b61", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#_scoped_view", - "description": { - "zh": "为单次执行上下文构建能力受限的磁盘视图。\n", - "en": "Build the capability-scoped disk view for one execution context.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#_scoped_view" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#_call", - "description": { - "zh": "在执行上下文下调用 Python 可调用对象。\n", - "en": "Invoke a Python callable under an execution context.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#_call" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#_script", - "description": { - "zh": "在策略、挂载与审计之下运行 VScript 源码。\n", - "en": "Run a VScript source under policy, mounts and audit.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#_script" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#_execute", - "description": { - "zh": "执行单个操作并把结果记录到句柄上。\n", - "en": "Execute one operation, recording its outcome on the handle.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#_execute" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.governance.scoped", - "from_api": "rpc:pyvdisk.execution.ExecutionService#_scoped_view", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.scoped", - "label": { - "zh": "限定能力", - "en": "scopes capabilities" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.vscript.runtime.core", - "from_api": "rpc:pyvdisk.execution.ExecutionService#_script", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "label": { - "zh": "运行 VScript", - "en": "runs VScript" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.execution.service.queue": { - "uid": "a0000903", - "id": "pyvdisk.execution.service.queue", - "parent": "pyvdisk.execution.service", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "队列驱动执行", - "en": "Queue-Driven Run" - }, - "description": { - "zh": "队列驱动的执行:带去重的操作入队,以及带租约处理的领取-运行循环。\n", - "en": "Queue-driven execution: operation enqueue with dedup, and the claim-and-run loop with lease handling.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py", - "line": 168, - "end_line": 252 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.024Z", - "fingerprint": "4152ec61e453494829e848f89f2834faa980e43e4bb670d7b0814b68d3187b61", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#enqueue_operation", - "description": { - "zh": "从提交的操作推导队列状态,并按幂等键去重。\n", - "en": "Derive queue state from a submitted operation, deduplicating by idempotency key.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#enqueue_operation" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#run_next", - "description": { - "zh": "在租约内领取并运行下一个就绪任务。\n", - "en": "Claim and run the next ready task within a lease.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#run_next" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#poll_once", - "description": { - "zh": "未运行 worker 循环时轮询队列一次。\n", - "en": "Poll the queue once if a worker loop is not running.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#poll_once" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.queue.lifecycle", - "from_api": "rpc:pyvdisk.execution.ExecutionService#run_next", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim", - "label": { - "zh": "领取任务", - "en": "claims task" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.execution.service.setup": { - "uid": "a0000901", - "id": "pyvdisk.execution.service.setup", - "parent": "pyvdisk.execution.service", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "服务初始化", - "en": "Service Setup" - }, - "description": { - "zh": "ExecutionService 构造与 worker 池控制:同步内联执行与后台处理之间的边界。\n", - "en": "ExecutionService construction and worker pool control: the boundary between inline execution and background processing.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py", - "line": 18, - "end_line": 115 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "4152ec61e453494829e848f89f2834faa980e43e4bb670d7b0814b68d3187b61", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService", - "description": { - "zh": "同步执行平面,可选后台 worker。\n", - "en": "Synchronous execution plane, optionally with background workers.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#worker_count", - "description": { - "zh": "当前运行中的 worker 线程数。\n", - "en": "Number of worker threads currently running.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#worker_count" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#start_workers", - "description": { - "zh": "启动轮询持久队列的后台 worker 线程。\n", - "en": "Start background worker threads polling the durable queue.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#start_workers" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#stop_workers", - "description": { - "zh": "停止 worker,可选等待在途任务。\n", - "en": "Stop workers, optionally waiting for in-flight tasks.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#stop_workers" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#enqueue_async", - "description": { - "zh": "把任务加入队列异步执行并返回句柄。\n", - "en": "Enqueue a task for asynchronous execution and return its handle.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#enqueue_async" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.queue.store", - "from_api": "rpc:pyvdisk.execution.ExecutionService", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue", - "label": { - "zh": "持有持久队列", - "en": "holds durable queue" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.api", - "from_api": "rpc:pyvdisk.execution.ExecutionService", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#get_metadata", - "label": { - "zh": "读取元数据", - "en": "reads metadata" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.execution.service.submit": { - "uid": "a0000904", - "id": "pyvdisk.execution.service.submit", - "parent": "pyvdisk.execution.service", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "提交与取消", - "en": "Submit and Cancel" - }, - "description": { - "zh": "ExecutionPlane 协议的实现:submit、阻塞式 run 与取消。\n", - "en": "The ExecutionPlane protocol implementation: submit, blocking run and cancellation.\n" - }, - "source": [ - { - "path": "pyvdisk/execution.py", - "line": 253, - "end_line": 284 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.308Z", - "fingerprint": "4152ec61e453494829e848f89f2834faa980e43e4bb670d7b0814b68d3187b61", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#submit", - "description": { - "zh": "提交操作并立即返回 RunHandle。\n", - "en": "Submit an operation and return a RunHandle immediately.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#submit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#run", - "description": { - "zh": "提交操作并阻塞至完成。\n", - "en": "Submit an operation and block until it finishes.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#run" - }, - { - "protocol": "rpc", - "path": "pyvdisk.execution.ExecutionService#cancel", - "description": { - "zh": "协作式取消已提交的操作。\n", - "en": "Cooperatively cancel a submitted operation.\n" - }, - "key": "rpc:pyvdisk.execution.ExecutionService#cancel" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.contracts.runhandle", - "from_api": "rpc:pyvdisk.execution.ExecutionService#submit", - "to_api": "rpc:pyvdisk.contracts.RunHandle", - "label": { - "zh": "返回句柄", - "en": "returns handle" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.governance": { - "uid": "a000031e", - "id": "pyvdisk.governance", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "security" - ], - "name": { - "zh": "能力治理", - "en": "Capability Governance" - }, - "description": { - "zh": "能力治理:路径归一化、受保护命名空间适配器,以及交给不可信调用方的 ScopedDataDisk。\n", - "en": "Capability governance: path normalization, guarded namespace adapters and the ScopedDataDisk handed to untrusted callers.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/capabilities.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.219Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", - "aggregate": { - "descendant_count": 4, - "own_api_count": 0, - "inherited_api_count": 26, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.governance.data": { - "uid": "a0000810", - "id": "pyvdisk.governance.data", - "parent": "pyvdisk.governance", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "受限数据服务", - "en": "Scoped Data Services" - }, - "description": { - "zh": "能力治理的向量与日志半边:按集合与流划分范围,区分读、写、追加与 admin 权限。\n", - "en": "Vector and log halves of capability governance: collection- and stream-level scoping with read, write, append and admin permissions.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 83, - "end_line": 127 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.219Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedVectorNamespace", - "description": { - "zh": "把每个集合限制在能力范围内的向量适配器。\n", - "en": "Vector adapter that confines each collection to a capability scope.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#_scope", - "description": { - "zh": "推导集合的范围路径。\n", - "en": "Derive the scope path of a collection.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#_scope" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#create_collection", - "description": { - "zh": "带权限检查的集合创建。\n", - "en": "Permission-checked collection creation.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#create_collection" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#upsert", - "description": { - "zh": "带权限检查的记录 upsert。\n", - "en": "Permission-checked record upsert.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#upsert" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#search", - "description": { - "zh": "带权限检查的相似度检索。\n", - "en": "Permission-checked similarity search.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#search" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedLogNamespace", - "description": { - "zh": "把每个流限制在能力范围内的日志适配器。\n", - "en": "Log adapter that confines each stream to a capability scope.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedLogNamespace#append", - "description": { - "zh": "带权限检查的事件追加。\n", - "en": "Permission-checked event append.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#append" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedLogNamespace#enforce_retention", - "description": { - "zh": "带权限检查的保留策略执行。\n", - "en": "Permission-checked retention enforcement.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#enforce_retention" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vector.records", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#upsert", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "label": { - "zh": "委托给向量盘", - "en": "delegates to vector disk" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.log.append", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#append", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "label": { - "zh": "委托给日志盘", - "en": "delegates to log disk" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.governance.files": { - "uid": "a000080f", - "id": "pyvdisk.governance.files", - "parent": "pyvdisk.governance", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "受限文件系统", - "en": "Scoped Filesystem" - }, - "description": { - "zh": "能力治理的文件系统半边:每个 VFS 方法都必须经过权限与范围检查才能触达。\n", - "en": "Filesystem half of capability governance: every VFS method is reachable only through a permission and scope check.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 50, - "end_line": 81 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.220Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace", - "description": { - "zh": "在每次文件系统调用前检查逐路径权限的 VFS 适配器。\n", - "en": "VFS adapter that checks a per-path permission before every filesystem call.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#_check_file", - "description": { - "zh": "检查单个路径的读、写或删除权限。\n", - "en": "Check read, write or delete permission on one path.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#_check_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#exists", - "description": { - "zh": "带权限检查的路径存在性判定。\n", - "en": "Permission-checked path existence test.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#exists" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#listdir", - "description": { - "zh": "带权限检查的目录列举。\n", - "en": "Permission-checked directory listing.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#listdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#read_file", - "description": { - "zh": "带权限检查的整文件读取。\n", - "en": "Permission-checked whole-file read.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#read_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#write_file", - "description": { - "zh": "带权限检查的整文件写入。\n", - "en": "Permission-checked whole-file write.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#write_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#rmtree", - "description": { - "zh": "带权限检查的递归删除。\n", - "en": "Permission-checked recursive removal.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#rmtree" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedFileNamespace#fsck", - "description": { - "zh": "运行 fsck,修复时要求 admin 能力。\n", - "en": "Run fsck, requiring the admin capability when repairing.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#fsck" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#read_file", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", - "label": { - "zh": "委托给 VFS", - "en": "delegates to VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.governance.namespace": { - "uid": "a000080e", - "id": "pyvdisk.governance.namespace", - "parent": "pyvdisk.governance", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "能力门禁", - "en": "Capability Gate" - }, - "description": { - "zh": "能力门禁:路径归一、范围包含判定,以及所有受限命名空间共用的受保护委托辅助。\n", - "en": "The capability gate: path normalization, scope containment and the guarded delegation helper all scoped namespaces share.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 7, - "end_line": 49 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._path", - "description": { - "zh": "把能力范围归一到以 / 为根、以斜线为界的路径。\n", - "en": "Normalize a capability scope into a rooted, slash-bounded path.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities._path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities._inside", - "description": { - "zh": "路径被包含在范围内时为真。\n", - "en": "True when a path is contained in a scope.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities._inside" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace", - "description": { - "zh": "基础适配器:在委托前把能力检查变为守卫条件。\n", - "en": "Base adapter that turns capability checks into guard clauses before delegating.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "description": { - "zh": "对照执行上下文范围检查单个权限。\n", - "en": "Check one permission against the execution context scope.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call", - "description": { - "zh": "受保护的委托调用,向下传递所需权限与范围。\n", - "en": "Guarded delegated call that propagates the required permission and scope.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.contracts.capability", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", - "label": { - "zh": "检查授权", - "en": "checks grants" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.governance.scoped": { - "uid": "a0000811", - "id": "pyvdisk.governance.scoped", - "parent": "pyvdisk.governance", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "受限容器", - "en": "Scoped Container" - }, - "description": { - "zh": "检查点范围限定,以及执行层交给不可信代码的 ScopedDataDisk 对象与工厂。\n", - "en": "Checkpoint scoping plus the ScopedDataDisk object and factory that execution passes to untrusted code.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/capabilities.py", - "line": 130, - "end_line": 162 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.221Z", - "fingerprint": "6e43b5202db42eeca8d389509c7b4cc39ed45eea060f91c8c3a05087de3f820f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace", - "description": { - "zh": "把每个键限制在能力集内的检查点适配器。\n", - "en": "Checkpoint adapter that scopes each key to the capability set.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk", - "description": { - "zh": "交给不可信调用方的单一对象:DataDisk 及其能力上下文。\n", - "en": "The single object handed to untrusted callers: a DataDisk plus its capability context.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__", - "description": { - "zh": "挂载底层容器并返回受限视图。\n", - "en": "Mount the underlying container and return the scoped view.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__", - "description": { - "zh": "上下文退出时关闭底层容器。\n", - "en": "Close the underlying container on context exit.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.capabilities.scoped", - "description": { - "zh": "把一个 DataDisk 包装为单次执行上下文视图的便利工厂。\n", - "en": "Convenience factory that wraps a DataDisk for one execution context.\n" - }, - "key": "rpc:pyvdisk.infrastructure.capabilities.scoped" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.platform": { - "uid": "a000032f", - "id": "pyvdisk.platform", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "name": { - "zh": "平台适配层", - "en": "Platform Adaptation" - }, - "description": { - "zh": "唯一直接触碰操作系统原语的地方:定位读写、整文件锁、目录 fsync、进程身份与符号链接支持。其余模块一律经由它,平台差异只处理一次,而不是在每个调用点各写一份。\n", - "en": "The single place that touches operating-system primitives: positional IO, whole-file locking, directory fsync, process identity and symlink support. Every other module goes through it, so Windows differences are handled once instead of at each call site.\n" - }, - "source": [ - { - "path": "pyvdisk/compat.py" - }, - { - "path": "pyvdisk/disk.py" - }, - { - "path": "pyvdisk/infrastructure/checkpoint.py" - }, - { - "path": "pyvdisk/vscript/host.py" - }, - { - "path": "pyvdisk/fuse_mount.py" - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.623Z", - "fingerprint": "a36d0bc58d4a6da6854f4c155bbc8fca838d7a7ff82d379b18b17490bdb29657", - "aggregate": { - "descendant_count": 4, - "own_api_count": 0, - "inherited_api_count": 13, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.platform.dispatch": { - "uid": "a0000330", - "id": "pyvdisk.platform.dispatch", - "parent": "pyvdisk.platform", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "实现选择", - "en": "Implementation Dispatch" - }, - "description": { - "zh": "决定当前生效的实现并对外描述它。Windows 判定基于 sys.platform;use_implementation() 是测试缝,让模拟分支能在 Linux 上真正被执行;describe() 如实报告当前生效的实现(包括模拟),调用方不会拿到一份\"在说另一个平台\"的报告。\n", - "en": "Chooses the implementation in force and describes it. Windows detection is sys.platform based; use_implementation() is the seam that lets the emulated branches be exercised on Linux, and describe() reports what is actually live -- the emulation included -- so a caller never gets a report about a platform that is not the one running.\n" - }, - "source": [ - { - "path": "pyvdisk/compat.py", - "line": 41, - "end_line": 100 - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.621Z", - "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.compat.implementation", - "description": { - "zh": "当前生效的实现:posix 或 windows。\n", - "en": "The implementation in force: posix or windows.\n" - }, - "key": "rpc:pyvdisk.compat.implementation" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.use_implementation", - "description": { - "zh": "临时强制指定实现;上下文管理器,退出时还原,供测试在 Linux 上执行 Windows 分支。\n", - "en": "Temporarily force an implementation; a context manager that restores the previous one, used by tests to execute the Windows branches on Linux.\n" - }, - "key": "rpc:pyvdisk.compat.use_implementation" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.describe", - "description": { - "zh": "当前生效的实现实际会做什么:定位读写、文件锁、目录 fsync、身份与符号链接各由什么原语支撑。描述的是 implementation(),而不是宿主平台。\n", - "en": "What the implementation in force actually does: which primitive backs positional IO, locking, directory fsync, identity and symlinks. Follows implementation(), not the host platform.\n" - }, - "key": "rpc:pyvdisk.compat.describe" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.platform.durability": { - "uid": "a0000333", - "id": "pyvdisk.platform.durability", - "parent": "pyvdisk.platform", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "持久化与身份", - "en": "Durability and Identity" - }, - "description": { - "zh": "其余平台差异:改名后刷盘目录、报告进程身份、探测符号链接支持、选择当前实现。它们都返回可判断的值而非抛异常,因为单拿出来都不致命。\n", - "en": "The remaining platform differences: flushing a directory after a rename, reporting process identity, probing symlink support, and selecting the implementation in force. Each returns a value the caller can branch on instead of raising, because none of them is fatal on its own.\n" - }, - "source": [ - { - "path": "pyvdisk/compat.py", - "line": 202, - "end_line": 283 - }, - { - "path": "pyvdisk/compat.py", - "line": 41, - "end_line": 100 - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T14:30:00Z", - "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.compat.fsync_dir", - "description": { - "zh": "刷盘目录,让改名能抵住崩溃。真的执行了才返回 True;Windows 无法把目录当文件打开,所以返回 False 表示\"未执行\",而不是假装成功。\n", - "en": "Flush a directory so a rename survives a crash. Returns True when it actually ran; Windows cannot open a directory as a file, so it returns False to mean not performed rather than claiming success.\n" - }, - "key": "rpc:pyvdisk.compat.fsync_dir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.uid", - "description": { - "zh": "进程 uid;平台没有该概念时返回 0。\n", - "en": "Effective uid, or 0 where the platform has no such notion.\n" - }, - "key": "rpc:pyvdisk.compat.uid" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.gid", - "description": { - "zh": "进程 gid;平台没有该概念时返回 0。\n", - "en": "Effective gid, or 0 where the platform has no such notion.\n" - }, - "key": "rpc:pyvdisk.compat.gid" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.uid_or", - "description": { - "zh": "取 uid,无该概念时用传入的缺省值。用它而不是 `uid() or default`:uid 0 是 root,不是\"未设置\"。\n", - "en": "uid, or the given fallback. Prefer this over `uid() or default`: uid 0 is root, not unset.\n" - }, - "key": "rpc:pyvdisk.compat.uid_or" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.gid_or", - "description": { - "zh": "取 gid,无该概念时用传入的缺省值。\n", - "en": "gid, or the given fallback.\n" - }, - "key": "rpc:pyvdisk.compat.gid_or" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.can_symlink", - "description": { - "zh": "探测指定目录下能否创建符号链接(不抛异常)。Windows 需要开发者模式,调用方据此降级而不是直接失败。\n", - "en": "Probe whether a symlink can be created in the given directory without raising. Windows needs developer mode, so callers degrade instead of failing.\n" - }, - "key": "rpc:pyvdisk.compat.can_symlink" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.platform.locking": { - "uid": "a0000332", - "id": "pyvdisk.platform.locking", - "parent": "pyvdisk.platform", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "跨进程文件锁", - "en": "Cross-Process Locking" - }, - "description": { - "zh": "跨线程、跨进程的整文件写串行化:POSIX 用 fcntl.flock,Windows 用 msvcrt 字节区间锁。Windows 路径刻意用 LK_NBLCK 轮询:LK_LOCK 约十秒后会报错,而 flock 会一直等下去。\n", - "en": "Whole-file write serialisation across threads and processes: fcntl.flock on POSIX, an msvcrt byte range on Windows. The Windows path polls with LK_NBLCK on purpose: LK_LOCK errors out after about ten seconds where flock keeps waiting.\n" - }, - "source": [ - { - "path": "pyvdisk/compat.py", - "line": 128, - "end_line": 198 - }, - { - "path": "pyvdisk/compat.py", - "line": 55 - }, - { - "path": "pyvdisk/compat.py", - "line": 58 - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T14:30:00Z", - "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.compat.lock", - "description": { - "zh": "取得整文件锁。blocking=True 等待,timeout=N 秒后放弃并返回 False,blocking=False 只试一次。返回是否拿到锁。\n", - "en": "Take the whole-file lock. blocking=True waits, timeout=N seconds gives up and returns False, blocking=False tries once. Returns whether the lock is held.\n" - }, - "key": "rpc:pyvdisk.compat.lock" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.unlock", - "description": { - "zh": "释放锁。句柄已关闭也能调用,因为卸载路径与出错路径都会走到它。\n", - "en": "Release the lock. Tolerates an already-closed handle, because unmount and error paths both call it.\n" - }, - "key": "rpc:pyvdisk.compat.unlock" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.platform.positional": { - "uid": "a0000331", - "id": "pyvdisk.platform.positional", - "parent": "pyvdisk.platform", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "定位读写", - "en": "Positioned IO" - }, - "description": { - "zh": "不依赖也不改动文件游标的原子定位读写。模拟实现不只是方便:没有那把锁,两个线程共用一个句柄时会互相越位 seek,直接写坏数据块。\n", - "en": "Atomic positioned reads and writes that neither depend on nor disturb the file cursor. The emulation is not merely a convenience: without the lock, two threads sharing a handle would seek past each other and corrupt blocks.\n" - }, - "source": [ - { - "path": "pyvdisk/compat.py", - "line": 102, - "end_line": 127 - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T14:30:00Z", - "fingerprint": "00f27482df9157d059e546cd531a5773775112816081092a7b689393b4e6197b", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.compat.pread", - "description": { - "zh": "从 offset 处读取至多 length 字节。POSIX 用 os.pread;模拟实现用进程级互斥锁包住 lseek+read,避免与其它线程的 seek 交错。\n", - "en": "Positioned read of up to length bytes. POSIX uses os.pread; the emulation holds a process-wide lock across lseek+read so the pair is not interleaved with another thread's seek.\n" - }, - "key": "rpc:pyvdisk.compat.pread" - }, - { - "protocol": "rpc", - "path": "pyvdisk.compat.pwrite", - "description": { - "zh": "向 offset 处写入。POSIX 用 os.pwrite;模拟实现用同一把锁串行化 seek+write。\n", - "en": "Positioned write. POSIX uses os.pwrite; the emulation serialises seek+write under the same lock.\n" - }, - "key": "rpc:pyvdisk.compat.pwrite" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage": { - "uid": "a0000301", - "id": "pyvdisk.storage", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "storage" - ], - "name": { - "zh": "存储平面", - "en": "Storage Plane" - }, - "description": { - "zh": "存储平面:块镜像、磁盘身份、盘上文件系统、高层 VFS、多盘卷、向量盘与日志盘、结构化日志、模拟驱动器、可选 FUSE 挂载、统一 DataDisk 容器、WAL 与检查点。\n", - "en": "Storage plane: block image, disk identity, on-disk filesystem, high-level VFS, multi-disk volumes, vector and log disks, structured logging, simulated drive bay, optional FUSE mount, the unified DataDisk container, WAL and checkpoints.\n" - }, - "source": [ - { - "path": "pyvdisk/disk.py" - }, - { - "path": "pyvdisk/identity.py" - }, - { - "path": "pyvdisk/rwlock.py" - }, - { - "path": "pyvdisk/fs.py" - }, - { - "path": "pyvdisk/vfs.py" - }, - { - "path": "pyvdisk/volume.py" - }, - { - "path": "pyvdisk/vector_disk.py" - }, - { - "path": "pyvdisk/log_disk.py" - }, - { - "path": "pyvdisk/logging_core.py" - }, - { - "path": "pyvdisk/driver.py" - }, - { - "path": "pyvdisk/fuse_mount.py" - }, - { - "path": "pyvdisk/infrastructure/disk.py" - }, - { - "path": "pyvdisk/infrastructure/wal.py" - }, - { - "path": "pyvdisk/infrastructure/checkpoint.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "80d794b29e5404773680587fc27ceeac047cd72e0ab8cc13715f9aaa02d75a68", - "aggregate": { - "descendant_count": 108, - "own_api_count": 0, - "inherited_api_count": 384, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.block": { - "uid": "a0000302", - "id": "pyvdisk.storage.block", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "块镜像", - "en": "Block Image" - }, - "description": { - "zh": "块级镜像 IO:把一个 .vdisk 文件当作块设备,使用 os.pread/os.pwrite 与 POSIX advisory 写锁。\n", - "en": "Block-level image IO: one .vdisk file treated as a block device with os.pread/os.pwrite and POSIX advisory write locking.\n" - }, - "source": [ - { - "path": "pyvdisk/disk.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 12, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.block.access": { - "uid": "a0000205", - "id": "pyvdisk.storage.block.access", - "parent": "pyvdisk.storage.block", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "块访问", - "en": "Block Access" - }, - "description": { - "zh": "已打开镜像上的块级与字节级访问:块读写、裸字节区间与镜像扩缩。\n", - "en": "Block and byte access on an open image: block read/write, raw byte ranges and image resize.\n" - }, - "source": [ - { - "path": "pyvdisk/disk.py", - "line": 143, - "end_line": 188 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#read_block", - "description": { - "zh": "带越界检查地读取一个完整块。\n", - "en": "Read one whole block with bounds checking.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#read_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#write_block", - "description": { - "zh": "写入一个块,不足处补零。\n", - "en": "Write one block, zero-padding short payloads.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#write_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#read_bytes", - "description": { - "zh": "按字节偏移读取一段数据。\n", - "en": "Read a byte range at an arbitrary offset.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#read_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#write_bytes", - "description": { - "zh": "按字节偏移写入一段数据。\n", - "en": "Write a byte range at an arbitrary offset.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#write_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#truncate_bytes", - "description": { - "zh": "把镜像调整到整块数大小。\n", - "en": "Resize the image to a whole number of blocks.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#truncate_bytes" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.io", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#read_block", - "label": { - "zh": "定位读取", - "en": "positional read" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.block.io", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", - "label": { - "zh": "定位写入", - "en": "positioned write" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 3 - } - }, - "pyvdisk.storage.block.image": { - "uid": "a0000204", - "id": "pyvdisk.storage.block.image", - "parent": "pyvdisk.storage.block", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "镜像生命周期", - "en": "Image Lifecycle" - }, - "description": { - "zh": "VirtualDisk 生命周期:稀疏创建、加锁打开、上下文管理、刷新与关闭。锁来自平台适配层,因此写串行化在 POSIX 与 Windows 上都真实存在,而不是悄悄退化为空操作。\n", - "en": "VirtualDisk lifecycle: sparse creation, locked open, context manager, flush and close. The lock is taken from the platform layer, so write serialisation exists on both POSIX and Windows instead of silently degrading to a no-op.\n" - }, - "source": [ - { - "path": "pyvdisk/disk.py", - "line": 60, - "end_line": 141 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk", - "description": { - "zh": "以普通宿主文件为背衬的块设备。\n", - "en": "Block device backed by a plain host file.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#create", - "description": { - "zh": "创建指定大小的稀疏镜像文件并返回块数。\n", - "en": "Create the sparse image file of a given size and return its block count.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#open", - "description": { - "zh": "打开镜像,写锁经由平台适配层获取:POSIX 用 flock,Windows 用 msvcrt 字节区间锁。抢锁失败会关掉句柄报错,而不是无声地无锁继续跑。\n", - "en": "Open the image, taking the write lock through the platform layer: flock on POSIX, an msvcrt byte range on Windows. A lock failure closes the handle and raises rather than silently continuing unlocked.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#flush", - "description": { - "zh": "刷新并 fsync 镜像文件。\n", - "en": "Flush and fsync the image file.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#flush" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk.VirtualDisk#close", - "description": { - "zh": "释放 advisory 锁并关闭镜像。\n", - "en": "Release the advisory lock and close the image.\n" - }, - "key": "rpc:pyvdisk.disk.VirtualDisk#close" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.platform.locking", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "label": { - "zh": "整文件写锁", - "en": "whole-file write lock" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.block.io": { - "uid": "a0000203", - "id": "pyvdisk.storage.block.io", - "parent": "pyvdisk.storage.block", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "定位 IO 原语", - "en": "Positional IO" - }, - "description": { - "zh": "无缓冲定位读写原语,供镜像上的所有块级与字节级访问使用;经由平台适配层,同一份代码在 Windows 上也能跑。\n", - "en": "Unbuffered positional read/write primitives used by every block and byte access on the image, routed through the platform layer so the same code runs on Windows.\n" - }, - "source": [ - { - "path": "pyvdisk/disk.py", - "line": 22, - "end_line": 57 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:41:14.329Z", - "fingerprint": "88da0b2f3ce22b186edf88eab3d800c8e50671236a9ed1b9dbed478ff6837d16", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.disk._pread_all", - "description": { - "zh": "定位读取,除 EOF 外保证读满。转发给 compat.pread,因此 Windows 上得到的是加锁的 seek+read,而不是 os.pread。\n", - "en": "Positional read that fills the buffer unless EOF is hit. Delegates to compat.pread, so Windows gets a lock-protected seek+read instead of os.pread.\n" - }, - "key": "rpc:pyvdisk.disk._pread_all" - }, - { - "protocol": "rpc", - "path": "pyvdisk.disk._pwrite_all", - "description": { - "zh": "定位写入,保证写满全部字节。转发给 compat.pwrite,在 Windows 上用同一把锁串行化 seek+write。\n", - "en": "Positional write that guarantees every byte is written. Delegates to compat.pwrite, which serialises seek+write on Windows.\n" - }, - "key": "rpc:pyvdisk.disk._pwrite_all" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.platform.positional", - "from_api": "rpc:pyvdisk.disk._pread_all", - "to_api": "rpc:pyvdisk.compat.pread", - "label": { - "zh": "定位读取", - "en": "positioned read" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.platform.positional", - "from_api": "rpc:pyvdisk.disk._pwrite_all", - "to_api": "rpc:pyvdisk.compat.pwrite", - "label": { - "zh": "定位写入", - "en": "positioned write" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 2 - } - }, - "pyvdisk.storage.checkpoint": { - "uid": "a000030f", - "id": "pyvdisk.storage.checkpoint", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "检查点存储", - "en": "Checkpoint Store" - }, - "description": { - "zh": "检查点存储:以 VFS 路径或宿主目录为背衬的持久键值进度与结果记录,带跨进程锁与原子落盘。\n", - "en": "Checkpoint store: durable key/value progress and result records backed by a VFS path or a host directory, with cross-process locking and atomic saves.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/checkpoint.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 11, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.checkpoint.io": { - "uid": "a0000805", - "id": "pyvdisk.storage.checkpoint.io", - "parent": "pyvdisk.storage.checkpoint", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "检查点 IO", - "en": "Checkpoint IO" - }, - "description": { - "zh": "检查点 IO:键值记录映射的加载、读取、暂存与原子保存。\n", - "en": "Checkpoint IO: load, read, stage and atomically save the key/value record map.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/checkpoint.py", - "line": 99, - "end_line": 145 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#_load", - "description": { - "zh": "从背衬存储加载记录映射。\n", - "en": "Load the record map from the backing store.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#_load" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#get", - "description": { - "zh": "读取单个检查点值。\n", - "en": "Read one checkpoint value.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#set", - "description": { - "zh": "把单个检查点值写入内存映射。\n", - "en": "Write one checkpoint value into the in-memory map.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#set" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#save", - "description": { - "zh": "原子地持久化整个记录映射。\n", - "en": "Atomically persist the whole record map.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.checkpoint.open": { - "uid": "a0000804", - "id": "pyvdisk.storage.checkpoint.open", - "parent": "pyvdisk.storage.checkpoint", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "检查点存储", - "en": "Checkpoint Store" - }, - "description": { - "zh": "检查点存储的构造与加锁:后端选择、VFS 或宿主背衬,以及独占写周期。本模块过去在顶层 import fcntl,导致整个包在 Windows 上无法导入;现在锁来自平台适配层。\n", - "en": "Checkpoint store construction and locking: backend selection, VFS or host backing, and the exclusive write cycle. This module used to import fcntl at the top level, which made the whole package unimportable on Windows; the lock now comes from the platform layer.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/checkpoint.py", - "line": 15, - "end_line": 98 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:40:40.830Z", - "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore", - "description": { - "zh": "带跨进程锁与原子落盘的持久键值存储。\n", - "en": "Durable key/value store with cross-process locking and atomic saves.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#__init__", - "description": { - "zh": "基于显式后端或 VFS 路径创建存储。\n", - "en": "Create a store over an explicit backend or a VFS path.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs", - "description": { - "zh": "构建以已挂载 VFS 为背衬的存储。\n", - "en": "Build a store backed by a mounted VFS.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", - "description": { - "zh": "在读-改-写周期内持有跨进程锁的上下文管理器。\n", - "en": "Context manager holding the cross-process lock for a read-modify-write cycle.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#from_host", - "description": { - "zh": "构建以宿主目录为背衬的存储。\n", - "en": "Build a store backed by a host directory.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_host" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.platform.locking", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", - "label": { - "zh": "跨进程锁", - "en": "cross-process lock" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 3 - } - }, - "pyvdisk.storage.checkpoint.triggers": { - "uid": "a0000806", - "id": "pyvdisk.storage.checkpoint.triggers", - "parent": "pyvdisk.storage.checkpoint", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "触发器检查点", - "en": "Trigger Checkpoints" - }, - "description": { - "zh": "面向触发器的便利层,为调度器提供持久的事件去重保证。\n", - "en": "Trigger-facing convenience layer that gives the scheduler durable exactly-once event dedup.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/checkpoint.py", - "line": 146, - "end_line": 152 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "9ca9673053b671140cc605c35d9a339dee71a77fee8e2598d5b2483bcfd26539", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#mark_success", - "description": { - "zh": "记录某触发器已消费某事件 id。\n", - "en": "Record that a trigger already consumed an event id.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#mark_success" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.checkpoint.CheckpointStore#last_event", - "description": { - "zh": "读取某触发器最近成功处理的事件 id。\n", - "en": "Read the last successfully processed event id of a trigger.\n" - }, - "key": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#last_event" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.vscript.triggers", - "label": { - "zh": "支撑触发器去重", - "en": "backs trigger dedup" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.datadisk": { - "uid": "a000030d", - "id": "pyvdisk.storage.datadisk", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "acid", - "transaction" - ], - "name": { - "zh": "DataDisk 容器", - "en": "DataDisk Container" - }, - "description": { - "zh": "统一 DataDisk 容器:一个挂载的 VFS 加上 FS/向量/日志命名空间服务,带撤销日志的元数据事务、WAL 与重挂载恢复。\n", - "en": "Unified DataDisk container: one mounted VFS plus namespaced FS/vector/log services, a metadata transaction with undo journal, WAL and remount recovery.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.225Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "aggregate": { - "descendant_count": 7, - "own_api_count": 0, - "inherited_api_count": 39, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.datadisk.api": { - "uid": "a000080d", - "id": "pyvdisk.storage.datadisk.api", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "DataDisk 接口", - "en": "DataDisk Interface" - }, - "description": { - "zh": "容器生命周期与面向调用方的接口:挂载、manifest、事务、元数据访问与能力受限视图。\n", - "en": "Container lifecycle and the caller-facing surface: mount, manifest, transactions, metadata access and capability-scoped views.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 566, - "end_line": 609 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.225Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#mount", - "description": { - "zh": "挂载容器及其三个命名空间。\n", - "en": "Mount the container and its three namespaces.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#close", - "description": { - "zh": "关闭全部命名空间与底层 VFS。\n", - "en": "Close all namespaces and the underlying VFS.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#close" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#mounted", - "description": { - "zh": "报告容器当前是否已挂载。\n", - "en": "Report whether the container is currently mounted.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#mounted" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#manifest", - "description": { - "zh": "返回描述命名空间与元数据根的容器 manifest。\n", - "en": "Return the container manifest describing namespaces and metadata root.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#manifest" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#transaction", - "description": { - "zh": "在容器上开启元数据事务。\n", - "en": "Open a metadata transaction over the container.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#transaction" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#get_metadata", - "description": { - "zh": "读取一个元数据键。\n", - "en": "Read one metadata key.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#get_metadata" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#set_metadata", - "description": { - "zh": "在事务内写入一个元数据键。\n", - "en": "Write one metadata key inside a transaction.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#set_metadata" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#scoped", - "description": { - "zh": "把容器包装为面向执行上下文的能力受限视图。\n", - "en": "Wrap the container in a capability-scoped view for an execution context.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.governance.scoped", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk", - "label": { - "zh": "构建受限视图", - "en": "builds scoped view" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#transaction", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "label": { - "zh": "开启事务", - "en": "opens transaction" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 2 - } - }, - "pyvdisk.storage.datadisk.codec": { - "uid": "a0000807", - "id": "pyvdisk.storage.datadisk.codec", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "元数据编解码", - "en": "Metadata Codec" - }, - "description": { - "zh": "DataDisk 的值编码与错误词表,供事务、manifest 与命名空间层共用。\n", - "en": "DataDisk value encoding and error vocabulary shared by the transaction, manifest and namespace layers.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 13, - "end_line": 19 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.226Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDiskError", - "description": { - "zh": "DataDisk 容器的运行时错误基类。\n", - "en": "Base runtime error for the DataDisk container.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDiskError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk._Missing", - "description": { - "zh": "在元数据事务中标记值被删除的哨兵。\n", - "en": "Sentinel that marks a value as deleted inside the metadata transaction.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk._Missing" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk._json", - "description": { - "zh": "元数据值的规范 JSON 编码。\n", - "en": "Canonical JSON encoding for metadata values.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk._json" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk._enc", - "description": { - "zh": "manifest 与事务日志用来内嵌值的 base64 包装。\n", - "en": "Base64 wrapper the manifest and transaction journal use to embed values.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk._enc" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk._dec", - "description": { - "zh": "base64 包装的逆操作。\n", - "en": "Reverse of the base64 wrapper.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk._dec" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.datadisk.core": { - "uid": "a000080c", - "id": "pyvdisk.storage.datadisk.core", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "DataDisk 核心", - "en": "DataDisk Core" - }, - "description": { - "zh": "DataDisk 构造、元数据原子持久化,以及挂载时的 WAL 重放与恢复报告。\n", - "en": "DataDisk construction, atomic metadata persistence, and the WAL replay performed on mount together with its recovery report.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 407, - "end_line": 565 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.226Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk", - "description": { - "zh": "磁盘容器本体。\n", - "en": "The disk container itself.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#create", - "description": { - "zh": "按容量、块大小与标签创建磁盘镜像。\n", - "en": "Creates a disk image with a size, block size and label.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#_atomic_json", - "description": { - "zh": "原子写入 JSON 元数据。\n", - "en": "Writes JSON metadata atomically.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#_atomic_json" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#_append_metadata_wal", - "description": { - "zh": "向事务 WAL 追加一条元数据记录。\n", - "en": "Appends one metadata record to the transaction WAL.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#_append_metadata_wal" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#_recover_transactions", - "description": { - "zh": "挂载时重放 WAL:已提交事务重做,未提交事务回滚。\n", - "en": "Replays the WAL on mount: committed transactions redo, uncommitted roll back.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#_recover_transactions" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.DataDisk#recovery_report", - "description": { - "zh": "最近一次恢复对每个事务做了什么。\n", - "en": "What the last recovery did, per transaction.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.DataDisk#recovery_report" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.wal.journal", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_append_metadata_wal", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog", - "label": { - "zh": "使用元数据 WAL", - "en": "uses metadata WAL" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.datadisk.namespace": { - "uid": "a000080a", - "id": "pyvdisk.storage.datadisk.namespace", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "文件系统命名空间", - "en": "Filesystem Namespace" - }, - "description": { - "zh": "事务性文件系统命名空间:读方法透传给 VFS,而每次变更都登记撤销意图。\n", - "en": "Transactional filesystem namespace: read methods pass through to the VFS while every mutation registers an undo intent.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 246, - "end_line": 341 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.227Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk._snapshot_dir", - "description": { - "zh": "捕获目录子树的信息以便撤销删除。\n", - "en": "Capture enough of a directory subtree to undo a removal.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk._snapshot_dir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace", - "description": { - "zh": "把变更记录为事务意图的文件系统命名空间。\n", - "en": "Filesystem namespace whose mutations are recorded as transaction intents.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#write_file", - "description": { - "zh": "事务性文件写入。\n", - "en": "Transactional file write.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#write_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#append_file", - "description": { - "zh": "事务性文件追加。\n", - "en": "Transactional file append.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#append_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#remove", - "description": { - "zh": "事务性文件删除。\n", - "en": "Transactional file removal.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#remove" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#rmtree", - "description": { - "zh": "以目录快照为背衬的事务性递归删除。\n", - "en": "Transactional recursive tree removal backed by a directory snapshot.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#rmtree" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#rename", - "description": { - "zh": "事务性重命名。\n", - "en": "Transactional rename.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#rename" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.FileNamespace#makedirs", - "description": { - "zh": "事务性递归目录创建。\n", - "en": "Transactional recursive directory creation.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.FileNamespace#makedirs" - } - ], - "deps": [ - { - "kind": "dataflow", - "to": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.infrastructure.disk.FileNamespace#write_file", - "to_api": "rpc:pyvdisk.vfs.VFS#write_file", - "label": { - "zh": "委托给 VFS", - "en": "delegates to VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.datadisk.services": { - "uid": "a000080b", - "id": "pyvdisk.storage.datadisk.services", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "服务命名空间", - "en": "Service Namespaces" - }, - "description": { - "zh": "向量与日志命名空间:透传到各自磁盘,同时作为一等事务参与者。\n", - "en": "Vector and log namespaces that pass through to their disks while remaining first-class transaction participants.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 344, - "end_line": 405 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.227Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.VectorNamespace", - "description": { - "zh": "参与元数据事务的透传向量命名空间。\n", - "en": "Read-through vector namespace participating in metadata transactions.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.VectorNamespace" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.LogNamespace", - "description": { - "zh": "参与元数据事务的透传事件日志命名空间。\n", - "en": "Read-through event-log namespace participating in metadata transactions.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.LogNamespace" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vector.records", - "from_api": "rpc:pyvdisk.infrastructure.disk.VectorNamespace", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "label": { - "zh": "包装向量盘", - "en": "wraps vector disk" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.log.append", - "from_api": "rpc:pyvdisk.infrastructure.disk.LogNamespace", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "label": { - "zh": "包装日志盘", - "en": "wraps log disk" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.storage.datadisk.tx": { - "uid": "a0000808", - "id": "pyvdisk.storage.datadisk.tx", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "元数据事务", - "en": "Metadata Transaction" - }, - "description": { - "zh": "元数据事务核心:参与者协议、暂存写入,以及使命名空间变更可回滚的撤销日志。\n", - "en": "Metadata transaction core: participant protocol, staged writes and the undo journal that makes namespace mutations reversible.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 103, - "end_line": 180 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.228Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.TransactionParticipant", - "description": { - "zh": "命名空间加入元数据事务所实现的协议。\n", - "en": "Protocol a namespace implements to join a metadata transaction.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.TransactionParticipant" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction", - "description": { - "zh": "两阶段元数据事务:暂存键值、招募参与者并为撤销记录文件系统意图。\n", - "en": "Two-phase metadata transaction staging keys, enlisting participants and recording filesystem intents for undo.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#set", - "description": { - "zh": "暂存一次元数据键写入。\n", - "en": "Stage a metadata key write.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#set" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#delete", - "description": { - "zh": "暂存一次元数据键删除。\n", - "en": "Stage a metadata key deletion.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#delete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#enlist", - "description": { - "zh": "招募命名空间参与者,可选带意图。\n", - "en": "Enlist a namespace participant, optionally with an intent.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#enlist" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#intent", - "description": { - "zh": "声明操作用意图,用于冲突检测与重试。\n", - "en": "Declare an operation intent used for conflict detection and retry.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#intent" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.datadisk.tx-lifecycle": { - "uid": "a0000809", - "id": "pyvdisk.storage.datadisk.tx-lifecycle", - "parent": "pyvdisk.storage.datadisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "事务结局", - "en": "Transaction Outcome" - }, - "description": { - "zh": "事务的完整结局:进入、经 WAL 的持久提交、带撤销的回滚,以及异常驱动的自动回滚。abort 现在先把 intent 落盘,再按逆序在进程内通知每个已登记的 participant,最后才展开文件系统回退。\n", - "en": "How a transaction ends: enter, durable commit through the WAL, rollback with undo, and exception-driven auto-abort. Abort now persists the intents first and then notifies every enlisted participant in reverse order, in-process, before unwinding the filesystem.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/disk.py", - "line": 181, - "end_line": 244 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.228Z", - "fingerprint": "9e43dcc0192ae7fcb043dfd6e12b09e42ba36fa2b8b01c445b2e84a45d351d93", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#__enter__", - "description": { - "zh": "以上下文管理器进入事务,冲突时可选重试。\n", - "en": "Enter the transaction as a context manager, optionally retrying on conflict.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#__enter__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "description": { - "zh": "经 WAL 提交事务,应用元数据与命名空间变更。\n", - "en": "Commit the transaction through the WAL, applying metadata and namespace changes.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#abort", - "description": { - "zh": "回滚事务并撤销已记录的文件系统意图。\n", - "en": "Abort the transaction and unwind recorded filesystem intents.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#abort" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.disk.MetadataTransaction#__exit__", - "description": { - "zh": "结束上下文块,成功时提交、异常时回滚。\n", - "en": "Finish the context block, committing on success and aborting on exception.\n" - }, - "key": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#__exit__" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.wal.entries", - "from_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#commit", - "label": { - "zh": "写入 WAL 记录", - "en": "writes WAL entries" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 3 - } - }, - "pyvdisk.storage.driver": { - "uid": "a000030b", - "id": "pyvdisk.storage.driver", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "模拟驱动器", - "en": "Drive Manager" - }, - "description": { - "zh": "模拟驱动器:扫描宿主目录、按尾标识别盘、组装卷并按卷标挂载。\n", - "en": "Simulated drive bay: scan a host directory, identify disks by their trailer, assemble volumes and mount everything under volume labels.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.229Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 27, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.driver.assembled": { - "uid": "a0000709", - "id": "pyvdisk.storage.driver.assembled", - "parent": "pyvdisk.storage.driver", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷组装", - "en": "Volume Assembly" - }, - "description": { - "zh": "单个卷的组装结果:找到哪些成员以及必须按何顺序打开。\n", - "en": "Assembly result for one volume: which members were found and in what order they must be opened.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py", - "line": 30, - "end_line": 54 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.229Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.driver.AssembledVolume", - "description": { - "zh": "根据共享卷元数据聚合为单个卷的成员盘集合。\n", - "en": "Member disks grouped into one volume by their shared volume metadata.\n" - }, - "key": "rpc:pyvdisk.driver.AssembledVolume" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.AssembledVolume#complete", - "description": { - "zh": "所有需要的成员都找到时为真。\n", - "en": "True when every required member was found.\n" - }, - "key": "rpc:pyvdisk.driver.AssembledVolume#complete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.AssembledVolume#found", - "description": { - "zh": "在宿主上找到的成员数。\n", - "en": "Number of members located on the host.\n" - }, - "key": "rpc:pyvdisk.driver.AssembledVolume#found" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.AssembledVolume#needed", - "description": { - "zh": "该卷需要的成员数。\n", - "en": "Number of members the volume requires.\n" - }, - "key": "rpc:pyvdisk.driver.AssembledVolume#needed" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.AssembledVolume#ordered_paths", - "description": { - "zh": "按逻辑序号排列的成员路径。\n", - "en": "Member paths in logical index order.\n" - }, - "key": "rpc:pyvdisk.driver.AssembledVolume#ordered_paths" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.driver.lifecycle": { - "uid": "a000070d", - "id": "pyvdisk.storage.driver.lifecycle", - "parent": "pyvdisk.storage.driver", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卸载与热插拔", - "en": "Unmount and Hotplug" - }, - "description": { - "zh": "模拟驱动器的卸载、热插拔重扫与诊断汇总。\n", - "en": "Unmount, hotplug rescan and diagnostic summary for the simulated drive bay.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py", - "line": 259, - "end_line": 310 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.230Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#unmount", - "description": { - "zh": "卸载单个卷标。\n", - "en": "Unmount one label.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#unmount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#unmount_all", - "description": { - "zh": "卸载全部已挂载介质。\n", - "en": "Unmount every mounted medium.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#unmount_all" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#hotplug", - "description": { - "zh": "重新扫描目录并挂载新出现的盘。\n", - "en": "Rescan the directory and mount newly appeared disks.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#hotplug" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#summary", - "description": { - "zh": "汇总已扫描、已组装与已挂载介质以供诊断。\n", - "en": "Summarize scanned, assembled and mounted media for diagnostics.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#summary" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.driver.manager": { - "uid": "a000070b", - "id": "pyvdisk.storage.driver.manager", - "parent": "pyvdisk.storage.driver", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "磁盘管理器", - "en": "Disk Manager" - }, - "description": { - "zh": "驱动器扫描与组装:识别宿主目录中的介质及其成员如何聚合成卷。\n", - "en": "Drive bay scanning and assembly: identify what is in a host directory and how members group into volumes.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py", - "line": 102, - "end_line": 178 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.230Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager", - "description": { - "zh": "面向单个宿主目录的驱动器。\n", - "en": "Drive bay over one host directory.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#__init__", - "description": { - "zh": "把管理器绑定到宿主目录与块大小。\n", - "en": "Bind the manager to a host directory and block size.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#scan", - "description": { - "zh": "扫描目录并探测每个 .vdisk 文件。\n", - "en": "Scan the directory and probe every .vdisk file.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#scan" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#assemble", - "description": { - "zh": "把扫描到的盘分组为单盘、向量盘、日志盘与卷。\n", - "en": "Group scanned disks into singles, vectors, logs and volumes.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#assemble" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#_unique_label", - "description": { - "zh": "用计数器后缀解决卷标冲突。\n", - "en": "Resolve label collisions by suffixing a counter.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#_unique_label" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.identity.probe", - "from_api": "rpc:pyvdisk.driver.DiskManager#scan", - "to_api": "rpc:pyvdisk.identity.probe_disk", - "label": { - "zh": "探测盘", - "en": "probes disks" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.driver.mounting": { - "uid": "a000070c", - "id": "pyvdisk.storage.driver.mounting", - "parent": "pyvdisk.storage.driver", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "挂载分发", - "en": "Mount Dispatch" - }, - "description": { - "zh": "挂载分发:每类介质一条路径,以及 CLI 使用的整体挂载与卷标查询。\n", - "en": "Mounting dispatch: one code path per medium kind plus the aggregate mount-all and label lookup used by the CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py", - "line": 180, - "end_line": 258 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.230Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#mount_all", - "description": { - "zh": "挂载全部已组装介质并返回卷标到 VFS 的映射。\n", - "en": "Mount all assembled media and return the label-to-VFS map.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#mount_all" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#get", - "description": { - "zh": "按卷标查询单个已挂载介质。\n", - "en": "Look up one mounted medium by label.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#labels", - "description": { - "zh": "列出当前已挂载介质的卷标。\n", - "en": "List the labels of currently mounted media.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#labels" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#_mount_single", - "description": { - "zh": "挂载单盘文件系统镜像。\n", - "en": "Mount a single-disk filesystem image.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#_mount_single" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#_mount_vector", - "description": { - "zh": "挂载向量盘。\n", - "en": "Mount a vector disk.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#_mount_vector" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#_mount_log", - "description": { - "zh": "挂载日志盘。\n", - "en": "Mount a log disk.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#_mount_log" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.DiskManager#_mount_volume", - "description": { - "zh": "挂载已组装的多成员卷。\n", - "en": "Mount an assembled multi-member volume.\n" - }, - "key": "rpc:pyvdisk.driver.DiskManager#_mount_volume" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vector.open", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_vector", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#mount", - "label": { - "zh": "挂载向量盘", - "en": "mounts vector disk" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.log.open", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_log", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#mount", - "label": { - "zh": "挂载日志盘", - "en": "mounts log disk" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.volume.open", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_volume", - "to_api": "rpc:pyvdisk.volume.Volume#open", - "label": { - "zh": "打开卷", - "en": "opens volume" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 3, - "dep_in": 0 - } - }, - "pyvdisk.storage.driver.mounts": { - "uid": "a000070a", - "id": "pyvdisk.storage.driver.mounts", - "parent": "pyvdisk.storage.driver", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "挂载介质", - "en": "Mounted Media" - }, - "description": { - "zh": "日志盘、向量盘与文件系统介质的统一挂载包装,使驱动器可统一处理。\n", - "en": "Uniform mounted-object wrappers for log, vector and filesystem media so the drive manager can treat them alike.\n" - }, - "source": [ - { - "path": "pyvdisk/driver.py", - "line": 56, - "end_line": 100 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.231Z", - "fingerprint": "76f9a54ec25f379e05c35c2a7114db125da395fe4814209b88907793e6514122", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedLog", - "description": { - "zh": "已挂载的日志盘及其自动创建的默认流。\n", - "en": "A mounted log disk together with its auto-created default stream.\n" - }, - "key": "rpc:pyvdisk.driver.MountedLog" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedVector", - "description": { - "zh": "已挂载的向量盘。\n", - "en": "A mounted vector disk.\n" - }, - "key": "rpc:pyvdisk.driver.MountedVector" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedFS", - "description": { - "zh": "已挂载的文件系统卷及其 VFS 句柄与卷标。\n", - "en": "A mounted filesystem volume with its VFS handle and label.\n" - }, - "key": "rpc:pyvdisk.driver.MountedFS" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedFS#__enter__", - "description": { - "zh": "返回已挂载的 VFS 以用作上下文管理器。\n", - "en": "Return the mounted VFS for use as a context manager.\n" - }, - "key": "rpc:pyvdisk.driver.MountedFS#__enter__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedFS#__exit__", - "description": { - "zh": "上下文退出时关闭已挂载的 VFS。\n", - "en": "Close the mounted VFS on context exit.\n" - }, - "key": "rpc:pyvdisk.driver.MountedFS#__exit__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.driver.MountedLog#close", - "description": { - "zh": "关闭已挂载对象。\n", - "en": "Close the mounted object.\n" - }, - "key": "rpc:pyvdisk.driver.MountedLog#close" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs": { - "uid": "a0000305", - "id": "pyvdisk.storage.fs", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "fs", - "inode" - ], - "name": { - "zh": "文件系统", - "en": "Filesystem" - }, - "description": { - "zh": "盘上文件系统:超级块、inode 表、位图、间接块指针、目录、路径解析、fsck 与在线扩容。\n", - "en": "The on-disk filesystem: superblock, inode table, bitmaps, indirect block pointers, directories, path resolution, fsck and online grow.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "aggregate": { - "descendant_count": 23, - "own_api_count": 0, - "inherited_api_count": 82, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.attrs": { - "uid": "a000040f", - "id": "pyvdisk.storage.fs.attrs", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "属性与链接", - "en": "Attributes and Links" - }, - "description": { - "zh": "属性与链接:硬链接、模式、属主、时间戳,以及 VFS 使用的权限检查。\n", - "en": "Attributes and links: hard links, mode, ownership, timestamps and the permission check used by VFS.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 643, - "end_line": 701 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#link", - "description": { - "zh": "从既有路径创建指向新名字的硬链接。\n", - "en": "Create a hard link from an existing path to a new name.\n" - }, - "key": "rpc:pyvdisk.fs.FS#link" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#chmod", - "description": { - "zh": "修改 inode 权限位。\n", - "en": "Change inode permission bits.\n" - }, - "key": "rpc:pyvdisk.fs.FS#chmod" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#chown", - "description": { - "zh": "修改 inode 属主与属组。\n", - "en": "Change inode owner and group.\n" - }, - "key": "rpc:pyvdisk.fs.FS#chown" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#utime", - "description": { - "zh": "设置 inode 访问与修改时间。\n", - "en": "Set inode access and modification times.\n" - }, - "key": "rpc:pyvdisk.fs.FS#utime" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#access", - "description": { - "zh": "针对 uid/gid 的 POSIX 模式位访问检查。\n", - "en": "POSIX mode-bit access check for a uid/gid pair.\n" - }, - "key": "rpc:pyvdisk.fs.FS#access" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.fs.bitmap": { - "uid": "a0000408", - "id": "pyvdisk.storage.fs.bitmap", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "位图分配", - "en": "Bitmap Allocation" - }, - "description": { - "zh": "inode 与数据块分配共用的位图原语。\n", - "en": "Bitmap primitives shared by inode and data-block allocation.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 320, - "end_line": 350 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_bitmap_get", - "description": { - "zh": "测试盘上位图区域中的某一位。\n", - "en": "Test one bit in an on-disk bitmap region.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_bitmap_get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_bitmap_set", - "description": { - "zh": "设置或清除盘上位图区域中的某一位。\n", - "en": "Set or clear one bit in an on-disk bitmap region.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_bitmap_set" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_bitmap_alloc", - "description": { - "zh": "在位图区域中查找首个空闲位(可从提示位开始)。\n", - "en": "Find the first free bit in a bitmap region, optionally from a hint.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_bitmap_alloc" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.block-alloc": { - "uid": "a000040a", - "id": "pyvdisk.storage.fs.block-alloc", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "块分配器", - "en": "Block Allocator" - }, - "description": { - "zh": "建立在块位图之上的数据块分配器。\n", - "en": "Data block allocator on top of the block bitmap.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 377, - "end_line": 389 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#alloc_block", - "description": { - "zh": "分配一个空闲数据块并标记为已用。\n", - "en": "Allocate a free data block and mark it used.\n" - }, - "key": "rpc:pyvdisk.fs.FS#alloc_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#free_block", - "description": { - "zh": "释放数据块并清除其位图位。\n", - "en": "Free a data block and clear its bitmap bit.\n" - }, - "key": "rpc:pyvdisk.fs.FS#free_block" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.create": { - "uid": "a0000410", - "id": "pyvdisk.storage.fs.create", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "创建节点", - "en": "Node Creation" - }, - "description": { - "zh": "节点创建:文件、目录、符号链接及其共享构造器。\n", - "en": "Node creation: files, directories, symlinks and their shared constructor.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 703, - "end_line": 778 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_create_node", - "description": { - "zh": "文件、目录与符号链接共享的节点构造器。\n", - "en": "Shared node constructor for files, directories and symlinks.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_create_node" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#create", - "description": { - "zh": "在指定路径创建普通文件。\n", - "en": "Create a regular file at a path.\n" - }, - "key": "rpc:pyvdisk.fs.FS#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#mkdir", - "description": { - "zh": "在指定路径创建目录。\n", - "en": "Create a directory at a path.\n" - }, - "key": "rpc:pyvdisk.fs.FS#mkdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#symlink", - "description": { - "zh": "创建指向目标字符串的符号链接。\n", - "en": "Create a symbolic link pointing at a target string.\n" - }, - "key": "rpc:pyvdisk.fs.FS#symlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#readlink", - "description": { - "zh": "读取符号链接 inode 的目标。\n", - "en": "Read the target of a symlink inode.\n" - }, - "key": "rpc:pyvdisk.fs.FS#readlink" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.inode-io", - "from_api": "rpc:pyvdisk.fs.FS#_create_node", - "to_api": "rpc:pyvdisk.fs.FS#alloc_inode", - "label": { - "zh": "分配 inode", - "en": "reserves inode" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.dir": { - "uid": "a000040c", - "id": "pyvdisk.storage.fs.dir", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "目录读取", - "en": "Directory Read" - }, - "description": { - "zh": "目录读取路径:目录项解码、列举与按名查找。\n", - "en": "Directory read path: entry decoding, listing and name lookup.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 490, - "end_line": 522 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_dir_entries_block", - "description": { - "zh": "解码某个数据块中存储的全部有效目录项。\n", - "en": "Decode all valid directory entries stored in one data block.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_dir_entries_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#dir_list", - "description": { - "zh": "列出目录中的名字、inode 与类型三元组。\n", - "en": "List name, inode and type triples in a directory.\n" - }, - "key": "rpc:pyvdisk.fs.FS#dir_list" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#dir_lookup", - "description": { - "zh": "在目录中查找单个名字。\n", - "en": "Look up one name in a directory.\n" - }, - "key": "rpc:pyvdisk.fs.FS#dir_lookup" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.fs.dir-mutate": { - "uid": "a000040d", - "id": "pyvdisk.storage.fs.dir-mutate", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "目录写入", - "en": "Directory Write" - }, - "description": { - "zh": "目录写入路径:槽位查找、目录项插入与删除。\n", - "en": "Directory write path: slot search, entry insertion and entry removal.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 524, - "end_line": 586 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_find_free_dir_slot", - "description": { - "zh": "查找空闲目录项槽位,必要时扩展目录块。\n", - "en": "Find a free directory-entry slot, growing the directory block when needed.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_find_free_dir_slot" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#dir_add_entry", - "description": { - "zh": "向目录添加名字到 inode 的映射。\n", - "en": "Add a name-to-inode entry into a directory.\n" - }, - "key": "rpc:pyvdisk.fs.FS#dir_add_entry" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#dir_remove_entry", - "description": { - "zh": "从目录删除名字并返回被删除的目录项。\n", - "en": "Remove a name from a directory and return the removed entry.\n" - }, - "key": "rpc:pyvdisk.fs.FS#dir_remove_entry" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.fsck": { - "uid": "a0000415", - "id": "pyvdisk.storage.fs.fsck", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "一致性检查", - "en": "Filesystem Check" - }, - "description": { - "zh": "一致性检查器:校验超级块、交叉核对 inode 与块位图、链接数与目录项,并支持修复模式。\n", - "en": "Consistency checker: validates superblock, cross-checks inode and block bitmaps, link counts and directory entries, with an optional repair mode.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 1080, - "end_line": 1194 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#fsck", - "description": { - "zh": "检查文件系统一致性,可选修复发现的问题。\n", - "en": "Check filesystem consistency, optionally repairing what is found.\n" - }, - "key": "rpc:pyvdisk.fs.FS#fsck" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_fsck_impl", - "description": { - "zh": "扫描超级块、位图、inode 链接与目录项并产出报告。\n", - "en": "Scan superblock, bitmaps, inode links and directory entries and produce a report.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_fsck_impl" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.grow": { - "uid": "a0000416", - "id": "pyvdisk.storage.fs.grow", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "在线扩容", - "en": "Online Grow" - }, - "description": { - "zh": "在线扩容:扩大底层镜像并重写超级块几何。\n", - "en": "Online growth: enlarge the underlying image and rewrite the superblock geometry.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 1197, - "end_line": 1226 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.grow", - "description": { - "zh": "把既有文件系统镜像扩容到更大尺寸并返回新超级块。\n", - "en": "Extend an existing filesystem image to a larger size and return the new superblock.\n" - }, - "key": "rpc:pyvdisk.fs.grow" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.access", - "from_api": "rpc:pyvdisk.fs.grow", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#truncate_bytes", - "label": { - "zh": "扩大镜像", - "en": "enlarges image" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.inode": { - "uid": "a0000405", - "id": "pyvdisk.storage.fs.inode", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "Inode", - "en": "Inode" - }, - "description": { - "zh": "inode 结构及其二进制编解码与空节点工厂。\n", - "en": "Inode structure with its binary codec and empty-node factory.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 157, - "end_line": 226 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.Inode", - "description": { - "zh": "inode 值对象:类型、模式、链接数、属主、时间戳、尺寸与块指针。\n", - "en": "Inode value object: type, mode, links, ownership, timestamps, size and block pointers.\n" - }, - "key": "rpc:pyvdisk.fs.Inode" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Inode#to_bytes", - "description": { - "zh": "把 inode 序列化为 101 字节打包形式。\n", - "en": "Serialize the inode into its 101-byte packed form.\n" - }, - "key": "rpc:pyvdisk.fs.Inode#to_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Inode#from_bytes", - "description": { - "zh": "从打包字节解析 inode。\n", - "en": "Parse an inode from its packed bytes.\n" - }, - "key": "rpc:pyvdisk.fs.Inode#from_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Inode#empty", - "description": { - "zh": "构造指针全零的空 inode。\n", - "en": "Build an empty inode with zeroed pointers.\n" - }, - "key": "rpc:pyvdisk.fs.Inode#empty" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.inode-io": { - "uid": "a0000409", - "id": "pyvdisk.storage.fs.inode-io", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "Inode 表 IO", - "en": "Inode Table IO" - }, - "description": { - "zh": "inode 表 IO:128 字节 inode 记录的分配、释放与定位读写。\n", - "en": "Inode table IO: allocation, release and positioned read/write of 128-byte inode records.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 352, - "end_line": 375 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#alloc_inode", - "description": { - "zh": "分配一个空闲 inode 号。\n", - "en": "Allocate a free inode number.\n" - }, - "key": "rpc:pyvdisk.fs.FS#alloc_inode" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#free_inode", - "description": { - "zh": "释放 inode 并清除其位图位。\n", - "en": "Release an inode and clear its bitmap bit.\n" - }, - "key": "rpc:pyvdisk.fs.FS#free_inode" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_inode_offset", - "description": { - "zh": "计算 inode 在 inode 表中的字节偏移。\n", - "en": "Compute the byte offset of an inode inside the inode table.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_inode_offset" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#read_inode", - "description": { - "zh": "读取并解码一个 inode。\n", - "en": "Read and decode one inode.\n" - }, - "key": "rpc:pyvdisk.fs.FS#read_inode" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#write_inode", - "description": { - "zh": "把一个 inode 编码后写回表。\n", - "en": "Encode and write one inode back to the table.\n" - }, - "key": "rpc:pyvdisk.fs.FS#write_inode" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.access", - "from_api": "rpc:pyvdisk.fs.FS#read_inode", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#read_bytes", - "label": { - "zh": "读取 inode 表", - "en": "reads inode table" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.fs.layout": { - "uid": "a0000402", - "id": "pyvdisk.storage.fs.layout", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "盘上布局", - "en": "On-Disk Layout" - }, - "description": { - "zh": "盘上布局常量:魔数、版本、inode 与目录项几何,以及推导出的文件尺寸上限。\n", - "en": "On-disk layout constants: magic, version, inode and directory entry geometry and the derived file-size ceiling.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 81, - "end_line": 107 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.MAGIC", - "description": { - "zh": "文件系统魔数 VDK1。\n", - "en": "Filesystem magic bytes VDK1.\n" - }, - "key": "rpc:pyvdisk.fs.MAGIC" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.VERSION", - "description": { - "zh": "盘上文件系统格式版本。\n", - "en": "On-disk filesystem format version.\n" - }, - "key": "rpc:pyvdisk.fs.VERSION" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.INODE_SIZE", - "description": { - "zh": "inode 打包尺寸(字节)。\n", - "en": "Packed inode size in bytes.\n" - }, - "key": "rpc:pyvdisk.fs.INODE_SIZE" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.DIRECT_COUNT", - "description": { - "zh": "每个 inode 的直接块指针数。\n", - "en": "Number of direct block pointers per inode.\n" - }, - "key": "rpc:pyvdisk.fs.DIRECT_COUNT" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.MAX_FILE_SIZE", - "description": { - "zh": "由直接加单/双间接指针决定的最大文件尺寸。\n", - "en": "Maximum representable file size given direct plus single and double indirect pointers.\n" - }, - "key": "rpc:pyvdisk.fs.MAX_FILE_SIZE" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.locking": { - "uid": "a0000401", - "id": "pyvdisk.storage.fs.locking", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "FS 加锁", - "en": "FS Locking" - }, - "description": { - "zh": "逐方法读写加锁,以及让同一镜像上的多个 FS 实例互斥的跨实例锁注册表。\n", - "en": "Per-method read/write locking plus the cross-instance lock registry that makes concurrent FS instances over one image mutually exclusive.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 32, - "end_line": 79 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs._read_locked", - "description": { - "zh": "用共享读锁包裹方法。\n", - "en": "Wrap a method with the shared read lock.\n" - }, - "key": "rpc:pyvdisk.fs._read_locked" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs._write_locked", - "description": { - "zh": "用独占写锁包裹方法。\n", - "en": "Wrap a method with the exclusive write lock.\n" - }, - "key": "rpc:pyvdisk.fs._write_locked" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs._disk_lock_key", - "description": { - "zh": "根据盘/卷背后的真实路径推导稳定锁键。\n", - "en": "Derive a stable lock key from the real paths behind a disk or volume.\n" - }, - "key": "rpc:pyvdisk.fs._disk_lock_key" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs._shared_lock_for", - "description": { - "zh": "返回同一镜像上所有实例共享的进程级 RWLock。\n", - "en": "Return the process-wide RWLock shared by all instances over the same image.\n" - }, - "key": "rpc:pyvdisk.fs._shared_lock_for" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.rwlock.core", - "from_api": "rpc:pyvdisk.fs._shared_lock_for", - "to_api": "rpc:pyvdisk.rwlock.RWLock", - "label": { - "zh": "创建读写锁", - "en": "creates RWLock" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.mkfs": { - "uid": "a0000417", - "id": "pyvdisk.storage.fs.mkfs", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "格式化", - "en": "Format" - }, - "description": { - "zh": "格式化:构建带保留区的空文件系统,并写入磁盘身份尾标;身份写入不可用时不影响格式化。\n", - "en": "Formatting: builds an empty filesystem with reserved regions and stamps the disk identity trailer without failing the format when identity writing is unavailable.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 1229, - "end_line": 1330 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.mkfs", - "description": { - "zh": "格式化镜像:写入超级块、位图、根目录与磁盘身份尾标。\n", - "en": "Format a disk image: write the superblock, bitmaps, root directory and the disk identity trailer.\n" - }, - "key": "rpc:pyvdisk.fs.mkfs" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.identity.probe", - "from_api": "rpc:pyvdisk.fs.mkfs", - "to_api": "rpc:pyvdisk.identity.write_identity_to_block0", - "label": { - "zh": "写入身份尾标", - "en": "stamps identity" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.fs.mount": { - "uid": "a0000407", - "id": "pyvdisk.storage.fs.mount", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "挂载", - "en": "Mount" - }, - "description": { - "zh": "FS 构造、挂载时超级块校验与超级块持久化。\n", - "en": "FS construction, mount-time superblock validation and superblock persistence.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 273, - "end_line": 318 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS", - "description": { - "zh": "绑定到单个块设备的文件系统;持有超级块与共享锁。\n", - "en": "Filesystem bound to one block device; holds the superblock and shared lock.\n" - }, - "key": "rpc:pyvdisk.fs.FS" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#mount", - "description": { - "zh": "挂载文件系统并校验盘上超级块。\n", - "en": "Mount the filesystem and validate the on-disk superblock.\n" - }, - "key": "rpc:pyvdisk.fs.FS#mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#flush_superblock", - "description": { - "zh": "把内存中的超级块写回 block 0。\n", - "en": "Persist the in-memory superblock back to block 0.\n" - }, - "key": "rpc:pyvdisk.fs.FS#flush_superblock" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.access", - "from_api": "rpc:pyvdisk.fs.FS#mount", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#read_block", - "label": { - "zh": "读取 block 0", - "en": "reads block 0" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.fs.mutate": { - "uid": "a0000411", - "id": "pyvdisk.storage.fs.mutate", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "删除与重命名", - "en": "Delete and Rename" - }, - "description": { - "zh": "删除与重命名:unlink、rmdir、节点解绑与目标替换。\n", - "en": "Deletion and rename: unlink, rmdir, node detach and destination replacement.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 780, - "end_line": 858 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#unlink", - "description": { - "zh": "删除一个名字;最后一个链接消失时释放 inode。\n", - "en": "Remove one name; the inode is freed when the last link disappears.\n" - }, - "key": "rpc:pyvdisk.fs.FS#unlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#rmdir", - "description": { - "zh": "删除空目录。\n", - "en": "Remove an empty directory.\n" - }, - "key": "rpc:pyvdisk.fs.FS#rmdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_remove_node", - "description": { - "zh": "把名字与 inode 解绑,无链接时释放 inode。\n", - "en": "Detach a name from its inode and drop the inode when unlinked.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_remove_node" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#rename", - "description": { - "zh": "重命名或移动路径,并替换目标目录项。\n", - "en": "Rename or move a path, replacing the destination entry.\n" - }, - "key": "rpc:pyvdisk.fs.FS#rename" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.pointers", - "from_api": "rpc:pyvdisk.fs.FS#_remove_node", - "to_api": "rpc:pyvdisk.fs.FS#_free_all_blocks", - "label": { - "zh": "回收数据块", - "en": "reclaims blocks" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.names": { - "uid": "a0000403", - "id": "pyvdisk.storage.fs.names", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "名字编解码", - "en": "Name Codec" - }, - "description": { - "zh": "目录槽位名编解码,以及跨文件系统接口使用的 FSError。\n", - "en": "Name codec for directory slots plus the FSError type used across the filesystem surface.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 254, - "end_line": 270 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs._encode_name", - "description": { - "zh": "把目录名编码进固定的 27 字节槽位。\n", - "en": "Encode a directory name into the fixed 27-byte slot.\n" - }, - "key": "rpc:pyvdisk.fs._encode_name" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs._decode_name", - "description": { - "zh": "解码定宽目录名槽位。\n", - "en": "Decode a fixed-width directory name slot.\n" - }, - "key": "rpc:pyvdisk.fs._decode_name" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs._ceil_div", - "description": { - "zh": "整数向上取整除法。\n", - "en": "Integer ceiling division helper.\n" - }, - "key": "rpc:pyvdisk.fs._ceil_div" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FSError", - "description": { - "zh": "路径非法或元数据损坏时抛出的文件系统错误。\n", - "en": "Filesystem-level error raised for invalid paths and corrupted metadata.\n" - }, - "key": "rpc:pyvdisk.fs.FSError" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.paths": { - "uid": "a000040e", - "id": "pyvdisk.storage.fs.paths", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "路径解析", - "en": "Path Resolution" - }, - "description": { - "zh": "路径解析:分量拆分、带深度上限的符号链接感知查找,以及创建所需的父目录解析。\n", - "en": "Path resolution: component splitting, symlink-aware lookup with a depth bound, and parent resolution for creation.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 588, - "end_line": 641 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_split_path", - "description": { - "zh": "把 POSIX 路径拆分为非空分量。\n", - "en": "Split a POSIX path into non-empty components.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_split_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#resolve", - "description": { - "zh": "把路径解析为 inode 号,跟踪符号链接并限制深度。\n", - "en": "Resolve a path to an inode number, following symlinks and bounding depth.\n" - }, - "key": "rpc:pyvdisk.fs.FS#resolve" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#resolve_parent", - "description": { - "zh": "把路径解析为父目录 inode 与末段名字。\n", - "en": "Resolve a path to its parent directory inode and final name.\n" - }, - "key": "rpc:pyvdisk.fs.FS#resolve_parent" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.dir", - "from_api": "rpc:pyvdisk.fs.FS#resolve", - "to_api": "rpc:pyvdisk.fs.FS#dir_lookup", - "label": { - "zh": "逐级遍历目录", - "en": "walks directories" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.pointers": { - "uid": "a000040b", - "id": "pyvdisk.storage.fs.pointers", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "块指针", - "en": "Block Pointers" - }, - "description": { - "zh": "直接与间接块指针树:解析、扩展与回收 inode 的块映射。\n", - "en": "Direct and indirect block pointer tree: resolve, extend and reclaim an inode's block map.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 391, - "end_line": 488 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_read_ptr", - "description": { - "zh": "从间接块中读出一个指针。\n", - "en": "Read one pointer out of an indirect block.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_read_ptr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_write_ptr", - "description": { - "zh": "把一个指针写入间接块。\n", - "en": "Write one pointer into an indirect block.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_write_ptr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_get_block_ptr", - "description": { - "zh": "沿直接/单/双间接指针树把逻辑块号解析为物理块。\n", - "en": "Resolve a logical block index to a physical block through the direct/single/double indirect pointer tree.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_get_block_ptr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_ensure_block_ptr", - "description": { - "zh": "为寻址某逻辑块按需分配间接块。\n", - "en": "Allocate the indirect blocks needed to address a logical block.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_ensure_block_ptr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_free_all_blocks", - "description": { - "zh": "释放 inode 引用的全部数据块与间接块。\n", - "en": "Free every data and indirect block referenced by an inode.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_free_all_blocks" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.fs.query": { - "uid": "a0000414", - "id": "pyvdisk.storage.fs.query", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "状态与空间查询", - "en": "Stat and Space Queries" - }, - "description": { - "zh": "只读查询:stat 变体、空闲对象计数,以及 df/du 使用的 statfs 汇总。\n", - "en": "Read-only queries: stat variants, free-object counts and the statfs summary consumed by df/du.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 1018, - "end_line": 1078 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#stat", - "description": { - "zh": "按 inode 号取 stat。\n", - "en": "Stat an inode by number.\n" - }, - "key": "rpc:pyvdisk.fs.FS#stat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#stat_path", - "description": { - "zh": "按路径取 stat,可选是否跟踪末尾符号链接。\n", - "en": "Stat a path, optionally following the final symlink.\n" - }, - "key": "rpc:pyvdisk.fs.FS#stat_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#lstat_path", - "description": { - "zh": "不跟踪末尾符号链接地取 stat。\n", - "en": "Stat a path without following the final symlink.\n" - }, - "key": "rpc:pyvdisk.fs.FS#lstat_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#count_free_blocks", - "description": { - "zh": "统计空闲数据块。\n", - "en": "Count free data blocks.\n" - }, - "key": "rpc:pyvdisk.fs.FS#count_free_blocks" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#count_free_inodes", - "description": { - "zh": "统计空闲 inode。\n", - "en": "Count free inodes.\n" - }, - "key": "rpc:pyvdisk.fs.FS#count_free_inodes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#statfs", - "description": { - "zh": "报告文件系统几何与剩余空间统计。\n", - "en": "Report filesystem geometry and free-space statistics.\n" - }, - "key": "rpc:pyvdisk.fs.FS#statfs" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.fs.readwrite": { - "uid": "a0000412", - "id": "pyvdisk.storage.fs.readwrite", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "文件读写", - "en": "File Read and Write" - }, - "description": { - "zh": "文件数据路径:定位读取、追加、覆盖与按需分配块的偏移写入。\n", - "en": "File data path: positional read, append, overwrite and offset write with on-demand block allocation.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 860, - "end_line": 946 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#read_file", - "description": { - "zh": "从 inode 读取一段字节。\n", - "en": "Read a byte range from an inode.\n" - }, - "key": "rpc:pyvdisk.fs.FS#read_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#append_path", - "description": { - "zh": "向路径追加字节,不存在时创建文件。\n", - "en": "Append bytes to a path, creating the file when absent.\n" - }, - "key": "rpc:pyvdisk.fs.FS#append_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#write_path", - "description": { - "zh": "用给定字节覆盖写入路径。\n", - "en": "Overwrite a path with the given bytes.\n" - }, - "key": "rpc:pyvdisk.fs.FS#write_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#write_file", - "description": { - "zh": "按字节偏移写入 inode,按需分配数据块。\n", - "en": "Write bytes into an inode at a byte offset, allocating blocks as needed.\n" - }, - "key": "rpc:pyvdisk.fs.FS#write_file" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.pointers", - "from_api": "rpc:pyvdisk.fs.FS#write_file", - "to_api": "rpc:pyvdisk.fs.FS#_ensure_block_ptr", - "label": { - "zh": "扩展块映射", - "en": "extends block map" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.fs.stat": { - "uid": "a0000406", - "id": "pyvdisk.storage.fs.stat", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "Stat 视图", - "en": "Stat View" - }, - "description": { - "zh": "stat 结果对象及类型判定,供 VFS、FUSE 与 CLI 使用。\n", - "en": "Stat result object with the type predicates consumed by VFS, FUSE and the CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 229, - "end_line": 251 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.Stat", - "description": { - "zh": "返回给调用方的只读 stat 视图。\n", - "en": "Read-only stat view returned to callers.\n" - }, - "key": "rpc:pyvdisk.fs.Stat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Stat#is_dir", - "description": { - "zh": "inode 是目录(或指向目录的符号链接)时为真。\n", - "en": "True when the inode is a directory or symlink pointing at one.\n" - }, - "key": "rpc:pyvdisk.fs.Stat#is_dir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Stat#is_file", - "description": { - "zh": "inode 是普通文件时为真。\n", - "en": "True when the inode is a regular file.\n" - }, - "key": "rpc:pyvdisk.fs.Stat#is_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.Stat#is_symlink", - "description": { - "zh": "inode 是符号链接时为真。\n", - "en": "True when the inode is a symbolic link.\n" - }, - "key": "rpc:pyvdisk.fs.Stat#is_symlink" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.superblock": { - "uid": "a0000404", - "id": "pyvdisk.storage.fs.superblock", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "超级块", - "en": "Superblock" - }, - "description": { - "zh": "超级块结构及其二进制编解码;镜像上所有区域偏移的唯一事实来源。\n", - "en": "Superblock structure and its binary codec; the single source of truth for every region offset on the image.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 111, - "end_line": 155 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.SuperBlock", - "description": { - "zh": "描述全部区域偏移与几何的超级块值对象。\n", - "en": "Superblock value object describing all region offsets and geometry.\n" - }, - "key": "rpc:pyvdisk.fs.SuperBlock" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.SuperBlock#to_bytes", - "description": { - "zh": "把超级块序列化为打包表示。\n", - "en": "Serialize the superblock into its packed representation.\n" - }, - "key": "rpc:pyvdisk.fs.SuperBlock#to_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.SuperBlock#from_bytes", - "description": { - "zh": "解析超级块并校验魔数与版本。\n", - "en": "Parse a superblock and validate its magic and version.\n" - }, - "key": "rpc:pyvdisk.fs.SuperBlock#from_bytes" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fs.truncate": { - "uid": "a0000413", - "id": "pyvdisk.storage.fs.truncate", - "parent": "pyvdisk.storage.fs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "截断", - "en": "Truncate" - }, - "description": { - "zh": "截断操作及其后续的间接块清理。\n", - "en": "Truncation and the indirect-block cleanup that follows it.\n" - }, - "source": [ - { - "path": "pyvdisk/fs.py", - "line": 948, - "end_line": 1015 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "fde0821495837c3fa00bf19673cc22de703e3102ef613b5ee9d3469056a21ebf", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#truncate", - "description": { - "zh": "调整 inode 尺寸,增长时补零、收缩时释放块。\n", - "en": "Resize an inode, zero-filling growth and releasing blocks on shrink.\n" - }, - "key": "rpc:pyvdisk.fs.FS#truncate" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_clear_block_ptr", - "description": { - "zh": "清除一个逻辑块指针并释放其数据块。\n", - "en": "Clear one logical block pointer and free its block.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_clear_block_ptr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fs.FS#_maybe_free_indirect", - "description": { - "zh": "在截断后释放不再需要的间接块。\n", - "en": "Release indirect blocks that are no longer needed after a truncate.\n" - }, - "key": "rpc:pyvdisk.fs.FS#_maybe_free_indirect" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fuse": { - "uid": "a000030c", - "id": "pyvdisk.storage.fuse", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "fuse", - "optional" - ], - "name": { - "zh": "FUSE 挂载", - "en": "FUSE Mount" - }, - "description": { - "zh": "可选 FUSE 挂载:把 VFS 暴露为宿主目录;缺少 fusepy 时给出清晰的 ImportError。\n", - "en": "Optional FUSE mount that exposes a VFS as a host directory; degrades to a clear ImportError when fusepy is absent.\n" - }, - "source": [ - { - "path": "pyvdisk/fuse_mount.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", - "aggregate": { - "descendant_count": 4, - "own_api_count": 0, - "inherited_api_count": 20, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.fuse.data": { - "uid": "a000070f", - "id": "pyvdisk.storage.fuse.data", - "parent": "pyvdisk.storage.fuse", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "FUSE 数据处理", - "en": "FUSE Data Ops" - }, - "description": { - "zh": "FUSE 数据与命名空间变更:read、write、create、mkdir、rmdir、unlink 与 rename 处理。\n", - "en": "FUSE data and namespace mutations: read, write, create, mkdir, rmdir, unlink and rename handlers.\n" - }, - "source": [ - { - "path": "pyvdisk/fuse_mount.py", - "line": 85, - "end_line": 121 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_read", - "description": { - "zh": "通过 VFS 取字节区间实现 read。\n", - "en": "Implement read by fetching a byte range through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_write", - "description": { - "zh": "通过 VFS 存字节实现 write。\n", - "en": "Implement write by storing bytes through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_write" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_create", - "description": { - "zh": "实现 create,只读挂载时拒绝。\n", - "en": "Implement create, rejecting it when mounted read-only.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_mkdir", - "description": { - "zh": "通过 VFS 实现 mkdir。\n", - "en": "Implement mkdir through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_mkdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_rmdir", - "description": { - "zh": "通过 VFS 实现 rmdir。\n", - "en": "Implement rmdir through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_rmdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_unlink", - "description": { - "zh": "通过 VFS 实现 unlink。\n", - "en": "Implement unlink through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_unlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_rename", - "description": { - "zh": "通过 VFS 实现 rename。\n", - "en": "Implement rename through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_rename" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_write", - "to_api": "rpc:pyvdisk.vfs.VFS#write_file", - "label": { - "zh": "写文件", - "en": "writes file" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fuse.handlers": { - "uid": "a0000710", - "id": "pyvdisk.storage.fuse.handlers", - "parent": "pyvdisk.storage.fuse", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "FUSE 链接处理", - "en": "FUSE Link Ops" - }, - "description": { - "zh": "其余 FUSE 处理:truncate、链接、open/release、chmod,以及动态 Operations 子类装配。readlink 以不追随后一段的方式解析,读符号链接返回目标路径而不是 EINVAL。\n", - "en": "The remaining FUSE handlers: truncate, links, open/release, chmod and the dynamic Operations subclass assembly. readlink resolves without following the final component, so reading a symlink returns its target instead of EINVAL.\n" - }, - "source": [ - { - "path": "pyvdisk/fuse_mount.py", - "line": 119, - "end_line": 233 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_truncate", - "description": { - "zh": "通过 VFS 实现 truncate。\n", - "en": "Implement truncate through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_truncate" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_symlink", - "description": { - "zh": "实现符号链接创建。\n", - "en": "Implement symlink creation.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_symlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_readlink", - "description": { - "zh": "实现 readlink。\n", - "en": "Implement readlink.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_readlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_open", - "description": { - "zh": "实现 open,并检查写模式权限。\n", - "en": "Implement open with write-mode permission checking.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_release", - "description": { - "zh": "实现 release,清理缓存状态。\n", - "en": "Implement release by dropping cached state.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_release" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_chmod", - "description": { - "zh": "实现 chmod,并带只读保护。\n", - "en": "Implement chmod with a read-only guard.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_chmod" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._build_fuse_class", - "description": { - "zh": "根据处理表装配 fusepy 的 Operations 子类。\n", - "en": "Assemble the fusepy Operations subclass from the handler table.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._build_fuse_class" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.fuse.meta": { - "uid": "a000070e", - "id": "pyvdisk.storage.fuse.meta", - "parent": "pyvdisk.storage.fuse", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "FUSE 属性", - "en": "FUSE Attributes" - }, - "description": { - "zh": "stat 到 fuse 的映射与目录项对象:类型、mode、大小、时间戳与属主。身份来自平台适配层,同时修掉一个真实缺陷:此前 uid 0(root)与\"平台没有 uid\"无法区分。\n", - "en": "Stat-to-fuse mapping and the entry object: type, mode, size, timestamps and ownership. Identity comes from the platform layer, which also fixes a real bug: uid 0 (root) was previously indistinguishable from \"no uid available\".\n" - }, - "source": [ - { - "path": "pyvdisk/fuse_mount.py", - "line": 24, - "end_line": 80 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T11:37:33.368Z", - "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._have_fuse", - "description": { - "zh": "fusepy 可导入时为真。\n", - "en": "True when fusepy is importable.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._have_fuse" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations", - "description": { - "zh": "把内核调用翻译为 VFS 调用的 FUSE 操作类。\n", - "en": "FUSE operation class translating kernel calls into VFS calls.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_getattr", - "description": { - "zh": "通过 VFS stat 实现 getattr。\n", - "en": "Implement getattr by statting through the VFS.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount._VFuseOperations#_readdir", - "description": { - "zh": "通过列举 VFS 目录实现 readdir。\n", - "en": "Implement readdir by listing the VFS directory.\n" - }, - "key": "rpc:pyvdisk.fuse_mount._VFuseOperations#_readdir" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.platform.durability", - "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "label": { - "zh": "进程身份", - "en": "process identity" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.fuse.mount": { - "uid": "a0000711", - "id": "pyvdisk.storage.fuse.mount", - "parent": "pyvdisk.storage.fuse", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "FUSE 挂载入口", - "en": "FUSE Mount Entry" - }, - "description": { - "zh": "公开挂载入口,包含容忍忙挂载的 main 循环补丁与线程化变体。\n", - "en": "Public mount entry points, including the patched main loop that tolerates busy mounts and the threaded variant.\n" - }, - "source": [ - { - "path": "pyvdisk/fuse_mount.py", - "line": 234, - "end_line": 283 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "c711d0ed315e831e5d1d2873c7557dc5e72c8dcb01ee91556eb39cb3065c5d76", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount.mount", - "description": { - "zh": "把 VFS 挂载到宿主挂载点;缺少 fusepy 时给出清晰错误。\n", - "en": "Mount a VFS at a host mountpoint, raising a clear error when fusepy is unavailable.\n" - }, - "key": "rpc:pyvdisk.fuse_mount.mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.fuse_mount.mount_in_thread", - "description": { - "zh": "在后台线程运行 FUSE 主循环。\n", - "en": "Run the FUSE main loop on a background thread.\n" - }, - "key": "rpc:pyvdisk.fuse_mount.mount_in_thread" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.lifetime", - "from_api": "rpc:pyvdisk.fuse_mount.mount", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.identity": { - "uid": "a0000303", - "id": "pyvdisk.storage.identity", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "磁盘身份", - "en": "Disk Identity" - }, - "description": { - "zh": "磁盘身份:block 0 末尾的 112 字节 VDID 尾标,让每块 .vdisk 不依赖路径即可被识别。\n", - "en": "Disk identity: a 112-byte VDID trailer in block 0 that identifies each .vdisk file independently of its path.\n" - }, - "source": [ - { - "path": "pyvdisk/identity.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "79d877b6840991d3a1de01a41018bf417b9d899c8649bb49dd7b7f5f9ed0f2ab", - "aggregate": { - "descendant_count": 4, - "own_api_count": 0, - "inherited_api_count": 12, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.identity.format": { - "uid": "a0000207", - "id": "pyvdisk.storage.identity.format", - "parent": "pyvdisk.storage.identity", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "身份格式", - "en": "Identity Format" - }, - "description": { - "zh": "尾标布局常量、.vdisk 后缀规则与身份错误类型。\n", - "en": "Trailer layout constants, the .vdisk suffix rule and the identity error type.\n" - }, - "source": [ - { - "path": "pyvdisk/identity.py", - "line": 30, - "end_line": 53 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "79d877b6840991d3a1de01a41018bf417b9d899c8649bb49dd7b7f5f9ed0f2ab", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.identity.validate_disk_path", - "description": { - "zh": "要求用户可见的磁盘容器使用 .vdisk 后缀。\n", - "en": "Require a .vdisk suffix for user-visible disk containers.\n" - }, - "key": "rpc:pyvdisk.identity.validate_disk_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.IdentityError", - "description": { - "zh": "身份解析或写入失败时抛出。\n", - "en": "Raised when a disk identity cannot be parsed or written.\n" - }, - "key": "rpc:pyvdisk.identity.IdentityError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.DISK_ID_TRAILER_SIZE", - "description": { - "zh": "block 0 末尾保留的尾标长度常量(112 字节)。\n", - "en": "Trailer length constant (112 bytes) reserved at the end of block 0.\n" - }, - "key": "rpc:pyvdisk.identity.DISK_ID_TRAILER_SIZE" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.identity.model": { - "uid": "a0000209", - "id": "pyvdisk.storage.identity.model", - "parent": "pyvdisk.storage.identity", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "身份模型", - "en": "Identity Model" - }, - "description": { - "zh": "DiskIdentity 值对象及其类型判定与简短展示形式。\n", - "en": "DiskIdentity value object plus its kind predicates and short display form.\n" - }, - "source": [ - { - "path": "pyvdisk/identity.py", - "line": 116, - "end_line": 156 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "79d877b6840991d3a1de01a41018bf417b9d899c8649bb49dd7b7f5f9ed0f2ab", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.identity.DiskIdentity", - "description": { - "zh": "身份记录:类型、磁盘 UUID、卷 ID、卷标、标志位与可选卷元数据。\n", - "en": "Identity record: kind, disk uuid, volume id, label, flags and optional volume metadata.\n" - }, - "key": "rpc:pyvdisk.identity.DiskIdentity" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.DiskIdentity#is_single", - "description": { - "zh": "该盘是独立文件系统镜像时为真。\n", - "en": "True when the disk is a standalone filesystem image.\n" - }, - "key": "rpc:pyvdisk.identity.DiskIdentity#is_single" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.DiskIdentity#is_complete_member", - "description": { - "zh": "该盘为成员盘且卷元数据已成功解析时为真。\n", - "en": "True when the disk is a volume member whose volume metadata parsed.\n" - }, - "key": "rpc:pyvdisk.identity.DiskIdentity#is_complete_member" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.DiskIdentity#short", - "description": { - "zh": "紧凑的人类可读身份摘要。\n", - "en": "Compact human-readable identity summary.\n" - }, - "key": "rpc:pyvdisk.identity.DiskIdentity#short" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.identity.probe": { - "uid": "a000020a", - "id": "pyvdisk.storage.identity.probe", - "parent": "pyvdisk.storage.identity", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "身份探测", - "en": "Identity Probe" - }, - "description": { - "zh": "身份 IO:写尾标、不挂载即探测盘文件,以及 UUID 生成。\n", - "en": "Identity IO: writing the trailer, probing a disk file without mounting it, and uuid generation.\n" - }, - "source": [ - { - "path": "pyvdisk/identity.py", - "line": 159, - "end_line": 226 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "79d877b6840991d3a1de01a41018bf417b9d899c8649bb49dd7b7f5f9ed0f2ab", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.identity.write_identity_to_block0", - "description": { - "zh": "以读-改-写方式把身份尾标写入 block 0 末尾。\n", - "en": "Read-modify-write the identity trailer at the end of block 0.\n" - }, - "key": "rpc:pyvdisk.identity.write_identity_to_block0" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.probe_disk", - "description": { - "zh": "探测一个 .vdisk 文件,判定其为成员盘、单盘、向量盘、日志盘或未知。\n", - "en": "Probe one .vdisk file and classify it as member, single, vector, log or unknown.\n" - }, - "key": "rpc:pyvdisk.identity.probe_disk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.new_disk_uuid", - "description": { - "zh": "生成新的随机磁盘 UUID。\n", - "en": "Generate a new random disk uuid.\n" - }, - "key": "rpc:pyvdisk.identity.new_disk_uuid" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.identity.trailer", - "from_api": "rpc:pyvdisk.identity.probe_disk", - "to_api": "rpc:pyvdisk.identity.parse_trailer", - "label": { - "zh": "解析尾标", - "en": "parses trailer" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.identity.trailer": { - "uid": "a0000208", - "id": "pyvdisk.storage.identity.trailer", - "parent": "pyvdisk.storage.identity", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "尾标编解码", - "en": "Trailer Codec" - }, - "description": { - "zh": "身份尾标的二进制编解码:定长 112 字节布局的打包与解析。\n", - "en": "Binary codec for the identity trailer: pack and parse the fixed-width 112-byte layout.\n" - }, - "source": [ - { - "path": "pyvdisk/identity.py", - "line": 56, - "end_line": 113 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "79d877b6840991d3a1de01a41018bf417b9d899c8649bb49dd7b7f5f9ed0f2ab", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.identity.make_trailer", - "description": { - "zh": "把 disk_uuid、vol_id、label 与 flags 打包成 112 字节尾标。\n", - "en": "Pack disk_uuid, vol_id, label and flags into the 112-byte trailer.\n" - }, - "key": "rpc:pyvdisk.identity.make_trailer" - }, - { - "protocol": "rpc", - "path": "pyvdisk.identity.parse_trailer", - "description": { - "zh": "从块尾解析尾标;魔数不匹配时返回 None。\n", - "en": "Parse the trailer from a block; returns None when the magic does not match.\n" - }, - "key": "rpc:pyvdisk.identity.parse_trailer" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.identity.model", - "from_api": "rpc:pyvdisk.identity.parse_trailer", - "to_api": "rpc:pyvdisk.identity.DiskIdentity", - "label": { - "zh": "构造身份模型", - "en": "builds identity model" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.log": { - "uid": "a0000309", - "id": "pyvdisk.storage.log", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "log", - "event" - ], - "name": { - "zh": "日志盘", - "en": "Log Disk" - }, - "description": { - "zh": "日志盘:分段事件流,带序号、游标、ack、replay、保留策略与压缩。\n", - "en": "Log disk: segmented event streams with sequence numbers, cursors, ack, replay, retention and compaction.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.233Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "aggregate": { - "descendant_count": 6, - "own_api_count": 0, - "inherited_api_count": 22, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.log.append": { - "uid": "a0000608", - "id": "pyvdisk.storage.log.append", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志追加", - "en": "Log Append" - }, - "description": { - "zh": "事件摄入:单条与批量追加,自动分段。\n", - "en": "Event ingestion: single and batch append with automatic segmentation.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 104, - "end_line": 149 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.233Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#append", - "description": { - "zh": "追加一个事件,赋予序号、分段与时间戳。\n", - "en": "Append one event, assigning sequence, segment and timestamp.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#append" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#append_many", - "description": { - "zh": "批量追加事件。\n", - "en": "Append a batch of events.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#append_many" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.filter", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "to_api": "rpc:pyvdisk.log_disk._json", - "label": { - "zh": "编码记录", - "en": "encodes record" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 4 - } - }, - "pyvdisk.storage.log.filter": { - "uid": "a0000605", - "id": "pyvdisk.storage.log.filter", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志过滤", - "en": "Log Filtering" - }, - "description": { - "zh": "日志记录值过滤与规范 JSON 编码,供追加与查询共用。\n", - "en": "Log record value filter and canonical JSON encoding shared by append and query.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 11, - "end_line": 37 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.234Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDiskError", - "description": { - "zh": "日志盘特定失败时抛出。\n", - "en": "Raised for log-disk specific failures.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDiskError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk._json", - "description": { - "zh": "每条持久日志记录使用的规范紧凑 JSON 编码。\n", - "en": "Canonical compact JSON encoding used for every persisted log record.\n" - }, - "key": "rpc:pyvdisk.log_disk._json" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk._match", - "description": { - "zh": "把记录与嵌套的 where 比较/列表过滤条件匹配。\n", - "en": "Match a record against a nested where-filter of comparisons and lists.\n" - }, - "key": "rpc:pyvdisk.log_disk._match" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.log.open": { - "uid": "a0000606", - "id": "pyvdisk.storage.log.open", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志盘打开", - "en": "Log Disk Open" - }, - "description": { - "zh": "LogDisk 生命周期及日志命名空间下按流的 JSON 辅助。\n", - "en": "LogDisk lifecycle and the per-stream JSON helpers under the log namespace.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 38, - "end_line": 80 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.234Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk", - "description": { - "zh": "以分段事件日志形式暴露的 .vdisk 镜像。\n", - "en": "A .vdisk image exposed as a segmented event log.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#create", - "description": { - "zh": "格式化新的日志盘镜像。\n", - "en": "Format a new log disk image.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#mount", - "description": { - "zh": "挂载日志盘并确保日志命名空间存在。\n", - "en": "Mount the log disk and ensure the log namespace exists.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#close", - "description": { - "zh": "关闭底层 VFS。\n", - "en": "Close the underlying VFS.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#close" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.lifetime", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#mount", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.log.query": { - "uid": "a0000609", - "id": "pyvdisk.storage.log.query", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志查询", - "en": "Log Query" - }, - "description": { - "zh": "日志盘读取侧:带过滤查询、消费端游标、ack、replay、计数、tail 与实时 follow。\n", - "en": "Read side of the log disk: filtered queries, consumer cursors, ack, replay, counting, tailing and live follow.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 149, - "end_line": 195 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.234Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#query", - "description": { - "zh": "按时间窗、级别、logger、tag、属性过滤与上限查询流。\n", - "en": "Query a stream by time window, level, logger, tag, attribute filter and limit.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#query" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#cursor", - "description": { - "zh": "读取持久化的消费端游标。\n", - "en": "Read the persisted consumer cursor.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#cursor" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#ack", - "description": { - "zh": "把消费端游标推进到指定序号。\n", - "en": "Advance a consumer cursor to a sequence number.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#ack" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#replay", - "description": { - "zh": "重放消费端游标之后的全部事件。\n", - "en": "Re-read everything after the consumer cursor.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#replay" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#count", - "description": { - "zh": "统计匹配的事件数。\n", - "en": "Count matching events.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#count" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#tail", - "description": { - "zh": "按顺序返回最近 n 条匹配事件。\n", - "en": "Return the last n matching events in order.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#tail" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#follow", - "description": { - "zh": "持续产出新追加的事件,直到 stop 事件被设置。\n", - "en": "Yield new events as they are appended until the stop event is set.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#follow" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.filter", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#query", - "to_api": "rpc:pyvdisk.log_disk._match", - "label": { - "zh": "应用 where 过滤", - "en": "applies where-filter" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.log.retention": { - "uid": "a000060a", - "id": "pyvdisk.storage.log.retention", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "保留与压缩", - "en": "Retention and Compaction" - }, - "description": { - "zh": "日志盘的存储治理:保留策略执行、压缩与统计。保留如今同时清理被删事件的 event_ids 并校验消费者游标,不再留下指向已裁剪位置的游标。\n", - "en": "Log-disk storage governance: retention enforcement, compaction and statistics. Retention also drops the event ids it removed and re-validates consumer cursors, so it can no longer leave a cursor pointing past the trimmed history.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 196, - "end_line": 238 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.235Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#enforce_retention", - "description": { - "zh": "丢弃超出保留窗口或数量上限的分段与事件。\n", - "en": "Drop segments and events outside the retention window or count cap.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#enforce_retention" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#compact", - "description": { - "zh": "通过重写分段压缩流。\n", - "en": "Compact a stream by rewriting its segments.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#compact" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#stats", - "description": { - "zh": "报告每流的分段、事件与字节统计。\n", - "en": "Report per-stream segment, event and byte statistics.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#stats" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.streams", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#enforce_retention", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#create_stream", - "label": { - "zh": "读取流配置", - "en": "reads stream config" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.log.streams": { - "uid": "a0000607", - "id": "pyvdisk.storage.log.streams", - "parent": "pyvdisk.storage.log", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志流", - "en": "Log Streams" - }, - "description": { - "zh": "流目录:带保留策略的创建、列举与删除。\n", - "en": "Stream catalogue: creation with retention policy, listing and removal.\n" - }, - "source": [ - { - "path": "pyvdisk/log_disk.py", - "line": 81, - "end_line": 103 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.235Z", - "fingerprint": "4b31d03456b1ae4db1ebceef13f447e5093e6459bdea0d2d648139d215bd89a4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#create_stream", - "description": { - "zh": "创建流:段大小、保留窗口与最大事件数。\n", - "en": "Create a stream with segment size, retention window and max event count.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#create_stream" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#list_streams", - "description": { - "zh": "列出流名称及其配置与计数。\n", - "en": "List stream names with their configuration and counters.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#list_streams" - }, - { - "protocol": "rpc", - "path": "pyvdisk.log_disk.LogDisk#drop_stream", - "description": { - "zh": "删除流及其分段。\n", - "en": "Drop a stream and its segments.\n" - }, - "key": "rpc:pyvdisk.log_disk.LogDisk#drop_stream" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.logging": { - "uid": "a000030a", - "id": "pyvdisk.storage.logging", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "结构化日志", - "en": "Structured Logging" - }, - "description": { - "zh": "结构化日志核心:级别归一、LogEvent、上下文绑定、可插拔 sink、UnifiedLogger 与标准库 logging 桥接。\n", - "en": "Structured logging core: level normalization, LogEvent, context binding, pluggable sinks, UnifiedLogger and a stdlib logging bridge.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.235Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 18, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.logging.bridge": { - "uid": "a000060f", - "id": "pyvdisk.storage.logging.bridge", - "parent": "pyvdisk.storage.logging", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志桥接", - "en": "Logging Bridge" - }, - "description": { - "zh": "与标准库 logging 模块的桥接,以及模块级日志器工厂。\n", - "en": "Bridge to the standard library logging module plus the module-level logger factory.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py", - "line": 112, - "end_line": 125 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.236Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.StandardLoggingHandler", - "description": { - "zh": "把标准库日志记录转发到 sink 的 handler。\n", - "en": "stdlib logging handler that forwards records into a sink.\n" - }, - "key": "rpc:pyvdisk.logging_core.StandardLoggingHandler" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.get_logger", - "description": { - "zh": "按名称、sink 与级别创建 UnifiedLogger 的工厂。\n", - "en": "Factory building a UnifiedLogger with the given name, sinks and level.\n" - }, - "key": "rpc:pyvdisk.logging_core.get_logger" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.logging.sinks", - "from_api": "rpc:pyvdisk.logging_core.StandardLoggingHandler", - "to_api": "rpc:pyvdisk.logging_core.LogSink", - "label": { - "zh": "转发到 sink", - "en": "forwards to sinks" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.logging.context": { - "uid": "a000060c", - "id": "pyvdisk.storage.logging.context", - "parent": "pyvdisk.storage.logging", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志上下文", - "en": "Log Context" - }, - "description": { - "zh": "基于 contextvar 的环境字段,会合入每个产出的事件。\n", - "en": "Contextvar-based ambient fields that are merged into every emitted event.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py", - "line": 51, - "end_line": 59 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.236Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.log_context", - "description": { - "zh": "向环境日志上下文添加字段的上下文管理器。\n", - "en": "Context manager adding fields to the ambient log context.\n" - }, - "key": "rpc:pyvdisk.logging_core.log_context" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.bind_context", - "description": { - "zh": "把字段永久合入环境日志上下文。\n", - "en": "Permanently merge fields into the ambient log context.\n" - }, - "key": "rpc:pyvdisk.logging_core.bind_context" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.clear_context", - "description": { - "zh": "清空环境日志上下文。\n", - "en": "Clear the ambient log context.\n" - }, - "key": "rpc:pyvdisk.logging_core.clear_context" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.logging.events": { - "uid": "a000060b", - "id": "pyvdisk.storage.logging.events", - "parent": "pyvdisk.storage.logging", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志事件", - "en": "Log Events" - }, - "description": { - "zh": "结构化事件值类型及其级别归一与 JSON 转换。\n", - "en": "The structured event value type and its level normalization and JSON conversion.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py", - "line": 11, - "end_line": 49 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.236Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.normalize_level", - "description": { - "zh": "把文本或数字级别归一为规范级别名。\n", - "en": "Normalize a textual or numeric level into a canonical level name.\n" - }, - "key": "rpc:pyvdisk.logging_core.normalize_level" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.LogEvent", - "description": { - "zh": "不可变结构化日志记录:级别、消息、字段、标签、异常与时间戳。\n", - "en": "Immutable structured log record with level, message, fields, tags, exception and timestamp.\n" - }, - "key": "rpc:pyvdisk.logging_core.LogEvent" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.LogEvent#to_dict", - "description": { - "zh": "把事件转为 JSON 安全的普通字典。\n", - "en": "Convert the event into a plain JSON-safe dictionary.\n" - }, - "key": "rpc:pyvdisk.logging_core.LogEvent#to_dict" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.LogEvent#from_dict", - "description": { - "zh": "从字典形式重建事件。\n", - "en": "Rebuild an event from its dictionary form.\n" - }, - "key": "rpc:pyvdisk.logging_core.LogEvent#from_dict" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.logging.logger": { - "uid": "a000060e", - "id": "pyvdisk.storage.logging.logger", - "parent": "pyvdisk.storage.logging", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "统一日志器", - "en": "Unified Logger" - }, - "description": { - "zh": "UnifiedLogger:级别门限、上下文与字段合并、标签绑定与异常捕获。\n", - "en": "UnifiedLogger: level gate, context and field merging, tag binding and exception capture.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py", - "line": 83, - "end_line": 110 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.237Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.UnifiedLogger", - "description": { - "zh": "把一个事件扇出到多个 sink 的结构化日志器。\n", - "en": "Structured logger fanning one event out to several sinks.\n" - }, - "key": "rpc:pyvdisk.logging_core.UnifiedLogger" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.UnifiedLogger#bind", - "description": { - "zh": "返回附带额外绑定字段的日志器。\n", - "en": "Return a logger with additional bound fields.\n" - }, - "key": "rpc:pyvdisk.logging_core.UnifiedLogger#bind" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.UnifiedLogger#with_tags", - "description": { - "zh": "返回附带额外字符串标签的日志器。\n", - "en": "Return a logger with additional string tags.\n" - }, - "key": "rpc:pyvdisk.logging_core.UnifiedLogger#with_tags" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.UnifiedLogger#log", - "description": { - "zh": "以显式级别产出一个事件。\n", - "en": "Emit one event at an explicit level.\n" - }, - "key": "rpc:pyvdisk.logging_core.UnifiedLogger#log" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.UnifiedLogger#exception", - "description": { - "zh": "产出携带当前异常信息的 ERROR 事件。\n", - "en": "Emit an ERROR event carrying the current exception info.\n" - }, - "key": "rpc:pyvdisk.logging_core.UnifiedLogger#exception" - } - ], - "deps": [ - { - "kind": "event", - "to": "pyvdisk.storage.logging.sinks", - "from_api": "rpc:pyvdisk.logging_core.UnifiedLogger#log", - "to_api": "rpc:pyvdisk.logging_core.LogSink", - "label": { - "zh": "向 sink 发送", - "en": "emits to sinks" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.logging.sinks": { - "uid": "a000060d", - "id": "pyvdisk.storage.logging.sinks", - "parent": "pyvdisk.storage.logging", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志 Sink", - "en": "Log Sinks" - }, - "description": { - "zh": "sink 协议及其三种实现:内存、流与日志盘持久化。\n", - "en": "Sink protocol and its three implementations: memory, stream and log-disk backed persistence.\n" - }, - "source": [ - { - "path": "pyvdisk/logging_core.py", - "line": 61, - "end_line": 81 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.237Z", - "fingerprint": "b09c0a892a4245c749b1b656f75fea42c069ef41438429402f0b180223f5b281", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.LogSink", - "description": { - "zh": "sink 协议:emit、flush 与 close。\n", - "en": "Sink protocol with emit, flush and close.\n" - }, - "key": "rpc:pyvdisk.logging_core.LogSink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.MemorySink", - "description": { - "zh": "保留最新事件的有界内存 sink。\n", - "en": "Bounded in-memory sink keeping the newest events.\n" - }, - "key": "rpc:pyvdisk.logging_core.MemorySink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.StreamSink", - "description": { - "zh": "向流写入可读行的 sink。\n", - "en": "Sink writing human-readable lines to a stream.\n" - }, - "key": "rpc:pyvdisk.logging_core.StreamSink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.logging_core.LogDiskSink", - "description": { - "zh": "把事件持久化到日志盘流的 sink。\n", - "en": "Sink persisting events into a log disk stream.\n" - }, - "key": "rpc:pyvdisk.logging_core.LogDiskSink" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.append", - "from_api": "rpc:pyvdisk.logging_core.LogDiskSink", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "label": { - "zh": "追加事件", - "en": "appends events" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.rwlock": { - "uid": "a0000304", - "id": "pyvdisk.storage.rwlock", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "读写锁", - "en": "Read-Write Lock" - }, - "description": { - "zh": "可重入、写者优先的读写锁,供同一镜像上并发打开的多个 FS 实例共享。\n", - "en": "Reentrant writer-preferring read-write lock shared by concurrently opened FS instances over the same image.\n" - }, - "source": [ - { - "path": "pyvdisk/rwlock.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "102a869f8df4b9493ae35d1e0df2a33e5d36355f636d2e1d0432a50b39a31062", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 9, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.rwlock.core": { - "uid": "a000020c", - "id": "pyvdisk.storage.rwlock.core", - "parent": "pyvdisk.storage.rwlock", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "锁核心", - "en": "Lock Core" - }, - "description": { - "zh": "锁核心:每线程重入、写者优先,以及仅限唯一读者时的读锁升级。\n", - "en": "Lock core: per-thread reentrancy, writer priority and read-to-write upgrade with a single-reader guard.\n" - }, - "source": [ - { - "path": "pyvdisk/rwlock.py", - "line": 32, - "end_line": 122 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "102a869f8df4b9493ae35d1e0df2a33e5d36355f636d2e1d0432a50b39a31062", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock", - "description": { - "zh": "可重入、写者优先的读写锁。\n", - "en": "Reentrant writer-preferring read-write lock.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#acquire_read", - "description": { - "zh": "获取共享读锁,同线程可重入。\n", - "en": "Acquire a shared read lock, reentrant per thread.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#acquire_read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#release_read", - "description": { - "zh": "释放当前线程的一层读锁。\n", - "en": "Release one level of the current thread read lock.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#release_read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#acquire_write", - "description": { - "zh": "获取独占写锁,必要时从唯一读者升级。\n", - "en": "Acquire the exclusive write lock, upgrading from a sole reader if needed.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#acquire_write" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#release_write", - "description": { - "zh": "释放写锁,最外层释放时唤醒所有等待者。\n", - "en": "Release the write lock, waking all waiters at the outermost level.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#release_write" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.rwlock.ctx": { - "uid": "a000020d", - "id": "pyvdisk.storage.rwlock.ctx", - "parent": "pyvdisk.storage.rwlock", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "锁上下文", - "en": "Lock Contexts" - }, - "description": { - "zh": "供 FS 锁装饰器与 VFS/FS 公开接口使用的 with 语句辅助类型。\n", - "en": "with-statement helpers used by the FS lock decorators and the VFS/FS public surface.\n" - }, - "source": [ - { - "path": "pyvdisk/rwlock.py", - "line": 124, - "end_line": 145 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "102a869f8df4b9493ae35d1e0df2a33e5d36355f636d2e1d0432a50b39a31062", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.ReadCtx", - "description": { - "zh": "获取共享读锁的上下文管理器。\n", - "en": "Context manager acquiring the shared read lock.\n" - }, - "key": "rpc:pyvdisk.rwlock.ReadCtx" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.WriteCtx", - "description": { - "zh": "获取独占写锁的上下文管理器。\n", - "en": "Context manager acquiring the exclusive write lock.\n" - }, - "key": "rpc:pyvdisk.rwlock.WriteCtx" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#read", - "description": { - "zh": "构造读锁上下文管理器。\n", - "en": "Build a read-lock context manager.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.rwlock.RWLock#write", - "description": { - "zh": "构造写锁上下文管理器。\n", - "en": "Build a write-lock context manager.\n" - }, - "key": "rpc:pyvdisk.rwlock.RWLock#write" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.rwlock.core", - "from_api": "rpc:pyvdisk.rwlock.ReadCtx", - "to_api": "rpc:pyvdisk.rwlock.RWLock#acquire_read", - "label": { - "zh": "获取读锁", - "en": "acquires read lock" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vector": { - "uid": "a0000308", - "id": "pyvdisk.storage.vector", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "vector", - "hnsw" - ], - "name": { - "zh": "向量盘", - "en": "Vector Disk" - }, - "description": { - "zh": "向量盘:基于 HNSW 的具名记录集合,带 generation、checksum、过滤器与相似度检索。\n", - "en": "Vector disk: HNSW-backed collections of named records with generation tracking, checksum, filters and similarity search.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_disk.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 23, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vector.collections": { - "uid": "a0000602", - "id": "pyvdisk.storage.vector.collections", - "parent": "pyvdisk.storage.vector", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "集合目录", - "en": "Collections" - }, - "description": { - "zh": "集合目录:按维度与度量创建、带配置列举,以及连同每集合 HNSW 索引一起删除。\n", - "en": "Collection catalogue: create with dimension and metric, list with configuration, and drop along with the per-collection HNSW index.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_disk.py", - "line": 129, - "end_line": 163 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#create_collection", - "description": { - "zh": "以固定维度与度量创建具名集合。\n", - "en": "Create a named collection with a fixed dimension and metric.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#list_collections", - "description": { - "zh": "列出集合名称及其配置。\n", - "en": "List the collection names with their configuration.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#list_collections" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#drop_collection", - "description": { - "zh": "删除集合及其索引文件。\n", - "en": "Drop a collection and its index files.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.vector.flat-index": { - "uid": "a0000334", - "id": "pyvdisk.storage.vector.flat-index", - "parent": "pyvdisk.storage.vector", - "tree": "pyvdisk", - "depth": 4, - "tags": [ - "zero-dependency", - "vector" - ], - "name": { - "zh": "扁平索引后端", - "en": "Flat Index Backend" - }, - "description": { - "zh": "纯 Python 精确索引,接口形状对齐 hnswlib,VectorDisk 因此可以直接回退而不必在调用点分支。查询是 O(n) 且向量常驻内存:适合中小集合,不是大规模下 HNSW 的替代品。\n", - "en": "A pure-Python exact index that mirrors hnswlib's calling shape, so VectorDisk can fall back to it without branching. Query is O(n) and the vectors stay in memory: correct for small and medium collections, not a replacement for HNSW at scale.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_index.py", - "line": 38, - "end_line": 47 - }, - { - "path": "pyvdisk/vector_index.py", - "line": 51, - "end_line": 83 - }, - { - "path": "pyvdisk/vector_index.py", - "line": 169, - "end_line": 251 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "c2a8e20da7599125065676cf6a3cea638d1a8108df234b9873b098dbfffb547d", - "apis": [ - { - "protocol": "rpc", - "path": "vector_index:distance", - "description": { - "zh": "按 hnswlib 的约定计算距离,两种后端在调用点可直接互换:cosine = 1 - 相似度,l2 = 平方欧氏距离,ip = 1 - 点积。\n", - "en": "Distance in the convention hnswlib uses, so the two backends are interchangeable at the call site: cosine = 1 - similarity, l2 = squared euclidean, ip = 1 - dot product.\n" - }, - "key": "rpc:vector_index:distance" - }, - { - "protocol": "rpc", - "path": "vector_index:read_kind", - "description": { - "zh": "从索引文件读出写入方标识:是 hnswlib 写的还是 flat 后端写的,不需要解析其余内容。\n", - "en": "Read the writer's tag from an index file: whether it was written by hnswlib or by the flat backend, without parsing the rest.\n" - }, - "key": "rpc:vector_index:read_kind" - }, - { - "protocol": "rpc", - "path": "vector_index:serialize", - "description": { - "zh": "序列化为 flat 格式:8 字节魔数、空间与维度,然后是标签与 float32 向量。\n", - "en": "Serialise to the flat format: an 8-byte magic, the space and dimension, then labels and float32 vectors.\n" - }, - "key": "rpc:vector_index:serialize" - }, - { - "protocol": "rpc", - "path": "vector_index:deserialize", - "description": { - "zh": "解析 flat 索引;内容被截断或根本不是该格式时报错,而不是当成正确数据读下去。\n", - "en": "Parse a flat index, rejecting a truncated or foreign payload instead of misreading it.\n" - }, - "key": "rpc:vector_index:deserialize" - }, - { - "protocol": "rpc", - "path": "vector_index:serialize_from_backend", - "description": { - "zh": "序列化任一后端的索引:flat 索引直接写自己,hnswlib 索引走它自己的 save_index 落到临时文件,需要负责清理。\n", - "en": "Serialise an index of either backend: a flat index writes itself, an hnswlib index goes through its own save_index into a temporary file that must be unlinked.\n" - }, - "key": "rpc:vector_index:serialize_from_backend" - }, - { - "protocol": "rpc", - "path": "vector_index:FlatIndex.add_item", - "description": { - "zh": "写入一条带标签的向量。维度与索引不一致时报错,维度尚未确定的空索引也拒绝写入。\n", - "en": "Add a labelled vector. Rejects a vector whose dimension disagrees with the index, and refuses a fresh index whose dimension was never set.\n" - }, - "key": "rpc:vector_index:FlatIndex.add_item" - }, - { - "protocol": "rpc", - "path": "vector_index:FlatIndex.knn_query", - "description": { - "zh": "精确 k 近邻搜索。距离相同时按标签排序,保证多次运行结果稳定;可选断言用于筛选候选记录。\n", - "en": "Exact k-nearest search. Ties break on the label so results are stable across runs, and an optional predicate filters the candidate records.\n" - }, - "key": "rpc:vector_index:FlatIndex.knn_query" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.vector.open": { - "uid": "a0000601", - "id": "pyvdisk.storage.vector.open", - "parent": "pyvdisk.storage.vector", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "向量盘打开", - "en": "Vector Disk Open" - }, - "description": { - "zh": "VectorDisk 的构建与挂载。这里不再要求装 hnswlib:集合用内置 flat 索引也能打开并作答,只有恰好装了加速器才会用它。\n", - "en": "VectorDisk construction and mounting. Nothing here requires hnswlib: a collection opens and answers with the built-in flat index, and the accelerator is picked up only if it happens to be installed.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_disk.py", - "line": 13, - "end_line": 127 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDiskError", - "description": { - "zh": "向量盘特定失败(如缺少 hnswlib 后端)时抛出。\n", - "en": "Raised for vector-disk specific failures such as a missing hnswlib backend.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDiskError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk", - "description": { - "zh": "以集合存储形式暴露的 .vdisk 镜像。\n", - "en": "A .vdisk image exposed as a collection store.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#create", - "description": { - "zh": "格式化新的向量盘镜像。\n", - "en": "Format a new vector disk image.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#mount", - "description": { - "zh": "挂载镜像并加载向量命名空间。\n", - "en": "Mount the image and load the vector namespace.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#close", - "description": { - "zh": "关闭底层 VFS。\n", - "en": "Close the underlying VFS.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#close" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.lifetime", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#mount", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.vector.records": { - "uid": "a0000603", - "id": "pyvdisk.storage.vector.records", - "parent": "pyvdisk.storage.vector", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "向量记录", - "en": "Vector Records" - }, - "description": { - "zh": "记录 CRUD:维度校验、单条与批量 upsert、获取、删除与计数。\n", - "en": "Record CRUD: dimension validation, upsert (single and batch), fetch, delete and count.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_disk.py", - "line": 165, - "end_line": 221 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#upsert", - "description": { - "zh": "插入或替换一条带向量与元数据的记录。\n", - "en": "Insert or replace one record with a vector and metadata.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#upsert" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#upsert_many", - "description": { - "zh": "单次 flush 内批量 upsert。\n", - "en": "Batch upsert inside a single flush.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#upsert_many" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#get", - "description": { - "zh": "按 id 取一条记录。\n", - "en": "Fetch one record by id.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#delete", - "description": { - "zh": "删除一条记录,必要时重建索引。\n", - "en": "Delete one record, rebuilding the index when needed.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#delete" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#count", - "description": { - "zh": "统计集合内记录数。\n", - "en": "Count the records in a collection.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#count" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vector.collections", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection", - "label": { - "zh": "校验集合", - "en": "verifies collection" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.vector.search": { - "uid": "a0000604", - "id": "pyvdisk.storage.vector.search", - "parent": "pyvdisk.storage.vector", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "向量检索", - "en": "Vector Search" - }, - "description": { - "zh": "索引构建、加载与查询。后端在加载时由文件魔数决定:装了 hnswlib 就用它,否则用内置 flat 索引。以一次改名发布,并发读方看到的要么是旧索引要么是新索引。\n", - "en": "Index construction, loading and query. The backend is chosen at load time from the file's magic tag: hnswlib when installed, the built-in flat index otherwise. Published with a single rename, so a concurrent reader sees either the old index or the new one.\n" - }, - "source": [ - { - "path": "pyvdisk/vector_disk.py", - "line": 223, - "end_line": 267 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "ee801e56c4d436543de323aa02bb0c3a4e78339ef28b5c1ec180ad68cee817b0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#_rebuild_index", - "description": { - "zh": "由记录重建索引,并以一次改名原子发布,读方不会看到写了一半的索引。\n", - "en": "Rebuild the index from the records and publish it with one rename, so a reader never sees a half-written index.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#_load_index", - "description": { - "zh": "加载集合索引。由文件魔数决定路径:flat 直接解析,hnswlib 索引经 hnswlib 加载,缺 hnswlib 时回退为按记录重建的精确索引。\n", - "en": "Load the collection index. The file's magic decides how: flat parses directly, hnswlib loads through hnswlib, and a missing hnswlib falls back to an exact index over the records.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vector_disk.VectorDisk#search", - "description": { - "zh": "最近邻检索,可带元数据过滤。\n", - "en": "Nearest-neighbour search with an optional metadata filter.\n" - }, - "key": "rpc:pyvdisk.vector_disk.VectorDisk#search" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vector.flat-index", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", - "label": { - "zh": "后端回退", - "en": "backend fallback" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs": { - "uid": "a0000306", - "id": "pyvdisk.storage.vfs", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "虚拟文件系统", - "en": "Virtual File System" - }, - "description": { - "zh": "FS 之上的高层路径式 VFS:类文件对象、权限检查、宿主导入导出、遍历、空间统计与卷自动识别。\n", - "en": "High-level path-based VFS over FS: file objects, permission checks, host import/export, walk, space stats and volume auto-detection.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "aggregate": { - "descendant_count": 16, - "own_api_count": 0, - "inherited_api_count": 62, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.attrs": { - "uid": "a000050a", - "id": "pyvdisk.storage.vfs.attrs", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "元数据变更", - "en": "Metadata Writes" - }, - "description": { - "zh": "VFS 门面上的元数据变更:模式、属主、时间戳、权限检查与截断。\n", - "en": "Metadata mutations on the VFS facade: mode, ownership, timestamps, access checks and truncation.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 364, - "end_line": 406 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#chmod", - "description": { - "zh": "修改模式位,可选穿透符号链接。\n", - "en": "Change mode bits, optionally through a symlink.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#chmod" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#chown", - "description": { - "zh": "修改属主,可选穿透符号链接。\n", - "en": "Change ownership, optionally through a symlink.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#chown" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#utime", - "description": { - "zh": "设置时间戳,可选穿透符号链接。\n", - "en": "Set timestamps, optionally through a symlink.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#utime" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#access", - "description": { - "zh": "对路径做权限检查。\n", - "en": "Permission check on a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#access" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#truncate", - "description": { - "zh": "调整路径上文件的尺寸。\n", - "en": "Resize a file at a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#truncate" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.create": { - "uid": "a0000502", - "id": "pyvdisk.storage.vfs.create", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "创建盘与卷", - "en": "Create Disk or Volume" - }, - "description": { - "zh": "VFS 门面上的磁盘与卷创建入口。\n", - "en": "Disk and volume creation entry points on the VFS facade.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 101, - "end_line": 142 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#create", - "description": { - "zh": "格式化新的单盘文件系统镜像。\n", - "en": "Format a new single-disk filesystem image.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#create" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#create_volume", - "description": { - "zh": "创建多盘卷并格式化。\n", - "en": "Create a multi-disk volume and format it.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#create_volume" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.mkfs", - "from_api": "rpc:pyvdisk.vfs.VFS#create", - "label": { - "zh": "格式化磁盘", - "en": "formats disk" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.dirs": { - "uid": "a0000506", - "id": "pyvdisk.storage.vfs.dirs", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "目录创建", - "en": "Directory Creation" - }, - "description": { - "zh": "目录创建辅助,含用于命名空间初始化的递归变体。\n", - "en": "Directory creation helpers, including the recursive variant used for namespace setup.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 248, - "end_line": 263 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#mkdir", - "description": { - "zh": "创建单个目录。\n", - "en": "Create one directory.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#mkdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#makedirs", - "description": { - "zh": "递归创建目录树,忽略已存在的层。\n", - "en": "Create a directory tree, ignoring existing components.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#makedirs" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.files": { - "uid": "a0000507", - "id": "pyvdisk.storage.vfs.files", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "整文件 IO", - "en": "Whole-File IO" - }, - "description": { - "zh": "建立在定位式 FS 文件 API 之上的整文件读、写与追加便利接口。\n", - "en": "Whole-file read, write and append conveniences on top of the positioned FS file API.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 265, - "end_line": 302 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#read_file", - "description": { - "zh": "把整个文件读为 bytes。\n", - "en": "Read a whole file into bytes.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#read_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#write_file", - "description": { - "zh": "把字节写入路径并替换其内容。\n", - "en": "Write bytes to a path, replacing its contents.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#write_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#append_file", - "description": { - "zh": "向路径追加字节。\n", - "en": "Append bytes to a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#append_file" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.readwrite", - "from_api": "rpc:pyvdisk.vfs.VFS#write_file", - "to_api": "rpc:pyvdisk.fs.FS#write_path", - "label": { - "zh": "写入文件数据", - "en": "writes file data" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 3 - } - }, - "pyvdisk.storage.vfs.hostio": { - "uid": "a000050b", - "id": "pyvdisk.storage.vfs.hostio", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "宿主交换", - "en": "Host Interchange" - }, - "description": { - "zh": "宿主交换:文件对象打开,以及虚拟与宿主文件系统之间的单文件与递归导入导出。\n", - "en": "Host interchange: file object opening plus single-file and recursive import/export between the virtual and host filesystems.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 408, - "end_line": 435 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#open", - "description": { - "zh": "以模式字符串打开文件对象。\n", - "en": "Open a file object with a mode string.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#import_host_file", - "description": { - "zh": "把一个宿主文件复制进 VFS。\n", - "en": "Copy one host file into the VFS.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#import_host_file" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#export_to_host", - "description": { - "zh": "把一个 VFS 文件复制到宿主路径。\n", - "en": "Copy one VFS file out to a host path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#export_to_host" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#import_host_tree", - "description": { - "zh": "递归导入宿主目录树。\n", - "en": "Recursively import a host directory tree.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#import_host_tree" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.lifetime": { - "uid": "a0000503", - "id": "pyvdisk.storage.vfs.lifetime", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "挂载生命周期", - "en": "Mount Lifecycle" - }, - "description": { - "zh": "挂载与关闭生命周期,包含测试与 CLI 广泛使用的 with 协议。\n", - "en": "Mount and close lifecycle, including the with-statement protocol used throughout the tests and CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 143, - "end_line": 161 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.423Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#mount", - "description": { - "zh": "挂载文件系统并返回自身以链式调用。\n", - "en": "Mount the filesystem and return self for chaining.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#mount" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#close", - "description": { - "zh": "刷新并关闭底层磁盘。\n", - "en": "Flush and close the underlying disk.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#close" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#__enter__", - "description": { - "zh": "上下文管理器入口,返回已挂载的 VFS。\n", - "en": "Context manager entry returning a mounted VFS.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#__enter__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#__exit__", - "description": { - "zh": "上下文管理器退出时关闭 VFS。\n", - "en": "Context manager exit that closes the VFS.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#__exit__" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.mount", - "from_api": "rpc:pyvdisk.vfs.VFS#mount", - "to_api": "rpc:pyvdisk.fs.FS#mount", - "label": { - "zh": "挂载文件系统", - "en": "mounts filesystem" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 3 - } - }, - "pyvdisk.storage.vfs.open": { - "uid": "a0000501", - "id": "pyvdisk.storage.vfs.open", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFS 打开", - "en": "VFS Open" - }, - "description": { - "zh": "VFS 构造与传输选择:单个镜像可按普通盘或多成员卷打开。\n", - "en": "VFS construction and transport selection: one image is opened either as a plain disk or as a multi-member volume.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 24, - "end_line": 100 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS", - "description": { - "zh": "单个磁盘或卷之上的高层路径视图。\n", - "en": "High-level path-based view over one disk or volume.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#__init__", - "description": { - "zh": "把 VFS 绑定到路径;底层盘在 mount 时打开。\n", - "en": "Bind a VFS to a path; the underlying disk is opened during mount.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_open_disk_or_volume", - "description": { - "zh": "打开盘文件,自动识别是单盘还是卷。\n", - "en": "Open a disk file, auto-detecting whether it is a single disk or a volume.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_open_disk_or_volume" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.image", - "from_api": "rpc:pyvdisk.vfs.VFS#_open_disk_or_volume", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "label": { - "zh": "打开镜像", - "en": "opens image" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.storage.vfs.permissions": { - "uid": "a0000504", - "id": "pyvdisk.storage.vfs.permissions", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "权限门禁", - "en": "Permission Gate" - }, - "description": { - "zh": "每次 VFS 变更前的权限门禁:inode 模式位、路径遍历与父目录检查。\n", - "en": "The permission gate applied before every VFS mutation: inode bits, path traversal and parent-directory checks.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 163, - "end_line": 202 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_fs_or_raise", - "description": { - "zh": "返回已挂载的 FS,未挂载时抛错。\n", - "en": "Return the mounted FS or raise when the VFS was never mounted.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_fs_or_raise" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_perm_enabled", - "description": { - "zh": "除显式关闭权限检查外为真。\n", - "en": "True unless permission checks are explicitly disabled.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_perm_enabled" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_check", - "description": { - "zh": "inode 不满足请求位时抛出 PermissionError。\n", - "en": "Raise PermissionError unless the inode grants the requested bits.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_check" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_check_traverse", - "description": { - "zh": "要求路径上每一级目录具备执行权限。\n", - "en": "Require execute permission on every directory along a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_check_traverse" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#_check_parent", - "description": { - "zh": "要求路径父目录具备指定权限。\n", - "en": "Require permission on the parent directory of a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#_check_parent" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.attrs", - "from_api": "rpc:pyvdisk.vfs.VFS#_check", - "to_api": "rpc:pyvdisk.fs.FS#access", - "label": { - "zh": "POSIX 权限检查", - "en": "POSIX access check" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.query": { - "uid": "a0000505", - "id": "pyvdisk.storage.vfs.query", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFS 查询", - "en": "VFS Queries" - }, - "description": { - "zh": "VFS 门面上的存在性、类型判定与目录列举。\n", - "en": "Existence, type predicates and directory listing on the VFS facade.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 204, - "end_line": 246 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#exists", - "description": { - "zh": "路径存在时为真。\n", - "en": "True when the path exists.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#exists" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#isfile", - "description": { - "zh": "路径为普通文件时为真。\n", - "en": "True when the path is a regular file.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#isfile" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#isdir", - "description": { - "zh": "路径为目录时为真。\n", - "en": "True when the path is a directory.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#isdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#listdir", - "description": { - "zh": "列出目录中的名字。\n", - "en": "List the names in a directory.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#listdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#listdir_with_stat", - "description": { - "zh": "列出目录项及其 Stat 对象。\n", - "en": "List directory entries together with their Stat objects.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#listdir_with_stat" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.remove": { - "uid": "a0000508", - "id": "pyvdisk.storage.vfs.remove", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "删除与重命名", - "en": "Delete and Rename" - }, - "description": { - "zh": "删除与重命名操作,含检查点清理使用的递归目录删除。\n", - "en": "Deletion and rename operations, including the recursive tree removal used by checkpoint cleanup.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 304, - "end_line": 337 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#remove", - "description": { - "zh": "删除文件。\n", - "en": "Remove a file.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#remove" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#rmdir", - "description": { - "zh": "删除空目录。\n", - "en": "Remove an empty directory.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#rmdir" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#rmtree", - "description": { - "zh": "递归删除目录树。\n", - "en": "Recursively remove a directory tree.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#rmtree" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#rename", - "description": { - "zh": "重命名或移动路径。\n", - "en": "Rename or move a path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#rename" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.space": { - "uid": "a000050d", - "id": "pyvdisk.storage.vfs.space", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "空间与维护", - "en": "Space and Maintenance" - }, - "description": { - "zh": "VFS 门面暴露的诊断与维护能力:空间统计、一致性检查与在线扩容。\n", - "en": "Diagnostics and maintenance exposed by the VFS facade: space accounting, consistency checking and online growth.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 459, - "end_line": 499 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#statfs", - "description": { - "zh": "文件系统几何与剩余空间统计。\n", - "en": "Filesystem geometry and free-space statistics.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#statfs" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#df", - "description": { - "zh": "对应 df 的可读空间汇总。\n", - "en": "Human-readable space summary mirroring df.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#df" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#du", - "description": { - "zh": "子树递归占用字节数。\n", - "en": "Recursive disk usage of a subtree in bytes.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#du" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#fsck", - "description": { - "zh": "运行文件系统一致性检查。\n", - "en": "Run a filesystem consistency check.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#fsck" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#grow", - "description": { - "zh": "就地扩容已挂载文件系统。\n", - "en": "Grow the mounted filesystem in place.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#grow" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.vfs.walk", - "from_api": "rpc:pyvdisk.vfs.VFS#du", - "label": { - "zh": "遍历目录树", - "en": "walks tree" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.stat": { - "uid": "a0000509", - "id": "pyvdisk.storage.vfs.stat", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "元数据读取", - "en": "Metadata Reads" - }, - "description": { - "zh": "暴露给调用方与 FUSE 的元数据读取与链接操作。\n", - "en": "Metadata reads and link operations exposed to callers and to FUSE.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 339, - "end_line": 362 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#stat", - "description": { - "zh": "按路径取 stat,默认跟踪末尾符号链接。\n", - "en": "Stat a path, following the final symlink by default.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#stat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#lstat", - "description": { - "zh": "不跟踪末尾符号链接地取 stat。\n", - "en": "Stat a path without following the final symlink.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#lstat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#symlink", - "description": { - "zh": "创建符号链接。\n", - "en": "Create a symbolic link.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#symlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#readlink", - "description": { - "zh": "读取符号链接目标。\n", - "en": "Read a symbolic link target.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#readlink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#link", - "description": { - "zh": "创建硬链接。\n", - "en": "Create a hard link.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#link" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.query", - "from_api": "rpc:pyvdisk.vfs.VFS#stat", - "to_api": "rpc:pyvdisk.fs.FS#stat_path", - "label": { - "zh": "读取 inode", - "en": "reads inode" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.vfile": { - "uid": "a000050e", - "id": "pyvdisk.storage.vfs.vfile", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFile 对象", - "en": "VFile Object" - }, - "description": { - "zh": "打开文件对象的 VFile 构造与 inode 自省。\n", - "en": "VFile construction and inode introspection for the open-file object.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 501, - "end_line": 549 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile", - "description": { - "zh": "VFS 路径之上的缓冲文件对象。\n", - "en": "Buffered file object over a VFS path.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#__init__", - "description": { - "zh": "把文件对象绑定到路径并解析模式字符串。\n", - "en": "Bind a file object to a path and parse its mode string.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#ino", - "description": { - "zh": "返回该文件对象背后的 inode 号。\n", - "en": "Return the inode number behind this file object.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#ino" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.vfile-ctx": { - "uid": "a0000510", - "id": "pyvdisk.storage.vfs.vfile-ctx", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFile 协议", - "en": "VFile Protocol" - }, - "description": { - "zh": "打开 VFile 对象的 with 语句与迭代协议。\n", - "en": "with-statement and iteration protocol for open VFile objects.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 600, - "end_line": 612 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#__enter__", - "description": { - "zh": "上下文管理器入口,返回打开的文件对象。\n", - "en": "Context manager entry returning the open file object.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#__enter__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#__exit__", - "description": { - "zh": "上下文管理器退出时关闭文件对象。\n", - "en": "Context manager exit that closes the file object.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#__exit__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#__iter__", - "description": { - "zh": "按行迭代文件。\n", - "en": "Iterate over the file line by line.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#__iter__" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.vfile-io": { - "uid": "a000050f", - "id": "pyvdisk.storage.vfs.vfile-io", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFile 读写", - "en": "VFile IO" - }, - "description": { - "zh": "打开 VFile 上的定位读写、seek、tell、truncate、flush 与 close。\n", - "en": "Positioned read/write, seek, tell, truncate, flush and close on an open VFile.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 550, - "end_line": 598 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#read", - "description": { - "zh": "在当前位置最多读取 size 字节。\n", - "en": "Read up to size bytes at the current position.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#readall", - "description": { - "zh": "读取剩余文件内容。\n", - "en": "Read the remaining file contents.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#readall" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#write", - "description": { - "zh": "在当前位置写入字节并前移位置。\n", - "en": "Write bytes at the current position and advance it.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#write" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#seek", - "description": { - "zh": "移动文件位置。\n", - "en": "Move the file position.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#seek" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#tell", - "description": { - "zh": "报告当前文件位置。\n", - "en": "Report the current file position.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#tell" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#truncate", - "description": { - "zh": "把文件截断到指定尺寸,缺省为当前位置。\n", - "en": "Truncate the file to a size, defaulting to the current position.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#truncate" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#flush", - "description": { - "zh": "把未决写入刷新到磁盘。\n", - "en": "Flush pending writes to the disk.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#flush" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFile#close", - "description": { - "zh": "刷新并释放文件对象。\n", - "en": "Flush and release the file object.\n" - }, - "key": "rpc:pyvdisk.vfs.VFile#close" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.readwrite", - "from_api": "rpc:pyvdisk.vfs.VFile#write", - "to_api": "rpc:pyvdisk.fs.FS#write_file", - "label": { - "zh": "定位写入", - "en": "positioned write" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.vfs.walk": { - "uid": "a000050c", - "id": "pyvdisk.storage.vfs.walk", - "parent": "pyvdisk.storage.vfs", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "目录遍历", - "en": "Directory Walk" - }, - "description": { - "zh": "递归目录遍历生成器,供 import_host_tree、du 与 CLI 树视图使用。\n", - "en": "Recursive directory traversal generator, used by import_host_tree, du and the CLI tree view.\n" - }, - "source": [ - { - "path": "pyvdisk/vfs.py", - "line": 437, - "end_line": 457 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "78228a31bb30dd6ec27c3232a667df6190a704471e3002c8369ace907f2cd070", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vfs.VFS#walk", - "description": { - "zh": "自某目录起递归产出 (path, dirnames, filenames) 三元组。\n", - "en": "Recursively yield (path, dirnames, filenames) triples rooted at a directory.\n" - }, - "key": "rpc:pyvdisk.vfs.VFS#walk" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.volume": { - "uid": "a0000307", - "id": "pyvdisk.storage.volume", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "raid" - ], - "name": { - "zh": "多盘卷", - "en": "Multi-Disk Volume" - }, - "description": { - "zh": "多盘卷:concat、stripe、mirror 三种模式对外沿用单盘的块 IO 接口,成员元数据存于 block 0。\n", - "en": "Multi-disk volume: concat, stripe and mirror modes behind the same block IO interface as a single image, with member metadata in block 0.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "aggregate": { - "descendant_count": 8, - "own_api_count": 0, - "inherited_api_count": 31, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.blocks": { - "uid": "a0000704", - "id": "pyvdisk.storage.volume.blocks", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "逻辑块", - "en": "Logical Blocks" - }, - "description": { - "zh": "按模式分发到具体地址映射的逻辑块入口。\n", - "en": "Logical block entry points that dispatch to the mode-specific address mapping.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 260, - "end_line": 302 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#truncate_bytes", - "description": { - "zh": "调整逻辑卷及每个成员的尺寸。\n", - "en": "Resize the logical volume and every member.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#truncate_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#read_block", - "description": { - "zh": "按当前模式读取一个逻辑块。\n", - "en": "Read one logical block through the active mode.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#read_block" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#write_block", - "description": { - "zh": "按当前模式写入一个逻辑块。\n", - "en": "Write one logical block through the active mode.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#write_block" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.storage.volume.bytes": { - "uid": "a0000706", - "id": "pyvdisk.storage.volume.bytes", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "字节传输", - "en": "Byte Transport" - }, - "description": { - "zh": "字节级传输、描述符复制与 CLI 使用的状态报告。\n", - "en": "Byte-level transport, descriptor replication and the status report consumed by the CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 375, - "end_line": 477 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#read_bytes", - "description": { - "zh": "跨逻辑块读取非对齐字节。\n", - "en": "Read unaligned bytes across logical block boundaries.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#read_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#write_bytes", - "description": { - "zh": "跨逻辑块写入非对齐字节。\n", - "en": "Write unaligned bytes across logical block boundaries.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#write_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_write_meta_to_all", - "description": { - "zh": "把卷描述符复制到每个成员的 block 0。\n", - "en": "Replicate the volume descriptor into every member block 0.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_write_meta_to_all" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#status", - "description": { - "zh": "报告卷模式、成员健康状况与容量汇总。\n", - "en": "Report volume mode, member health and capacity summary.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#status" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.create": { - "uid": "a0000707", - "id": "pyvdisk.storage.volume.create", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷创建", - "en": "Volume Creation" - }, - "description": { - "zh": "VFS 门面与 CLI 使用的卷创建与打开辅助。\n", - "en": "Volume creation and opening helpers used by the VFS facade and the CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 479, - "end_line": 557 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.create_volume", - "description": { - "zh": "创建成员、写入卷描述符并在卷上格式化文件系统。\n", - "en": "Create members, write the volume descriptor and format a filesystem over the volume.\n" - }, - "key": "rpc:pyvdisk.volume.create_volume" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.open_volume", - "description": { - "zh": "从成员路径打开既有卷。\n", - "en": "Open an existing volume from its member paths.\n" - }, - "key": "rpc:pyvdisk.volume.open_volume" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fs.mkfs", - "from_api": "rpc:pyvdisk.volume.create_volume", - "label": { - "zh": "格式化卷", - "en": "formats volume" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.layout": { - "uid": "a0000705", - "id": "pyvdisk.storage.volume.layout", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "RAID 映射", - "en": "RAID Mapping" - }, - "description": { - "zh": "分模式地址映射:拼接、条带与镜像,镜像读取支持副本回退。\n", - "en": "Mode-specific address mapping: concatenation, striping and mirroring with replica fallback on read.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 303, - "end_line": 374 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_read_concat", - "description": { - "zh": "在 concat 成员上线性映射逻辑块。\n", - "en": "Map a logical block linearly across concat members.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_read_concat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_write_concat", - "description": { - "zh": "在拼接位置写入一个块。\n", - "en": "Write one block at its concatenated position.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_write_concat" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_stripe_locate", - "description": { - "zh": "定位条带化逻辑块所属成员与成员内偏移。\n", - "en": "Locate the member and intra-member offset of a striped logical block.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_stripe_locate" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_read_stripe", - "description": { - "zh": "读取一个条带块。\n", - "en": "Read one striped block.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_read_stripe" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_write_stripe", - "description": { - "zh": "写入一个条带块。\n", - "en": "Write one striped block.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_write_stripe" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_read_mirror", - "description": { - "zh": "读取镜像块,副本损坏时回退到存活副本。\n", - "en": "Read a mirrored block, falling back to a surviving replica.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_read_mirror" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_write_mirror", - "description": { - "zh": "把镜像块写入每个副本。\n", - "en": "Write a mirrored block to every replica.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_write_mirror" - } - ], - "deps": [ - { - "kind": "dataflow", - "to": "pyvdisk.storage.volume.blocks", - "from_api": "rpc:pyvdisk.volume.Volume#_read_mirror", - "to_api": "rpc:pyvdisk.volume.Volume#read_block", - "label": { - "zh": "读取成员", - "en": "reads members" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.meta": { - "uid": "a0000701", - "id": "pyvdisk.storage.volume.meta", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷元数据", - "en": "Volume Metadata" - }, - "description": { - "zh": "卷元数据模型:写入每个成员的描述符及其内部的成员记录。\n", - "en": "Volume metadata model: the descriptor written into every member and the member records inside it.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 41, - "end_line": 123 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.VolumeError", - "description": { - "zh": "卷几何、成员与模式错误时抛出。\n", - "en": "Raised for volume geometry, member and mode failures.\n" - }, - "key": "rpc:pyvdisk.volume.VolumeError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.DiskMember", - "description": { - "zh": "单个成员盘:序号、UUID、路径、块数与角色标志。\n", - "en": "One member disk: index, uuid, path, block count and role flags.\n" - }, - "key": "rpc:pyvdisk.volume.DiskMember" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.VolumeMeta", - "description": { - "zh": "卷描述符:名称、模式、块大小、成员表与几何。\n", - "en": "Volume descriptor: name, mode, block size, member list and geometry.\n" - }, - "key": "rpc:pyvdisk.volume.VolumeMeta" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.VolumeMeta#to_bytes", - "description": { - "zh": "把卷描述符序列化,供存入成员 block 0。\n", - "en": "Serialize the volume descriptor for storage in member block 0.\n" - }, - "key": "rpc:pyvdisk.volume.VolumeMeta#to_bytes" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.VolumeMeta#from_bytes", - "description": { - "zh": "解析已存卷描述符并校验成员布局。\n", - "en": "Parse a stored volume descriptor and validate its member layout.\n" - }, - "key": "rpc:pyvdisk.volume.VolumeMeta#from_bytes" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.model": { - "uid": "a0000702", - "id": "pyvdisk.storage.volume.model", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷模型", - "en": "Volume Model" - }, - "description": { - "zh": "卷模型,以及按模式把成员容量换算为逻辑地址空间的几何计算。\n", - "en": "Volume model and the geometry computation that turns member capacities into a logical address space per mode.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 125, - "end_line": 179 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume", - "description": { - "zh": "把成员盘聚合到单一块接口后的卷对象。\n", - "en": "Volume object aggregating member disks behind one block interface.\n" - }, - "key": "rpc:pyvdisk.volume.Volume" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#__init__", - "description": { - "zh": "把卷绑定到成员路径与块大小。\n", - "en": "Bind a volume to its member paths and block size.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#compute_geometry", - "description": { - "zh": "根据成员容量计算 concat/stripe/mirror 几何。\n", - "en": "Compute concat/stripe/mirror geometry from member capacities.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#compute_geometry" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.volume.open": { - "uid": "a0000703", - "id": "pyvdisk.storage.volume.open", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷打开", - "en": "Volume Open" - }, - "description": { - "zh": "卷打开路径:成员打开、跨成员一致性校验与关闭/刷新生命周期。\n", - "en": "Volume open path: member opening, cross-member consistency verification and close/flush lifecycle.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 180, - "end_line": 259 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#open", - "description": { - "zh": "打开全部成员、校验身份一致性并从 block 0 加载描述符。\n", - "en": "Open every member, validate identity consistency and load the descriptor from block 0.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#_verify_members", - "description": { - "zh": "校验全部预期成员已就位、可读且彼此一致。\n", - "en": "Guard that all expected members are present, readable and mutually consistent.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#_verify_members" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#close", - "description": { - "zh": "关闭全部成员盘。\n", - "en": "Close every member disk.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#close" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.Volume#flush", - "description": { - "zh": "刷新全部成员盘。\n", - "en": "Flush every member disk.\n" - }, - "key": "rpc:pyvdisk.volume.Volume#flush" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.block.image", - "from_api": "rpc:pyvdisk.volume.Volume#open", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "label": { - "zh": "打开成员", - "en": "opens members" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.storage.volume.repair": { - "uid": "a0000708", - "id": "pyvdisk.storage.volume.repair", - "parent": "pyvdisk.storage.volume", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "镜像维护", - "en": "Mirror Maintenance" - }, - "description": { - "zh": "在线镜像维护:新增、移除与重新同步副本。\n", - "en": "Online mirror maintenance: add, remove and resynchronize replicas.\n" - }, - "source": [ - { - "path": "pyvdisk/volume.py", - "line": 558, - "end_line": 648 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "012cb5deb104e9e9e4018756e48a6e666fe02353c225133d0615315a17b7d08e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.volume.add_mirror", - "description": { - "zh": "不中断卷使用地新增镜像成员。\n", - "en": "Add a mirror member without interrupting the volume.\n" - }, - "key": "rpc:pyvdisk.volume.add_mirror" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.remove_mirror", - "description": { - "zh": "确认剩余副本充足后移除镜像成员。\n", - "en": "Remove a mirror member after verifying the remaining replicas.\n" - }, - "key": "rpc:pyvdisk.volume.remove_mirror" - }, - { - "protocol": "rpc", - "path": "pyvdisk.volume.resync_mirror", - "description": { - "zh": "以权威副本重新同步镜像成员。\n", - "en": "Resynchronize mirror members from the authoritative copy.\n" - }, - "key": "rpc:pyvdisk.volume.resync_mirror" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.volume.open", - "from_api": "rpc:pyvdisk.volume.resync_mirror", - "to_api": "rpc:pyvdisk.volume.Volume#open", - "label": { - "zh": "重开卷", - "en": "reopens volume" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.storage.wal": { - "uid": "a000030e", - "id": "pyvdisk.storage.wal", - "parent": "pyvdisk.storage", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "预写日志", - "en": "Write-Ahead Log" - }, - "description": { - "zh": "预写日志:同一套带检查点与截断的分段 WAL,由 DataDisk 事务与 VScript 事务撤销共用,而不是两份并行实现。\n", - "en": "Write-ahead logging: one segmented WAL implementation with checkpointing and truncation, shared by DataDisk transactions and VScript transaction undo instead of two parallel implementations.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/wal.py" - }, - { - "path": "pyvdisk/vscript/wal.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.238Z", - "fingerprint": "50ae6934d1990a4ceaed243e96fd51f677869ffe1300820ea255672f1d3868fa", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 16, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.storage.wal.entries": { - "uid": "a0000802", - "id": "pyvdisk.storage.wal.entries", - "parent": "pyvdisk.storage.wal", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "WAL 记录", - "en": "WAL Entries" - }, - "description": { - "zh": "事务日志动词与崩溃恢复重放:begin/append/prepare/commit/abort,以及重放所依赖的读取入口。\n", - "en": "Transaction log verbs and crash-recovery replay: begin/append/prepare/commit/abort, plus the readers that replay consumes.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/wal.py", - "line": 107, - "end_line": 139 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.238Z", - "fingerprint": "0d8c340fb6943bf9dfde1cc4cb2cb552f203bcc13d2f2ff3586e378c57495e08", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#begin", - "description": { - "zh": "追加 begin 记录以开启事务。\n", - "en": "Opens a transaction by appending a begin record.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#begin" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#append", - "description": { - "zh": "在已开启的事务中记录一个操作。\n", - "en": "Records one operation inside an open transaction.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#append" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#prepare", - "description": { - "zh": "标记事务已就绪待提交。\n", - "en": "Marks the transaction ready to commit.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#prepare" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#commit", - "description": { - "zh": "标记事务已提交。\n", - "en": "Marks the transaction committed.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#commit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#abort", - "description": { - "zh": "标记事务已中止。\n", - "en": "Marks the transaction aborted.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#abort" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#recover", - "description": { - "zh": "用传入的 undo/redo 回调重放日志,并报告未能结算的部分。\n", - "en": "Replays the log through the supplied undo and redo callables, and reports what stayed unresolved.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#_read", - "description": { - "zh": "解码日志中当前的全部记录。\n", - "en": "Decodes every record currently in the log.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#_last_sequence", - "description": { - "zh": "已写入的最大序号。\n", - "en": "Highest sequence number written so far.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_last_sequence" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 3 - } - }, - "pyvdisk.storage.wal.journal": { - "uid": "a0000801", - "id": "pyvdisk.storage.wal.journal", - "parent": "pyvdisk.storage.wal", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "元数据 WAL", - "en": "Metadata WAL" - }, - "description": { - "zh": "DataDisk 事务使用的元数据预写日志:存储后端、行编解码,以及分配序号的追加写入。\n", - "en": "Metadata write-ahead log used by DataDisk transactions: the storage backends, the record codec and the append path that assigns sequence numbers.\n" - }, - "source": [ - { - "path": "pyvdisk/infrastructure/wal.py", - "line": 80, - "end_line": 106 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.239Z", - "fingerprint": "0d8c340fb6943bf9dfde1cc4cb2cb552f203bcc13d2f2ff3586e378c57495e08", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog", - "description": { - "zh": "WAL 本体:存储后端、记录编码与带序号分配的追加。\n", - "en": "The WAL itself: storage backend, record encoding and append with sequence assignment.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#__init__", - "description": { - "zh": "把日志绑定到 VFS 路径或宿主文件。\n", - "en": "Binds the log to a VFS path or a host file.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#__init__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#append_record", - "description": { - "zh": "追加一条完整记录,并分配其序号。\n", - "en": "Appends a fully formed record, allocating its sequence number.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#append_record" - }, - { - "protocol": "rpc", - "path": "pyvdisk.infrastructure.wal.WriteAheadLog#_append", - "description": { - "zh": "编码并追加一个 kind/txid 组合。\n", - "en": "Encodes and appends one kind/txid pair.\n" - }, - "key": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_append" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.storage.wal.undo": { - "uid": "a0000803", - "id": "pyvdisk.storage.wal.undo", - "parent": "pyvdisk.storage.wal", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "宿主撤销 WAL", - "en": "Host Undo WAL" - }, - "description": { - "zh": "VScript 侧的 WAL 入口:独立的宿主路径实现已取消——本模块直接复用同一套 WriteAheadLog,并给出撤销记录使用的 kind 集与编解码。\n", - "en": "VScript-side WAL entry point: the separate host-path implementation is gone -- this module re-exports the shared WriteAheadLog together with the record kinds and codecs the undo records use.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/wal.py", - "line": 1, - "end_line": 11 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.239Z", - "fingerprint": "52cf7418ca7ca365477273fa2f1cb4ad9c418bddbdc6413489ec12b2689d9015", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.wal.WriteAheadLog", - "description": { - "zh": "复用同一套 WAL 类,供 VScript 侧使用。\n", - "en": "The shared WAL class, re-exported for VScript.\n" - }, - "key": "rpc:pyvdisk.vscript.wal.WriteAheadLog" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.wal.RECORD_KINDS", - "description": { - "zh": "两个平面现在共用的记录种类集合。\n", - "en": "Record kinds both planes now agree on.\n" - }, - "key": "rpc:pyvdisk.vscript.wal.RECORD_KINDS" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.wal.encode_record", - "description": { - "zh": "与 DataDisk 共用的记录编解码。\n", - "en": "Record codec shared with DataDisk.\n" - }, - "key": "rpc:pyvdisk.vscript.wal.encode_record" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.wal.decode_records", - "description": { - "zh": "与 DataDisk 共用的批量解码。\n", - "en": "Batch decoder shared with DataDisk.\n" - }, - "key": "rpc:pyvdisk.vscript.wal.decode_records" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.storage.wal.journal", - "from_api": "rpc:pyvdisk.vscript.wal.WriteAheadLog", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog", - "label": { - "zh": "复用共享 WAL 实现", - "en": "reuses the shared WAL" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.tests": { - "uid": "a0000320", - "id": "pyvdisk.tests", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "tests" - ], - "name": { - "zh": "测试套件", - "en": "Test Suite" - }, - "description": { - "zh": "测试套件:447 项可执行校验,覆盖文件系统、卷、身份、锁、队列、事务、VScript、审计轨迹、FUSE 桥、平台适配层、沙箱与打包。缺 hnswlib 时有 4 项对照用例跳过。\n", - "en": "Test suite: 447 executable checks covering the filesystem, volumes, identity, locking, the queue, transactions, VScript, the audit trail, the FUSE bridge, the platform layer, the sandbox and packaging. Four comparison cases skip when hnswlib is absent.\n" - }, - "source": [ - { - "path": "tests/conftest.py" - }, - { - "path": "tests/test_vdisk.py" - }, - { - "path": "tests/test_vscript.py" - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.627Z", - "fingerprint": "b6440af3d48834c687f05de99c57cf0e3582d53a09d2ffb04b28579e901b64b1", - "aggregate": { - "descendant_count": 58, - "own_api_count": 0, - "inherited_api_count": 74, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.agent-sandbox": { - "uid": "a000033f", - "id": "pyvdisk.tests.agent-sandbox", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "沙箱测试", - "en": "Sandbox Tests" - }, - "description": { - "zh": "把 AgentSandbox 当作一组承诺来测,而不是按实现来测:越权路径、Windows 样式路径、被隐藏的容器簿记、只读与禁删模式、含伪造行的审计链、脚本的宿主隔离与输出上限、\"脚本入口与 Python 入口共用一个根\"这条规则,以及防止 README 示例漂移、确保它仍能按真实 API 执行的守卫。\n", - "en": "Tests AgentSandbox as a set of promises rather than an implementation: escape attempts, Windows-looking paths, hidden bookkeeping, read-only and no-delete modes, the audit trail including forged rows, script host isolation and output caps, the rule that the script door and the Python door share one root, and guards that keep the README demo executing against the real API.\n" - }, - "source": [ - { - "path": "tests/test_agent_sandbox.py" - } - ], - "revision": "f163400c098f68cbdfb0393a9bf488037d012aaf", - "updated_at": "2026-09-24T11:48:38.687Z", - "fingerprint": "e44e25577e09fe09eef14d1d56de5975ad490fb995cfce45029bb93e2768012e", - "apis": [ - { - "protocol": "file", - "path": "tests/test_agent_sandbox.py", - "description": { - "zh": "沙箱的承诺:路径约束、只读、审计链与脚本隔离。\n", - "en": "Sandbox promises: path confinement, read-only, audit chain and script isolation.\n" - }, - "key": "file:tests/test_agent_sandbox.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.agentic-cli": { - "uid": "a0000e06", - "id": "pyvdisk.tests.agentic-cli", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "智能体 CLI 用例", - "en": "Agentic CLI Tests" - }, - "description": { - "zh": "面向智能体使用编写的 CLI 用例:可发现的输出与稳定的退出码。\n", - "en": "CLI tests written for agentic usage: discoverable output and stable exit codes.\n" - }, - "source": [ - { - "path": "tests/test_agentic_cli.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "c1ace473de65a09dacb70aacab8d41ae03518f3ec5de3532a95a04a873891510", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_agentic_cli.py", - "description": { - "zh": "智能体驱动的 CLI 工作流用例。\n", - "en": "Agent-driven CLI workflow tests.\n" - }, - "key": "rpc:tests/test_agentic_cli.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.cli.main", - "to_api": "rpc:pyvdisk.cli.main", - "label": { - "zh": "驱动入口", - "en": "drives entry point" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.api-governance": { - "uid": "a0000e07", - "id": "pyvdisk.tests.api-governance", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "API 治理用例", - "en": "API Governance Tests" - }, - "description": { - "zh": "检查公开能力 API 是否拒绝应当拒绝的调用,而不只验证正常路径。\n", - "en": "Checks that the public capability API denies what it should, not only that it allows the happy path.\n" - }, - "source": [ - { - "path": "tests/test_api_governance.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "482a982338fb697d275c3e8f0b731d272c86aec923665e5fb4ab6a0a69aedf30", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_api_governance.py", - "description": { - "zh": "能力治理接口断言。\n", - "en": "Capability governance surface assertions.\n" - }, - "key": "rpc:tests/test_api_governance.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.governance.namespace", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "label": { - "zh": "验证范围限定", - "en": "verifies scoping" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.atomic-save": { - "uid": "a0000e08", - "id": "pyvdisk.tests.atomic-save", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "原子保存用例", - "en": "Atomic Save Tests" - }, - "description": { - "zh": "验证元数据写入是全有或全无,即事务层所依赖的性质。\n", - "en": "Verifies that metadata writes are all-or-nothing, the property the transaction layer is built on.\n" - }, - "source": [ - { - "path": "tests/test_atomic_vfs_save.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "ef2c08e8d92ecaf62dcb22be9753adaa7e64ca008d860af041310eeb8f56b0da", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_atomic_vfs_save.py", - "description": { - "zh": "含中断场景的 VFS 原子保存行为。\n", - "en": "Atomic VFS save behaviour including interruption.\n" - }, - "key": "rpc:tests/test_atomic_vfs_save.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.core", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_atomic_json", - "label": { - "zh": "验证原子写入", - "en": "verifies atomic write" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.audit-trail": { - "uid": "c92e7198", - "id": "pyvdisk.tests.audit-trail", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "audit" - ], - "name": { - "zh": "审计轨迹用例", - "en": "Audit Trail Tests" - }, - "description": { - "zh": "审计轨迹用例:哈希链校验(含在真实日志段内篡改记录)、查询筛选与保留策略。\n", - "en": "Audit trail tests: hash-chain verification, including a record edited inside a real log segment, query filters and retention.\n" - }, - "source": [ - { - "path": "tests/test_audit_trail.py", - "line": 1, - "end_line": 336 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.211Z", - "fingerprint": "90c6498b997b3407cee50ba6ed0b70222f14dcba819b2601da038e021aab0759", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_audit_trail.py", - "description": { - "zh": "审计写入、哈希链、查询与保留的 29 个用例。\n", - "en": "29 cases over audit emission, the hash chain, query and retention.\n" - }, - "key": "rpc:tests/test_audit_trail.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.audit.sinks", - "from_api": "rpc:tests/test_audit_trail.py", - "to_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#verify", - "label": { - "zh": "验证审计 Sink", - "en": "exercises audit sinks" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.cancellation": { - "uid": "a0000e1c", - "id": "pyvdisk.tests.cancellation", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "取消用例", - "en": "Cancellation Tests" - }, - "description": { - "zh": "验证协作式取消会让队列与运行状态保持一致,不停留在中间状态。\n", - "en": "Verifies cooperative cancellation leaves the queue and run state consistent, not stuck in a transient status.\n" - }, - "source": [ - { - "path": "tests/test_worker_cancellation.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.025Z", - "fingerprint": "9695cdadf64ad0f3f33e7a0b64ac2a10ae7d63faf258a1ae039e0ec99448f736", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_worker_cancellation.py", - "description": { - "zh": "任务运行中的 worker 取消。\n", - "en": "Worker cancellation during a running task.\n" - }, - "key": "rpc:tests/test_worker_cancellation.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.service.submit", - "to_api": "rpc:pyvdisk.execution.ExecutionService#cancel", - "label": { - "zh": "验证取消", - "en": "verifies cancellation" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.checkpoint": { - "uid": "a0000e09", - "id": "pyvdisk.tests.checkpoint", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "检查点用例", - "en": "Checkpoint Tests" - }, - "description": { - "zh": "为队列、运行、操作与审计提供背衬的持久键值存储的单元用例。\n", - "en": "Unit tests for the durable key/value store that backs queues, runs, operations and audit.\n" - }, - "source": [ - { - "path": "tests/test_checkpoint_store.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "58670b8459c125b158d8382488db44266dc27b9f5bec60e375f1c00cd2329fc9", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_checkpoint_store.py", - "description": { - "zh": "检查点存储的 get、set、save 与加锁。\n", - "en": "Checkpoint store get, set, save and locking.\n" - }, - "key": "rpc:tests/test_checkpoint_store.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.open", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "label": { - "zh": "验证存储", - "en": "verifies store" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.compat": { - "uid": "a000033e", - "id": "pyvdisk.tests.compat", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "平台兼容测试", - "en": "Platform Compat Tests" - }, - "description": { - "zh": "在 Linux 上执行 Windows 模拟:用 msvcrt 替身加 use_implementation() 让模拟分支在真实文件上运行,覆盖锁竞争与超时分支,并与原生实现逐字节对照一整套操作;同时固定 describe() 描述的是生效实现而不是宿主。替身锁是进程内的,因此无法证明两个进程之间互斥——这仍然需要 Windows runner,文件里写明了这一点。\n", - "en": "Exercises the Windows emulation from Linux: a stand-in for msvcrt plus use_implementation() runs the emulated branches against real files, including lock contention and the timeout path, and compares a whole workload against the native implementation byte for byte. It also pins describe() to the implementation in force rather than the host. The stand-in's lock is in-process, so it cannot show two processes contending -- that needs a Windows runner, and the file says so.\n" - }, - "source": [ - { - "path": "tests/test_compat.py" - } - ], - "revision": "3cb47877135592bd8565726610c54ebd1ecd9fba", - "updated_at": "2026-09-24T11:51:39.624Z", - "fingerprint": "49ec4bf92e42b64486091b5f313fcab34567167b3fdbe9d85ad538e501c2122d", - "apis": [ - { - "protocol": "file", - "path": "tests/test_compat.py", - "description": { - "zh": "把平台切到模拟实现跑整条用例。\n", - "en": "Run the whole suite with the platform switched to the emulated implementation.\n" - }, - "key": "file:tests/test_compat.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.contracts": { - "uid": "a0000e0a", - "id": "pyvdisk.tests.contracts", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "契约用例", - "en": "Contract Tests" - }, - "description": { - "zh": "保持抽象契约与具体实现一致的合规性用例。\n", - "en": "Conformance tests that keep the abstract contracts and their concrete implementations aligned.\n" - }, - "source": [ - { - "path": "tests/test_contracts.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:22:04.609Z", - "fingerprint": "28b37d826e5412d4b3ec6c3bed0679dd1d223682ec4d430269ea1123c1b70b7d", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_contracts.py", - "description": { - "zh": "契约类型的协议一致性断言。\n", - "en": "Protocol conformance assertions for the contract types.\n" - }, - "key": "rpc:tests/test_contracts.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.contracts.plane", - "to_api": "rpc:pyvdisk.contracts.ExecutionPlane#submit", - "label": { - "zh": "验证契约", - "en": "verifies contracts" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.crash-matrix": { - "uid": "a0000e0c", - "id": "pyvdisk.tests.crash-matrix", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "崩溃矩阵用例", - "en": "Crash Matrix Tests" - }, - "description": { - "zh": "最强的持久性用例:在每个阶段中断事务并断言恢复后落在合法状态。\n", - "en": "The strongest durability test: interrupts a transaction at each stage and asserts recovery lands on a legal state.\n" - }, - "source": [ - { - "path": "tests/test_datadisk_acid_crash_matrix.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-24T09:57:44.288Z", - "fingerprint": "e5dc0b698260945083aefe94df8258b286a859f386a258384ff9e0008f568d27", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_datadisk_acid_crash_matrix.py", - "description": { - "zh": "断言 DataDisk 事务 ACID 结果的崩溃点矩阵。\n", - "en": "Crash-point matrix asserting ACID outcomes for DataDisk transactions.\n" - }, - "key": "rpc:tests/test_datadisk_acid_crash_matrix.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.core", - "from_api": "rpc:tests/test_datadisk_acid_crash_matrix.py", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_recover_transactions", - "label": { - "zh": "验证事务重放", - "en": "verifies transaction replay" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.e2e": { - "uid": "a0000e1a", - "id": "pyvdisk.tests.e2e", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "端到端用例", - "en": "End-to-End Tests" - }, - "description": { - "zh": "遍历整个基础设施栈的集成用例,含在受限盘上运行脚本。\n", - "en": "The integration test that walks the whole infrastructure stack, including scripts run against scoped disks.\n" - }, - "source": [ - { - "path": "tests/test_unified_infrastructure_e2e.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "84c52b2de4b93cb962695fa0577a6c0ccd31b5d699128631cbf627e7ef60650e", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_unified_infrastructure_e2e.py", - "description": { - "zh": "跨统一栈的端到端基础设施演练。\n", - "en": "End-to-end infrastructure walkthrough across the unified stack.\n" - }, - "key": "rpc:tests/test_unified_infrastructure_e2e.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.api", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped", - "label": { - "zh": "驱动 DataDisk", - "en": "drives DataDisk" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.exactly-once-internal": { - "uid": "a0000e0d", - "id": "pyvdisk.tests.exactly-once-internal", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "内部精确一次用例", - "en": "Exactly-Once Internal Tests" - }, - "description": { - "zh": "验证重放操作不会重复生效,即精确一次的核心承诺。\n", - "en": "Verifies that replaying an operation does not reapply its effect, the core exactly-once promise.\n" - }, - "source": [ - { - "path": "tests/test_exactly_once_internal.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "17d44fe8e8e2577aa76afa13965f5354761454e03ca66fce1a1542115a190b89", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_exactly_once_internal.py", - "description": { - "zh": "内部队列操作的精确一次语义。\n", - "en": "Exactly-once semantics for internal queue operations.\n" - }, - "key": "rpc:tests/test_exactly_once_internal.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.operations.registry", - "to_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#has", - "label": { - "zh": "验证去重", - "en": "verifies dedup" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.exactly-once-operation": { - "uid": "a0000e0e", - "id": "pyvdisk.tests.exactly-once-operation", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "操作精确一次用例", - "en": "Exactly-Once Operation Tests" - }, - "description": { - "zh": "精确一次契约在操作层的半边,经公开执行接口观察。\n", - "en": "The operation-level half of the exactly-once contract, observed through the public execution surface.\n" - }, - "source": [ - { - "path": "tests/test_exactly_once_operation.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "292b6653c8846015b7c1aacc2741acc8ed7739ebd11f53d15fb182e3d36b3486", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_exactly_once_operation.py", - "description": { - "zh": "已提交操作的精确一次语义。\n", - "en": "Exactly-once semantics for submitted operations.\n" - }, - "key": "rpc:tests/test_exactly_once_operation.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.operations.registry", - "to_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#recover", - "label": { - "zh": "验证重放", - "en": "verifies replay" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.execution": { - "uid": "a0000e0f", - "id": "pyvdisk.tests.execution", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "执行用例", - "en": "Execution Tests" - }, - "description": { - "zh": "执行平面用例:分发、受限视图与结果传递。\n", - "en": "Execution plane tests: dispatch, scoped views and result propagation.\n" - }, - "source": [ - { - "path": "tests/test_execution.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "ae3435ad777cc2c8e8187f3907169284a12cad7c2f5d3ba172a6d87599f9ae7b", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_execution.py", - "description": { - "zh": "执行服务的 submit、run 与策略行为。\n", - "en": "Execution service submit, run and policy behaviour.\n" - }, - "key": "rpc:tests/test_execution.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.service.submit", - "to_api": "rpc:pyvdisk.execution.ExecutionService#run", - "label": { - "zh": "验证服务", - "en": "verifies service" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.execution-queue": { - "uid": "a0000e10", - "id": "pyvdisk.tests.execution-queue", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "执行队列用例", - "en": "Execution Queue Tests" - }, - "description": { - "zh": "把执行服务绑定到持久队列及其租约语义的集成用例。\n", - "en": "Integration tests binding the execution service to the durable queue and its lease semantics.\n" - }, - "source": [ - { - "path": "tests/test_execution_queue.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "e1d699956e464bd55b5ffba7f477d679d10cb02d3881c076c2a91f7f10db35a9", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_execution_queue.py", - "description": { - "zh": "持久队列之上的执行服务。\n", - "en": "Execution service over the durable queue.\n" - }, - "key": "rpc:tests/test_execution_queue.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.service.queue", - "to_api": "rpc:pyvdisk.execution.ExecutionService#run_next", - "label": { - "zh": "验证队列执行", - "en": "verifies queue run" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.fixtures": { - "uid": "a0000e01", - "id": "pyvdisk.tests.fixtures", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "测试夹具", - "en": "Test Fixtures" - }, - "description": { - "zh": "全套件各测试模块共享的 pytest 夹具定义。\n", - "en": "Pytest fixture definitions shared by every test module in the suite.\n" - }, - "source": [ - { - "path": "tests/conftest.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "b09095c4826eb664908a6c15f6dd731ee5dfc3755c806adcd1cc02f1312b5330", - "apis": [ - { - "protocol": "rpc", - "path": "tests/conftest.py", - "description": { - "zh": "共享 pytest 夹具:临时镜像路径、挂载与磁盘辅助。\n", - "en": "Shared pytest fixtures: temporary image paths, mounts and disk helpers.\n" - }, - "key": "rpc:tests/conftest.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.fuse-mount": { - "uid": "447d99b2", - "id": "pyvdisk.tests.fuse-mount", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "fuse" - ], - "name": { - "zh": "FUSE 挂载用例", - "en": "FUSE Mount Tests" - }, - "description": { - "zh": "FUSE 桥用例:属性与目录操作、truncate/link/chmod,以及此前对任何符号链接都返回 EINVAL 的 lstat 语义 readlink。\n", - "en": "FUSE bridge tests: attribute and directory operations, truncate/link/chmod, and the lstat-semantics readlink that used to fail every symlink with EINVAL.\n" - }, - "source": [ - { - "path": "tests/test_fuse_mount.py", - "line": 1, - "end_line": 251 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.212Z", - "fingerprint": "b0e0301f87cd1dbd412bd5c29ce373d1bba6eb5e77134f89d377365a340a373b", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_fuse_mount.py", - "description": { - "zh": "用桩 fuse 模块覆盖 FUSE 桥的 21 个用例。\n", - "en": "21 cases over the FUSE bridge with a stub fuse module.\n" - }, - "key": "rpc:tests/test_fuse_mount.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.fuse.handlers", - "from_api": "rpc:tests/test_fuse_mount.py", - "to_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_readlink", - "label": { - "zh": "验证 FUSE 操作表", - "en": "exercises FUSE operations" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.governance": { - "uid": "a0000e11", - "id": "pyvdisk.tests.governance", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "治理回归用例", - "en": "Governance Regression Tests" - }, - "description": { - "zh": "最大的治理测试模块:治理工作新增的受限命名空间的回归覆盖。\n", - "en": "The largest governance test module: regression coverage for the scoped namespaces added by the governance work.\n" - }, - "source": [ - { - "path": "tests/test_governance_regression.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "7be89d6d2739119b30c106932c8b649e55b6d6eff296a9a6596df647a362eb7f", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_governance_regression.py", - "description": { - "zh": "能力治理层的回归用例集。\n", - "en": "Regression suite for the capability governance layer.\n" - }, - "key": "rpc:tests/test_governance_regression.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.governance.files", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#_check_file", - "label": { - "zh": "验证受限文件系统", - "en": "verifies scoped fs" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.logdisk-compact": { - "uid": "a0000e12", - "id": "pyvdisk.tests.logdisk-compact", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "日志压缩用例", - "en": "Log Compaction Tests" - }, - "description": { - "zh": "守住压缩绝不可违反的性质:减少存储不得改变可观测的流状态。\n", - "en": "Guards the property compaction must never violate: reducing storage must not change observable stream state.\n" - }, - "source": [ - { - "path": "tests/test_logdisk_compact_preserves_state.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "7a9187ee29732e657f68810200e105353ea441bd926fbabc8811b387047a8a9d", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_logdisk_compact_preserves_state.py", - "description": { - "zh": "压缩保留流与状态元数据。\n", - "en": "Compaction preserves stream and state metadata.\n" - }, - "key": "rpc:tests/test_logdisk_compact_preserves_state.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.retention", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#compact", - "label": { - "zh": "验证压缩", - "en": "verifies compaction" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.logdisk-retention": { - "uid": "a0000e13", - "id": "pyvdisk.tests.logdisk-retention", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "日志保留用例", - "en": "Log Retention Tests" - }, - "description": { - "zh": "验证保留策略不会删除消费者尚未确认的事件。\n", - "en": "Verifies retention never drops an event a consumer has not yet acknowledged.\n" - }, - "source": [ - { - "path": "tests/test_logdisk_retention_event_ids.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "0ba50a397b61ec091c3b0a00bc29c99511bb368b54829ddf1b7e5cb23c1afc4a", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_logdisk_retention_event_ids.py", - "description": { - "zh": "保留策略遵守事件 id 边界。\n", - "en": "Retention honours event id boundaries.\n" - }, - "key": "rpc:tests/test_logdisk_retention_event_ids.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.retention", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#enforce_retention", - "label": { - "zh": "验证保留策略", - "en": "verifies retention" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.no-dependency": { - "uid": "a0000340", - "id": "pyvdisk.tests.no-dependency", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "零依赖测试", - "en": "Zero Dependency Tests" - }, - "description": { - "zh": "同一个承诺的三层校验:pyproject 不声明运行时依赖且把加速器留在 extra 里;屏蔽 hnswlib 时 VectorDisk 仍能正确作答,两种后端结果一致且能互读对方写的盘;examples/quickstart.py 在屏蔽 hnswlib 的子进程里能跑完,示例不会悄悄地开始依赖它。\n", - "en": "Three layers of the same claim: pyproject declares no runtime dependencies and keeps the accelerators as extras; VectorDisk answers correctly with hnswlib blocked, and the two backends agree and read each other's files; and examples/quickstart.py runs to completion in a subprocess with hnswlib blocked, so the example cannot quietly start needing it.\n" - }, - "source": [ - { - "path": "tests/test_no_dependency_path.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:40:00Z", - "fingerprint": "aca58c61b9b691e1849bc2f3a598cbaa1fd1e5c7db7193c969d3adbeb0c37073", - "apis": [ - { - "protocol": "file", - "path": "tests/test_no_dependency_path.py", - "description": { - "zh": "零依赖承诺:从打包、后端与示例三个层面校验。\n", - "en": "The zero-dependency promise, checked at packaging, backend and example level.\n" - }, - "key": "file:tests/test_no_dependency_path.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.packaging": { - "uid": "a0000e14", - "id": "pyvdisk.tests.packaging", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "打包用例", - "en": "Packaging Tests" - }, - "description": { - "zh": "验证包可构建安装,且 py.typed 标记与控制台入口完好。\n", - "en": "Verifies the package can be built and installed with its py.typed marker and console entry point intact.\n" - }, - "source": [ - { - "path": "tests/test_packaging.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.241Z", - "fingerprint": "323dfc7f33246bdb08212b6f90101d3b268797f3d8a95fe64486043926249d3b", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_packaging.py", - "description": { - "zh": "打包与分发元数据断言。\n", - "en": "Packaging and distribution metadata assertions.\n" - }, - "key": "rpc:tests/test_packaging.py" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.participant-compensation": { - "uid": "afb559b5", - "id": "pyvdisk.tests.participant-compensation", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "transaction", - "acid" - ], - "name": { - "zh": "参与者补偿用例", - "en": "Participant Compensation Tests" - }, - "description": { - "zh": "参与者补偿用例:持久化写前补偿、进程内 abort 的逆序分发、跨挂载的幂等重复补偿。\n", - "en": "Participant compensation tests: durable write-ahead compensation, reverse-order in-process abort dispatch, idempotent re-compensation across mounts.\n" - }, - "source": [ - { - "path": "tests/test_participant_compensation.py", - "line": 1, - "end_line": 358 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.212Z", - "fingerprint": "64c934ebf5a17e261b860af5ab6856ead8c9072cf123163c17ba128406b349e0", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_participant_compensation.py", - "description": { - "zh": "参与者登记、持久补偿日志与崩溃矩阵恢复的 38 个用例。\n", - "en": "38 cases over participant enlistment, the durable compensation log and crash-matrix recovery.\n" - }, - "key": "rpc:tests/test_participant_compensation.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "from_api": "rpc:tests/test_participant_compensation.py", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#abort", - "label": { - "zh": "验证事务补偿", - "en": "exercises tx compensation" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.queue": { - "uid": "a0000e15", - "id": "pyvdisk.tests.queue", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "队列用例", - "en": "Queue Tests" - }, - "description": { - "zh": "单进程内持久队列的状态迁移用例。\n", - "en": "State-transition tests for the durable queue in a single process.\n" - }, - "source": [ - { - "path": "tests/test_queue.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "d4b22a397ef34fa02381b197ff3d1de54be30621cf995082984de8aff1ac5bb8", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_queue.py", - "description": { - "zh": "持久队列单元用例。\n", - "en": "Durable queue unit tests.\n" - }, - "key": "rpc:tests/test_queue.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.queue.lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim", - "label": { - "zh": "验证队列", - "en": "verifies queue" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.queue-backoff": { - "uid": "a0000e16", - "id": "pyvdisk.tests.queue-backoff", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "退避与锁用例", - "en": "Backoff and Lock Tests" - }, - "description": { - "zh": "对指数退避与串行化队列变更的锁的时序敏感用例。\n", - "en": "Timing-sensitive tests for exponential backoff and the lock that serializes queue mutation.\n" - }, - "source": [ - { - "path": "tests/test_queue_backoff_and_lock.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "1a323e73b50428d480ab4d50b6fc70f024fa2199b20d48f34f3593d43c91a527", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_queue_backoff_and_lock.py", - "description": { - "zh": "重试退避时序与队列加锁。\n", - "en": "Retry backoff schedule and queue locking.\n" - }, - "key": "rpc:tests/test_queue_backoff_and_lock.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.queue.store", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_backoff_seconds", - "label": { - "zh": "验证退避", - "en": "verifies backoff" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.queue-crossprocess": { - "uid": "a0000e0b", - "id": "pyvdisk.tests.queue-crossprocess", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "跨进程队列用例", - "en": "Cross-Process Queue Tests" - }, - "description": { - "zh": "证明持久队列的租约与去重保证跨进程边界成立,而非仅限线程。\n", - "en": "Proves the durable queue's lease and dedup guarantees hold across process boundaries, not only threads.\n" - }, - "source": [ - { - "path": "tests/test_cross_process_queue.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "c105aaf834a3675ab01196cb358ac332be566ac56d37564606a20b703ba064db", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_cross_process_queue.py", - "description": { - "zh": "跨独立操作系统进程的队列行为。\n", - "en": "Queue behaviour across separate OS processes.\n" - }, - "key": "rpc:tests/test_cross_process_queue.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.queue.store", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue", - "label": { - "zh": "验证跨进程队列", - "en": "verifies cross-process queue" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.submit-conflict": { - "uid": "a0000e17", - "id": "pyvdisk.tests.submit-conflict", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "提交冲突用例", - "en": "Submit Conflict Tests" - }, - "description": { - "zh": "交互用例:提交时的版本冲突不得留下写一半的 VFS 变更。\n", - "en": "Interaction test: a version conflict on submit must not leave a half-written VFS change behind.\n" - }, - "source": [ - { - "path": "tests/test_submit_conflict_and_atomic_vfs.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "5b380c22c98ad59d559a3c9b684cc8c33bbefabf64a9196685158a3e9870dcc4", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_submit_conflict_and_atomic_vfs.py", - "description": { - "zh": "提交冲突解决与 VFS 原子保存的组合用例。\n", - "en": "Submit conflict resolution combined with atomic VFS save.\n" - }, - "key": "rpc:tests/test_submit_conflict_and_atomic_vfs.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.execution.runstate.store", - "to_api": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#transition", - "label": { - "zh": "验证冲突处理", - "en": "verifies conflict handling" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.tx-idempotency": { - "uid": "a0000e19", - "id": "pyvdisk.tests.tx-idempotency", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "事务幂等用例", - "en": "Transaction Idempotency Tests" - }, - "description": { - "zh": "小而关键的用例:同一事务提交两次不会产生副作用。\n", - "en": "Small but critical test that committing the same transaction twice is harmless.\n" - }, - "source": [ - { - "path": "tests/test_transaction_idempotency.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.309Z", - "fingerprint": "a6d47e9bf01673f76f415380a7026425bf6c9c2d5406b69189918c4ae324cd7c", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_transaction_idempotency.py", - "description": { - "zh": "重复提交下的事务幂等性。\n", - "en": "Transaction idempotency across repeated commits.\n" - }, - "key": "rpc:tests/test_transaction_idempotency.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "label": { - "zh": "验证幂等", - "en": "verifies idempotency" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.tx-rollback": { - "uid": "a0000e18", - "id": "pyvdisk.tests.tx-rollback", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "事务回滚用例", - "en": "Transaction Rollback Tests" - }, - "description": { - "zh": "撤销日志用例:失败事务内的文件系统变更必须被精确还原。\n", - "en": "The undo-journal test: filesystem mutations inside a failed transaction must be reverted exactly.\n" - }, - "source": [ - { - "path": "tests/test_transaction_fs_rollback.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "532b14c832235f962c411f2de0ea7f44cf07ba3eeca21d0cd6d7bdef3c729770", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_transaction_fs_rollback.py", - "description": { - "zh": "经元数据事务的文件系统回滚。\n", - "en": "Filesystem rollback through the metadata transaction.\n" - }, - "key": "rpc:tests/test_transaction_fs_rollback.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.datadisk.namespace", - "to_api": "rpc:pyvdisk.infrastructure.disk.FileNamespace#rmtree", - "label": { - "zh": "验证回滚", - "en": "verifies abort" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk": { - "uid": "a0000321", - "id": "pyvdisk.tests.vdisk", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VFS 行为规格", - "en": "VFS Behaviour Spec" - }, - "description": { - "zh": "以真实镜像上的测试类表达的 VFS/FS/卷/锁/CLI/向量/日志行为规格。\n", - "en": "The behavioral specification of VFS/FS/volume/locking/CLI/vector/log behaviour, expressed as test classes over real images.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.241Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "aggregate": { - "descendant_count": 19, - "own_api_count": 0, - "inherited_api_count": 34, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.base": { - "uid": "a0000d01", - "id": "pyvdisk.tests.vdisk.base", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VFS 测试基类", - "en": "VFS Test Base" - }, - "description": { - "zh": "测试基类与基础路径用例:启动镜像的夹具,以及最小的 VFS 行为。\n", - "en": "Test base and the basic-path suite: the fixture that boots an image, plus the smallest VFS behaviours.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 19, - "end_line": 78 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.242Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::VFSTestBase", - "description": { - "zh": "为每个用例创建临时镜像并挂载 VFS 的共享夹具。\n", - "en": "Shared fixture that creates a temporary image and mounts a VFS for each test.\n" - }, - "key": "rpc:tests/test_vdisk.py::VFSTestBase" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestBasic", - "description": { - "zh": "根目录、mkdir、makedirs、小文件写、覆盖与追加重为。\n", - "en": "Root directory, mkdir, makedirs, small write, overwrite and append behaviour.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestBasic" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.cli": { - "uid": "a0000d08", - "id": "pyvdisk.tests.vdisk.cli", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "CLI 用例", - "en": "CLI Tests" - }, - "description": { - "zh": "CLI 契约用例:以用户方式调用每个子命令并断言其输出形态。\n", - "en": "The CLI contract test: every subcommand is invoked the way a user would and its output shape asserted.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 536, - "end_line": 670 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.242Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestCLI", - "description": { - "zh": "驱动 argparse 接口的端到端 CLI 子命令用例。\n", - "en": "End-to-end CLI subcommand tests driving the argparse surface.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestCLI" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.disk-manager": { - "uid": "a0000d0f", - "id": "pyvdisk.tests.vdisk.disk-manager", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "磁盘管理用例", - "en": "Disk Manager Tests" - }, - "description": { - "zh": "驱动层用例:挂载记账与已挂载文件系统的管理接口。\n", - "en": "Driver-level tests: mount bookkeeping and the management surface around mounted filesystems.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1073, - "end_line": 1208 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.243Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestDiskManager", - "description": { - "zh": "DiskManager 的挂载、卸载、列举与卷组装行为。\n", - "en": "DiskManager mount, unmount, listing and volume assembly behaviour.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestDiskManager" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.exhaustion": { - "uid": "a0000d09", - "id": "pyvdisk.tests.vdisk.exhaustion", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "空间耗尽用例", - "en": "Space Exhaustion Tests" - }, - "description": { - "zh": "空间耗尽行为:分配失败必须上报,不得静默损坏。\n", - "en": "Space exhaustion behaviour, where allocation failure must be reported rather than silently corrupting.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 671, - "end_line": 681 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.244Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestSpaceExhaustion", - "description": { - "zh": "镜像写满时的行为:暴露 ENOSPC 而不损坏元数据。\n", - "en": "Behaviour when the image is full: ENOSPC surfaces instead of corrupting metadata.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestSpaceExhaustion" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.identity": { - "uid": "a0000d0e", - "id": "pyvdisk.tests.vdisk.identity", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "身份用例", - "en": "Identity Tests" - }, - "description": { - "zh": "身份用例:让宿主文件可被识别为 pyvdisk 镜像的尾标。\n", - "en": "Identity tests: the trailer that lets a host file be recognised as a pyvdisk image.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1007, - "end_line": 1072 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.244Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestIdentity", - "description": { - "zh": "身份尾标生成、校验与损坏拒绝。\n", - "en": "Identity trailer generation, validation and corruption rejection.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestIdentity" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.io": { - "uid": "a0000d04", - "id": "pyvdisk.tests.vdisk.io", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "持久性与 IO 用例", - "en": "Persistence and IO Tests" - }, - "description": { - "zh": "持久性与 IO 边界用例:重挂载持久性、宿主传输与非法路径错误。\n", - "en": "Durability and IO boundary tests: remount persistence, host transfer and invalid-path errors.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 241, - "end_line": 319 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.245Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestPersistence", - "description": { - "zh": "重新挂载后数据与结构的持久性。\n", - "en": "Remount persistence of data and structure.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestPersistence" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestImportExport", - "description": { - "zh": "宿主文件与目录树的导入导出。\n", - "en": "Host import and export of files and trees.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestImportExport" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestEdgeCases", - "description": { - "zh": "缺失或非法路径的错误与边界用例。\n", - "en": "Error and boundary cases for missing or invalid paths.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestEdgeCases" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.large-files": { - "uid": "a0000d02", - "id": "pyvdisk.tests.vdisk.large-files", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "大文件与删除用例", - "en": "Large File and Remove Tests" - }, - "description": { - "zh": "间接块与目录删除行为,即块记账与 inode 复用最易出错的两处。\n", - "en": "Indirect-block and directory-removal behaviour, the two places where block accounting and inode reuse most often break.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 79, - "end_line": 151 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.245Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestLargeFiles", - "description": { - "zh": "单/双间接块映射、部分读写与截断扩缩。\n", - "en": "Single and double indirect block mapping, partial IO and truncate grow/shrink.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestLargeFiles" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestDirsAndRemove", - "description": { - "zh": "文件删除、rmdir 语义与深度递归 rmtree。\n", - "en": "File removal, rmdir semantics and deep recursive rmtree.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestDirsAndRemove" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.links": { - "uid": "a0000d05", - "id": "pyvdisk.tests.vdisk.links", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "链接与属性用例", - "en": "Link and Attribute Tests" - }, - "description": { - "zh": "inode 层行为:硬链接、属性修改与稀疏分配。\n", - "en": "Inode-level behaviour: hard links, attribute mutations and sparse allocation.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 320, - "end_line": 420 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.246Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestHardLinks", - "description": { - "zh": "硬链接创建、引用计数与共享内容行为。\n", - "en": "Hard link creation, refcount and shared-content behaviour.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestHardLinks" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestAttributes", - "description": { - "zh": "模式、uid、gid 与时间戳属性处理。\n", - "en": "Mode, uid, gid and timestamp attribute handling.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestAttributes" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestSparseFile", - "description": { - "zh": "稀疏文件空洞与表观大小对比实占大小。\n", - "en": "Sparse file holes and apparent versus allocated size.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestSparseFile" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.locking": { - "uid": "a0000d10", - "id": "pyvdisk.tests.vdisk.locking", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "并发用例", - "en": "Concurrency Tests" - }, - "description": { - "zh": "并发用例:单独验证锁原语,以及真实并发访问下的 VFS。\n", - "en": "Concurrency tests: the locking primitive in isolation and the VFS under real concurrent access.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1209, - "end_line": 1418 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.246Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestRWLock", - "description": { - "zh": "读写锁的获取、升级与超时语义。\n", - "en": "Read/write lock acquisition, upgrade and timeout semantics.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestRWLock" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestConcurrency", - "description": { - "zh": "多线程与多进程下的并发 VFS 访问。\n", - "en": "Concurrent VFS access under threads and processes.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestConcurrency" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.log": { - "uid": "a0000d13", - "id": "pyvdisk.tests.vdisk.log", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "日志盘用例", - "en": "Log Disk Tests" - }, - "description": { - "zh": "日志盘与日志集成用例,即存储平面用例的末端。\n", - "en": "Log disk and logging integration tests, the end of the storage-plane suite.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1595, - "end_line": 1650 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.247Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestLogDiskAndLogging", - "description": { - "zh": "日志盘流与 logging-core 桥接。\n", - "en": "Log disk streams and the logging-core bridge.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestLogDiskAndLogging" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.maintenance": { - "uid": "a0000d06", - "id": "pyvdisk.tests.vdisk.maintenance", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "维护用例", - "en": "Maintenance Tests" - }, - "description": { - "zh": "维护类用例:一致性检查、就地扩容与空间统计。\n", - "en": "Maintenance tests: consistency checking, in-place growth and space accounting.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 421, - "end_line": 511 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.248Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestFsck", - "description": { - "zh": "对注入的元数据损坏进行 fsck 检测与修复。\n", - "en": "fsck detection and repair of injected metadata damage.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestFsck" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestGrow", - "description": { - "zh": "就地镜像扩容与后续分配。\n", - "en": "In-place image growth and continued allocation.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestGrow" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestSpaceInfo", - "description": { - "zh": "df 与 du 空间统计。\n", - "en": "df and du space accounting.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestSpaceInfo" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.names": { - "uid": "a0000d03", - "id": "pyvdisk.tests.vdisk.names", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "命名空间用例", - "en": "Namespace Tests" - }, - "description": { - "zh": "命名空间语义:重命名、符号链接与文件对象接口。\n", - "en": "Namespace semantics: rename, symbolic links and the file-object interface.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 152, - "end_line": 240 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.248Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestRename", - "description": { - "zh": "文件与目录重命名,含覆盖与顺序。\n", - "en": "File and directory rename including overwrite and ordering.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestRename" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestSymlink", - "description": { - "zh": "符号链接创建、路径解析、环路检测与相对目标。\n", - "en": "Symlink creation, path resolution, loop detection and relative targets.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestSymlink" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVFile", - "description": { - "zh": "VFile 的读/写/seek/append 语义。\n", - "en": "VFile read/write/seek/append semantics.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVFile" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.permissions": { - "uid": "a0000d11", - "id": "pyvdisk.tests.vdisk.permissions", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "权限用例", - "en": "Permission Tests" - }, - "description": { - "zh": "权限用例:跨 uid 与 gid 组合遵守读、写、执行位。\n", - "en": "Permission tests: read, write and execute bits honoured across uid and gid combinations.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1419, - "end_line": 1536 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.249Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestPermissions", - "description": { - "zh": "模式、属主与 root 旁路的权限强制。\n", - "en": "Permission enforcement for mode, owner and root bypass.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestPermissions" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.raw-fs": { - "uid": "a0000d07", - "id": "pyvdisk.tests.vdisk.raw-fs", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "裸文件系统用例", - "en": "Raw Filesystem Tests" - }, - "description": { - "zh": "直接操作块设备与磁盘布局、绕过 VFS 门面的用例。\n", - "en": "Tests that exercise the block device and on-disk layout directly, bypassing the VFS facade.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 512, - "end_line": 535 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.249Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestRawFS", - "description": { - "zh": "绕过 VFS 的裸块设备级读写。\n", - "en": "Raw block-device level reads and writes outside the VFS.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestRawFS" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.vector": { - "uid": "a0000d12", - "id": "pyvdisk.tests.vdisk.vector", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "向量盘用例", - "en": "Vector Disk Tests" - }, - "description": { - "zh": "向量盘行为,即存储平面同时承载的非文件系统负载。\n", - "en": "Vector disk behaviour, the non-filesystem payload the storage plane also carries.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 1537, - "end_line": 1594 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.250Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVectorDisk", - "description": { - "zh": "向量盘集合、记录与相似度检索。\n", - "en": "Vector disk collections, records and similarity search.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVectorDisk" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.volume": { - "uid": "a0000d0a", - "id": "pyvdisk.tests.vdisk.volume", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷模式用例", - "en": "Volume Mode Tests" - }, - "description": { - "zh": "拼接与条带两种无冗余模式的卷用例。\n", - "en": "Volume mode tests for concatenation and striping, the two modes without redundancy.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 682, - "end_line": 781 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.251Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeBase", - "description": { - "zh": "构建成员镜像的共享卷夹具。\n", - "en": "Shared volume fixture building member images.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeBase" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeConcat", - "description": { - "zh": "跨多个成员的拼接卷。\n", - "en": "Concatenation volume spanning multiple members.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeConcat" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeStripe", - "description": { - "zh": "条带卷的分布与读回。\n", - "en": "Striped volume distribution and read-back.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeStripe" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.volume-detect": { - "uid": "a0000d0d", - "id": "pyvdisk.tests.vdisk.volume-detect", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷检测用例", - "en": "Volume Detection Tests" - }, - "description": { - "zh": "从设备内容而非配置自动检测卷成员关系。\n", - "en": "Automatic detection of volume membership from device contents, not configuration.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 949, - "end_line": 1006 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.252Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeAutoDetect", - "description": { - "zh": "基于扫描的卷自动检测与挂载。\n", - "en": "Scan-based automatic volume detection and mounting.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeAutoDetect" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.volume-meta": { - "uid": "a0000d0c", - "id": "pyvdisk.tests.vdisk.volume-meta", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "卷元数据用例", - "en": "Volume Metadata Tests" - }, - "description": { - "zh": "卷元数据与错误处理,以及卷 CLI 接口。\n", - "en": "Volume metadata and error handling plus the volume CLI surface.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 851, - "end_line": 948 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.252Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeMeta", - "description": { - "zh": "卷元数据、成员记录与几何持久化。\n", - "en": "Volume metadata, member records and geometry persistence.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeMeta" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeErrors", - "description": { - "zh": "成员缺失、重复或不匹配的错误用例。\n", - "en": "Error cases for missing, duplicated or mismatched members.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeErrors" - }, - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeCLI", - "description": { - "zh": "卷 CLI 子命令接口。\n", - "en": "Volume CLI subcommand surface.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeCLI" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vdisk.volume-mirror": { - "uid": "a0000d0b", - "id": "pyvdisk.tests.vdisk.volume-mirror", - "parent": "pyvdisk.tests.vdisk", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "镜像卷用例", - "en": "Mirror Volume Tests" - }, - "description": { - "zh": "镜像模式用例:区别于拼接与条带的冗余契约。\n", - "en": "Mirror-mode tests: the redundancy contract that distinguishes it from concat and stripe.\n" - }, - "source": [ - { - "path": "tests/test_vdisk.py", - "line": 782, - "end_line": 850 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.253Z", - "fingerprint": "3855e965b1d64d49d91e1f55344fdf67a6ec626f3493b5cb3a5fd8c83bc6e9cf", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vdisk.py::TestVolumeMirror", - "description": { - "zh": "镜像卷冗余、成员丢失与重新同步。\n", - "en": "Mirror volume redundancy, member loss and resync.\n" - }, - "key": "rpc:tests/test_vdisk.py::TestVolumeMirror" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript": { - "uid": "a0000e02", - "id": "pyvdisk.tests.vscript", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 用例", - "en": "VScript Tests" - }, - "description": { - "zh": "VScript 语言用例加上针对真实盘的端到端运行,是全套件中最广的单个测试模块。\n", - "en": "VScript language tests plus the end-to-end run against real disks, the broadest single test module of the suite.\n" - }, - "source": [ - { - "path": "tests/test_vscript.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "b5eb8d42d0e0d9313171bb65d64aa35be955e1cd5f91c4146acafb1bd2feb6f7", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript.py::FakeFS", - "description": { - "zh": "驱动原生 fs 接口的内存 VFS 替身。\n", - "en": "In-memory VFS double exercising the native fs surface.\n" - }, - "key": "rpc:tests/test_vscript.py::FakeFS" - }, - { - "protocol": "rpc", - "path": "tests/test_vscript.py::VScriptTests", - "description": { - "zh": "语言与原生模块单元用例:词法、事务、任务、能力与资源限额。\n", - "en": "Language and native-module unit tests: lexing, transactions, tasks, capabilities and resource limits.\n" - }, - "key": "rpc:tests/test_vscript.py::VScriptTests" - }, - { - "protocol": "rpc", - "path": "tests/test_vscript.py::VScriptEndToEndTests", - "description": { - "zh": "针对真实文件系统、向量与日志盘的端到端脚本执行。\n", - "en": "End-to-end script execution against real filesystem, vector and log disks.\n" - }, - "key": "rpc:tests/test_vscript.py::VScriptEndToEndTests" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.runtime.core", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "label": { - "zh": "验证解释器", - "en": "exercises interpreter" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-audit": { - "uid": "a0000e03", - "id": "pyvdisk.tests.vscript-audit", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "审计用例", - "en": "Audit Tests" - }, - "description": { - "zh": "对一次运行后审计记录必须包含的内容,以及两种 sink 均持久化它的断言。\n", - "en": "Assertions on what an audit record must contain after a run, and that both sinks persist it.\n" - }, - "source": [ - { - "path": "tests/test_vscript_audit.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "7441f64b06d467b1fd896ba20567a8b913116ce74d1a39d58d53aecb6975a5fb", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_audit.py", - "description": { - "zh": "审计记录内容与 sink 行为断言。\n", - "en": "Audit record content and sink behaviour assertions.\n" - }, - "key": "rpc:tests/test_vscript_audit.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.audit.record", - "to_api": "rpc:pyvdisk.vscript.audit.AuditRecord", - "label": { - "zh": "验证审计", - "en": "verifies audit" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-cron": { - "uid": "1cbfc35e", - "id": "pyvdisk.tests.vscript-cron", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "vscript", - "cron" - ], - "name": { - "zh": "Cron 用例", - "en": "Cron Tests" - }, - "description": { - "zh": "Cron 用例:字段解析、日/星期并集语义、步长与区间写法,以及下次触发时间计算。\n", - "en": "Cron tests: field parsing, DOM/DOW union semantics, step and range forms, and next-fire calculation.\n" - }, - "source": [ - { - "path": "tests/test_vscript_cron.py", - "line": 1, - "end_line": 109 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.213Z", - "fingerprint": "2fbf8277488694b433afe2cca201c9ecdd57759b921b02f8a91484dfe7f331e2", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_cron.py", - "description": { - "zh": "cron 字段解析、匹配与下次触发计算的 29 个用例。\n", - "en": "29 cases over cron field parsing, matching and next-fire computation.\n" - }, - "key": "rpc:tests/test_vscript_cron.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.cron", - "from_api": "rpc:tests/test_vscript_cron.py", - "to_api": "rpc:pyvdisk.vscript.cron.CronExpression#next_after", - "label": { - "zh": "验证 cron 表达式", - "en": "exercises cron expressions" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-host": { - "uid": "a0000e04", - "id": "pyvdisk.tests.vscript-host", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "宿主隔离用例", - "en": "Host Confinement Tests" - }, - "description": { - "zh": "验证 host 模块拒绝根外路径——VScript 所依赖的安全边界。\n", - "en": "Verifies the host module rejects out-of-root paths - the security boundary VScript depends on.\n" - }, - "source": [ - { - "path": "tests/test_vscript_host.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.253Z", - "fingerprint": "b0bfafaaf016b380762f3021f7ac6f169323bdcdfde4494aa05db3ab2841279b", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_host.py", - "description": { - "zh": "宿主读写根隔离断言。\n", - "en": "Host read/write root confinement assertions.\n" - }, - "key": "rpc:tests/test_vscript_host.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.host.guard", - "to_api": "rpc:pyvdisk.vscript.host.HostProxy#_check", - "label": { - "zh": "验证隔离", - "en": "verifies confinement" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-optional": { - "uid": "a0000e05", - "id": "pyvdisk.tests.vscript-optional", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "可选链用例", - "en": "Optional Chain Tests" - }, - "description": { - "zh": "语言边界用例:可选成员访问如何短路而非报错。\n", - "en": "Language edge case: how optional member access short-circuits instead of raising.\n" - }, - "source": [ - { - "path": "tests/test_vscript_optional_chain.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "e8cb9f8260c13e5b730c465c3939478ae00cb10bc99ba2ded4e2a62fa9b59117", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_optional_chain.py", - "description": { - "zh": "可选链与空安全成员访问语义。\n", - "en": "Optional chaining and null-safe member access semantics.\n" - }, - "key": "rpc:tests/test_vscript_optional_chain.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.runtime.expressions", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#eval", - "label": { - "zh": "验证求值", - "en": "verifies evaluation" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-triggers": { - "uid": "35b668fb", - "id": "pyvdisk.tests.vscript-triggers", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "vscript", - "triggers" - ], - "name": { - "zh": "触发器用例", - "en": "Trigger Tests" - }, - "description": { - "zh": "触发器用例:单调水位线排序(此前用随机事件 id 作文本比较会静默丢事件)、注册时空 pattern/stream 的拒绝,以及 poll_once 行为。\n", - "en": "Trigger tests: monotonic watermark ordering (a random event id used as a text watermark silently dropped events), empty pattern/stream rejection at registration, and poll_once behaviour.\n" - }, - "source": [ - { - "path": "tests/test_vscript_triggers.py", - "line": 1, - "end_line": 282 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.213Z", - "fingerprint": "b1079ad935b3695ebcb3c4682ab7849a80d348c1157e0634d225057496340185", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_triggers.py", - "description": { - "zh": "文件与日志触发器、其水位线与注册规则的 19 个用例。\n", - "en": "19 cases over file and log triggers, their watermarks and their registration rules.\n" - }, - "key": "rpc:tests/test_vscript_triggers.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.triggers.daemon", - "from_api": "rpc:tests/test_vscript_triggers.py", - "to_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "label": { - "zh": "验证触发器守护进程", - "en": "exercises trigger daemon" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.vscript-undo": { - "uid": "c9d0c415", - "id": "pyvdisk.tests.vscript-undo", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "vscript", - "undo" - ], - "name": { - "zh": "撤销用例", - "en": "Undo Tests" - }, - "description": { - "zh": "撤销用例:每个 fs 动词在生效前记账、大正文落盘、restore_tree 与崩溃后遗留快照的清理。\n", - "en": "Undo tests: every fs verb journalled before it mutates, large bodies spilled to the transaction area, restore_tree and orphan-spill cleanup after a crash.\n" - }, - "source": [ - { - "path": "tests/test_vscript_undo.py", - "line": 1, - "end_line": 373 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.214Z", - "fingerprint": "ac95991d897d56633679357d40f3e5463cee13f38c4e2730da86fb757cd72d7f", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_vscript_undo.py", - "description": { - "zh": "撤销词汇表、落盘、崩溃恢复,以及词汇与动词覆盖校验的 22 个用例。\n", - "en": "22 cases over the undo vocabulary, spilling, crash recovery and the vocabulary-vs-verb coverage check.\n" - }, - "key": "rpc:tests/test_vscript_undo.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.undo", - "from_api": "rpc:tests/test_vscript_undo.py", - "to_api": "rpc:pyvdisk.vscript.undo.apply_undo", - "label": { - "zh": "验证撤销解释器", - "en": "exercises undo interpreter" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.wal-checkpoint": { - "uid": "a8e30c5c", - "id": "pyvdisk.tests.wal-checkpoint", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "tests", - "wal", - "recovery" - ], - "name": { - "zh": "WAL 检查点用例", - "en": "WAL Checkpoint Tests" - }, - "description": { - "zh": "WAL 检查点用例:检查点后的截断、不再全量重放的恢复,以及 DataDisk 与 VScript 共用的同一套实现。\n", - "en": "WAL checkpoint tests: truncation after a checkpoint, replay without rescanning the full log, and the shared implementation used by both DataDisk and VScript.\n" - }, - "source": [ - { - "path": "tests/test_wal_checkpoint_and_recovery.py", - "line": 1, - "end_line": 267 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.214Z", - "fingerprint": "1c79a1bbb852a5a70a892b5919057cfef978163774e48defdcf15c74b4921b8d", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_wal_checkpoint_and_recovery.py", - "description": { - "zh": "共享 WAL 的检查点、截断与恢复行为。\n", - "en": "Checkpoint, truncation and recovery behaviour of the shared WAL.\n" - }, - "key": "rpc:tests/test_wal_checkpoint_and_recovery.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.wal.entries", - "from_api": "rpc:tests/test_wal_checkpoint_and_recovery.py", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover", - "label": { - "zh": "验证 WAL 检查点", - "en": "verifies WAL checkpointing" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.tests.wal-recovery": { - "uid": "a0000e1b", - "id": "pyvdisk.tests.wal-recovery", - "parent": "pyvdisk.tests", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "WAL 恢复用例", - "en": "WAL Recovery Tests" - }, - "description": { - "zh": "日志重放的专项用例:已回滚事务在恢复后必须不可见。\n", - "en": "Focused test of journal replay: an aborted transaction must be invisible after recovery.\n" - }, - "source": [ - { - "path": "tests/test_wal_abort_recovery.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.253Z", - "fingerprint": "460baab1c07bd01c140b0540d8220942e6c883f3296de958426ed0a0d999e514", - "apis": [ - { - "protocol": "rpc", - "path": "tests/test_wal_abort_recovery.py", - "description": { - "zh": "回滚与崩溃后的 WAL 重放。\n", - "en": "WAL replay after abort and crash.\n" - }, - "key": "rpc:tests/test_wal_abort_recovery.py" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.wal.entries", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover", - "label": { - "zh": "验证 WAL 恢复", - "en": "verifies WAL recovery" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript": { - "uid": "a0000315", - "id": "pyvdisk.vscript", - "parent": "pyvdisk", - "tree": "pyvdisk", - "depth": 2, - "tags": [ - "language", - "interpreter" - ], - "name": { - "zh": "VScript 语言", - "en": "VScript Language" - }, - "description": { - "zh": "VScript:安全工作流语言,含词法、语法、树遍历运行时、能力受限标准库、策略/预算、审计与调度。\n", - "en": "VScript: a safe workflow language with lexer, parser, tree-walking runtime, capability-confined standard library, policy/budget, audit and scheduling.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/__init__.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/ast.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/audit.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/cli.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/cron.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/errors.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/host.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/lexer.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/mounts.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/parser.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/policy.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/runtime.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/stdlib.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/tokens.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/triggers.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/undo.py", - "line": 1 - }, - { - "path": "pyvdisk/vscript/wal.py", - "line": 1 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "98f6c61340ebda42ddbd0fced95d0ae3c9f008ca45b2b60b7730cb2330c980a6", - "aggregate": { - "descendant_count": 41, - "own_api_count": 0, - "inherited_api_count": 143, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.audit": { - "uid": "a000031d", - "id": "pyvdisk.vscript.audit", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 审计", - "en": "VScript Audit" - }, - "description": { - "zh": "VScript 审计:稳定的脚本与策略哈希、带执行平面关联字段的 AuditRecord,以及持久化 sink。\n", - "en": "VScript audit: stable script and policy hashes, the AuditRecord shape with execution-plane correlation fields, and durable sinks.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.257Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "aggregate": { - "descendant_count": 5, - "own_api_count": 0, - "inherited_api_count": 25, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.audit.clock": { - "uid": "a0000b10", - "id": "pyvdisk.vscript.audit.clock", - "parent": "pyvdisk.vscript.audit", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "运行标识", - "en": "Run Identity" - }, - "description": { - "zh": "用于填充审计记录的运行标识与耗时测量。\n", - "en": "Run identity and duration measurement used to fill audit records.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py", - "line": 99, - "end_line": 104 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.258Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.new_run_id", - "description": { - "zh": "生成唯一且按创建时间可排序的 run id。\n", - "en": "Generate a run id that is unique and sortable by creation time.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.new_run_id" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.monotonic_ms", - "description": { - "zh": "自单调起点起经过的毫秒数。\n", - "en": "Milliseconds elapsed since a monotonic start point.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.monotonic_ms" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.audit.hashing": { - "uid": "a0000b0d", - "id": "pyvdisk.vscript.audit.hashing", - "parent": "pyvdisk.vscript.audit", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "审计哈希", - "en": "Audit Hashing" - }, - "description": { - "zh": "脚本与策略的确定性哈希,以及审计哈希链:每行都带上前驱哈希,verify 报告第一条不匹配的记录——包括在真实日志段内做的手脚。\n", - "en": "Deterministic hashing for scripts and policies, plus the audit hash chain: rows are stamped with their predecessor's hash, and verify reports the first record that does not match, including an edit made inside a real log segment.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py", - "line": 16, - "end_line": 37 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.258Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.script_hash", - "description": { - "zh": "脚本的确定性哈希。\n", - "en": "Deterministic hash of a script.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.script_hash" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.policy_hash", - "description": { - "zh": "策略的确定性哈希。\n", - "en": "Deterministic hash of a policy.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.policy_hash" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.row_hash", - "description": { - "zh": "把一条审计行与其前驱一起哈希。\n", - "en": "Hashes one audit row together with its predecessor.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.row_hash" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.stamp_row", - "description": { - "zh": "为一行打上哈希链的链接字段。\n", - "en": "Stamps a row with the hash chain link.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.stamp_row" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.chain_rows", - "description": { - "zh": "对一批行重算整条链。\n", - "en": "Recomputes the chain across a list of rows.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.chain_rows" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.verify_chain", - "description": { - "zh": "校验一条链,断开时报告断裂位置。\n", - "en": "Verifies a chain and reports where it broke, if it did.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.verify_chain" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.audit.query": { - "uid": "a51f4f49", - "id": "pyvdisk.vscript.audit.query", - "parent": "pyvdisk.vscript.audit", - "tree": "pyvdisk", - "depth": 4, - "tags": [ - "vscript", - "audit", - "query", - "retention" - ], - "name": { - "zh": "审计查询与保留", - "en": "Audit Query and Retention" - }, - "description": { - "zh": "审计轨迹的读取侧:按运行/任务/状态/时间筛选记录,并支持显式保留裁剪,使轨迹既可查也可有界,而不是只能追加。\n", - "en": "Reading side of the audit trail: record selection by run/task/status/time and explicit retention, so a trail can be inspected and bounded instead of only appended to.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py", - "line": 108, - "end_line": 158 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.210Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.query_rows", - "description": { - "zh": "按运行、任务、状态与时间窗筛选审计记录,可要求按最新优先。\n", - "en": "Selects audit records by run, task, status and time window, optionally newest first.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.query_rows" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.retain_rows", - "description": { - "zh": "按条数与时间裁剪记录列表,返回保留与丢弃两部分。\n", - "en": "Trims a record list by count and age, returning what was kept and what was dropped.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.retain_rows" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.audit.record": { - "uid": "a0000b0e", - "id": "pyvdisk.vscript.audit.record", - "parent": "pyvdisk.vscript.audit", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "审计记录", - "en": "Audit Record" - }, - "description": { - "zh": "解释器、执行服务与 Sink 共用的审计记录形态,含使其可校验(而非仅可追加)的链字段。\n", - "en": "The audit record shape shared by the interpreter, the execution service and the sinks, including the chain fields that make a trail verifiable rather than merely append-only.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py", - "line": 160, - "end_line": 178 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.258Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.AuditRecord", - "description": { - "zh": "单条审计记录:run id、脚本与策略哈希、结果、计数与执行平面关联字段。\n", - "en": "One audit record: run id, script and policy hashes, outcome, counters and execution-plane correlation.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.AuditRecord" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.AuditRecord#to_dict", - "description": { - "zh": "把记录渲染为 JSON 安全字典。\n", - "en": "Render the record as a JSON-safe dictionary.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.AuditRecord#to_dict" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.audit.sinks": { - "uid": "a0000b0f", - "id": "pyvdisk.vscript.audit.sinks", - "parent": "pyvdisk.vscript.audit", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "审计 Sink", - "en": "Audit Sinks" - }, - "description": { - "zh": "持久审计目的地:检查点存储里的有界保留,或日志盘上的只追加审计流。两者现在都可读:查询筛选、显式保留、哈希链校验,以及供外部锚定的链头。\n", - "en": "Durable audit destinations: bounded retention in a checkpoint store, or an append-only audit stream on a log disk. Both are now readable: query filters, explicit retention, hash-chain verification and a head for external anchoring.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/audit.py", - "line": 181, - "end_line": 307 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.259Z", - "fingerprint": "e7c398721e85cdb58382b2b377443a1448877191f1be8c698b03443173fc2e4f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink", - "description": { - "zh": "把最新记录保存在检查点存储中的审计 Sink。\n", - "en": "Audit sink that keeps the newest records in a checkpoint store.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#emit", - "description": { - "zh": "持久化一条审计记录。\n", - "en": "Persists one audit record.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#records", - "description": { - "zh": "返回保留的审计记录。\n", - "en": "Returns the retained audit records.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#records" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#query", - "description": { - "zh": "按运行、任务、状态或时间窗选取记录。\n", - "en": "Selects records by run, task, status or time window.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#query" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#retain", - "description": { - "zh": "按条数与时间裁剪。\n", - "en": "Trims by count and age.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#retain" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#verify", - "description": { - "zh": "校验哈希链。\n", - "en": "Verifies the hash chain.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#verify" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#head", - "description": { - "zh": "当前链头,供外部锚定。\n", - "en": "Current chain head, for external anchoring.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#head" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.CheckpointAuditSink#adopt", - "description": { - "zh": "接管一个锚点,使重建的链能与记录值比对。\n", - "en": "Adopts an anchor so a rebuilt chain can be compared with a recorded one.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#adopt" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.DataDiskAuditSink", - "description": { - "zh": "日志盘上的只追加审计流。\n", - "en": "Append-only audit stream on a log disk.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.DataDiskAuditSink#emit", - "description": { - "zh": "把一条审计记录追加到 audit 流。\n", - "en": "Appends one audit record to the audit stream.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#emit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.DataDiskAuditSink#query", - "description": { - "zh": "把流读回为记录行。\n", - "en": "Reads the stream back as rows.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#query" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.DataDiskAuditSink#retain", - "description": { - "zh": "保留策略委派给日志盘自身的执行。\n", - "en": "Delegates retention to the log disk's own enforcement.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#retain" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.audit.DataDiskAuditSink#verify", - "description": { - "zh": "在流上校验哈希链。\n", - "en": "Verifies the chain over the stream.\n" - }, - "key": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#verify" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.log.append", - "from_api": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#emit", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "label": { - "zh": "追加到日志流", - "en": "appends to log stream" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.io", - "from_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save", - "label": { - "zh": "经检查点持久化", - "en": "persists via checkpoint" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 13, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 2 - } - }, - "pyvdisk.vscript.cli": { - "uid": "a000031c", - "id": "pyvdisk.vscript.cli", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 命令行", - "en": "VScript CLI" - }, - "description": { - "zh": "VScript 命令行入口:check、run、run-disk 与交互式 REPL,含挂载授权参数解析。\n", - "en": "VScript CLI surface: check, run, run-disk and the interactive REPL, including mount authorization parsing.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/cli.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.259Z", - "fingerprint": "b93664d4ede6142b0a1f77adbe3592f0ee285c15f7e00e3627f7acae3a5a3431", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 8, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.cli.commands": { - "uid": "a0000c01", - "id": "pyvdisk.vscript.cli.commands", - "parent": "pyvdisk.vscript.cli", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VScript 命令", - "en": "VScript Commands" - }, - "description": { - "zh": "VScript 命令接口:参数解析、挂载授权与 check/run 入口,含使 host.* 可用的宿主读/写根目录选项。\n", - "en": "VScript command surface: argument parsing, mount authorisation and the check/run entry points, including the host read/write root options that make host.* usable.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/cli.py", - "line": 7, - "end_line": 46 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.259Z", - "fingerprint": "b93664d4ede6142b0a1f77adbe3592f0ee285c15f7e00e3627f7acae3a5a3431", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli._pairs", - "description": { - "zh": "把重复的 key=value 命令行参数解析为字典。\n", - "en": "Parse repeated key=value CLI arguments into a dictionary.\n" - }, - "key": "rpc:pyvdisk.vscript.cli._pairs" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli._mounts", - "description": { - "zh": "从 name=path=permissions 参数构建挂载句柄。\n", - "en": "Build mount handles from name=path=permissions arguments.\n" - }, - "key": "rpc:pyvdisk.vscript.cli._mounts" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli.command", - "description": { - "zh": "分发 check、run 与 run-disk 子命令。\n", - "en": "Dispatch the check, run and run-disk subcommands.\n" - }, - "key": "rpc:pyvdisk.vscript.cli.command" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.mounts", - "from_api": "rpc:pyvdisk.vscript.cli._mounts", - "to_api": "rpc:pyvdisk.vscript.mounts.MountRegistry#grant", - "label": { - "zh": "授予挂载", - "en": "grants mounts" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.cli.parser": { - "uid": "a0000c03", - "id": "pyvdisk.vscript.cli.parser", - "parent": "pyvdisk.vscript.cli", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VScript 参数注册", - "en": "VScript Parser Hook" - }, - "description": { - "zh": "把 VScript 接口挂到 pyvdisk 主 CLI 上的 argparse 注册。\n", - "en": "argparse registration that grafts the VScript surface onto the main pyvdisk CLI.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/cli.py", - "line": 152, - "end_line": 159 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "b93664d4ede6142b0a1f77adbe3592f0ee285c15f7e00e3627f7acae3a5a3431", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli.add_parser", - "description": { - "zh": "挂载 vscript 子解析器及其 check、run、run-disk 与 repl 选项。\n", - "en": "Attach the vscript subparser with its check, run, run-disk and repl options.\n" - }, - "key": "rpc:pyvdisk.vscript.cli.add_parser" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.cli.repl": { - "uid": "a0000c02", - "id": "pyvdisk.vscript.cli.repl", - "parent": "pyvdisk.vscript.cli", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "VScript REPL", - "en": "VScript REPL" - }, - "description": { - "zh": "交互式 VScript REPL:行包装、值格式化、帮助,以及跨输入保持状态的循环。\n", - "en": "The interactive VScript REPL: line wrapping, value formatting, help and the loop that keeps state across inputs.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/cli.py", - "line": 47, - "end_line": 151 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.260Z", - "fingerprint": "b93664d4ede6142b0a1f77adbe3592f0ee285c15f7e00e3627f7acae3a5a3431", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli._repl_source", - "description": { - "zh": "把 REPL 输入行包装为脚本源码。\n", - "en": "Wrap a REPL line as a script source.\n" - }, - "key": "rpc:pyvdisk.vscript.cli._repl_source" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli._repl_type", - "description": { - "zh": "格式化 REPL 值以便展示。\n", - "en": "Format a REPL value for display.\n" - }, - "key": "rpc:pyvdisk.vscript.cli._repl_type" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli._repl_help", - "description": { - "zh": "打印 REPL 帮助文本。\n", - "en": "Print the REPL help text.\n" - }, - "key": "rpc:pyvdisk.vscript.cli._repl_help" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cli.repl", - "description": { - "zh": "在持久解释器状态上的交互式读取-求值-打印循环。\n", - "en": "Interactive read-eval-print loop over a persistent interpreter state.\n" - }, - "key": "rpc:pyvdisk.vscript.cli.repl" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.runtime.core", - "from_api": "rpc:pyvdisk.vscript.cli.repl", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "label": { - "zh": "运行源码", - "en": "runs sources" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.cron": { - "uid": "a0000a0a", - "id": "pyvdisk.vscript.cron", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "Cron 表达式", - "en": "Cron Expressions" - }, - "description": { - "zh": "定时触发器所需的 cron 支持:字段解析、匹配与下次触发计算。\n", - "en": "Cron support for scheduled triggers: field parsing, matching and next-fire computation.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/cron.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:10:41.894Z", - "fingerprint": "2c377873cb40f385dd5256018381f5c9b79dcd3b26f5e1761235b6b8de0804a0", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cron.CronError", - "description": { - "zh": "cron 表达式非法时抛出。\n", - "en": "Raised for malformed cron expressions.\n" - }, - "key": "rpc:pyvdisk.vscript.cron.CronError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cron.CronExpression", - "description": { - "zh": "已解析的五字段 cron 表达式,支持范围与步长。\n", - "en": "Parsed five-field cron expression with range and step support.\n" - }, - "key": "rpc:pyvdisk.vscript.cron.CronExpression" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cron.CronExpression#matches", - "description": { - "zh": "判断某值是否匹配该表达式。\n", - "en": "Test whether a value matches the expression.\n" - }, - "key": "rpc:pyvdisk.vscript.cron.CronExpression#matches" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cron.CronExpression#next_after", - "description": { - "zh": "计算给定时间之后的下一个匹配时间戳。\n", - "en": "Compute the next matching timestamp after a given one.\n" - }, - "key": "rpc:pyvdisk.vscript.cron.CronExpression#next_after" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.cron.cron", - "description": { - "zh": "解析 cron 表达式字符串。\n", - "en": "Parse a cron expression string.\n" - }, - "key": "rpc:pyvdisk.vscript.cron.cron" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.frontend": { - "uid": "a0000316", - "id": "pyvdisk.vscript.frontend", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 前端", - "en": "VScript Front End" - }, - "description": { - "zh": "VScript 前端:词法单元、最大匹配 lexer、AST 节点、递归下降语句解析器、Pratt 表达式解析器与带位置诊断。\n", - "en": "VScript front end: tokens, maximal-munch lexer, AST nodes, recursive-descent statement parser, Pratt expression parser and positional diagnostics.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/tokens.py" - }, - { - "path": "pyvdisk/vscript/lexer.py" - }, - { - "path": "pyvdisk/vscript/ast.py" - }, - { - "path": "pyvdisk/vscript/parser.py" - }, - { - "path": "pyvdisk/vscript/errors.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "1805b338520ee48ed0e2810b53e547a9c2935f836670909bdac8c21739c0a114", - "aggregate": { - "descendant_count": 6, - "own_api_count": 0, - "inherited_api_count": 30, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.frontend.ast": { - "uid": "a0000a03", - "id": "pyvdisk.vscript.frontend.ast", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "AST 节点", - "en": "AST Nodes" - }, - "description": { - "zh": "AST 节点词表:表达式、语句、声明,以及工作流特有的 transaction、task、parallel 与 await 节点。\n", - "en": "The AST node vocabulary: expressions, statements, declarations and the workflow-specific transaction, task, parallel and await nodes.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/ast.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "169e17c9bfb255011f2591c4a267a9db6425c10791bb0202e196977753ef435d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Node", - "description": { - "zh": "携带源码位置的 AST 节点基类。\n", - "en": "Base AST node carrying its source span.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Node" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Program", - "description": { - "zh": "持有语句列表与语言版本的根节点。\n", - "en": "Root node holding the statement list and language version.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Program" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Let", - "description": { - "zh": "let / 常量声明,可选 export。\n", - "en": "Let or constant declaration, optionally exported.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Let" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.If", - "description": { - "zh": "条件语句,含可选 else 分支。\n", - "en": "Conditional statement with optional else branch.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.If" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.FunctionDecl", - "description": { - "zh": "带块体的具名函数声明。\n", - "en": "Named function declaration with a block body.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.FunctionDecl" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Import", - "description": { - "zh": "带可选别名的模块导入。\n", - "en": "Module import with an optional alias.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Import" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Requirement", - "description": { - "zh": "声明能力及其权限的 require 节点。\n", - "en": "Requirement declaration naming a capability and its permissions.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Requirement" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.ast.Transaction", - "description": { - "zh": "事务块节点。\n", - "en": "Transaction block node.\n" - }, - "key": "rpc:pyvdisk.vscript.ast.Transaction" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.SourceSpan", - "label": { - "zh": "位置来自 errors 模块", - "en": "spans from errors module" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.vscript.frontend.errors": { - "uid": "a0000a06", - "id": "pyvdisk.vscript.frontend.errors", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "错误类型", - "en": "Error Types" - }, - "description": { - "zh": "错误层次:把语言各阶段映射为可区分、可捕获、可审计的失败。\n", - "en": "The error hierarchy that maps language phases to distinguishable, catchable and auditable failures.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/errors.py", - "line": 52, - "end_line": 133 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "b30ccf2593d5b73a8f9b6644f111e23bb1a7ca5878893f4efa8ce4bbca7ebc2c", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.VScriptError", - "description": { - "zh": "所有 VScript 失败的基类错误,携带诊断与位置。\n", - "en": "Base error carrying a diagnostic and span for every VScript failure.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.VScriptError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.LexError", - "description": { - "zh": "扫描器抛出的词法失败。\n", - "en": "Lexical failure raised by the scanner.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.LexError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.ParseError", - "description": { - "zh": "解析器抛出的语法失败。\n", - "en": "Syntactic failure raised by the parser.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.ParseError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.CompileError", - "description": { - "zh": "执行前准备阶段抛出的失败。\n", - "en": "Failure raised while preparing a program for execution.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.CompileError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.RuntimeError", - "description": { - "zh": "脚本执行过程中的运行时失败。\n", - "en": "Runtime failure inside an executing script.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.RuntimeError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.CapabilityError", - "description": { - "zh": "脚本触及授权外资源时抛出。\n", - "en": "Raised when a script touches a resource outside its granted capabilities.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.CapabilityError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.ResourceLimitError", - "description": { - "zh": "步骤、字节等策略预算耗尽时抛出。\n", - "en": "Raised when a policy budget such as steps or bytes is exhausted.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.ResourceLimitError" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.ScriptThrown", - "description": { - "zh": "封装脚本自身 throw 的值。\n", - "en": "Wraps a value thrown by the script itself.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.ScriptThrown" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.Diagnostic", - "label": { - "zh": "由诊断构造", - "en": "built from diagnostics" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 8, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.vscript.frontend.lexer": { - "uid": "a0000a02", - "id": "pyvdisk.vscript.frontend.lexer", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "词法器", - "en": "Lexer" - }, - "description": { - "zh": "词法器:注释与空白处理、数字与字符串字面量、运算符与最大匹配。\n", - "en": "The lexer: comment and whitespace handling, number and string literals, operators and maximal-munch matching.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/lexer.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.310Z", - "fingerprint": "54c9f38247be141005b9edbef9b5c4c3b7ee922e1267afaedbf49624d146eaff", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.lexer.Lexer", - "description": { - "zh": "对 VScript 源码的最大匹配扫描器。\n", - "en": "Maximal-munch scanner over VScript source.\n" - }, - "key": "rpc:pyvdisk.vscript.lexer.Lexer" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.lexer.Lexer#scan", - "description": { - "zh": "把整份源码扫描为以 EOF 结尾的单元列表。\n", - "en": "Scan the whole source into a token list ending with EOF.\n" - }, - "key": "rpc:pyvdisk.vscript.lexer.Lexer#scan" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.lexer.Lexer#peek", - "description": { - "zh": "不消费地向前查看 n 个单元。\n", - "en": "Look ahead n tokens without consuming.\n" - }, - "key": "rpc:pyvdisk.vscript.lexer.Lexer#peek" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.lexer.Lexer#advance", - "description": { - "zh": "消费并返回下一个字符。\n", - "en": "Consume and return the next character.\n" - }, - "key": "rpc:pyvdisk.vscript.lexer.Lexer#advance" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.lexer.lex", - "description": { - "zh": "对源字符串做词法分析的便利函数。\n", - "en": "Convenience function lexing a source string.\n" - }, - "key": "rpc:pyvdisk.vscript.lexer.lex" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.frontend.errors", - "from_api": "rpc:pyvdisk.vscript.lexer.Lexer#scan", - "to_api": "rpc:pyvdisk.vscript.errors.LexError", - "label": { - "zh": "抛出词法错误", - "en": "raises lex errors" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.vscript.frontend.parser": { - "uid": "a0000a04", - "id": "pyvdisk.vscript.frontend.parser", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "语法解析器", - "en": "Parser" - }, - "description": { - "zh": "语法实现:语句、声明、控制流、match 分支与工作流构造。\n", - "en": "Grammar implementation: statements, declarations, control flow, match arms and the workflow constructs.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/parser.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:13.026Z", - "fingerprint": "71f29c6ad29ae5453ef68af56bc96aa54ae9d0f95c23e0c633f8bf4d231ac79e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.parser.Parser", - "description": { - "zh": "递归下降语句解析器,表达式部分用 Pratt 解析。\n", - "en": "Recursive-descent statement parser with Pratt expression parsing.\n" - }, - "key": "rpc:pyvdisk.vscript.parser.Parser" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.parser.parse", - "description": { - "zh": "对源字符串做词法与语法分析并返回 Program 的便利函数。\n", - "en": "Convenience function lexing and parsing a source string into a Program.\n" - }, - "key": "rpc:pyvdisk.vscript.parser.parse" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.frontend.lexer", - "from_api": "rpc:pyvdisk.vscript.parser.parse", - "to_api": "rpc:pyvdisk.vscript.lexer.lex", - "label": { - "zh": "词法分析", - "en": "lexes source" - }, - "cross_tree": false - }, - { - "kind": "dataflow", - "to": "pyvdisk.vscript.frontend.ast", - "from_api": "rpc:pyvdisk.vscript.parser.Parser", - "to_api": "rpc:pyvdisk.vscript.ast.Program", - "label": { - "zh": "构建 AST", - "en": "builds AST" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.vscript.frontend.span": { - "uid": "a0000a05", - "id": "pyvdisk.vscript.frontend.span", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "位置与诊断", - "en": "Span and Diagnostic" - }, - "description": { - "zh": "位置与诊断原语:事情发生在哪里,以及如何向用户报告。\n", - "en": "Position and diagnostic primitives: where something happened and how it is reported to the user.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/errors.py", - "line": 10, - "end_line": 51 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "b30ccf2593d5b73a8f9b6644f111e23bb1a7ca5878893f4efa8ce4bbca7ebc2c", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.SourceSpan", - "description": { - "zh": "脚本内的行列范围,并提供零位置哨兵。\n", - "en": "Line and column range inside a script, with a zero span sentinel.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.SourceSpan" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.SourceSpan#__str__", - "description": { - "zh": "把位置渲染为 line:col。\n", - "en": "Render the span as line:col.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.SourceSpan#__str__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.Diagnostic", - "description": { - "zh": "带严重级别、代码、消息、位置与源码行的诊断。\n", - "en": "A diagnostic with severity, code, message, span and source line.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.Diagnostic" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.errors.Diagnostic#format", - "description": { - "zh": "把诊断格式化为单行编译器风格输出。\n", - "en": "Format the diagnostic as a single compiler-style line.\n" - }, - "key": "rpc:pyvdisk.vscript.errors.Diagnostic#format" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 3 - } - }, - "pyvdisk.vscript.frontend.tokens": { - "uid": "a0000a01", - "id": "pyvdisk.vscript.frontend.tokens", - "parent": "pyvdisk.vscript.frontend", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "词法单元", - "en": "Token Types" - }, - "description": { - "zh": "语言的词法单元词表:lexer 能产出的全部关键字、运算符与字面量。\n", - "en": "The token vocabulary of the language: every keyword, operator and literal the lexer can emit.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/tokens.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:20:48.310Z", - "fingerprint": "ba8c01c0d894a1eea1877104b4f729f40f057a27f38fcf137157f2d5e9e7b00d", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.tokens.TokenType", - "description": { - "zh": "词法单元类型枚举:关键字、运算符、字面量与结构符号。\n", - "en": "Token kind enum covering keywords, operators, literals and structural tokens.\n" - }, - "key": "rpc:pyvdisk.vscript.tokens.TokenType" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.tokens.Token", - "description": { - "zh": "一个已词法化的单元,携带类型、字面、位置与可选值。\n", - "en": "A lexed token carrying type, lexeme, span and optional value.\n" - }, - "key": "rpc:pyvdisk.vscript.tokens.Token" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.tokens.Token#is_eof", - "description": { - "zh": "该单元为输入终止符时为真。\n", - "en": "True when the token terminates input.\n" - }, - "key": "rpc:pyvdisk.vscript.tokens.Token#is_eof" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.SourceSpan", - "label": { - "zh": "携带源码位置", - "en": "carries source spans" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.host": { - "uid": "a000031a", - "id": "pyvdisk.vscript.host", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "security" - ], - "name": { - "zh": "宿主访问", - "en": "Host Access" - }, - "description": { - "zh": "VScript 宿主访问:白名单 HostProxy,把脚本文件传输限制在声明的目录根内。\n", - "en": "VScript host access: an allowlisted HostProxy that confines script file transfer to declared directory roots.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/host.py" - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 7, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.host.guard": { - "uid": "a0000b0b", - "id": "pyvdisk.vscript.host.guard", - "parent": "pyvdisk.vscript.host", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "宿主隔离", - "en": "Host Confinement" - }, - "description": { - "zh": "宿主隔离:声明脚本可读写的宿主目录,其余路径一律拒绝。写入末尾会刷盘目录,让改名本身落地;该刷盘经由平台适配层,因为 Windows 无法把目录当文件打开。\n", - "en": "Host confinement: declares which host directories a script may read and write and refuses everything else. Writes end with a directory flush so the rename itself is durable; that flush goes through the platform layer, since Windows cannot open a directory as a file.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/host.py", - "line": 8, - "end_line": 79 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostCapability", - "description": { - "zh": "宿主模块允许触及的读根与写根。\n", - "en": "Read and write roots the host module may touch.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostCapability" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostCapability#proxy", - "description": { - "zh": "为该能力构建脚本可见的宿主代理。\n", - "en": "Build the script-visible host proxy for this capability.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostCapability#proxy" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostProxy", - "description": { - "zh": "强制执行读/写根白名单的宿主文件系统代理。\n", - "en": "Allowlisted host filesystem proxy enforcing read and write roots.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostProxy" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostProxy#_check", - "description": { - "zh": "拒绝声明根之外的路径。\n", - "en": "Reject paths outside the declared roots.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostProxy#_check" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostProxy#read", - "description": { - "zh": "把宿主文件读入内存。\n", - "en": "Read a host file into memory.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostProxy#read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.HostProxy#write", - "description": { - "zh": "写入宿主数据,可选禁止覆盖。\n", - "en": "Write host data with an optional no-overwrite guard.\n" - }, - "key": "rpc:pyvdisk.vscript.host.HostProxy#write" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.platform.durability", - "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", - "label": { - "zh": "刷盘目录", - "en": "flush the directory" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 2 - } - }, - "pyvdisk.vscript.host.module": { - "uid": "a0000b0c", - "id": "pyvdisk.vscript.host.module", - "parent": "pyvdisk.vscript.host", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "宿主模块", - "en": "Host Module" - }, - "description": { - "zh": "host 原生模块:面向脚本的读取、写入与传输入口,全部经隔离代理。\n", - "en": "The host native module: script-facing read, write and transfer entry points that all funnel through the confinement proxy.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/host.py", - "line": 80, - "end_line": 92 - } - ], - "revision": "2c9009ba74afb515d301cc96e1946087268479a2", - "updated_at": "2026-09-24T13:45:00Z", - "fingerprint": "b041b5a92b2d5d9ff7cfc03f3d5bd925f17d1a1137ec559745e0608f984f0d8a", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.host.create_host_module", - "description": { - "zh": "构建含 read、write、import_file 与 export_file 的 host 原生模块。\n", - "en": "Build the host native module with read, write, import_file and export_file.\n" - }, - "key": "rpc:pyvdisk.vscript.host.create_host_module" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.host.guard", - "from_api": "rpc:pyvdisk.vscript.host.create_host_module", - "to_api": "rpc:pyvdisk.vscript.host.HostProxy#read", - "label": { - "zh": "经代理限权", - "en": "guards via proxy" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.mounts": { - "uid": "a0000a09", - "id": "pyvdisk.vscript.mounts", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "挂载注册表", - "en": "Mount Registry" - }, - "description": { - "zh": "挂载授权:把 CLI 挂载参数转为能力受限句柄并在运行后关闭的注册表。\n", - "en": "Mount authorization: the registry that turns CLI mount flags into capability-limited handles and closes them after the run.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/mounts.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:19:48.424Z", - "fingerprint": "585606c58ad1f62de4c8a0ae519916c27755abe335bbb128d5be7c67cd88d4c4", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry", - "description": { - "zh": "单次脚本运行所授予的挂载句柄注册表。\n", - "en": "Registry of mount handles granted to one script run.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry#grant", - "description": { - "zh": "在目标上按权限与根范围授予具名句柄。\n", - "en": "Grant a named handle over a target with permissions and a root scope.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry#grant" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry#open", - "description": { - "zh": "打开资源并为其授予句柄。\n", - "en": "Open a resource and grant a handle for it.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry#open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry#get", - "description": { - "zh": "按名称查询已授予能力。\n", - "en": "Look up a granted capability by name.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry#handles", - "description": { - "zh": "返回脚本可见的句柄映射。\n", - "en": "Return the script-visible handle map.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry#handles" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.mounts.MountRegistry#close", - "description": { - "zh": "运行结束时关闭全部自有资源。\n", - "en": "Close every owned resource at the end of a run.\n" - }, - "key": "rpc:pyvdisk.vscript.mounts.MountRegistry#close" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.policy.capability", - "from_api": "rpc:pyvdisk.vscript.mounts.MountRegistry#grant", - "to_api": "rpc:pyvdisk.vscript.policy.Capability", - "label": { - "zh": "创建能力", - "en": "creates capability" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.vscript.policy": { - "uid": "a0000317", - "id": "pyvdisk.vscript.policy", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "策略与预算", - "en": "Policy and Budget" - }, - "description": { - "zh": "VScript 策略与预算:调用深度、循环、IO 与 Host 传输限额,以及脚本可 require 的受保护能力集。\n", - "en": "VScript policy and budget: call-depth, loop, IO and host-transfer limits, plus the protected capability set a script may require.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/policy.py" - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "ff47ac976336485cb37963fa8268f69553eddc1f28f20df0efb89166391276a6", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 8, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.policy.budget": { - "uid": "a0000a07", - "id": "pyvdisk.vscript.policy.budget", - "parent": "pyvdisk.vscript.policy", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "策略与预算", - "en": "Policy and Budget" - }, - "description": { - "zh": "脚本的资源治理:声明式限额与执行计费并强制限额的运行时计数器。\n", - "en": "Resource governance for scripts: the declarative limits and the runtime counter that enforces them.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/policy.py", - "line": 9, - "end_line": 36 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "ff47ac976336485cb37963fa8268f69553eddc1f28f20df0efb89166391276a6", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Policy", - "description": { - "zh": "执行策略:调用深度、循环、IO 与 Host 传输限额。\n", - "en": "Execution policy: call depth, loop, IO and host-transfer limits.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Policy" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Budget", - "description": { - "zh": "解释器计费的单次运行预算计数器。\n", - "en": "Per-run budget counter charged by the interpreter.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Budget" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Budget#tick", - "description": { - "zh": "向预算计入一个解释器步骤。\n", - "en": "Charge one interpreter step against the budget.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Budget#tick" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Budget#charge_read", - "description": { - "zh": "向预算计入读取字节。\n", - "en": "Charge read bytes against the budget.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Budget#charge_read" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Budget#charge_write", - "description": { - "zh": "向预算计入写入字节。\n", - "en": "Charge written bytes against the budget.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Budget#charge_write" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Budget#charge_output", - "description": { - "zh": "向预算计入产出字节。\n", - "en": "Charge produced output bytes against the budget.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Budget#charge_output" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.policy.capability": { - "uid": "a0000a08", - "id": "pyvdisk.vscript.policy.capability", - "parent": "pyvdisk.vscript.policy", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "脚本能力", - "en": "Script Capability" - }, - "description": { - "zh": "脚本可见的能力对象及其权限门禁。\n", - "en": "The script-visible capability object and its permission gate.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/policy.py", - "line": 38, - "end_line": 46 - } - ], - "revision": "6d203c0d5f54ce2e4293edd8054c10a109f8b83d", - "updated_at": "2026-09-23T07:00:00Z", - "fingerprint": "ff47ac976336485cb37963fa8268f69553eddc1f28f20df0efb89166391276a6", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Capability", - "description": { - "zh": "已授权句柄及脚本可经其使用的权限集。\n", - "en": "A granted handle plus the permission set a script may use through it.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Capability" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.policy.Capability#require", - "description": { - "zh": "缺少任一权限时抛出能力错误。\n", - "en": "Raise a capability error unless every listed permission is granted.\n" - }, - "key": "rpc:pyvdisk.vscript.policy.Capability#require" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - }, - "pyvdisk.vscript.runtime": { - "uid": "a0000318", - "id": "pyvdisk.vscript.runtime", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "interpreter" - ], - "name": { - "zh": "VScript 运行时", - "en": "VScript Runtime" - }, - "description": { - "zh": "VScript 运行时:树遍历求值器、词法 Env 链、闭包、控制流、确定性 task/parallel、事务与模块加载。\n", - "en": "VScript runtime: tree-walking evaluator, lexical Env chain, closures, control flow, deterministic task/parallel, transactions and module loading.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.261Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "aggregate": { - "descendant_count": 7, - "own_api_count": 0, - "inherited_api_count": 29, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.runtime.callables": { - "uid": "a0000b03", - "id": "pyvdisk.vscript.runtime.callables", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "可调用对象与任务", - "en": "Callables and Tasks" - }, - "description": { - "zh": "可调用对象与任务:参数绑定、对定义作用域的闭包,以及 await 等待的任务句柄。\n", - "en": "Callables and tasks: parameter binding, closures over the defining scope and the task handle awaited by await.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 140, - "end_line": 176 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.261Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Task", - "description": { - "zh": "parallel 构造产出的确定性任务句柄。\n", - "en": "Deterministic task handle produced by the parallel construct.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Task" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Task#await_result", - "description": { - "zh": "返回任务结果,并重新抛出其错误。\n", - "en": "Return the task result, re-raising its error.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Task#await_result" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Function", - "description": { - "zh": "已声明函数的可调用包装,负责参数绑定。\n", - "en": "Callable wrapper around a declared function, binding parameters.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Function" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Function#__call__", - "description": { - "zh": "以新的子作用域调用函数。\n", - "en": "Invoke the function with a fresh child scope.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Function#__call__" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.LambdaFunction", - "description": { - "zh": "表达式体的 lambda 可调用对象。\n", - "en": "Expression-bodied lambda callable.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.LambdaFunction" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.runtime.core": { - "uid": "a0000b04", - "id": "pyvdisk.vscript.runtime.core", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "解释器核心", - "en": "Interpreter Core" - }, - "description": { - "zh": "解释器核心:构造与原生模块安装、带参数的顶层运行、原生模块调用的记账入口,以及语句块执行。\n", - "en": "Interpreter core: construction and native-module installation, top-level run with arguments, the journaling entry point native modules call, and statement-block execution.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 178, - "end_line": 223 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.262Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime", - "description": { - "zh": "解释器:策略、挂载、审计 Sink 与事务记账。\n", - "en": "The interpreter: policy, mounts, audit sink and transaction bookkeeping.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#stringify", - "description": { - "zh": "按 REPL 的方式渲染一个值。\n", - "en": "Renders one value the way the REPL prints it.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#stringify" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#run", - "description": { - "zh": "跑完一个程序并返回结果。\n", - "en": "Runs a program to completion and returns its result.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#run" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#journal", - "description": { - "zh": "解释器自身的记账入口,供原生模块调用。\n", - "en": "The interpreter's own journaling entry point, used by native modules.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#journal" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#transactions_open", - "description": { - "zh": "当前尚未结算的事务数。\n", - "en": "How many transactions are still open.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#transactions_open" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#exec_block", - "description": { - "zh": "在某个作用域中执行一个语句块。\n", - "en": "Executes one block of statements in a scope.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#exec_block" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.policy.budget", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "to_api": "rpc:pyvdisk.vscript.policy.Budget#tick", - "label": { - "zh": "计入预算", - "en": "charges budget" - }, - "cross_tree": false - }, - { - "kind": "event", - "to": "pyvdisk.vscript.audit.sinks", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "to_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit", - "label": { - "zh": "产出审计记录", - "en": "emits audit records" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 3 - } - }, - "pyvdisk.vscript.runtime.env": { - "uid": "a0000b02", - "id": "pyvdisk.vscript.runtime.env", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "作用域与控制流", - "en": "Scope and Flow" - }, - "description": { - "zh": "作用域与控制流机制:Env 链,以及以异常实现 return、break、continue 的信号。\n", - "en": "Scope and control-flow machinery: the Env chain and the exception-based signals that implement return, break and continue.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 117, - "end_line": 139 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.262Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Env", - "description": { - "zh": "带父链与常量名集合的词法作用域。\n", - "en": "Lexical scope with a parent chain and a set of constant names.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Env" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Env#define", - "description": { - "zh": "在本层声明名字,可选常量。\n", - "en": "Declare a name in this scope, optionally constant.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Env#define" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Env#get", - "description": { - "zh": "沿作用域链解析名字。\n", - "en": "Resolve a name through the scope chain.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Env#get" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Env#set", - "description": { - "zh": "为已存在名字赋值,拒绝修改常量。\n", - "en": "Assign an existing name, rejecting constants.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Env#set" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.ReturnFlow", - "description": { - "zh": "携带返回值的控制流信号。\n", - "en": "Control-flow signal carrying a return value.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.ReturnFlow" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.BreakFlow", - "description": { - "zh": "解开循环的控制流信号。\n", - "en": "Control-flow signal unwinding a loop.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.BreakFlow" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.ContinueFlow", - "description": { - "zh": "继续循环的控制流信号。\n", - "en": "Control-flow signal continuing a loop.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.ContinueFlow" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 7, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.runtime.expressions": { - "uid": "a0000b07", - "id": "pyvdisk.vscript.runtime.expressions", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "表达式求值", - "en": "Expression Evaluation" - }, - "description": { - "zh": "表达式求值:字面量、运算符、调用、成员与下标访问,以及赋值语义。\n", - "en": "Expression evaluation: literals, operators, calls, member and index access, and assignment semantics.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 323, - "end_line": 389 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.262Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#eval", - "description": { - "zh": "求值单个表达式节点,含短路与可选成员语义。\n", - "en": "Evaluate one expression node, including short-circuit and optional-member semantics.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#eval" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#member", - "description": { - "zh": "解析对象或句柄上的成员访问。\n", - "en": "Resolve a member access on an object or handle.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#member" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#assign", - "description": { - "zh": "向名字、下标或成员目标赋值。\n", - "en": "Assign to a name, index or member target.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#assign" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#apply_assign", - "description": { - "zh": "应用复合或一元赋值运算符。\n", - "en": "Apply a compound or unary assignment operator.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#apply_assign" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.runtime.modules": { - "uid": "a0000b06", - "id": "pyvdisk.vscript.runtime.modules", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "模块加载", - "en": "Module Loading" - }, - "description": { - "zh": "模块加载:在内置原生模块与已配置模块根下解析 import 名称。\n", - "en": "Module loading: resolves import names against built-in native modules and configured module roots.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 304, - "end_line": 322 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.263Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#load_module", - "description": { - "zh": "在已配置的模块根下解析并执行 import。\n", - "en": "Resolve and execute an import against the configured module roots.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#load_module" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.stdlib.factory", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#load_module", - "to_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "label": { - "zh": "加载原生模块", - "en": "loads native module" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.runtime.statements": { - "uid": "a0000b05", - "id": "pyvdisk.vscript.runtime.statements", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "语句执行", - "en": "Statement Execution" - }, - "description": { - "zh": "语句执行:解释器中最大的分发表,覆盖语言的全部语句种类。\n", - "en": "Statement execution: the largest dispatch table of the interpreter, covering every statement kind of the language.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 224, - "end_line": 303 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.263Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.Runtime#execute", - "description": { - "zh": "分发单个语句节点:声明、控制流、循环、match、transaction、task 与 parallel。\n", - "en": "Dispatch one statement node: declarations, control flow, loops, match, transaction, task and parallel.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.Runtime#execute" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.runtime.callables", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#execute", - "to_api": "rpc:pyvdisk.vscript.runtime.Function#__call__", - "label": { - "zh": "调用与返回", - "en": "calls and returns" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 0 - } - }, - "pyvdisk.vscript.runtime.tx": { - "uid": "a0000b01", - "id": "pyvdisk.vscript.runtime.tx", - "parent": "pyvdisk.vscript.runtime", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "脚本事务", - "en": "Script Transaction" - }, - "description": { - "zh": "脚本事务支持:每个可撤销的 fs 变更在生效前落账,进程内回滚与崩溃恢复走同一个撤销解释器,超过 64 KiB 的快照正文落到事务目录。\n", - "en": "Script transaction support: every reversible fs change is journalled before it takes effect, in-process rollback and crash recovery run through the same undo interpreter, and snapshot bodies above 64 KiB spill to the transaction area.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/runtime.py", - "line": 11, - "end_line": 116 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.264Z", - "fingerprint": "2ddb2e01919be6c65aac4dd5d0babfa3f19bb115f24b6fa6da68c57b3b4756ef", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.TransactionContext", - "description": { - "zh": "收集单次脚本事务的撤销记录与落盘槽位。\n", - "en": "Collects one script transaction's undo records and its spill slots.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.TransactionContext" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.TransactionContext#journal", - "description": { - "zh": "在效果生效**之前**记入一条可撤销账,大正文落盘而不驻留内存。\n", - "en": "Journals one reversible effect BEFORE it is applied, spilling large bodies out of memory.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.TransactionContext#journal" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.TransactionContext#commit", - "description": { - "zh": "结算事务并清理其落盘快照。\n", - "en": "Settles the transaction and drops its spill files.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.TransactionContext#commit" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.TransactionContext#rollback", - "description": { - "zh": "按逆序通过共享撤销解释器回放账本。\n", - "en": "Replays the journal in reverse order through the shared undo interpreter.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.TransactionContext#rollback" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.runtime.recover_wal", - "description": { - "zh": "崩溃恢复入口:用同一个撤销解释器回放持久化 WAL,并清理遗留快照。\n", - "en": "Crash-recovery entry point: replays a persisted WAL through the same undo interpreter and drops orphaned spills.\n" - }, - "key": "rpc:pyvdisk.vscript.runtime.recover_wal" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.undo", - "from_api": "rpc:pyvdisk.vscript.runtime.TransactionContext#rollback", - "label": { - "zh": "重放撤销记录", - "en": "replays undo records" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.storage.wal.undo", - "from_api": "rpc:pyvdisk.vscript.runtime.recover_wal", - "label": { - "zh": "消费事务 WAL", - "en": "consumes the tx WAL" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 5, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 0 - } - }, - "pyvdisk.vscript.stdlib": { - "uid": "a0000319", - "id": "pyvdisk.vscript.stdlib", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "VScript 标准库", - "en": "VScript Standard Library" - }, - "description": { - "zh": "VScript 标准库:fs、vector、log、json 的能力受限原生模块,脚本只能通过 Handle 包装访问。\n", - "en": "VScript standard library: capability-confined native modules for fs, vector, log and json, exposed to scripts only through Handle wrappers.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/stdlib.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.264Z", - "fingerprint": "c8f6852ff21b7b08e89e6c158274eeaef3d0a02376ac5600831b15124942de6e", - "aggregate": { - "descendant_count": 3, - "own_api_count": 0, - "inherited_api_count": 9, - "dep_out": 0, - "dep_in": 0 - } - }, - "pyvdisk.vscript.stdlib.factory": { - "uid": "a0000b0a", - "id": "pyvdisk.vscript.stdlib.factory", - "parent": "pyvdisk.vscript.stdlib", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "标准库工厂", - "en": "Stdlib Factory" - }, - "description": { - "zh": "标准库工厂:文件系统、向量、日志与 json 原生函数,均受能力守卫与字节预算约束。每个会改动的 fs 动词在触碰存储之前先记入撤销账,事务失败时可回滚,而不留半成品写入。\n", - "en": "Stdlib factory: filesystem, vector, log and json native functions, all behind capability guards and byte budgets. Every mutating fs verb journals its undo record before it touches the store, so a failed transaction can be rolled back instead of leaving half-applied writes.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/stdlib.py", - "line": 46, - "end_line": 118 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.264Z", - "fingerprint": "c8f6852ff21b7b08e89e6c158274eeaef3d0a02376ac5600831b15124942de6e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.create_stdlib", - "description": { - "zh": "构建绑定到单个运行时的 fs、vector、log 与 json 原生模块。\n", - "en": "Build the fs, vector, log and json native modules bound to one runtime.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.create_stdlib" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.vscript.stdlib.guards", - "from_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "to_api": "rpc:pyvdisk.vscript.stdlib._cap", - "label": { - "zh": "使用守卫", - "en": "uses guards" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.vscript.stdlib.native", - "from_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "to_api": "rpc:pyvdisk.vscript.stdlib.NativeModule", - "label": { - "zh": "包装原生模块", - "en": "wraps native modules" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 1, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 1 - } - }, - "pyvdisk.vscript.stdlib.guards": { - "uid": "a0000b09", - "id": "pyvdisk.vscript.stdlib.guards", - "parent": "pyvdisk.vscript.stdlib", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "原生守卫", - "en": "Native Guards" - }, - "description": { - "zh": "每个原生函数触及资源前调用的两个守卫:类型与权限检查,以及路径范围限定。\n", - "en": "The two guard helpers every native function calls before touching a resource: kind and permission checks, and path scoping.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/stdlib.py", - "line": 28, - "end_line": 44 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.265Z", - "fingerprint": "c8f6852ff21b7b08e89e6c158274eeaef3d0a02376ac5600831b15124942de6e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib._cap", - "description": { - "zh": "要求句柄为预期类型并持有指定权限。\n", - "en": "Require a handle to be of an expected kind and to hold the given permissions.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib._cap" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib._vpath", - "description": { - "zh": "在能力根内归一化并限定脚本路径。\n", - "en": "Normalize and scope a script path inside a capability root.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib._vpath" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 2, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.stdlib.native": { - "uid": "a0000b08", - "id": "pyvdisk.vscript.stdlib.native", - "parent": "pyvdisk.vscript.stdlib", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "原生模块", - "en": "Native Modules" - }, - "description": { - "zh": "原生模块基础设施与 Handle 包装:让原生资源留在能力检查之后,而非暴露裸 Python 对象。\n", - "en": "Native module plumbing and the Handle wrapper that keeps native resources behind capability checks rather than raw Python objects.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/stdlib.py", - "line": 9, - "end_line": 26 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.265Z", - "fingerprint": "c8f6852ff21b7b08e89e6c158274eeaef3d0a02376ac5600831b15124942de6e", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.NativeFunction", - "description": { - "zh": "暴露给脚本的原生函数包装。\n", - "en": "Native function wrapper exposed to scripts.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.NativeFunction" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.NativeModule", - "description": { - "zh": "组成单个可导入模块的具名原生成员集合。\n", - "en": "Named collection of native members forming one importable module.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.NativeModule" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.NativeModule#member", - "description": { - "zh": "解析原生模块的成员。\n", - "en": "Resolve a member of the native module.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.NativeModule#member" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.Handle", - "description": { - "zh": "对已授予能力的不透明脚本可见包装。\n", - "en": "Opaque script-visible wrapper around a granted capability.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.Handle" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.Handle#kind", - "description": { - "zh": "报告句柄所指资源的类型。\n", - "en": "Report the kind of resource the handle refers to.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.Handle#kind" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.stdlib.Handle#name", - "description": { - "zh": "报告脚本可见的句柄名称。\n", - "en": "Report the handle name visible to the script.\n" - }, - "key": "rpc:pyvdisk.vscript.stdlib.Handle#name" - } - ], - "deps": [ - { - "kind": "reference", - "to": "pyvdisk.vscript.policy.capability", - "from_api": "rpc:pyvdisk.vscript.stdlib.Handle", - "to_api": "rpc:pyvdisk.vscript.policy.Capability", - "label": { - "zh": "包装能力", - "en": "wraps capability" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 6, - "inherited_api_count": 0, - "dep_out": 1, - "dep_in": 1 - } - }, - "pyvdisk.vscript.triggers": { - "uid": "a000031b", - "id": "pyvdisk.vscript.triggers", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "name": { - "zh": "触发器", - "en": "Trigger Registry" - }, - "description": { - "zh": "VScript 调度:持久触发器注册表,带事件去重与轮询守护进程执行注册脚本。\n", - "en": "VScript scheduling: durable trigger registry with emitted-event dedup and a polling daemon that runs registered scripts.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/triggers.py" - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.265Z", - "fingerprint": "531549cadc018163544e7928ca49da1cef4f71bd76c32347aeb01fadee9d949f", - "aggregate": { - "descendant_count": 2, - "own_api_count": 0, - "inherited_api_count": 7, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.triggers.daemon": { - "uid": "a0000a0c", - "id": "pyvdisk.vscript.triggers.daemon", - "parent": "pyvdisk.vscript.triggers", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "调度守护进程", - "en": "Scheduler Daemon" - }, - "description": { - "zh": "轮询守护进程:每轮评估到期的文件与日志触发器并分发动作,按单调水位线排序事件,不再静默跳过到期事件。\n", - "en": "The polling daemon: evaluates due file and log triggers once per tick and dispatches their actions, ordering events by the monotonic watermark so no due event is silently skipped.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/triggers.py", - "line": 75, - "end_line": 108 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.266Z", - "fingerprint": "531549cadc018163544e7928ca49da1cef4f71bd76c32347aeb01fadee9d949f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.SchedulerDaemon", - "description": { - "zh": "把文件与日志事件转为处理调用的轮询守护进程。\n", - "en": "Polling daemon that turns file and log events into handler invocations.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "description": { - "zh": "对每条触发器轮询一次,并经检查点存储对已发事件去重。\n", - "en": "Poll each trigger once, deduplicating emitted events through the checkpoint store.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.SchedulerDaemon#run", - "description": { - "zh": "持续轮询直到 stop 事件被设置。\n", - "en": "Run the polling loop until the stop event is set.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#run" - } - ], - "deps": [ - { - "kind": "call", - "to": "pyvdisk.storage.checkpoint.triggers", - "from_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#mark_success", - "label": { - "zh": "事件去重", - "en": "dedups events" - }, - "cross_tree": false - }, - { - "kind": "call", - "to": "pyvdisk.vscript.triggers.registry", - "from_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "to_api": "rpc:pyvdisk.vscript.triggers.TriggerRegistry", - "label": { - "zh": "读取触发器", - "en": "reads triggers" - }, - "cross_tree": false - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 3, - "inherited_api_count": 0, - "dep_out": 2, - "dep_in": 1 - } - }, - "pyvdisk.vscript.triggers.registry": { - "uid": "a0000a0b", - "id": "pyvdisk.vscript.triggers.registry", - "parent": "pyvdisk.vscript.triggers", - "tree": "pyvdisk", - "depth": 4, - "name": { - "zh": "触发器注册表", - "en": "Trigger Registry" - }, - "description": { - "zh": "触发器的注册与列举。注册即校验输入(空文件 pattern 以前能注册成功、随后把轮询循环打挂),水位线比较改用单调事件序号,而不再拿随机 uuid 作文本比较。\n", - "en": "Trigger registration and listing. Registration validates its inputs immediately -- an empty file pattern used to register fine and then break the poll loop -- and the watermark comparison uses the monotonic event sequence instead of a random uuid compared as text.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/triggers.py", - "line": 14, - "end_line": 73 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.266Z", - "fingerprint": "531549cadc018163544e7928ca49da1cef4f71bd76c32347aeb01fadee9d949f", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.Trigger", - "description": { - "zh": "一个已注册触发器:文件 glob 或日志流,加上其动作。\n", - "en": "One registered trigger: a file pattern or a log stream, plus its action.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.Trigger" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.TriggerRegistry", - "description": { - "zh": "注册与列举触发器;空 pattern 或 stream 在注册处就被拒绝。\n", - "en": "Registers and lists triggers, rejecting an empty pattern or stream up front.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.TriggerRegistry" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.event_position", - "description": { - "zh": "事件的单调位置,优先使用序号。\n", - "en": "Monotonic position of an event, preferring its sequence number.\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.event_position" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.triggers.is_newer", - "description": { - "zh": "判断位置是否新于水位线(两者可解析为数字时按数字比)。\n", - "en": "Whether a position is newer than a watermark (numeric when both parse).\n" - }, - "key": "rpc:pyvdisk.vscript.triggers.is_newer" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 4, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 1 - } - }, - "pyvdisk.vscript.undo": { - "uid": "77079781", - "id": "pyvdisk.vscript.undo", - "parent": "pyvdisk.vscript", - "tree": "pyvdisk", - "depth": 3, - "tags": [ - "vscript", - "transaction", - "undo", - "durability" - ], - "name": { - "zh": "事务撤销记账", - "en": "Transaction Undo Bookkeeping" - }, - "description": { - "zh": "VScript 事务的撤销记账:每个可撤销的 fs 变更在生效之前就落账,进程内回滚与崩溃恢复共用同一个解释器;超过 64 KiB 的快照正文落到 /.system/tx,不再整份驻留内存。\n", - "en": "Undo bookkeeping for VScript transactions: every reversible fs change is journalled before it takes effect, the in-process rollback and the crash-recovery pass share one interpreter, and snapshot bodies above 64 KiB spill to /.system/tx instead of staying in memory.\n" - }, - "source": [ - { - "path": "pyvdisk/vscript/undo.py", - "line": 1, - "end_line": 210 - } - ], - "revision": "c3881eee5dced2b180cd3b383e5d848026224154", - "updated_at": "2026-09-24T09:58:38.210Z", - "fingerprint": "45715e912e2168183a77a42b313761b2973190999957980141f83dfda88223e2", - "apis": [ - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.normalize", - "description": { - "zh": "把一条撤销记录规范化,使进程内回滚与崩溃恢复两个解释器不会漂移。\n", - "en": "Canonicalises one undo record so the in-process and the crash-recovery interpreters cannot drift apart.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.normalize" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.spill_path", - "description": { - "zh": "解析存放某个已落盘快照正文的磁盘槽位。\n", - "en": "Resolves the on-disk slot that holds one spilled snapshot body.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.spill_path" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.store_body", - "description": { - "zh": "保存快照正文,超过阈值时落到事务目录而不是留在内存。\n", - "en": "Stores a snapshot body, spilling to the transaction area once it exceeds the threshold.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.store_body" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.load_body", - "description": { - "zh": "读回快照正文,可能来自内存,也可能来自事务目录。\n", - "en": "Reads back a snapshot body, from memory or from the transaction area.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.load_body" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.snapshot_tree", - "description": { - "zh": "在递归删除登记逆操作之前,先为整棵子树拍快照。\n", - "en": "Captures a directory tree before a recursive removal journals reverse operations.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.snapshot_tree" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.spill_conflict", - "description": { - "zh": "当快照位置本身落在待撤销操作的删除范围内时拒绝记账。\n", - "en": "Refuses a snapshot whose location would itself be removed by the operation it must undo.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.spill_conflict" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.apply_undo", - "description": { - "zh": "针对某个存储重放一条撤销记录。\n", - "en": "Replays one undo record against a store.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.apply_undo" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.discard_spill_area", - "description": { - "zh": "事务结算后清理遗留的落盘快照文件。\n", - "en": "Drops orphaned spill files after a transaction settles.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.discard_spill_area" - }, - { - "protocol": "rpc", - "path": "pyvdisk.vscript.undo.KINDS", - "description": { - "zh": "撤销解释器认识的全部操作种类。\n", - "en": "Every operation kind the undo interpreter understands.\n" - }, - "key": "rpc:pyvdisk.vscript.undo.KINDS" - } - ], - "aggregate": { - "descendant_count": 0, - "own_api_count": 9, - "inherited_api_count": 0, - "dep_out": 0, - "dep_in": 2 - } - } - }, - "api_index": { - "file:.github/workflows/ci.yml": "pyvdisk.delivery.ci", - "file:.github/workflows/ci.yml#no-dependencies": "pyvdisk.delivery.ci", - "file:.github/workflows/pylint.yml": "pyvdisk.delivery.lint", - "file:CHANGELOG.md": "pyvdisk.docs.changelog", - "file:docs/API_GOVERNANCE.md": "pyvdisk.docs.api-governance", - "file:docs/ARCHITECTURE.md": "pyvdisk.docs.architecture", - "file:docs/CONTRACTS.md": "pyvdisk.docs.contracts", - "file:docs/VSCRIPT_SPEC.md": "pyvdisk.docs.vscript-spec", - "file:examples/agent_tools.py:scripted_model": "pyvdisk.examples.agent-tools", - "file:examples/quickstart.py": "pyvdisk.examples.quickstart", - "file:MANIFEST.in": "pyvdisk.delivery.packaging", - "file:pyproject.toml": "pyvdisk.delivery.packaging", - "file:pyvdisk/__main__.py": "pyvdisk.cli.entry", - "file:pyvdisk/py.typed": "pyvdisk.delivery.packaging", - "file:README.md": "pyvdisk.docs.readme", - "file:tests/test_agent_sandbox.py": "pyvdisk.tests.agent-sandbox", - "file:tests/test_compat.py": "pyvdisk.tests.compat", - "file:tests/test_no_dependency_path.py": "pyvdisk.tests.no-dependency", - "rpc:pyvdisk.AgentSandbox": "pyvdisk.api", - "rpc:pyvdisk.CheckpointStore": "pyvdisk.api", - "rpc:pyvdisk.cli._add_cred_args": "pyvdisk.cli.format", - "rpc:pyvdisk.cli._human_size": "pyvdisk.cli.format", - "rpc:pyvdisk.cli._json_arg": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli._open_vfs": "pyvdisk.cli.open", - "rpc:pyvdisk.cli._parse_size": "pyvdisk.cli.format", - "rpc:pyvdisk.cli._type_str": "pyvdisk.cli.format", - "rpc:pyvdisk.cli.build_parser": "pyvdisk.cli.parser", - "rpc:pyvdisk.cli.cmd_append": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.cmd_cat": "pyvdisk.cli.dirs", - "rpc:pyvdisk.cli.cmd_chmod": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_chown": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_cp": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.cmd_create": "pyvdisk.cli.image", - "rpc:pyvdisk.cli.cmd_df": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_du": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_export": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.cmd_format": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_fsck": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_import": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.cmd_info": "pyvdisk.cli.image", - "rpc:pyvdisk.cli.cmd_label": "pyvdisk.cli.drive", - "rpc:pyvdisk.cli.cmd_ln": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_log_compact": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_create": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_emit": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_query": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_retention": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_stats": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_stream": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_log_tail": "pyvdisk.cli.log", - "rpc:pyvdisk.cli.cmd_ls": "pyvdisk.cli.image", - "rpc:pyvdisk.cli.cmd_mkdir": "pyvdisk.cli.dirs", - "rpc:pyvdisk.cli.cmd_mount": "pyvdisk.cli.inspect", - "rpc:pyvdisk.cli.cmd_mount_all": "pyvdisk.cli.drive", - "rpc:pyvdisk.cli.cmd_mv": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.cmd_resize": "pyvdisk.cli.admin", - "rpc:pyvdisk.cli.cmd_rm": "pyvdisk.cli.dirs", - "rpc:pyvdisk.cli.cmd_rmdir": "pyvdisk.cli.dirs", - "rpc:pyvdisk.cli.cmd_scan": "pyvdisk.cli.drive", - "rpc:pyvdisk.cli.cmd_stat": "pyvdisk.cli.inspect", - "rpc:pyvdisk.cli.cmd_status": "pyvdisk.cli.image", - "rpc:pyvdisk.cli.cmd_touch": "pyvdisk.cli.inspect", - "rpc:pyvdisk.cli.cmd_tree": "pyvdisk.cli.inspect", - "rpc:pyvdisk.cli.cmd_vec_collection": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_create": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_delete": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_get": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_list": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_search": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vec_upsert": "pyvdisk.cli.vector", - "rpc:pyvdisk.cli.cmd_vol_add": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_vol_create": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_vol_format": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_vol_remove": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_vol_resync": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_vol_status": "pyvdisk.cli.volume", - "rpc:pyvdisk.cli.cmd_write": "pyvdisk.cli.file-ops", - "rpc:pyvdisk.cli.main": "pyvdisk.cli.main", - "rpc:pyvdisk.compat": "pyvdisk.api", - "rpc:pyvdisk.compat.can_symlink": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.describe": "pyvdisk.platform.dispatch", - "rpc:pyvdisk.compat.fsync_dir": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.gid": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.gid_or": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.implementation": "pyvdisk.platform.dispatch", - "rpc:pyvdisk.compat.lock": "pyvdisk.platform.locking", - "rpc:pyvdisk.compat.pread": "pyvdisk.platform.positional", - "rpc:pyvdisk.compat.pwrite": "pyvdisk.platform.positional", - "rpc:pyvdisk.compat.uid": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.uid_or": "pyvdisk.platform.durability", - "rpc:pyvdisk.compat.unlock": "pyvdisk.platform.locking", - "rpc:pyvdisk.compat.use_implementation": "pyvdisk.platform.dispatch", - "rpc:pyvdisk.contracts.BlockDevice": "pyvdisk.contracts.storage", - "rpc:pyvdisk.contracts.BlockDevice#read_block": "pyvdisk.contracts.storage", - "rpc:pyvdisk.contracts.BlockDevice#write_block": "pyvdisk.contracts.storage", - "rpc:pyvdisk.contracts.Capability": "pyvdisk.contracts.capability", - "rpc:pyvdisk.contracts.CapabilityGrant": "pyvdisk.contracts.capability", - "rpc:pyvdisk.contracts.CapabilityGrant#allows": "pyvdisk.contracts.capability", - "rpc:pyvdisk.contracts.CapabilityGrant#require": "pyvdisk.contracts.capability", - "rpc:pyvdisk.contracts.CollectionStore": "pyvdisk.contracts.storage", - "rpc:pyvdisk.contracts.Durability": "pyvdisk.contracts.durability", - "rpc:pyvdisk.contracts.DurabilityMode": "pyvdisk.contracts.durability", - "rpc:pyvdisk.contracts.Event": "pyvdisk.contracts.events", - "rpc:pyvdisk.contracts.EventStore": "pyvdisk.contracts.events", - "rpc:pyvdisk.contracts.EventStore#append": "pyvdisk.contracts.events", - "rpc:pyvdisk.contracts.EventStore#read": "pyvdisk.contracts.events", - "rpc:pyvdisk.contracts.ExecutionContext": "pyvdisk.contracts.execution", - "rpc:pyvdisk.contracts.ExecutionContext#expired": "pyvdisk.contracts.execution", - "rpc:pyvdisk.contracts.ExecutionContext#require": "pyvdisk.contracts.execution", - "rpc:pyvdisk.contracts.ExecutionPlane#submit": "pyvdisk.contracts.plane", - "rpc:pyvdisk.contracts.NamespaceStore": "pyvdisk.contracts.storage", - "rpc:pyvdisk.contracts.RunHandle": "pyvdisk.contracts.runhandle", - "rpc:pyvdisk.contracts.RunHandle#cancel": "pyvdisk.contracts.runhandle", - "rpc:pyvdisk.contracts.RunHandle#complete": "pyvdisk.contracts.runhandle", - "rpc:pyvdisk.contracts.RunHandle#fail": "pyvdisk.contracts.runhandle", - "rpc:pyvdisk.contracts.RunHandle#wait": "pyvdisk.contracts.runhandle", - "rpc:pyvdisk.DataDisk": "pyvdisk.api", - "rpc:pyvdisk.disk._pread_all": "pyvdisk.storage.block.io", - "rpc:pyvdisk.disk._pwrite_all": "pyvdisk.storage.block.io", - "rpc:pyvdisk.disk.VirtualDisk": "pyvdisk.storage.block.image", - "rpc:pyvdisk.disk.VirtualDisk#close": "pyvdisk.storage.block.image", - "rpc:pyvdisk.disk.VirtualDisk#create": "pyvdisk.storage.block.image", - "rpc:pyvdisk.disk.VirtualDisk#flush": "pyvdisk.storage.block.image", - "rpc:pyvdisk.disk.VirtualDisk#open": "pyvdisk.storage.block.image", - "rpc:pyvdisk.disk.VirtualDisk#read_block": "pyvdisk.storage.block.access", - "rpc:pyvdisk.disk.VirtualDisk#read_bytes": "pyvdisk.storage.block.access", - "rpc:pyvdisk.disk.VirtualDisk#truncate_bytes": "pyvdisk.storage.block.access", - "rpc:pyvdisk.disk.VirtualDisk#write_block": "pyvdisk.storage.block.access", - "rpc:pyvdisk.disk.VirtualDisk#write_bytes": "pyvdisk.storage.block.access", - "rpc:pyvdisk.driver.AssembledVolume": "pyvdisk.storage.driver.assembled", - "rpc:pyvdisk.driver.AssembledVolume#complete": "pyvdisk.storage.driver.assembled", - "rpc:pyvdisk.driver.AssembledVolume#found": "pyvdisk.storage.driver.assembled", - "rpc:pyvdisk.driver.AssembledVolume#needed": "pyvdisk.storage.driver.assembled", - "rpc:pyvdisk.driver.AssembledVolume#ordered_paths": "pyvdisk.storage.driver.assembled", - "rpc:pyvdisk.driver.DiskManager": "pyvdisk.storage.driver.manager", - "rpc:pyvdisk.driver.DiskManager#__init__": "pyvdisk.storage.driver.manager", - "rpc:pyvdisk.driver.DiskManager#_mount_log": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#_mount_single": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#_mount_vector": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#_mount_volume": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#_unique_label": "pyvdisk.storage.driver.manager", - "rpc:pyvdisk.driver.DiskManager#assemble": "pyvdisk.storage.driver.manager", - "rpc:pyvdisk.driver.DiskManager#get": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#hotplug": "pyvdisk.storage.driver.lifecycle", - "rpc:pyvdisk.driver.DiskManager#labels": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#mount_all": "pyvdisk.storage.driver.mounting", - "rpc:pyvdisk.driver.DiskManager#scan": "pyvdisk.storage.driver.manager", - "rpc:pyvdisk.driver.DiskManager#summary": "pyvdisk.storage.driver.lifecycle", - "rpc:pyvdisk.driver.DiskManager#unmount": "pyvdisk.storage.driver.lifecycle", - "rpc:pyvdisk.driver.DiskManager#unmount_all": "pyvdisk.storage.driver.lifecycle", - "rpc:pyvdisk.driver.MountedFS": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.driver.MountedFS#__enter__": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.driver.MountedFS#__exit__": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.driver.MountedLog": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.driver.MountedLog#close": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.driver.MountedVector": "pyvdisk.storage.driver.mounts", - "rpc:pyvdisk.DurableQueue": "pyvdisk.api", - "rpc:pyvdisk.execution.ExecutionService": "pyvdisk.execution.service.setup", - "rpc:pyvdisk.execution.ExecutionService#_call": "pyvdisk.execution.service.invoke", - "rpc:pyvdisk.execution.ExecutionService#_execute": "pyvdisk.execution.service.invoke", - "rpc:pyvdisk.execution.ExecutionService#_scoped_view": "pyvdisk.execution.service.invoke", - "rpc:pyvdisk.execution.ExecutionService#_script": "pyvdisk.execution.service.invoke", - "rpc:pyvdisk.execution.ExecutionService#cancel": "pyvdisk.execution.service.submit", - "rpc:pyvdisk.execution.ExecutionService#enqueue_async": "pyvdisk.execution.service.setup", - "rpc:pyvdisk.execution.ExecutionService#enqueue_operation": "pyvdisk.execution.service.queue", - "rpc:pyvdisk.execution.ExecutionService#poll_once": "pyvdisk.execution.service.queue", - "rpc:pyvdisk.execution.ExecutionService#run": "pyvdisk.execution.service.submit", - "rpc:pyvdisk.execution.ExecutionService#run_next": "pyvdisk.execution.service.queue", - "rpc:pyvdisk.execution.ExecutionService#start_workers": "pyvdisk.execution.service.setup", - "rpc:pyvdisk.execution.ExecutionService#stop_workers": "pyvdisk.execution.service.setup", - "rpc:pyvdisk.execution.ExecutionService#submit": "pyvdisk.execution.service.submit", - "rpc:pyvdisk.execution.ExecutionService#worker_count": "pyvdisk.execution.service.setup", - "rpc:pyvdisk.ExecutionService": "pyvdisk.api", - "rpc:pyvdisk.FlatIndex": "pyvdisk.api", - "rpc:pyvdisk.fs._ceil_div": "pyvdisk.storage.fs.names", - "rpc:pyvdisk.fs._decode_name": "pyvdisk.storage.fs.names", - "rpc:pyvdisk.fs._disk_lock_key": "pyvdisk.storage.fs.locking", - "rpc:pyvdisk.fs._encode_name": "pyvdisk.storage.fs.names", - "rpc:pyvdisk.fs._read_locked": "pyvdisk.storage.fs.locking", - "rpc:pyvdisk.fs._shared_lock_for": "pyvdisk.storage.fs.locking", - "rpc:pyvdisk.fs._write_locked": "pyvdisk.storage.fs.locking", - "rpc:pyvdisk.fs.DIRECT_COUNT": "pyvdisk.storage.fs.layout", - "rpc:pyvdisk.fs.FS": "pyvdisk.storage.fs.mount", - "rpc:pyvdisk.fs.FS#_bitmap_alloc": "pyvdisk.storage.fs.bitmap", - "rpc:pyvdisk.fs.FS#_bitmap_get": "pyvdisk.storage.fs.bitmap", - "rpc:pyvdisk.fs.FS#_bitmap_set": "pyvdisk.storage.fs.bitmap", - "rpc:pyvdisk.fs.FS#_clear_block_ptr": "pyvdisk.storage.fs.truncate", - "rpc:pyvdisk.fs.FS#_create_node": "pyvdisk.storage.fs.create", - "rpc:pyvdisk.fs.FS#_dir_entries_block": "pyvdisk.storage.fs.dir", - "rpc:pyvdisk.fs.FS#_ensure_block_ptr": "pyvdisk.storage.fs.pointers", - "rpc:pyvdisk.fs.FS#_find_free_dir_slot": "pyvdisk.storage.fs.dir-mutate", - "rpc:pyvdisk.fs.FS#_free_all_blocks": "pyvdisk.storage.fs.pointers", - "rpc:pyvdisk.fs.FS#_fsck_impl": "pyvdisk.storage.fs.fsck", - "rpc:pyvdisk.fs.FS#_get_block_ptr": "pyvdisk.storage.fs.pointers", - "rpc:pyvdisk.fs.FS#_inode_offset": "pyvdisk.storage.fs.inode-io", - "rpc:pyvdisk.fs.FS#_maybe_free_indirect": "pyvdisk.storage.fs.truncate", - "rpc:pyvdisk.fs.FS#_read_ptr": "pyvdisk.storage.fs.pointers", - "rpc:pyvdisk.fs.FS#_remove_node": "pyvdisk.storage.fs.mutate", - "rpc:pyvdisk.fs.FS#_split_path": "pyvdisk.storage.fs.paths", - "rpc:pyvdisk.fs.FS#_write_ptr": "pyvdisk.storage.fs.pointers", - "rpc:pyvdisk.fs.FS#access": "pyvdisk.storage.fs.attrs", - "rpc:pyvdisk.fs.FS#alloc_block": "pyvdisk.storage.fs.block-alloc", - "rpc:pyvdisk.fs.FS#alloc_inode": "pyvdisk.storage.fs.inode-io", - "rpc:pyvdisk.fs.FS#append_path": "pyvdisk.storage.fs.readwrite", - "rpc:pyvdisk.fs.FS#chmod": "pyvdisk.storage.fs.attrs", - "rpc:pyvdisk.fs.FS#chown": "pyvdisk.storage.fs.attrs", - "rpc:pyvdisk.fs.FS#count_free_blocks": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#count_free_inodes": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#create": "pyvdisk.storage.fs.create", - "rpc:pyvdisk.fs.FS#dir_add_entry": "pyvdisk.storage.fs.dir-mutate", - "rpc:pyvdisk.fs.FS#dir_list": "pyvdisk.storage.fs.dir", - "rpc:pyvdisk.fs.FS#dir_lookup": "pyvdisk.storage.fs.dir", - "rpc:pyvdisk.fs.FS#dir_remove_entry": "pyvdisk.storage.fs.dir-mutate", - "rpc:pyvdisk.fs.FS#flush_superblock": "pyvdisk.storage.fs.mount", - "rpc:pyvdisk.fs.FS#free_block": "pyvdisk.storage.fs.block-alloc", - "rpc:pyvdisk.fs.FS#free_inode": "pyvdisk.storage.fs.inode-io", - "rpc:pyvdisk.fs.FS#fsck": "pyvdisk.storage.fs.fsck", - "rpc:pyvdisk.fs.FS#link": "pyvdisk.storage.fs.attrs", - "rpc:pyvdisk.fs.FS#lstat_path": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#mkdir": "pyvdisk.storage.fs.create", - "rpc:pyvdisk.fs.FS#mount": "pyvdisk.storage.fs.mount", - "rpc:pyvdisk.fs.FS#read_file": "pyvdisk.storage.fs.readwrite", - "rpc:pyvdisk.fs.FS#read_inode": "pyvdisk.storage.fs.inode-io", - "rpc:pyvdisk.fs.FS#readlink": "pyvdisk.storage.fs.create", - "rpc:pyvdisk.fs.FS#rename": "pyvdisk.storage.fs.mutate", - "rpc:pyvdisk.fs.FS#resolve": "pyvdisk.storage.fs.paths", - "rpc:pyvdisk.fs.FS#resolve_parent": "pyvdisk.storage.fs.paths", - "rpc:pyvdisk.fs.FS#rmdir": "pyvdisk.storage.fs.mutate", - "rpc:pyvdisk.fs.FS#stat": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#stat_path": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#statfs": "pyvdisk.storage.fs.query", - "rpc:pyvdisk.fs.FS#symlink": "pyvdisk.storage.fs.create", - "rpc:pyvdisk.fs.FS#truncate": "pyvdisk.storage.fs.truncate", - "rpc:pyvdisk.fs.FS#unlink": "pyvdisk.storage.fs.mutate", - "rpc:pyvdisk.fs.FS#utime": "pyvdisk.storage.fs.attrs", - "rpc:pyvdisk.fs.FS#write_file": "pyvdisk.storage.fs.readwrite", - "rpc:pyvdisk.fs.FS#write_inode": "pyvdisk.storage.fs.inode-io", - "rpc:pyvdisk.fs.FS#write_path": "pyvdisk.storage.fs.readwrite", - "rpc:pyvdisk.fs.FSError": "pyvdisk.storage.fs.names", - "rpc:pyvdisk.fs.grow": "pyvdisk.storage.fs.grow", - "rpc:pyvdisk.fs.Inode": "pyvdisk.storage.fs.inode", - "rpc:pyvdisk.fs.INODE_SIZE": "pyvdisk.storage.fs.layout", - "rpc:pyvdisk.fs.Inode#empty": "pyvdisk.storage.fs.inode", - "rpc:pyvdisk.fs.Inode#from_bytes": "pyvdisk.storage.fs.inode", - "rpc:pyvdisk.fs.Inode#to_bytes": "pyvdisk.storage.fs.inode", - "rpc:pyvdisk.fs.MAGIC": "pyvdisk.storage.fs.layout", - "rpc:pyvdisk.fs.MAX_FILE_SIZE": "pyvdisk.storage.fs.layout", - "rpc:pyvdisk.fs.mkfs": "pyvdisk.storage.fs.mkfs", - "rpc:pyvdisk.fs.Stat": "pyvdisk.storage.fs.stat", - "rpc:pyvdisk.fs.Stat#is_dir": "pyvdisk.storage.fs.stat", - "rpc:pyvdisk.fs.Stat#is_file": "pyvdisk.storage.fs.stat", - "rpc:pyvdisk.fs.Stat#is_symlink": "pyvdisk.storage.fs.stat", - "rpc:pyvdisk.fs.SuperBlock": "pyvdisk.storage.fs.superblock", - "rpc:pyvdisk.fs.SuperBlock#from_bytes": "pyvdisk.storage.fs.superblock", - "rpc:pyvdisk.fs.SuperBlock#to_bytes": "pyvdisk.storage.fs.superblock", - "rpc:pyvdisk.fs.VERSION": "pyvdisk.storage.fs.layout", - "rpc:pyvdisk.fuse_mount._build_fuse_class": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._have_fuse": "pyvdisk.storage.fuse.meta", - "rpc:pyvdisk.fuse_mount._VFuseOperations": "pyvdisk.storage.fuse.meta", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_chmod": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_create": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr": "pyvdisk.storage.fuse.meta", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_mkdir": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_open": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_read": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_readdir": "pyvdisk.storage.fuse.meta", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_readlink": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_release": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_rename": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_rmdir": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_symlink": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_truncate": "pyvdisk.storage.fuse.handlers", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_unlink": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount._VFuseOperations#_write": "pyvdisk.storage.fuse.data", - "rpc:pyvdisk.fuse_mount.mount": "pyvdisk.storage.fuse.mount", - "rpc:pyvdisk.fuse_mount.mount_in_thread": "pyvdisk.storage.fuse.mount", - "rpc:pyvdisk.identity.DISK_ID_TRAILER_SIZE": "pyvdisk.storage.identity.format", - "rpc:pyvdisk.identity.DiskIdentity": "pyvdisk.storage.identity.model", - "rpc:pyvdisk.identity.DiskIdentity#is_complete_member": "pyvdisk.storage.identity.model", - "rpc:pyvdisk.identity.DiskIdentity#is_single": "pyvdisk.storage.identity.model", - "rpc:pyvdisk.identity.DiskIdentity#short": "pyvdisk.storage.identity.model", - "rpc:pyvdisk.identity.IdentityError": "pyvdisk.storage.identity.format", - "rpc:pyvdisk.identity.make_trailer": "pyvdisk.storage.identity.trailer", - "rpc:pyvdisk.identity.new_disk_uuid": "pyvdisk.storage.identity.probe", - "rpc:pyvdisk.identity.parse_trailer": "pyvdisk.storage.identity.trailer", - "rpc:pyvdisk.identity.probe_disk": "pyvdisk.storage.identity.probe", - "rpc:pyvdisk.identity.validate_disk_path": "pyvdisk.storage.identity.format", - "rpc:pyvdisk.identity.write_identity_to_block0": "pyvdisk.storage.identity.probe", - "rpc:pyvdisk.infrastructure.capabilities._inside": "pyvdisk.governance.namespace", - "rpc:pyvdisk.infrastructure.capabilities._path": "pyvdisk.governance.namespace", - "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace": "pyvdisk.governance.namespace", - "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_call": "pyvdisk.governance.namespace", - "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check": "pyvdisk.governance.namespace", - "rpc:pyvdisk.infrastructure.capabilities.scoped": "pyvdisk.governance.scoped", - "rpc:pyvdisk.infrastructure.capabilities.ScopedCheckpointNamespace": "pyvdisk.governance.scoped", - "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk": "pyvdisk.governance.scoped", - "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__enter__": "pyvdisk.governance.scoped", - "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk#__exit__": "pyvdisk.governance.scoped", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#_check_file": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#exists": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#fsck": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#listdir": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#read_file": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#rmtree": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#write_file": "pyvdisk.governance.files", - "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#append": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#enforce_retention": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#_scope": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#create_collection": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#search": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#upsert": "pyvdisk.governance.data", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore": "pyvdisk.storage.checkpoint.open", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#__init__": "pyvdisk.storage.checkpoint.open", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#_load": "pyvdisk.storage.checkpoint.io", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_host": "pyvdisk.storage.checkpoint.open", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#from_vfs": "pyvdisk.storage.checkpoint.open", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#get": "pyvdisk.storage.checkpoint.io", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#last_event": "pyvdisk.storage.checkpoint.triggers", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked": "pyvdisk.storage.checkpoint.open", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#mark_success": "pyvdisk.storage.checkpoint.triggers", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save": "pyvdisk.storage.checkpoint.io", - "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#set": "pyvdisk.storage.checkpoint.io", - "rpc:pyvdisk.infrastructure.disk._dec": "pyvdisk.storage.datadisk.codec", - "rpc:pyvdisk.infrastructure.disk._enc": "pyvdisk.storage.datadisk.codec", - "rpc:pyvdisk.infrastructure.disk._json": "pyvdisk.storage.datadisk.codec", - "rpc:pyvdisk.infrastructure.disk._Missing": "pyvdisk.storage.datadisk.codec", - "rpc:pyvdisk.infrastructure.disk._snapshot_dir": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.DataDisk": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#_append_metadata_wal": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#_atomic_json": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#_recover_transactions": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#close": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#create": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#get_metadata": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#manifest": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#mount": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#mounted": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#recovery_report": "pyvdisk.storage.datadisk.core", - "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#set_metadata": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDisk#transaction": "pyvdisk.storage.datadisk.api", - "rpc:pyvdisk.infrastructure.disk.DataDiskError": "pyvdisk.storage.datadisk.codec", - "rpc:pyvdisk.infrastructure.disk.FileNamespace": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#append_file": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#makedirs": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#remove": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#rename": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#rmtree": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.FileNamespace#write_file": "pyvdisk.storage.datadisk.namespace", - "rpc:pyvdisk.infrastructure.disk.LogNamespace": "pyvdisk.storage.datadisk.services", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#__enter__": "pyvdisk.storage.datadisk.tx-lifecycle", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#__exit__": "pyvdisk.storage.datadisk.tx-lifecycle", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#abort": "pyvdisk.storage.datadisk.tx-lifecycle", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit": "pyvdisk.storage.datadisk.tx-lifecycle", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#delete": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#enlist": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#intent": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#set": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.TransactionParticipant": "pyvdisk.storage.datadisk.tx", - "rpc:pyvdisk.infrastructure.disk.VectorNamespace": "pyvdisk.storage.datadisk.services", - "rpc:pyvdisk.infrastructure.operations._clear_callables": "pyvdisk.execution.operations.callables", - "rpc:pyvdisk.infrastructure.operations._describe_callable": "pyvdisk.execution.operations.describe", - "rpc:pyvdisk.infrastructure.operations._describe_payload": "pyvdisk.execution.operations.describe", - "rpc:pyvdisk.infrastructure.operations._describe_vscript": "pyvdisk.execution.operations.describe", - "rpc:pyvdisk.infrastructure.operations.describe_operation": "pyvdisk.execution.operations.describe", - "rpc:pyvdisk.infrastructure.operations.OperationError": "pyvdisk.execution.operations.errors", - "rpc:pyvdisk.infrastructure.operations.OperationNotFound": "pyvdisk.execution.operations.errors", - "rpc:pyvdisk.infrastructure.operations.OperationRecord": "pyvdisk.execution.operations.record", - "rpc:pyvdisk.infrastructure.operations.OperationRecord#from_json": "pyvdisk.execution.operations.record", - "rpc:pyvdisk.infrastructure.operations.OperationRecord#to_json": "pyvdisk.execution.operations.record", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_raw_get": "pyvdisk.execution.operations.storage", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_raw_put": "pyvdisk.execution.operations.storage", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#_resolve_callable": "pyvdisk.execution.operations.storage", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#backend": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#forget": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#has": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#load": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#recover": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.OperationRegistry#save": "pyvdisk.execution.operations.registry", - "rpc:pyvdisk.infrastructure.operations.register_callable": "pyvdisk.execution.operations.callables", - "rpc:pyvdisk.infrastructure.operations.registered_callables": "pyvdisk.execution.operations.callables", - "rpc:pyvdisk.infrastructure.operations.RegisteredCallable": "pyvdisk.execution.operations.callables", - "rpc:pyvdisk.infrastructure.operations.UnserializableOperation": "pyvdisk.execution.operations.errors", - "rpc:pyvdisk.infrastructure.queue.DurableQueue": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#_backoff_seconds": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#_save": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#_stamp_next_attempt": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#_state": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#_task": "pyvdisk.execution.queue.store", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#cancel": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#complete": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#dead_letter": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#enqueue": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#fail": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#get": "pyvdisk.execution.queue.recovery", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#heartbeat": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#list": "pyvdisk.execution.queue.recovery", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#recover_stale": "pyvdisk.execution.queue.recovery", - "rpc:pyvdisk.infrastructure.queue.DurableQueue#retry": "pyvdisk.execution.queue.lifecycle", - "rpc:pyvdisk.infrastructure.queue.InvalidTaskState": "pyvdisk.execution.queue.errors", - "rpc:pyvdisk.infrastructure.queue.LeaseLost": "pyvdisk.execution.queue.errors", - "rpc:pyvdisk.infrastructure.queue.QueueError": "pyvdisk.execution.queue.errors", - "rpc:pyvdisk.infrastructure.queue.QueueTask": "pyvdisk.execution.queue.task", - "rpc:pyvdisk.infrastructure.queue.QueueTask#from_dict": "pyvdisk.execution.queue.task", - "rpc:pyvdisk.infrastructure.queue.TaskNotFound": "pyvdisk.execution.queue.errors", - "rpc:pyvdisk.infrastructure.run_state.RunRecord": "pyvdisk.execution.runstate.model", - "rpc:pyvdisk.infrastructure.run_state.RunRecord#__post_init__": "pyvdisk.execution.runstate.model", - "rpc:pyvdisk.infrastructure.run_state.RunStateConflict": "pyvdisk.execution.runstate.model", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#create": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#from_data_disk": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#get": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#list": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#recover_stale": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.run_state.RunStateStore#transition": "pyvdisk.execution.runstate.store", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog": "pyvdisk.storage.wal.journal", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#__init__": "pyvdisk.storage.wal.journal", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_append": "pyvdisk.storage.wal.journal", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_last_sequence": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#_read": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#abort": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#append": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#append_record": "pyvdisk.storage.wal.journal", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#begin": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#commit": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#prepare": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover": "pyvdisk.storage.wal.entries", - "rpc:pyvdisk.log_disk._json": "pyvdisk.storage.log.filter", - "rpc:pyvdisk.log_disk._match": "pyvdisk.storage.log.filter", - "rpc:pyvdisk.log_disk.LogDisk": "pyvdisk.storage.log.open", - "rpc:pyvdisk.log_disk.LogDisk#ack": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#append": "pyvdisk.storage.log.append", - "rpc:pyvdisk.log_disk.LogDisk#append_many": "pyvdisk.storage.log.append", - "rpc:pyvdisk.log_disk.LogDisk#close": "pyvdisk.storage.log.open", - "rpc:pyvdisk.log_disk.LogDisk#compact": "pyvdisk.storage.log.retention", - "rpc:pyvdisk.log_disk.LogDisk#count": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#create": "pyvdisk.storage.log.open", - "rpc:pyvdisk.log_disk.LogDisk#create_stream": "pyvdisk.storage.log.streams", - "rpc:pyvdisk.log_disk.LogDisk#cursor": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#drop_stream": "pyvdisk.storage.log.streams", - "rpc:pyvdisk.log_disk.LogDisk#enforce_retention": "pyvdisk.storage.log.retention", - "rpc:pyvdisk.log_disk.LogDisk#follow": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#list_streams": "pyvdisk.storage.log.streams", - "rpc:pyvdisk.log_disk.LogDisk#mount": "pyvdisk.storage.log.open", - "rpc:pyvdisk.log_disk.LogDisk#query": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#replay": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDisk#stats": "pyvdisk.storage.log.retention", - "rpc:pyvdisk.log_disk.LogDisk#tail": "pyvdisk.storage.log.query", - "rpc:pyvdisk.log_disk.LogDiskError": "pyvdisk.storage.log.filter", - "rpc:pyvdisk.logging_core.bind_context": "pyvdisk.storage.logging.context", - "rpc:pyvdisk.logging_core.clear_context": "pyvdisk.storage.logging.context", - "rpc:pyvdisk.logging_core.get_logger": "pyvdisk.storage.logging.bridge", - "rpc:pyvdisk.logging_core.log_context": "pyvdisk.storage.logging.context", - "rpc:pyvdisk.logging_core.LogDiskSink": "pyvdisk.storage.logging.sinks", - "rpc:pyvdisk.logging_core.LogEvent": "pyvdisk.storage.logging.events", - "rpc:pyvdisk.logging_core.LogEvent#from_dict": "pyvdisk.storage.logging.events", - "rpc:pyvdisk.logging_core.LogEvent#to_dict": "pyvdisk.storage.logging.events", - "rpc:pyvdisk.logging_core.LogSink": "pyvdisk.storage.logging.sinks", - "rpc:pyvdisk.logging_core.MemorySink": "pyvdisk.storage.logging.sinks", - "rpc:pyvdisk.logging_core.normalize_level": "pyvdisk.storage.logging.events", - "rpc:pyvdisk.logging_core.StandardLoggingHandler": "pyvdisk.storage.logging.bridge", - "rpc:pyvdisk.logging_core.StreamSink": "pyvdisk.storage.logging.sinks", - "rpc:pyvdisk.logging_core.UnifiedLogger": "pyvdisk.storage.logging.logger", - "rpc:pyvdisk.logging_core.UnifiedLogger#bind": "pyvdisk.storage.logging.logger", - "rpc:pyvdisk.logging_core.UnifiedLogger#exception": "pyvdisk.storage.logging.logger", - "rpc:pyvdisk.logging_core.UnifiedLogger#log": "pyvdisk.storage.logging.logger", - "rpc:pyvdisk.logging_core.UnifiedLogger#with_tags": "pyvdisk.storage.logging.logger", - "rpc:pyvdisk.RunHandle": "pyvdisk.api", - "rpc:pyvdisk.rwlock.ReadCtx": "pyvdisk.storage.rwlock.ctx", - "rpc:pyvdisk.rwlock.RWLock": "pyvdisk.storage.rwlock.core", - "rpc:pyvdisk.rwlock.RWLock#acquire_read": "pyvdisk.storage.rwlock.core", - "rpc:pyvdisk.rwlock.RWLock#acquire_write": "pyvdisk.storage.rwlock.core", - "rpc:pyvdisk.rwlock.RWLock#read": "pyvdisk.storage.rwlock.ctx", - "rpc:pyvdisk.rwlock.RWLock#release_read": "pyvdisk.storage.rwlock.core", - "rpc:pyvdisk.rwlock.RWLock#release_write": "pyvdisk.storage.rwlock.core", - "rpc:pyvdisk.rwlock.RWLock#write": "pyvdisk.storage.rwlock.ctx", - "rpc:pyvdisk.rwlock.WriteCtx": "pyvdisk.storage.rwlock.ctx", - "rpc:pyvdisk.unified.DataDisk": "pyvdisk.compat.unified", - "rpc:pyvdisk.unified.MetadataTransaction": "pyvdisk.compat.unified", - "rpc:pyvdisk.vector_disk.VectorDisk": "pyvdisk.storage.vector.open", - "rpc:pyvdisk.vector_disk.VectorDisk#_load_index": "pyvdisk.storage.vector.search", - "rpc:pyvdisk.vector_disk.VectorDisk#_rebuild_index": "pyvdisk.storage.vector.search", - "rpc:pyvdisk.vector_disk.VectorDisk#close": "pyvdisk.storage.vector.open", - "rpc:pyvdisk.vector_disk.VectorDisk#count": "pyvdisk.storage.vector.records", - "rpc:pyvdisk.vector_disk.VectorDisk#create": "pyvdisk.storage.vector.open", - "rpc:pyvdisk.vector_disk.VectorDisk#create_collection": "pyvdisk.storage.vector.collections", - "rpc:pyvdisk.vector_disk.VectorDisk#delete": "pyvdisk.storage.vector.records", - "rpc:pyvdisk.vector_disk.VectorDisk#drop_collection": "pyvdisk.storage.vector.collections", - "rpc:pyvdisk.vector_disk.VectorDisk#get": "pyvdisk.storage.vector.records", - "rpc:pyvdisk.vector_disk.VectorDisk#list_collections": "pyvdisk.storage.vector.collections", - "rpc:pyvdisk.vector_disk.VectorDisk#mount": "pyvdisk.storage.vector.open", - "rpc:pyvdisk.vector_disk.VectorDisk#search": "pyvdisk.storage.vector.search", - "rpc:pyvdisk.vector_disk.VectorDisk#upsert": "pyvdisk.storage.vector.records", - "rpc:pyvdisk.vector_disk.VectorDisk#upsert_many": "pyvdisk.storage.vector.records", - "rpc:pyvdisk.vector_disk.VectorDiskError": "pyvdisk.storage.vector.open", - "rpc:pyvdisk.VectorDisk": "pyvdisk.api", - "rpc:pyvdisk.VFS": "pyvdisk.api", - "rpc:pyvdisk.vfs.VFile": "pyvdisk.storage.vfs.vfile", - "rpc:pyvdisk.vfs.VFile#__enter__": "pyvdisk.storage.vfs.vfile-ctx", - "rpc:pyvdisk.vfs.VFile#__exit__": "pyvdisk.storage.vfs.vfile-ctx", - "rpc:pyvdisk.vfs.VFile#__init__": "pyvdisk.storage.vfs.vfile", - "rpc:pyvdisk.vfs.VFile#__iter__": "pyvdisk.storage.vfs.vfile-ctx", - "rpc:pyvdisk.vfs.VFile#close": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#flush": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#ino": "pyvdisk.storage.vfs.vfile", - "rpc:pyvdisk.vfs.VFile#read": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#readall": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#seek": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#tell": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#truncate": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFile#write": "pyvdisk.storage.vfs.vfile-io", - "rpc:pyvdisk.vfs.VFS": "pyvdisk.storage.vfs.open", - "rpc:pyvdisk.vfs.VFS#__enter__": "pyvdisk.storage.vfs.lifetime", - "rpc:pyvdisk.vfs.VFS#__exit__": "pyvdisk.storage.vfs.lifetime", - "rpc:pyvdisk.vfs.VFS#__init__": "pyvdisk.storage.vfs.open", - "rpc:pyvdisk.vfs.VFS#_check": "pyvdisk.storage.vfs.permissions", - "rpc:pyvdisk.vfs.VFS#_check_parent": "pyvdisk.storage.vfs.permissions", - "rpc:pyvdisk.vfs.VFS#_check_traverse": "pyvdisk.storage.vfs.permissions", - "rpc:pyvdisk.vfs.VFS#_fs_or_raise": "pyvdisk.storage.vfs.permissions", - "rpc:pyvdisk.vfs.VFS#_open_disk_or_volume": "pyvdisk.storage.vfs.open", - "rpc:pyvdisk.vfs.VFS#_perm_enabled": "pyvdisk.storage.vfs.permissions", - "rpc:pyvdisk.vfs.VFS#access": "pyvdisk.storage.vfs.attrs", - "rpc:pyvdisk.vfs.VFS#append_file": "pyvdisk.storage.vfs.files", - "rpc:pyvdisk.vfs.VFS#chmod": "pyvdisk.storage.vfs.attrs", - "rpc:pyvdisk.vfs.VFS#chown": "pyvdisk.storage.vfs.attrs", - "rpc:pyvdisk.vfs.VFS#close": "pyvdisk.storage.vfs.lifetime", - "rpc:pyvdisk.vfs.VFS#create": "pyvdisk.storage.vfs.create", - "rpc:pyvdisk.vfs.VFS#create_volume": "pyvdisk.storage.vfs.create", - "rpc:pyvdisk.vfs.VFS#df": "pyvdisk.storage.vfs.space", - "rpc:pyvdisk.vfs.VFS#du": "pyvdisk.storage.vfs.space", - "rpc:pyvdisk.vfs.VFS#exists": "pyvdisk.storage.vfs.query", - "rpc:pyvdisk.vfs.VFS#export_to_host": "pyvdisk.storage.vfs.hostio", - "rpc:pyvdisk.vfs.VFS#fsck": "pyvdisk.storage.vfs.space", - "rpc:pyvdisk.vfs.VFS#grow": "pyvdisk.storage.vfs.space", - "rpc:pyvdisk.vfs.VFS#import_host_file": "pyvdisk.storage.vfs.hostio", - "rpc:pyvdisk.vfs.VFS#import_host_tree": "pyvdisk.storage.vfs.hostio", - "rpc:pyvdisk.vfs.VFS#isdir": "pyvdisk.storage.vfs.query", - "rpc:pyvdisk.vfs.VFS#isfile": "pyvdisk.storage.vfs.query", - "rpc:pyvdisk.vfs.VFS#link": "pyvdisk.storage.vfs.stat", - "rpc:pyvdisk.vfs.VFS#listdir": "pyvdisk.storage.vfs.query", - "rpc:pyvdisk.vfs.VFS#listdir_with_stat": "pyvdisk.storage.vfs.query", - "rpc:pyvdisk.vfs.VFS#lstat": "pyvdisk.storage.vfs.stat", - "rpc:pyvdisk.vfs.VFS#makedirs": "pyvdisk.storage.vfs.dirs", - "rpc:pyvdisk.vfs.VFS#mkdir": "pyvdisk.storage.vfs.dirs", - "rpc:pyvdisk.vfs.VFS#mount": "pyvdisk.storage.vfs.lifetime", - "rpc:pyvdisk.vfs.VFS#open": "pyvdisk.storage.vfs.hostio", - "rpc:pyvdisk.vfs.VFS#read_file": "pyvdisk.storage.vfs.files", - "rpc:pyvdisk.vfs.VFS#readlink": "pyvdisk.storage.vfs.stat", - "rpc:pyvdisk.vfs.VFS#remove": "pyvdisk.storage.vfs.remove", - "rpc:pyvdisk.vfs.VFS#rename": "pyvdisk.storage.vfs.remove", - "rpc:pyvdisk.vfs.VFS#rmdir": "pyvdisk.storage.vfs.remove", - "rpc:pyvdisk.vfs.VFS#rmtree": "pyvdisk.storage.vfs.remove", - "rpc:pyvdisk.vfs.VFS#stat": "pyvdisk.storage.vfs.stat", - "rpc:pyvdisk.vfs.VFS#statfs": "pyvdisk.storage.vfs.space", - "rpc:pyvdisk.vfs.VFS#symlink": "pyvdisk.storage.vfs.stat", - "rpc:pyvdisk.vfs.VFS#truncate": "pyvdisk.storage.vfs.attrs", - "rpc:pyvdisk.vfs.VFS#utime": "pyvdisk.storage.vfs.attrs", - "rpc:pyvdisk.vfs.VFS#walk": "pyvdisk.storage.vfs.walk", - "rpc:pyvdisk.vfs.VFS#write_file": "pyvdisk.storage.vfs.files", - "rpc:pyvdisk.VirtualDisk": "pyvdisk.api", - "rpc:pyvdisk.volume.add_mirror": "pyvdisk.storage.volume.repair", - "rpc:pyvdisk.volume.create_volume": "pyvdisk.storage.volume.create", - "rpc:pyvdisk.volume.DiskMember": "pyvdisk.storage.volume.meta", - "rpc:pyvdisk.volume.open_volume": "pyvdisk.storage.volume.create", - "rpc:pyvdisk.volume.remove_mirror": "pyvdisk.storage.volume.repair", - "rpc:pyvdisk.volume.resync_mirror": "pyvdisk.storage.volume.repair", - "rpc:pyvdisk.volume.Volume": "pyvdisk.storage.volume.model", - "rpc:pyvdisk.volume.Volume#__init__": "pyvdisk.storage.volume.model", - "rpc:pyvdisk.volume.Volume#_read_concat": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_read_mirror": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_read_stripe": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_stripe_locate": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_verify_members": "pyvdisk.storage.volume.open", - "rpc:pyvdisk.volume.Volume#_write_concat": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_write_meta_to_all": "pyvdisk.storage.volume.bytes", - "rpc:pyvdisk.volume.Volume#_write_mirror": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#_write_stripe": "pyvdisk.storage.volume.layout", - "rpc:pyvdisk.volume.Volume#close": "pyvdisk.storage.volume.open", - "rpc:pyvdisk.volume.Volume#compute_geometry": "pyvdisk.storage.volume.model", - "rpc:pyvdisk.volume.Volume#flush": "pyvdisk.storage.volume.open", - "rpc:pyvdisk.volume.Volume#open": "pyvdisk.storage.volume.open", - "rpc:pyvdisk.volume.Volume#read_block": "pyvdisk.storage.volume.blocks", - "rpc:pyvdisk.volume.Volume#read_bytes": "pyvdisk.storage.volume.bytes", - "rpc:pyvdisk.volume.Volume#status": "pyvdisk.storage.volume.bytes", - "rpc:pyvdisk.volume.Volume#truncate_bytes": "pyvdisk.storage.volume.blocks", - "rpc:pyvdisk.volume.Volume#write_block": "pyvdisk.storage.volume.blocks", - "rpc:pyvdisk.volume.Volume#write_bytes": "pyvdisk.storage.volume.bytes", - "rpc:pyvdisk.volume.VolumeError": "pyvdisk.storage.volume.meta", - "rpc:pyvdisk.volume.VolumeMeta": "pyvdisk.storage.volume.meta", - "rpc:pyvdisk.volume.VolumeMeta#from_bytes": "pyvdisk.storage.volume.meta", - "rpc:pyvdisk.volume.VolumeMeta#to_bytes": "pyvdisk.storage.volume.meta", - "rpc:pyvdisk.vscript.ast.FunctionDecl": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.If": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Import": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Let": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Node": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Program": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Requirement": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.ast.Transaction": "pyvdisk.vscript.frontend.ast", - "rpc:pyvdisk.vscript.audit.AuditRecord": "pyvdisk.vscript.audit.record", - "rpc:pyvdisk.vscript.audit.AuditRecord#to_dict": "pyvdisk.vscript.audit.record", - "rpc:pyvdisk.vscript.audit.chain_rows": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#adopt": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#head": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#query": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#records": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#retain": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#verify": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.DataDiskAuditSink": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#emit": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#query": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#retain": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#verify": "pyvdisk.vscript.audit.sinks", - "rpc:pyvdisk.vscript.audit.monotonic_ms": "pyvdisk.vscript.audit.clock", - "rpc:pyvdisk.vscript.audit.new_run_id": "pyvdisk.vscript.audit.clock", - "rpc:pyvdisk.vscript.audit.policy_hash": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.audit.query_rows": "pyvdisk.vscript.audit.query", - "rpc:pyvdisk.vscript.audit.retain_rows": "pyvdisk.vscript.audit.query", - "rpc:pyvdisk.vscript.audit.row_hash": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.audit.script_hash": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.audit.stamp_row": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.audit.verify_chain": "pyvdisk.vscript.audit.hashing", - "rpc:pyvdisk.vscript.checkpoint.CheckpointStore": "pyvdisk.compat.vscript", - "rpc:pyvdisk.vscript.cli._mounts": "pyvdisk.vscript.cli.commands", - "rpc:pyvdisk.vscript.cli._pairs": "pyvdisk.vscript.cli.commands", - "rpc:pyvdisk.vscript.cli._repl_help": "pyvdisk.vscript.cli.repl", - "rpc:pyvdisk.vscript.cli._repl_source": "pyvdisk.vscript.cli.repl", - "rpc:pyvdisk.vscript.cli._repl_type": "pyvdisk.vscript.cli.repl", - "rpc:pyvdisk.vscript.cli.add_parser": "pyvdisk.vscript.cli.parser", - "rpc:pyvdisk.vscript.cli.command": "pyvdisk.vscript.cli.commands", - "rpc:pyvdisk.vscript.cli.repl": "pyvdisk.vscript.cli.repl", - "rpc:pyvdisk.vscript.cron.cron": "pyvdisk.vscript.cron", - "rpc:pyvdisk.vscript.cron.CronError": "pyvdisk.vscript.cron", - "rpc:pyvdisk.vscript.cron.CronExpression": "pyvdisk.vscript.cron", - "rpc:pyvdisk.vscript.cron.CronExpression#matches": "pyvdisk.vscript.cron", - "rpc:pyvdisk.vscript.cron.CronExpression#next_after": "pyvdisk.vscript.cron", - "rpc:pyvdisk.vscript.errors.CapabilityError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.CompileError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.Diagnostic": "pyvdisk.vscript.frontend.span", - "rpc:pyvdisk.vscript.errors.Diagnostic#format": "pyvdisk.vscript.frontend.span", - "rpc:pyvdisk.vscript.errors.LexError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.ParseError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.ResourceLimitError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.RuntimeError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.ScriptThrown": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.errors.SourceSpan": "pyvdisk.vscript.frontend.span", - "rpc:pyvdisk.vscript.errors.SourceSpan#__str__": "pyvdisk.vscript.frontend.span", - "rpc:pyvdisk.vscript.errors.VScriptError": "pyvdisk.vscript.frontend.errors", - "rpc:pyvdisk.vscript.host.create_host_module": "pyvdisk.vscript.host.module", - "rpc:pyvdisk.vscript.host.HostCapability": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.host.HostCapability#proxy": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.host.HostProxy": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.host.HostProxy#_check": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.host.HostProxy#read": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.host.HostProxy#write": "pyvdisk.vscript.host.guard", - "rpc:pyvdisk.vscript.lexer.lex": "pyvdisk.vscript.frontend.lexer", - "rpc:pyvdisk.vscript.lexer.Lexer": "pyvdisk.vscript.frontend.lexer", - "rpc:pyvdisk.vscript.lexer.Lexer#advance": "pyvdisk.vscript.frontend.lexer", - "rpc:pyvdisk.vscript.lexer.Lexer#peek": "pyvdisk.vscript.frontend.lexer", - "rpc:pyvdisk.vscript.lexer.Lexer#scan": "pyvdisk.vscript.frontend.lexer", - "rpc:pyvdisk.vscript.mounts.MountRegistry": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.mounts.MountRegistry#close": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.mounts.MountRegistry#get": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.mounts.MountRegistry#grant": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.mounts.MountRegistry#handles": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.mounts.MountRegistry#open": "pyvdisk.vscript.mounts", - "rpc:pyvdisk.vscript.parser.parse": "pyvdisk.vscript.frontend.parser", - "rpc:pyvdisk.vscript.parser.Parser": "pyvdisk.vscript.frontend.parser", - "rpc:pyvdisk.vscript.policy.Budget": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.policy.Budget#charge_output": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.policy.Budget#charge_read": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.policy.Budget#charge_write": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.policy.Budget#tick": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.policy.Capability": "pyvdisk.vscript.policy.capability", - "rpc:pyvdisk.vscript.policy.Capability#require": "pyvdisk.vscript.policy.capability", - "rpc:pyvdisk.vscript.policy.Policy": "pyvdisk.vscript.policy.budget", - "rpc:pyvdisk.vscript.runtime.BreakFlow": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.ContinueFlow": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Env": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Env#define": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Env#get": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Env#set": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Function": "pyvdisk.vscript.runtime.callables", - "rpc:pyvdisk.vscript.runtime.Function#__call__": "pyvdisk.vscript.runtime.callables", - "rpc:pyvdisk.vscript.runtime.LambdaFunction": "pyvdisk.vscript.runtime.callables", - "rpc:pyvdisk.vscript.runtime.recover_wal": "pyvdisk.vscript.runtime.tx", - "rpc:pyvdisk.vscript.runtime.ReturnFlow": "pyvdisk.vscript.runtime.env", - "rpc:pyvdisk.vscript.runtime.Runtime": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Runtime#apply_assign": "pyvdisk.vscript.runtime.expressions", - "rpc:pyvdisk.vscript.runtime.Runtime#assign": "pyvdisk.vscript.runtime.expressions", - "rpc:pyvdisk.vscript.runtime.Runtime#eval": "pyvdisk.vscript.runtime.expressions", - "rpc:pyvdisk.vscript.runtime.Runtime#exec_block": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Runtime#execute": "pyvdisk.vscript.runtime.statements", - "rpc:pyvdisk.vscript.runtime.Runtime#journal": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Runtime#load_module": "pyvdisk.vscript.runtime.modules", - "rpc:pyvdisk.vscript.runtime.Runtime#member": "pyvdisk.vscript.runtime.expressions", - "rpc:pyvdisk.vscript.runtime.Runtime#run": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Runtime#stringify": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Runtime#transactions_open": "pyvdisk.vscript.runtime.core", - "rpc:pyvdisk.vscript.runtime.Task": "pyvdisk.vscript.runtime.callables", - "rpc:pyvdisk.vscript.runtime.Task#await_result": "pyvdisk.vscript.runtime.callables", - "rpc:pyvdisk.vscript.runtime.TransactionContext": "pyvdisk.vscript.runtime.tx", - "rpc:pyvdisk.vscript.runtime.TransactionContext#commit": "pyvdisk.vscript.runtime.tx", - "rpc:pyvdisk.vscript.runtime.TransactionContext#journal": "pyvdisk.vscript.runtime.tx", - "rpc:pyvdisk.vscript.runtime.TransactionContext#rollback": "pyvdisk.vscript.runtime.tx", - "rpc:pyvdisk.vscript.stdlib._cap": "pyvdisk.vscript.stdlib.guards", - "rpc:pyvdisk.vscript.stdlib._vpath": "pyvdisk.vscript.stdlib.guards", - "rpc:pyvdisk.vscript.stdlib.create_stdlib": "pyvdisk.vscript.stdlib.factory", - "rpc:pyvdisk.vscript.stdlib.Handle": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.stdlib.Handle#kind": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.stdlib.Handle#name": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.stdlib.NativeFunction": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.stdlib.NativeModule": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.stdlib.NativeModule#member": "pyvdisk.vscript.stdlib.native", - "rpc:pyvdisk.vscript.tokens.Token": "pyvdisk.vscript.frontend.tokens", - "rpc:pyvdisk.vscript.tokens.Token#is_eof": "pyvdisk.vscript.frontend.tokens", - "rpc:pyvdisk.vscript.tokens.TokenType": "pyvdisk.vscript.frontend.tokens", - "rpc:pyvdisk.vscript.triggers.event_position": "pyvdisk.vscript.triggers.registry", - "rpc:pyvdisk.vscript.triggers.is_newer": "pyvdisk.vscript.triggers.registry", - "rpc:pyvdisk.vscript.triggers.SchedulerDaemon": "pyvdisk.vscript.triggers.daemon", - "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once": "pyvdisk.vscript.triggers.daemon", - "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#run": "pyvdisk.vscript.triggers.daemon", - "rpc:pyvdisk.vscript.triggers.Trigger": "pyvdisk.vscript.triggers.registry", - "rpc:pyvdisk.vscript.triggers.TriggerRegistry": "pyvdisk.vscript.triggers.registry", - "rpc:pyvdisk.vscript.undo.apply_undo": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.discard_spill_area": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.KINDS": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.load_body": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.normalize": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.snapshot_tree": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.spill_conflict": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.spill_path": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.undo.store_body": "pyvdisk.vscript.undo", - "rpc:pyvdisk.vscript.wal.decode_records": "pyvdisk.storage.wal.undo", - "rpc:pyvdisk.vscript.wal.encode_record": "pyvdisk.storage.wal.undo", - "rpc:pyvdisk.vscript.wal.RECORD_KINDS": "pyvdisk.storage.wal.undo", - "rpc:pyvdisk.vscript.wal.WriteAheadLog": "pyvdisk.storage.wal.undo", - "rpc:sandbox:_hidden": "pyvdisk.agent.paths", - "rpc:sandbox:_SandboxFS": "pyvdisk.agent.script", - "rpc:sandbox:AgentSandbox._normalize": "pyvdisk.agent.paths", - "rpc:sandbox:AgentSandbox._visible": "pyvdisk.agent.paths", - "rpc:sandbox:AgentSandbox.audit": "pyvdisk.agent.audit", - "rpc:sandbox:AgentSandbox.call": "pyvdisk.agent.tools", - "rpc:sandbox:AgentSandbox.create": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.delete": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.dispatch": "pyvdisk.agent.tools", - "rpc:sandbox:AgentSandbox.exists": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.list": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.make_directory": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.open": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.read": "pyvdisk.agent.sandbox", - "rpc:sandbox:AgentSandbox.retain_audit": "pyvdisk.agent.audit", - "rpc:sandbox:AgentSandbox.run": "pyvdisk.agent.script", - "rpc:sandbox:AgentSandbox.stats": "pyvdisk.agent.audit", - "rpc:sandbox:AgentSandbox.tools": "pyvdisk.agent.tools", - "rpc:sandbox:AgentSandbox.verify_audit": "pyvdisk.agent.audit", - "rpc:sandbox:AgentSandbox.write": "pyvdisk.agent.sandbox", - "rpc:sandbox:TOOLS": "pyvdisk.agent.tools", - "rpc:tests/conftest.py": "pyvdisk.tests.fixtures", - "rpc:tests/test_agentic_cli.py": "pyvdisk.tests.agentic-cli", - "rpc:tests/test_api_governance.py": "pyvdisk.tests.api-governance", - "rpc:tests/test_atomic_vfs_save.py": "pyvdisk.tests.atomic-save", - "rpc:tests/test_audit_trail.py": "pyvdisk.tests.audit-trail", - "rpc:tests/test_checkpoint_store.py": "pyvdisk.tests.checkpoint", - "rpc:tests/test_contracts.py": "pyvdisk.tests.contracts", - "rpc:tests/test_cross_process_queue.py": "pyvdisk.tests.queue-crossprocess", - "rpc:tests/test_datadisk_acid_crash_matrix.py": "pyvdisk.tests.crash-matrix", - "rpc:tests/test_exactly_once_internal.py": "pyvdisk.tests.exactly-once-internal", - "rpc:tests/test_exactly_once_operation.py": "pyvdisk.tests.exactly-once-operation", - "rpc:tests/test_execution_queue.py": "pyvdisk.tests.execution-queue", - "rpc:tests/test_execution.py": "pyvdisk.tests.execution", - "rpc:tests/test_fuse_mount.py": "pyvdisk.tests.fuse-mount", - "rpc:tests/test_governance_regression.py": "pyvdisk.tests.governance", - "rpc:tests/test_logdisk_compact_preserves_state.py": "pyvdisk.tests.logdisk-compact", - "rpc:tests/test_logdisk_retention_event_ids.py": "pyvdisk.tests.logdisk-retention", - "rpc:tests/test_packaging.py": "pyvdisk.tests.packaging", - "rpc:tests/test_participant_compensation.py": "pyvdisk.tests.participant-compensation", - "rpc:tests/test_queue_backoff_and_lock.py": "pyvdisk.tests.queue-backoff", - "rpc:tests/test_queue.py": "pyvdisk.tests.queue", - "rpc:tests/test_submit_conflict_and_atomic_vfs.py": "pyvdisk.tests.submit-conflict", - "rpc:tests/test_transaction_fs_rollback.py": "pyvdisk.tests.tx-rollback", - "rpc:tests/test_transaction_idempotency.py": "pyvdisk.tests.tx-idempotency", - "rpc:tests/test_unified_infrastructure_e2e.py": "pyvdisk.tests.e2e", - "rpc:tests/test_vdisk.py::TestAttributes": "pyvdisk.tests.vdisk.links", - "rpc:tests/test_vdisk.py::TestBasic": "pyvdisk.tests.vdisk.base", - "rpc:tests/test_vdisk.py::TestCLI": "pyvdisk.tests.vdisk.cli", - "rpc:tests/test_vdisk.py::TestConcurrency": "pyvdisk.tests.vdisk.locking", - "rpc:tests/test_vdisk.py::TestDirsAndRemove": "pyvdisk.tests.vdisk.large-files", - "rpc:tests/test_vdisk.py::TestDiskManager": "pyvdisk.tests.vdisk.disk-manager", - "rpc:tests/test_vdisk.py::TestEdgeCases": "pyvdisk.tests.vdisk.io", - "rpc:tests/test_vdisk.py::TestFsck": "pyvdisk.tests.vdisk.maintenance", - "rpc:tests/test_vdisk.py::TestGrow": "pyvdisk.tests.vdisk.maintenance", - "rpc:tests/test_vdisk.py::TestHardLinks": "pyvdisk.tests.vdisk.links", - "rpc:tests/test_vdisk.py::TestIdentity": "pyvdisk.tests.vdisk.identity", - "rpc:tests/test_vdisk.py::TestImportExport": "pyvdisk.tests.vdisk.io", - "rpc:tests/test_vdisk.py::TestLargeFiles": "pyvdisk.tests.vdisk.large-files", - "rpc:tests/test_vdisk.py::TestLogDiskAndLogging": "pyvdisk.tests.vdisk.log", - "rpc:tests/test_vdisk.py::TestPermissions": "pyvdisk.tests.vdisk.permissions", - "rpc:tests/test_vdisk.py::TestPersistence": "pyvdisk.tests.vdisk.io", - "rpc:tests/test_vdisk.py::TestRawFS": "pyvdisk.tests.vdisk.raw-fs", - "rpc:tests/test_vdisk.py::TestRename": "pyvdisk.tests.vdisk.names", - "rpc:tests/test_vdisk.py::TestRWLock": "pyvdisk.tests.vdisk.locking", - "rpc:tests/test_vdisk.py::TestSpaceExhaustion": "pyvdisk.tests.vdisk.exhaustion", - "rpc:tests/test_vdisk.py::TestSpaceInfo": "pyvdisk.tests.vdisk.maintenance", - "rpc:tests/test_vdisk.py::TestSparseFile": "pyvdisk.tests.vdisk.links", - "rpc:tests/test_vdisk.py::TestSymlink": "pyvdisk.tests.vdisk.names", - "rpc:tests/test_vdisk.py::TestVectorDisk": "pyvdisk.tests.vdisk.vector", - "rpc:tests/test_vdisk.py::TestVFile": "pyvdisk.tests.vdisk.names", - "rpc:tests/test_vdisk.py::TestVolumeAutoDetect": "pyvdisk.tests.vdisk.volume-detect", - "rpc:tests/test_vdisk.py::TestVolumeBase": "pyvdisk.tests.vdisk.volume", - "rpc:tests/test_vdisk.py::TestVolumeCLI": "pyvdisk.tests.vdisk.volume-meta", - "rpc:tests/test_vdisk.py::TestVolumeConcat": "pyvdisk.tests.vdisk.volume", - "rpc:tests/test_vdisk.py::TestVolumeErrors": "pyvdisk.tests.vdisk.volume-meta", - "rpc:tests/test_vdisk.py::TestVolumeMeta": "pyvdisk.tests.vdisk.volume-meta", - "rpc:tests/test_vdisk.py::TestVolumeMirror": "pyvdisk.tests.vdisk.volume-mirror", - "rpc:tests/test_vdisk.py::TestVolumeStripe": "pyvdisk.tests.vdisk.volume", - "rpc:tests/test_vdisk.py::VFSTestBase": "pyvdisk.tests.vdisk.base", - "rpc:tests/test_vscript_audit.py": "pyvdisk.tests.vscript-audit", - "rpc:tests/test_vscript_cron.py": "pyvdisk.tests.vscript-cron", - "rpc:tests/test_vscript_host.py": "pyvdisk.tests.vscript-host", - "rpc:tests/test_vscript_optional_chain.py": "pyvdisk.tests.vscript-optional", - "rpc:tests/test_vscript_triggers.py": "pyvdisk.tests.vscript-triggers", - "rpc:tests/test_vscript_undo.py": "pyvdisk.tests.vscript-undo", - "rpc:tests/test_vscript.py::FakeFS": "pyvdisk.tests.vscript", - "rpc:tests/test_vscript.py::VScriptEndToEndTests": "pyvdisk.tests.vscript", - "rpc:tests/test_vscript.py::VScriptTests": "pyvdisk.tests.vscript", - "rpc:tests/test_wal_abort_recovery.py": "pyvdisk.tests.wal-recovery", - "rpc:tests/test_wal_checkpoint_and_recovery.py": "pyvdisk.tests.wal-checkpoint", - "rpc:tests/test_worker_cancellation.py": "pyvdisk.tests.cancellation", - "rpc:vector_index:deserialize": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:distance": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:FlatIndex.add_item": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:FlatIndex.knn_query": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:read_kind": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:serialize": "pyvdisk.storage.vector.flat-index", - "rpc:vector_index:serialize_from_backend": "pyvdisk.storage.vector.flat-index" - }, - "edges": [ - { - "from": "pyvdisk.api", - "from_api": "rpc:pyvdisk.AgentSandbox", - "to": "pyvdisk.agent.sandbox", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "转出沙箱门面", - "en": "re-exports the sandbox" - } - }, - { - "from": "pyvdisk.api", - "from_api": "rpc:pyvdisk.compat", - "to": "pyvdisk.platform", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "转出平台适配层", - "en": "re-exports the platform layer" - } - }, - { - "from": "pyvdisk.api", - "from_api": "rpc:pyvdisk.FlatIndex", - "to": "pyvdisk.storage.vector.flat-index", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "转出扁平索引", - "en": "re-exports the flat index" - } - }, - { - "from": "pyvdisk.cli.open", - "from_api": "rpc:pyvdisk.cli._open_vfs", - "to": "pyvdisk.storage.vfs.open", - "to_api": "rpc:pyvdisk.vfs.VFS", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "打开 VFS", - "en": "opens VFS" - } - }, - { - "from": "pyvdisk.cli.parser", - "from_api": "rpc:pyvdisk.cli.build_parser", - "to": "pyvdisk.vscript.cli.parser", - "to_api": "rpc:pyvdisk.vscript.cli.add_parser", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "添加 vscript 子解析器", - "en": "adds vscript parser" - } - }, - { - "from": "pyvdisk.docs.readme", - "from_api": "file:README.md", - "to": "pyvdisk.docs.architecture", - "to_api": "file:docs/ARCHITECTURE.md", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "指向架构文档", - "en": "points to architecture doc" - } - }, - { - "from": "pyvdisk.execution.operations.registry", - "from_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#save", - "to": "pyvdisk.storage.checkpoint.open", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "经检查点持久化", - "en": "persists via checkpoint" - } - }, - { - "from": "pyvdisk.execution.queue.store", - "from_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_save", - "to": "pyvdisk.storage.checkpoint.io", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "持久化状态", - "en": "persists state" - } - }, - { - "from": "pyvdisk.execution.runstate.store", - "from_api": "rpc:pyvdisk.infrastructure.run_state.RunStateStore", - "to": "pyvdisk.storage.checkpoint.open", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "持久化运行", - "en": "persists runs" - } - }, - { - "from": "pyvdisk.execution.service.invoke", - "from_api": "rpc:pyvdisk.execution.ExecutionService#_scoped_view", - "to": "pyvdisk.governance.scoped", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.scoped", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "限定能力", - "en": "scopes capabilities" - } - }, - { - "from": "pyvdisk.execution.service.invoke", - "from_api": "rpc:pyvdisk.execution.ExecutionService#_script", - "to": "pyvdisk.vscript.runtime.core", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "运行 VScript", - "en": "runs VScript" - } - }, - { - "from": "pyvdisk.execution.service.queue", - "from_api": "rpc:pyvdisk.execution.ExecutionService#run_next", - "to": "pyvdisk.execution.queue.lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "领取任务", - "en": "claims task" - } - }, - { - "from": "pyvdisk.execution.service.setup", - "from_api": "rpc:pyvdisk.execution.ExecutionService", - "to": "pyvdisk.execution.queue.store", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "持有持久队列", - "en": "holds durable queue" - } - }, - { - "from": "pyvdisk.execution.service.setup", - "from_api": "rpc:pyvdisk.execution.ExecutionService", - "to": "pyvdisk.storage.datadisk.api", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#get_metadata", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取元数据", - "en": "reads metadata" - } - }, - { - "from": "pyvdisk.execution.service.submit", - "from_api": "rpc:pyvdisk.execution.ExecutionService#submit", - "to": "pyvdisk.contracts.runhandle", - "to_api": "rpc:pyvdisk.contracts.RunHandle", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "返回句柄", - "en": "returns handle" - } - }, - { - "from": "pyvdisk.governance.data", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedLogNamespace#append", - "to": "pyvdisk.storage.log.append", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "委托给日志盘", - "en": "delegates to log disk" - } - }, - { - "from": "pyvdisk.governance.data", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedVectorNamespace#upsert", - "to": "pyvdisk.storage.vector.records", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "委托给向量盘", - "en": "delegates to vector disk" - } - }, - { - "from": "pyvdisk.governance.files", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#read_file", - "to": "pyvdisk.storage.vfs.files", - "to_api": "rpc:pyvdisk.vfs.VFS#read_file", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "委托给 VFS", - "en": "delegates to VFS" - } - }, - { - "from": "pyvdisk.governance.namespace", - "from_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "to": "pyvdisk.contracts.capability", - "to_api": "rpc:pyvdisk.contracts.CapabilityGrant#allows", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "检查授权", - "en": "checks grants" - } - }, - { - "from": "pyvdisk.storage.block.access", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#read_block", - "to": "pyvdisk.storage.block.io", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "定位读取", - "en": "positional read" - } - }, - { - "from": "pyvdisk.storage.block.access", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#write_block", - "to": "pyvdisk.storage.block.io", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "定位写入", - "en": "positioned write" - } - }, - { - "from": "pyvdisk.storage.block.image", - "from_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "to": "pyvdisk.platform.locking", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "整文件写锁", - "en": "whole-file write lock" - } - }, - { - "from": "pyvdisk.storage.block.io", - "from_api": "rpc:pyvdisk.disk._pread_all", - "to": "pyvdisk.platform.positional", - "to_api": "rpc:pyvdisk.compat.pread", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "定位读取", - "en": "positioned read" - } - }, - { - "from": "pyvdisk.storage.block.io", - "from_api": "rpc:pyvdisk.disk._pwrite_all", - "to": "pyvdisk.platform.positional", - "to_api": "rpc:pyvdisk.compat.pwrite", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "定位写入", - "en": "positioned write" - } - }, - { - "from": "pyvdisk.storage.checkpoint.open", - "from_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#locked", - "to": "pyvdisk.platform.locking", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "跨进程锁", - "en": "cross-process lock" - } - }, - { - "from": "pyvdisk.storage.checkpoint.triggers", - "to": "pyvdisk.vscript.triggers", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "支撑触发器去重", - "en": "backs trigger dedup" - } - }, - { - "from": "pyvdisk.storage.datadisk.api", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped", - "to": "pyvdisk.governance.scoped", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedDataDisk", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "构建受限视图", - "en": "builds scoped view" - } - }, - { - "from": "pyvdisk.storage.datadisk.api", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#transaction", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "开启事务", - "en": "opens transaction" - } - }, - { - "from": "pyvdisk.storage.datadisk.core", - "from_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_append_metadata_wal", - "to": "pyvdisk.storage.wal.journal", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "使用元数据 WAL", - "en": "uses metadata WAL" - } - }, - { - "from": "pyvdisk.storage.datadisk.namespace", - "from_api": "rpc:pyvdisk.infrastructure.disk.FileNamespace#write_file", - "to": "pyvdisk.storage.vfs.files", - "to_api": "rpc:pyvdisk.vfs.VFS#write_file", - "kind": "dataflow", - "cross_tree": false, - "label": { - "zh": "委托给 VFS", - "en": "delegates to VFS" - } - }, - { - "from": "pyvdisk.storage.datadisk.services", - "from_api": "rpc:pyvdisk.infrastructure.disk.LogNamespace", - "to": "pyvdisk.storage.log.append", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "包装日志盘", - "en": "wraps log disk" - } - }, - { - "from": "pyvdisk.storage.datadisk.services", - "from_api": "rpc:pyvdisk.infrastructure.disk.VectorNamespace", - "to": "pyvdisk.storage.vector.records", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "包装向量盘", - "en": "wraps vector disk" - } - }, - { - "from": "pyvdisk.storage.datadisk.tx-lifecycle", - "from_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "to": "pyvdisk.storage.wal.entries", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#commit", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "写入 WAL 记录", - "en": "writes WAL entries" - } - }, - { - "from": "pyvdisk.storage.driver.manager", - "from_api": "rpc:pyvdisk.driver.DiskManager#scan", - "to": "pyvdisk.storage.identity.probe", - "to_api": "rpc:pyvdisk.identity.probe_disk", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "探测盘", - "en": "probes disks" - } - }, - { - "from": "pyvdisk.storage.driver.mounting", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_log", - "to": "pyvdisk.storage.log.open", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载日志盘", - "en": "mounts log disk" - } - }, - { - "from": "pyvdisk.storage.driver.mounting", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_vector", - "to": "pyvdisk.storage.vector.open", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载向量盘", - "en": "mounts vector disk" - } - }, - { - "from": "pyvdisk.storage.driver.mounting", - "from_api": "rpc:pyvdisk.driver.DiskManager#_mount_volume", - "to": "pyvdisk.storage.volume.open", - "to_api": "rpc:pyvdisk.volume.Volume#open", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "打开卷", - "en": "opens volume" - } - }, - { - "from": "pyvdisk.storage.fs.create", - "from_api": "rpc:pyvdisk.fs.FS#_create_node", - "to": "pyvdisk.storage.fs.inode-io", - "to_api": "rpc:pyvdisk.fs.FS#alloc_inode", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "分配 inode", - "en": "reserves inode" - } - }, - { - "from": "pyvdisk.storage.fs.grow", - "from_api": "rpc:pyvdisk.fs.grow", - "to": "pyvdisk.storage.block.access", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#truncate_bytes", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "扩大镜像", - "en": "enlarges image" - } - }, - { - "from": "pyvdisk.storage.fs.inode-io", - "from_api": "rpc:pyvdisk.fs.FS#read_inode", - "to": "pyvdisk.storage.block.access", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#read_bytes", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取 inode 表", - "en": "reads inode table" - } - }, - { - "from": "pyvdisk.storage.fs.locking", - "from_api": "rpc:pyvdisk.fs._shared_lock_for", - "to": "pyvdisk.storage.rwlock.core", - "to_api": "rpc:pyvdisk.rwlock.RWLock", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "创建读写锁", - "en": "creates RWLock" - } - }, - { - "from": "pyvdisk.storage.fs.mkfs", - "from_api": "rpc:pyvdisk.fs.mkfs", - "to": "pyvdisk.storage.identity.probe", - "to_api": "rpc:pyvdisk.identity.write_identity_to_block0", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "写入身份尾标", - "en": "stamps identity" - } - }, - { - "from": "pyvdisk.storage.fs.mount", - "from_api": "rpc:pyvdisk.fs.FS#mount", - "to": "pyvdisk.storage.block.access", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#read_block", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取 block 0", - "en": "reads block 0" - } - }, - { - "from": "pyvdisk.storage.fs.mutate", - "from_api": "rpc:pyvdisk.fs.FS#_remove_node", - "to": "pyvdisk.storage.fs.pointers", - "to_api": "rpc:pyvdisk.fs.FS#_free_all_blocks", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "回收数据块", - "en": "reclaims blocks" - } - }, - { - "from": "pyvdisk.storage.fs.paths", - "from_api": "rpc:pyvdisk.fs.FS#resolve", - "to": "pyvdisk.storage.fs.dir", - "to_api": "rpc:pyvdisk.fs.FS#dir_lookup", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "逐级遍历目录", - "en": "walks directories" - } - }, - { - "from": "pyvdisk.storage.fs.readwrite", - "from_api": "rpc:pyvdisk.fs.FS#write_file", - "to": "pyvdisk.storage.fs.pointers", - "to_api": "rpc:pyvdisk.fs.FS#_ensure_block_ptr", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "扩展块映射", - "en": "extends block map" - } - }, - { - "from": "pyvdisk.storage.fuse.data", - "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_write", - "to": "pyvdisk.storage.vfs.files", - "to_api": "rpc:pyvdisk.vfs.VFS#write_file", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "写文件", - "en": "writes file" - } - }, - { - "from": "pyvdisk.storage.fuse.meta", - "from_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_getattr", - "to": "pyvdisk.platform.durability", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "进程身份", - "en": "process identity" - } - }, - { - "from": "pyvdisk.storage.fuse.mount", - "from_api": "rpc:pyvdisk.fuse_mount.mount", - "to": "pyvdisk.storage.vfs.lifetime", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - } - }, - { - "from": "pyvdisk.storage.identity.probe", - "from_api": "rpc:pyvdisk.identity.probe_disk", - "to": "pyvdisk.storage.identity.trailer", - "to_api": "rpc:pyvdisk.identity.parse_trailer", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "解析尾标", - "en": "parses trailer" - } - }, - { - "from": "pyvdisk.storage.identity.trailer", - "from_api": "rpc:pyvdisk.identity.parse_trailer", - "to": "pyvdisk.storage.identity.model", - "to_api": "rpc:pyvdisk.identity.DiskIdentity", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "构造身份模型", - "en": "builds identity model" - } - }, - { - "from": "pyvdisk.storage.log.append", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "to": "pyvdisk.storage.log.filter", - "to_api": "rpc:pyvdisk.log_disk._json", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "编码记录", - "en": "encodes record" - } - }, - { - "from": "pyvdisk.storage.log.open", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#mount", - "to": "pyvdisk.storage.vfs.lifetime", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - } - }, - { - "from": "pyvdisk.storage.log.query", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#query", - "to": "pyvdisk.storage.log.filter", - "to_api": "rpc:pyvdisk.log_disk._match", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "应用 where 过滤", - "en": "applies where-filter" - } - }, - { - "from": "pyvdisk.storage.log.retention", - "from_api": "rpc:pyvdisk.log_disk.LogDisk#enforce_retention", - "to": "pyvdisk.storage.log.streams", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#create_stream", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取流配置", - "en": "reads stream config" - } - }, - { - "from": "pyvdisk.storage.logging.bridge", - "from_api": "rpc:pyvdisk.logging_core.StandardLoggingHandler", - "to": "pyvdisk.storage.logging.sinks", - "to_api": "rpc:pyvdisk.logging_core.LogSink", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "转发到 sink", - "en": "forwards to sinks" - } - }, - { - "from": "pyvdisk.storage.logging.logger", - "from_api": "rpc:pyvdisk.logging_core.UnifiedLogger#log", - "to": "pyvdisk.storage.logging.sinks", - "to_api": "rpc:pyvdisk.logging_core.LogSink", - "kind": "event", - "cross_tree": false, - "label": { - "zh": "向 sink 发送", - "en": "emits to sinks" - } - }, - { - "from": "pyvdisk.storage.logging.sinks", - "from_api": "rpc:pyvdisk.logging_core.LogDiskSink", - "to": "pyvdisk.storage.log.append", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "追加事件", - "en": "appends events" - } - }, - { - "from": "pyvdisk.storage.rwlock.ctx", - "from_api": "rpc:pyvdisk.rwlock.ReadCtx", - "to": "pyvdisk.storage.rwlock.core", - "to_api": "rpc:pyvdisk.rwlock.RWLock#acquire_read", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "获取读锁", - "en": "acquires read lock" - } - }, - { - "from": "pyvdisk.storage.vector.open", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#mount", - "to": "pyvdisk.storage.vfs.lifetime", - "to_api": "rpc:pyvdisk.vfs.VFS#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载 VFS", - "en": "mounts VFS" - } - }, - { - "from": "pyvdisk.storage.vector.records", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#upsert", - "to": "pyvdisk.storage.vector.collections", - "to_api": "rpc:pyvdisk.vector_disk.VectorDisk#create_collection", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "校验集合", - "en": "verifies collection" - } - }, - { - "from": "pyvdisk.storage.vector.search", - "from_api": "rpc:pyvdisk.vector_disk.VectorDisk#_load_index", - "to": "pyvdisk.storage.vector.flat-index", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "后端回退", - "en": "backend fallback" - } - }, - { - "from": "pyvdisk.storage.vfs.create", - "from_api": "rpc:pyvdisk.vfs.VFS#create", - "to": "pyvdisk.storage.fs.mkfs", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "格式化磁盘", - "en": "formats disk" - } - }, - { - "from": "pyvdisk.storage.vfs.files", - "from_api": "rpc:pyvdisk.vfs.VFS#write_file", - "to": "pyvdisk.storage.fs.readwrite", - "to_api": "rpc:pyvdisk.fs.FS#write_path", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "写入文件数据", - "en": "writes file data" - } - }, - { - "from": "pyvdisk.storage.vfs.lifetime", - "from_api": "rpc:pyvdisk.vfs.VFS#mount", - "to": "pyvdisk.storage.fs.mount", - "to_api": "rpc:pyvdisk.fs.FS#mount", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "挂载文件系统", - "en": "mounts filesystem" - } - }, - { - "from": "pyvdisk.storage.vfs.open", - "from_api": "rpc:pyvdisk.vfs.VFS#_open_disk_or_volume", - "to": "pyvdisk.storage.block.image", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "打开镜像", - "en": "opens image" - } - }, - { - "from": "pyvdisk.storage.vfs.permissions", - "from_api": "rpc:pyvdisk.vfs.VFS#_check", - "to": "pyvdisk.storage.fs.attrs", - "to_api": "rpc:pyvdisk.fs.FS#access", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "POSIX 权限检查", - "en": "POSIX access check" - } - }, - { - "from": "pyvdisk.storage.vfs.space", - "from_api": "rpc:pyvdisk.vfs.VFS#du", - "to": "pyvdisk.storage.vfs.walk", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "遍历目录树", - "en": "walks tree" - } - }, - { - "from": "pyvdisk.storage.vfs.stat", - "from_api": "rpc:pyvdisk.vfs.VFS#stat", - "to": "pyvdisk.storage.fs.query", - "to_api": "rpc:pyvdisk.fs.FS#stat_path", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取 inode", - "en": "reads inode" - } - }, - { - "from": "pyvdisk.storage.vfs.vfile-io", - "from_api": "rpc:pyvdisk.vfs.VFile#write", - "to": "pyvdisk.storage.fs.readwrite", - "to_api": "rpc:pyvdisk.fs.FS#write_file", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "定位写入", - "en": "positioned write" - } - }, - { - "from": "pyvdisk.storage.volume.create", - "from_api": "rpc:pyvdisk.volume.create_volume", - "to": "pyvdisk.storage.fs.mkfs", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "格式化卷", - "en": "formats volume" - } - }, - { - "from": "pyvdisk.storage.volume.layout", - "from_api": "rpc:pyvdisk.volume.Volume#_read_mirror", - "to": "pyvdisk.storage.volume.blocks", - "to_api": "rpc:pyvdisk.volume.Volume#read_block", - "kind": "dataflow", - "cross_tree": false, - "label": { - "zh": "读取成员", - "en": "reads members" - } - }, - { - "from": "pyvdisk.storage.volume.open", - "from_api": "rpc:pyvdisk.volume.Volume#open", - "to": "pyvdisk.storage.block.image", - "to_api": "rpc:pyvdisk.disk.VirtualDisk#open", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "打开成员", - "en": "opens members" - } - }, - { - "from": "pyvdisk.storage.volume.repair", - "from_api": "rpc:pyvdisk.volume.resync_mirror", - "to": "pyvdisk.storage.volume.open", - "to_api": "rpc:pyvdisk.volume.Volume#open", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "重开卷", - "en": "reopens volume" - } - }, - { - "from": "pyvdisk.storage.wal.undo", - "from_api": "rpc:pyvdisk.vscript.wal.WriteAheadLog", - "to": "pyvdisk.storage.wal.journal", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "复用共享 WAL 实现", - "en": "reuses the shared WAL" - } - }, - { - "from": "pyvdisk.tests.agentic-cli", - "to": "pyvdisk.cli.main", - "to_api": "rpc:pyvdisk.cli.main", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "驱动入口", - "en": "drives entry point" - } - }, - { - "from": "pyvdisk.tests.api-governance", - "to": "pyvdisk.governance.namespace", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.CapabilityNamespace#_check", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证范围限定", - "en": "verifies scoping" - } - }, - { - "from": "pyvdisk.tests.atomic-save", - "to": "pyvdisk.storage.datadisk.core", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_atomic_json", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证原子写入", - "en": "verifies atomic write" - } - }, - { - "from": "pyvdisk.tests.audit-trail", - "from_api": "rpc:tests/test_audit_trail.py", - "to": "pyvdisk.vscript.audit.sinks", - "to_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#verify", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证审计 Sink", - "en": "exercises audit sinks" - } - }, - { - "from": "pyvdisk.tests.cancellation", - "to": "pyvdisk.execution.service.submit", - "to_api": "rpc:pyvdisk.execution.ExecutionService#cancel", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证取消", - "en": "verifies cancellation" - } - }, - { - "from": "pyvdisk.tests.checkpoint", - "to": "pyvdisk.storage.checkpoint.open", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证存储", - "en": "verifies store" - } - }, - { - "from": "pyvdisk.tests.contracts", - "to": "pyvdisk.contracts.plane", - "to_api": "rpc:pyvdisk.contracts.ExecutionPlane#submit", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证契约", - "en": "verifies contracts" - } - }, - { - "from": "pyvdisk.tests.crash-matrix", - "from_api": "rpc:tests/test_datadisk_acid_crash_matrix.py", - "to": "pyvdisk.storage.datadisk.core", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#_recover_transactions", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证事务重放", - "en": "verifies transaction replay" - } - }, - { - "from": "pyvdisk.tests.e2e", - "to": "pyvdisk.storage.datadisk.api", - "to_api": "rpc:pyvdisk.infrastructure.disk.DataDisk#scoped", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "驱动 DataDisk", - "en": "drives DataDisk" - } - }, - { - "from": "pyvdisk.tests.exactly-once-internal", - "to": "pyvdisk.execution.operations.registry", - "to_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#has", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证去重", - "en": "verifies dedup" - } - }, - { - "from": "pyvdisk.tests.exactly-once-operation", - "to": "pyvdisk.execution.operations.registry", - "to_api": "rpc:pyvdisk.infrastructure.operations.OperationRegistry#recover", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证重放", - "en": "verifies replay" - } - }, - { - "from": "pyvdisk.tests.execution", - "to": "pyvdisk.execution.service.submit", - "to_api": "rpc:pyvdisk.execution.ExecutionService#run", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证服务", - "en": "verifies service" - } - }, - { - "from": "pyvdisk.tests.execution-queue", - "to": "pyvdisk.execution.service.queue", - "to_api": "rpc:pyvdisk.execution.ExecutionService#run_next", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证队列执行", - "en": "verifies queue run" - } - }, - { - "from": "pyvdisk.tests.fuse-mount", - "from_api": "rpc:tests/test_fuse_mount.py", - "to": "pyvdisk.storage.fuse.handlers", - "to_api": "rpc:pyvdisk.fuse_mount._VFuseOperations#_readlink", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证 FUSE 操作表", - "en": "exercises FUSE operations" - } - }, - { - "from": "pyvdisk.tests.governance", - "to": "pyvdisk.governance.files", - "to_api": "rpc:pyvdisk.infrastructure.capabilities.ScopedFileNamespace#_check_file", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证受限文件系统", - "en": "verifies scoped fs" - } - }, - { - "from": "pyvdisk.tests.logdisk-compact", - "to": "pyvdisk.storage.log.retention", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#compact", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证压缩", - "en": "verifies compaction" - } - }, - { - "from": "pyvdisk.tests.logdisk-retention", - "to": "pyvdisk.storage.log.retention", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#enforce_retention", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证保留策略", - "en": "verifies retention" - } - }, - { - "from": "pyvdisk.tests.participant-compensation", - "from_api": "rpc:tests/test_participant_compensation.py", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#abort", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证事务补偿", - "en": "exercises tx compensation" - } - }, - { - "from": "pyvdisk.tests.queue", - "to": "pyvdisk.execution.queue.lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#claim", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证队列", - "en": "verifies queue" - } - }, - { - "from": "pyvdisk.tests.queue-backoff", - "to": "pyvdisk.execution.queue.store", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue#_backoff_seconds", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证退避", - "en": "verifies backoff" - } - }, - { - "from": "pyvdisk.tests.queue-crossprocess", - "to": "pyvdisk.execution.queue.store", - "to_api": "rpc:pyvdisk.infrastructure.queue.DurableQueue", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证跨进程队列", - "en": "verifies cross-process queue" - } - }, - { - "from": "pyvdisk.tests.submit-conflict", - "to": "pyvdisk.execution.runstate.store", - "to_api": "rpc:pyvdisk.infrastructure.run_state.RunStateStore#transition", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证冲突处理", - "en": "verifies conflict handling" - } - }, - { - "from": "pyvdisk.tests.tx-idempotency", - "to": "pyvdisk.storage.datadisk.tx-lifecycle", - "to_api": "rpc:pyvdisk.infrastructure.disk.MetadataTransaction#commit", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证幂等", - "en": "verifies idempotency" - } - }, - { - "from": "pyvdisk.tests.tx-rollback", - "to": "pyvdisk.storage.datadisk.namespace", - "to_api": "rpc:pyvdisk.infrastructure.disk.FileNamespace#rmtree", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证回滚", - "en": "verifies abort" - } - }, - { - "from": "pyvdisk.tests.vscript", - "to": "pyvdisk.vscript.runtime.core", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证解释器", - "en": "exercises interpreter" - } - }, - { - "from": "pyvdisk.tests.vscript-audit", - "to": "pyvdisk.vscript.audit.record", - "to_api": "rpc:pyvdisk.vscript.audit.AuditRecord", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证审计", - "en": "verifies audit" - } - }, - { - "from": "pyvdisk.tests.vscript-cron", - "from_api": "rpc:tests/test_vscript_cron.py", - "to": "pyvdisk.vscript.cron", - "to_api": "rpc:pyvdisk.vscript.cron.CronExpression#next_after", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证 cron 表达式", - "en": "exercises cron expressions" - } - }, - { - "from": "pyvdisk.tests.vscript-host", - "to": "pyvdisk.vscript.host.guard", - "to_api": "rpc:pyvdisk.vscript.host.HostProxy#_check", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证隔离", - "en": "verifies confinement" - } - }, - { - "from": "pyvdisk.tests.vscript-optional", - "to": "pyvdisk.vscript.runtime.expressions", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#eval", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证求值", - "en": "verifies evaluation" - } - }, - { - "from": "pyvdisk.tests.vscript-triggers", - "from_api": "rpc:tests/test_vscript_triggers.py", - "to": "pyvdisk.vscript.triggers.daemon", - "to_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证触发器守护进程", - "en": "exercises trigger daemon" - } - }, - { - "from": "pyvdisk.tests.vscript-undo", - "from_api": "rpc:tests/test_vscript_undo.py", - "to": "pyvdisk.vscript.undo", - "to_api": "rpc:pyvdisk.vscript.undo.apply_undo", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证撤销解释器", - "en": "exercises undo interpreter" - } - }, - { - "from": "pyvdisk.tests.wal-checkpoint", - "from_api": "rpc:tests/test_wal_checkpoint_and_recovery.py", - "to": "pyvdisk.storage.wal.entries", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证 WAL 检查点", - "en": "verifies WAL checkpointing" - } - }, - { - "from": "pyvdisk.tests.wal-recovery", - "to": "pyvdisk.storage.wal.entries", - "to_api": "rpc:pyvdisk.infrastructure.wal.WriteAheadLog#recover", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "验证 WAL 恢复", - "en": "verifies WAL recovery" - } - }, - { - "from": "pyvdisk.vscript.audit.sinks", - "from_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit", - "to": "pyvdisk.storage.checkpoint.io", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#save", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "经检查点持久化", - "en": "persists via checkpoint" - } - }, - { - "from": "pyvdisk.vscript.audit.sinks", - "from_api": "rpc:pyvdisk.vscript.audit.DataDiskAuditSink#emit", - "to": "pyvdisk.storage.log.append", - "to_api": "rpc:pyvdisk.log_disk.LogDisk#append", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "追加到日志流", - "en": "appends to log stream" - } - }, - { - "from": "pyvdisk.vscript.cli.commands", - "from_api": "rpc:pyvdisk.vscript.cli._mounts", - "to": "pyvdisk.vscript.mounts", - "to_api": "rpc:pyvdisk.vscript.mounts.MountRegistry#grant", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "授予挂载", - "en": "grants mounts" - } - }, - { - "from": "pyvdisk.vscript.cli.repl", - "from_api": "rpc:pyvdisk.vscript.cli.repl", - "to": "pyvdisk.vscript.runtime.core", - "to_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "运行源码", - "en": "runs sources" - } - }, - { - "from": "pyvdisk.vscript.frontend.ast", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.SourceSpan", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "位置来自 errors 模块", - "en": "spans from errors module" - } - }, - { - "from": "pyvdisk.vscript.frontend.errors", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.Diagnostic", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "由诊断构造", - "en": "built from diagnostics" - } - }, - { - "from": "pyvdisk.vscript.frontend.lexer", - "from_api": "rpc:pyvdisk.vscript.lexer.Lexer#scan", - "to": "pyvdisk.vscript.frontend.errors", - "to_api": "rpc:pyvdisk.vscript.errors.LexError", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "抛出词法错误", - "en": "raises lex errors" - } - }, - { - "from": "pyvdisk.vscript.frontend.parser", - "from_api": "rpc:pyvdisk.vscript.parser.Parser", - "to": "pyvdisk.vscript.frontend.ast", - "to_api": "rpc:pyvdisk.vscript.ast.Program", - "kind": "dataflow", - "cross_tree": false, - "label": { - "zh": "构建 AST", - "en": "builds AST" - } - }, - { - "from": "pyvdisk.vscript.frontend.parser", - "from_api": "rpc:pyvdisk.vscript.parser.parse", - "to": "pyvdisk.vscript.frontend.lexer", - "to_api": "rpc:pyvdisk.vscript.lexer.lex", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "词法分析", - "en": "lexes source" - } - }, - { - "from": "pyvdisk.vscript.frontend.tokens", - "to": "pyvdisk.vscript.frontend.span", - "to_api": "rpc:pyvdisk.vscript.errors.SourceSpan", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "携带源码位置", - "en": "carries source spans" - } - }, - { - "from": "pyvdisk.vscript.host.guard", - "from_api": "rpc:pyvdisk.vscript.host.HostProxy#write", - "to": "pyvdisk.platform.durability", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "刷盘目录", - "en": "flush the directory" - } - }, - { - "from": "pyvdisk.vscript.host.module", - "from_api": "rpc:pyvdisk.vscript.host.create_host_module", - "to": "pyvdisk.vscript.host.guard", - "to_api": "rpc:pyvdisk.vscript.host.HostProxy#read", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "经代理限权", - "en": "guards via proxy" - } - }, - { - "from": "pyvdisk.vscript.mounts", - "from_api": "rpc:pyvdisk.vscript.mounts.MountRegistry#grant", - "to": "pyvdisk.vscript.policy.capability", - "to_api": "rpc:pyvdisk.vscript.policy.Capability", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "创建能力", - "en": "creates capability" - } - }, - { - "from": "pyvdisk.vscript.runtime.core", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "to": "pyvdisk.vscript.audit.sinks", - "to_api": "rpc:pyvdisk.vscript.audit.CheckpointAuditSink#emit", - "kind": "event", - "cross_tree": false, - "label": { - "zh": "产出审计记录", - "en": "emits audit records" - } - }, - { - "from": "pyvdisk.vscript.runtime.core", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#run", - "to": "pyvdisk.vscript.policy.budget", - "to_api": "rpc:pyvdisk.vscript.policy.Budget#tick", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "计入预算", - "en": "charges budget" - } - }, - { - "from": "pyvdisk.vscript.runtime.modules", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#load_module", - "to": "pyvdisk.vscript.stdlib.factory", - "to_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "加载原生模块", - "en": "loads native module" - } - }, - { - "from": "pyvdisk.vscript.runtime.statements", - "from_api": "rpc:pyvdisk.vscript.runtime.Runtime#execute", - "to": "pyvdisk.vscript.runtime.callables", - "to_api": "rpc:pyvdisk.vscript.runtime.Function#__call__", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "调用与返回", - "en": "calls and returns" - } - }, - { - "from": "pyvdisk.vscript.runtime.tx", - "from_api": "rpc:pyvdisk.vscript.runtime.recover_wal", - "to": "pyvdisk.storage.wal.undo", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "消费事务 WAL", - "en": "consumes the tx WAL" - } - }, - { - "from": "pyvdisk.vscript.runtime.tx", - "from_api": "rpc:pyvdisk.vscript.runtime.TransactionContext#rollback", - "to": "pyvdisk.vscript.undo", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "重放撤销记录", - "en": "replays undo records" - } - }, - { - "from": "pyvdisk.vscript.stdlib.factory", - "from_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "to": "pyvdisk.vscript.stdlib.guards", - "to_api": "rpc:pyvdisk.vscript.stdlib._cap", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "使用守卫", - "en": "uses guards" - } - }, - { - "from": "pyvdisk.vscript.stdlib.factory", - "from_api": "rpc:pyvdisk.vscript.stdlib.create_stdlib", - "to": "pyvdisk.vscript.stdlib.native", - "to_api": "rpc:pyvdisk.vscript.stdlib.NativeModule", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "包装原生模块", - "en": "wraps native modules" - } - }, - { - "from": "pyvdisk.vscript.stdlib.native", - "from_api": "rpc:pyvdisk.vscript.stdlib.Handle", - "to": "pyvdisk.vscript.policy.capability", - "to_api": "rpc:pyvdisk.vscript.policy.Capability", - "kind": "reference", - "cross_tree": false, - "label": { - "zh": "包装能力", - "en": "wraps capability" - } - }, - { - "from": "pyvdisk.vscript.triggers.daemon", - "from_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "to": "pyvdisk.storage.checkpoint.triggers", - "to_api": "rpc:pyvdisk.infrastructure.checkpoint.CheckpointStore#mark_success", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "事件去重", - "en": "dedups events" - } - }, - { - "from": "pyvdisk.vscript.triggers.daemon", - "from_api": "rpc:pyvdisk.vscript.triggers.SchedulerDaemon#poll_once", - "to": "pyvdisk.vscript.triggers.registry", - "to_api": "rpc:pyvdisk.vscript.triggers.TriggerRegistry", - "kind": "call", - "cross_tree": false, - "label": { - "zh": "读取触发器", - "en": "reads triggers" - } - } - ], - "layouts": { - "pyvdisk": { - "schema_version": 1, - "id": "pyvdisk", - "updated_at": "2026-09-24T11:39:34.471Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "从底向上读:storage 是块设备、文件系统、容器与数据服务;execution 在其上提供执行平面;governance 是能力门禁;vscript 是可执行脚本语言;cli 是用户入口;contracts 是被各方实现的抽象契约;接着是对外一组——Agent 工作区与沙箱、导出面、以及沉底的平台适配层;examples/tests/docs/delivery 是示例、保障与交付。", - "en": "Read bottom-up: storage holds block devices, filesystems, containers and data services; execution layers the execution plane on top; governance is the capability gate; vscript is the executable script language; cli is the user entry; contracts are the abstractions others implement; then the outward-facing group -- the agent workspace and its sandbox, the exported API, and the platform layer everything sits on; examples/docs/tests/delivery provide assurance and delivery." - }, - "order": [ - "pyvdisk.storage", - "pyvdisk.execution", - "pyvdisk.governance", - "pyvdisk.vscript", - "pyvdisk.cli", - "pyvdisk.contracts", - "pyvdisk.agent", - "pyvdisk.api", - "pyvdisk.compat", - "pyvdisk.platform", - "pyvdisk.examples", - "pyvdisk.tests", - "pyvdisk.docs", - "pyvdisk.delivery" - ], - "groups": [ - { - "id": "engine", - "title": { - "zh": "存储与执行引擎", - "en": "Storage and Execution Engine" - }, - "children": [ - "pyvdisk.storage", - "pyvdisk.execution", - "pyvdisk.governance", - "pyvdisk.contracts" - ] - }, - { - "id": "language", - "title": { - "zh": "脚本语言与命令行", - "en": "Script Language and CLI" - }, - "children": [ - "pyvdisk.vscript", - "pyvdisk.cli" - ] - }, - { - "id": "surface", - "title": { - "zh": "对外接口与 Agent 入口", - "en": "Public Surface and Agent Entry" - }, - "children": [ - "pyvdisk.agent", - "pyvdisk.api", - "pyvdisk.compat", - "pyvdisk.platform" - ] - }, - { - "id": "meta", - "title": { - "zh": "示例、文档、测试与交付", - "en": "Examples, Docs, Tests and Delivery" - }, - "children": [ - "pyvdisk.examples", - "pyvdisk.tests", - "pyvdisk.docs", - "pyvdisk.delivery" - ] - } - ] - }, - "pyvdisk.agent": { - "schema_version": 1, - "id": "pyvdisk.agent", - "updated_at": "2026-09-24T11:33:31.064Z", - "mode": "groups", - "reading": { - "zh": "从左到右:路径能指向什么,有哪些工具,把两者合起来的门面,最后是调用在哪里执行、留下什么记录。", - "en": "Left to right: what a path may name, what tools exist, the facade that ties them together, then where a call runs and what it leaves behind." - }, - "order": [ - "pyvdisk.agent.paths", - "pyvdisk.agent.tools", - "pyvdisk.agent.sandbox", - "pyvdisk.agent.script", - "pyvdisk.agent.audit" - ], - "groups": [ - { - "id": "surface", - "title": { - "zh": "模型看到的面", - "en": "What the model sees" - }, - "children": [ - "pyvdisk.agent.paths", - "pyvdisk.agent.tools", - "pyvdisk.agent.sandbox" - ] - }, - { - "id": "execution", - "title": { - "zh": "执行与留痕", - "en": "Execution and evidence" - }, - "children": [ - "pyvdisk.agent.script", - "pyvdisk.agent.audit" - ] - } - ] - }, - "pyvdisk.cli": { - "schema_version": 1, - "id": "pyvdisk.cli", - "updated_at": "2026-09-23T07:26:44.335Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先是共享的格式化与打开 VFS 辅助,再是文件系统子命令(镜像生命周期、目录、整文件操作、检查、管理),随后是卷/驱动器/向量/日志数据子命令,最后是注册全部命令的解析器、分发入口与 python -m 钩子。", - "en": "Shared formatting and VFS-opening helpers, then the filesystem subcommands (image lifecycle, directories, whole-file operations, inspection, administration), then the volume/drive/vector/log data subcommands, and finally the parser that registers them all, the dispatch entry point and the python -m hook." - }, - "order": [ - "pyvdisk.cli.format", - "pyvdisk.cli.open", - "pyvdisk.cli.image", - "pyvdisk.cli.dirs", - "pyvdisk.cli.file-ops", - "pyvdisk.cli.inspect", - "pyvdisk.cli.admin", - "pyvdisk.cli.volume", - "pyvdisk.cli.drive", - "pyvdisk.cli.vector", - "pyvdisk.cli.log", - "pyvdisk.cli.parser", - "pyvdisk.cli.main", - "pyvdisk.cli.entry" - ], - "groups": [ - { - "id": "helpers", - "title": { - "zh": "共享辅助", - "en": "Shared Helpers" - }, - "children": [ - "pyvdisk.cli.format", - "pyvdisk.cli.open" - ] - }, - { - "id": "fs", - "title": { - "zh": "文件系统子命令", - "en": "Filesystem Subcommands" - }, - "children": [ - "pyvdisk.cli.image", - "pyvdisk.cli.dirs", - "pyvdisk.cli.file-ops", - "pyvdisk.cli.inspect", - "pyvdisk.cli.admin" - ] - }, - { - "id": "data", - "title": { - "zh": "卷与数据子命令", - "en": "Volume and Data Subcommands" - }, - "children": [ - "pyvdisk.cli.volume", - "pyvdisk.cli.drive", - "pyvdisk.cli.vector", - "pyvdisk.cli.log" - ] - }, - { - "id": "entry", - "title": { - "zh": "解析器与入口", - "en": "Parser and Entry Point" - }, - "children": [ - "pyvdisk.cli.parser", - "pyvdisk.cli.main", - "pyvdisk.cli.entry" - ] - } - ] - }, - "pyvdisk.compat": { - "schema_version": 1, - "id": "pyvdisk.compat", - "updated_at": "2026-09-23T07:26:31.537Z", - "reading": { - "zh": "两条保持可用的遗留导入路径:容器化之前的 Unified 名称,以及旧的 vscript.checkpoint 位置。", - "en": "Two legacy import paths kept working: the pre-container Unified names and the old vscript.checkpoint location." - }, - "order": [ - "pyvdisk.compat.unified", - "pyvdisk.compat.vscript" - ] - }, - "pyvdisk.contracts": { - "schema_version": 1, - "id": "pyvdisk.contracts", - "updated_at": "2026-09-23T07:24:03.694Z", - "mode": "groups", - "reading": { - "zh": "先是能力、存储与持久性原语,再是事件、执行与运行句柄协议,以及把它们串起来的 ExecutionPlane。", - "en": "The capability, storage and durability primitives, then the event, execution and run-handle protocols and the ExecutionPlane that ties them together." - }, - "order": [ - "pyvdisk.contracts.capability", - "pyvdisk.contracts.storage", - "pyvdisk.contracts.durability", - "pyvdisk.contracts.events", - "pyvdisk.contracts.execution", - "pyvdisk.contracts.runhandle", - "pyvdisk.contracts.plane" - ], - "groups": [ - { - "id": "primitives", - "title": { - "zh": "基础契约", - "en": "Primitive Contracts" - }, - "children": [ - "pyvdisk.contracts.capability", - "pyvdisk.contracts.storage", - "pyvdisk.contracts.durability" - ] - }, - { - "id": "plane", - "title": { - "zh": "事件与执行契约", - "en": "Event and Execution Contracts" - }, - "children": [ - "pyvdisk.contracts.events", - "pyvdisk.contracts.execution", - "pyvdisk.contracts.runhandle", - "pyvdisk.contracts.plane" - ] - } - ] - }, - "pyvdisk.delivery": { - "schema_version": 1, - "id": "pyvdisk.delivery", - "updated_at": "2026-09-23T07:24:04.294Z", - "reading": { - "zh": "先是打包元数据(构建与安装什么),再是守门的 CI 工作流与强制风格的 lint 配置。", - "en": "Packaging metadata first (what gets built and installed), then the CI workflow that gates merges and the lint configuration enforcing style." - }, - "order": [ - "pyvdisk.delivery.packaging", - "pyvdisk.delivery.ci", - "pyvdisk.delivery.lint" - ] - }, - "pyvdisk.docs": { - "schema_version": 1, - "id": "pyvdisk.docs", - "updated_at": "2026-09-24T09:56:14.155Z", - "reading": { - "zh": "先读 README 建立整体印象,再看架构总览、契约参考、能力治理设计说明与 VScript 语言规范;变更日志记录每个版本改了什么。", - "en": "Start with the README for orientation, then the architecture overview, the contract reference, the capability-governance design note and the VScript language specification; the changelog records what changed release by release." - }, - "order": [ - "pyvdisk.docs.readme", - "pyvdisk.docs.architecture", - "pyvdisk.docs.contracts", - "pyvdisk.docs.api-governance", - "pyvdisk.docs.vscript-spec", - "pyvdisk.docs.changelog" - ] - }, - "pyvdisk.examples": { - "schema_version": 1, - "id": "pyvdisk.examples", - "updated_at": "2026-09-24T11:34:32.619Z", - "mode": "grid", - "reading": { - "zh": "两个入口:自底向上跑通整条栈的导览,以及演示框架如何对接的 agent loop。", - "en": "Two entries: the bottom-up tour of the whole stack, and the agent loop that shows how a framework talks to it." - }, - "order": [ - "pyvdisk.examples.quickstart", - "pyvdisk.examples.agent-tools" - ] - }, - "pyvdisk.execution": { - "schema_version": 1, - "id": "pyvdisk.execution", - "updated_at": "2026-09-23T07:24:03.994Z", - "mode": "groups", - "reading": { - "zh": "先是持久状态:任务队列、带版本的运行记录,以及含可调用对象描述的操作注册表;service 拥有 worker 并向这三者分发执行。", - "en": "Durable state first: the task queue, the versioned run records and the operation registry with its callable descriptions; the service then owns the workers and dispatches into all three." - }, - "order": [ - "pyvdisk.execution.queue", - "pyvdisk.execution.runstate", - "pyvdisk.execution.operations", - "pyvdisk.execution.service" - ], - "groups": [ - { - "id": "durable", - "title": { - "zh": "持久状态", - "en": "Durable State" - }, - "children": [ - "pyvdisk.execution.queue", - "pyvdisk.execution.runstate", - "pyvdisk.execution.operations" - ] - }, - { - "id": "svc", - "title": { - "zh": "执行服务", - "en": "Execution Service" - }, - "children": [ - "pyvdisk.execution.service" - ] - } - ] - }, - "pyvdisk.execution.operations": { - "schema_version": 1, - "id": "pyvdisk.execution.operations", - "updated_at": "2026-09-23T07:24:44.073Z", - "reading": { - "zh": "先是错误词表与存储记录,再是可调用对象注册表与给操作稳定 id 的描述逻辑,最后是注册表门面及其背衬访问。", - "en": "Error vocabulary and the stored record first, then the callable registry and operation description that give an operation a stable id, then the registry facade and its backend access." - }, - "order": [ - "pyvdisk.execution.operations.errors", - "pyvdisk.execution.operations.record", - "pyvdisk.execution.operations.callables", - "pyvdisk.execution.operations.describe", - "pyvdisk.execution.operations.registry", - "pyvdisk.execution.operations.storage" - ] - }, - "pyvdisk.execution.queue": { - "schema_version": 1, - "id": "pyvdisk.execution.queue", - "updated_at": "2026-09-23T07:24:44.383Z", - "reading": { - "zh": "先是错误体系与任务值对象,再是状态持久化与重试退避,随后是完整任务生命周期,最后是过期租约回收与列举。", - "en": "Error taxonomy and the task value object, then state persistence with retry backoff, then the full task lifecycle, and finally stale-lease recovery and listing." - }, - "order": [ - "pyvdisk.execution.queue.errors", - "pyvdisk.execution.queue.task", - "pyvdisk.execution.queue.store", - "pyvdisk.execution.queue.lifecycle", - "pyvdisk.execution.queue.recovery" - ] - }, - "pyvdisk.execution.runstate": { - "schema_version": 1, - "id": "pyvdisk.execution.runstate", - "updated_at": "2026-09-23T07:24:44.749Z", - "reading": { - "zh": "model 是运行记录及其冲突类型,store 在其上提供带版本的迁移、幂等创建与过期运行回收。", - "en": "model is the run record and its conflict type, store adds versioned transitions, idempotent creation and stale-run recovery." - }, - "order": [ - "pyvdisk.execution.runstate.model", - "pyvdisk.execution.runstate.store" - ] - }, - "pyvdisk.execution.service": { - "schema_version": 1, - "id": "pyvdisk.execution.service", - "updated_at": "2026-09-23T07:24:45.085Z", - "reading": { - "zh": "先是构造与 worker 控制,再是单个操作如何被分发(受限视图加 Python 或 VScript 执行),随后是队列驱动的运行,最后是 submit/run/cancel 接口。", - "en": "Construction and worker control, then how one operation is dispatched (scoped view plus Python or VScript execution), then queue-driven runs, and finally the submit/run/cancel surface." - }, - "order": [ - "pyvdisk.execution.service.setup", - "pyvdisk.execution.service.invoke", - "pyvdisk.execution.service.queue", - "pyvdisk.execution.service.submit" - ] - }, - "pyvdisk.governance": { - "schema_version": 1, - "id": "pyvdisk.governance", - "updated_at": "2026-09-23T07:24:45.377Z", - "reading": { - "zh": "先是能力门禁(路径归一、范围包含与受保护委托),再是它保护的文件系统与向量/日志适配器,最后是交给不可信代码的 ScopedDataDisk 对象。", - "en": "The capability gate comes first (path scoping, containment and guarded delegation), then the filesystem and vector/log adapters it protects, and finally the ScopedDataDisk object handed to untrusted code." - }, - "order": [ - "pyvdisk.governance.namespace", - "pyvdisk.governance.files", - "pyvdisk.governance.data", - "pyvdisk.governance.scoped" - ] - }, - "pyvdisk.platform": { - "schema_version": 1, - "id": "pyvdisk.platform", - "updated_at": "2026-09-24T11:34:38.929Z", - "mode": "grid", - "max_columns": 2, - "reading": { - "zh": "先看当前用的是哪套实现,再看其余模块都会经过的四类原语:定位读写、文件锁、持久化与身份。", - "en": "Which implementation is in force, then the four primitive groups every other module goes through: positioned IO, locking, and durability/identity." - }, - "order": [ - "pyvdisk.platform.dispatch", - "pyvdisk.platform.positional", - "pyvdisk.platform.locking", - "pyvdisk.platform.durability" - ], - "groups": [ - { - "id": "primitives", - "title": { - "zh": "四类原语", - "en": "Primitives" - }, - "children": [ - "pyvdisk.platform.dispatch", - "pyvdisk.platform.positional", - "pyvdisk.platform.locking", - "pyvdisk.platform.durability" - ] - } - ] - }, - "pyvdisk.storage": { - "schema_version": 1, - "id": "pyvdisk.storage", - "updated_at": "2026-09-23T07:23:36.967Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "自下而上:block 是最底的块设备抽象,identity 给它贴身份,fs 在其上实现 inode/目录/块分配,vfs 提供路径式门面,rwlock 负责并发;volume 把多块盘组合成带冗余的卷;vector/log/logging 是块设备上的数据服务;datadisk+wal+checkpoint 组成事务性容器;driver 与 fuse 是挂载与宿主接入。", - "en": "Bottom-up: block is the raw device abstraction, identity labels it, fs implements inodes/directories/block allocation on top, vfs exposes a path-based facade and rwlock handles concurrency; volume combines disks into redundant volumes; vector/log/logging are data services over block devices; datadisk+wal+checkpoint form the transactional container; driver and fuse attach it to hosts." - }, - "order": [ - "pyvdisk.storage.fs", - "pyvdisk.storage.vfs", - "pyvdisk.storage.block", - "pyvdisk.storage.rwlock", - "pyvdisk.storage.identity", - "pyvdisk.storage.volume", - "pyvdisk.storage.vector", - "pyvdisk.storage.log", - "pyvdisk.storage.logging", - "pyvdisk.storage.datadisk", - "pyvdisk.storage.wal", - "pyvdisk.storage.checkpoint", - "pyvdisk.storage.driver", - "pyvdisk.storage.fuse" - ], - "groups": [ - { - "id": "corefs", - "title": { - "zh": "文件系统与块层", - "en": "Filesystem and Block Layer" - }, - "children": [ - "pyvdisk.storage.fs", - "pyvdisk.storage.vfs", - "pyvdisk.storage.block", - "pyvdisk.storage.rwlock", - "pyvdisk.storage.identity" - ] - }, - { - "id": "volumes", - "title": { - "zh": "卷与冗余", - "en": "Volumes and Redundancy" - }, - "children": [ - "pyvdisk.storage.volume" - ] - }, - { - "id": "services", - "title": { - "zh": "数据服务", - "en": "Data Services" - }, - "children": [ - "pyvdisk.storage.vector", - "pyvdisk.storage.log", - "pyvdisk.storage.logging" - ] - }, - { - "id": "containers", - "title": { - "zh": "容器与持久化", - "en": "Container and Durability" - }, - "children": [ - "pyvdisk.storage.datadisk", - "pyvdisk.storage.wal", - "pyvdisk.storage.checkpoint" - ] - }, - { - "id": "access", - "title": { - "zh": "访问入口", - "en": "Access Entry Points" - }, - "children": [ - "pyvdisk.storage.driver", - "pyvdisk.storage.fuse" - ] - } - ] - }, - "pyvdisk.storage.block": { - "schema_version": 1, - "id": "pyvdisk.storage.block", - "updated_at": "2026-09-23T07:23:37.893Z", - "reading": { - "zh": "io 是块级读写原语,image 负责镜像文件的打开与几何,access 是上层看到的设备接口。", - "en": "io holds the raw block read/write primitives, image handles image files and geometry, and access is the device interface seen by upper layers." - }, - "order": [ - "pyvdisk.storage.block.io", - "pyvdisk.storage.block.image", - "pyvdisk.storage.block.access" - ] - }, - "pyvdisk.storage.checkpoint": { - "schema_version": 1, - "id": "pyvdisk.storage.checkpoint", - "updated_at": "2026-09-23T07:23:38.263Z", - "reading": { - "zh": "open 决定背衬(VFS 或宿主目录)与锁;io 是读写保存;triggers 是给调度器的事件去重层。", - "en": "open chooses the backend (VFS or host directory) and the lock; io reads, writes and saves; triggers is the event-dedup layer used by the scheduler." - }, - "order": [ - "pyvdisk.storage.checkpoint.open", - "pyvdisk.storage.checkpoint.io", - "pyvdisk.storage.checkpoint.triggers" - ] - }, - "pyvdisk.storage.datadisk": { - "schema_version": 1, - "id": "pyvdisk.storage.datadisk", - "updated_at": "2026-09-23T07:23:38.616Z", - "mode": "groups", - "reading": { - "zh": "从元数据编解码与事务暂存机制开始,到事务的提交/回滚结局,再看文件系统与向量/日志的事务性命名空间,最后是 DataDisk 容器自身的核心与对外接口。", - "en": "From metadata codec and transaction staging, to commit/rollback outcomes, then the transactional filesystem and vector/log namespaces, and finally the DataDisk container core and its interface." - }, - "order": [ - "pyvdisk.storage.datadisk.codec", - "pyvdisk.storage.datadisk.tx", - "pyvdisk.storage.datadisk.tx-lifecycle", - "pyvdisk.storage.datadisk.namespace", - "pyvdisk.storage.datadisk.services", - "pyvdisk.storage.datadisk.core", - "pyvdisk.storage.datadisk.api" - ], - "groups": [ - { - "id": "txm", - "title": { - "zh": "事务机制", - "en": "Transaction Machinery" - }, - "children": [ - "pyvdisk.storage.datadisk.codec", - "pyvdisk.storage.datadisk.tx", - "pyvdisk.storage.datadisk.tx-lifecycle" - ] - }, - { - "id": "ns", - "title": { - "zh": "事务性命名空间", - "en": "Transactional Namespaces" - }, - "children": [ - "pyvdisk.storage.datadisk.namespace", - "pyvdisk.storage.datadisk.services" - ] - }, - { - "id": "container", - "title": { - "zh": "容器本体", - "en": "The Container" - }, - "children": [ - "pyvdisk.storage.datadisk.core", - "pyvdisk.storage.datadisk.api" - ] - } - ] - }, - "pyvdisk.storage.driver": { - "schema_version": 1, - "id": "pyvdisk.storage.driver", - "updated_at": "2026-09-23T07:23:39.653Z", - "reading": { - "zh": "assembled 是挂载结果对象,mounts 是挂载记录,manager 是扫描与台账,mounting 按类型分发挂载,lifecycle 负责卸载与恢复。", - "en": "assembled is the mount result object, mounts holds mount records, manager scans and keeps the ledger, mounting dispatches per disk type, lifecycle unmounts and recovers." - }, - "order": [ - "pyvdisk.storage.driver.assembled", - "pyvdisk.storage.driver.mounts", - "pyvdisk.storage.driver.manager", - "pyvdisk.storage.driver.mounting", - "pyvdisk.storage.driver.lifecycle" - ] - }, - "pyvdisk.storage.fs": { - "schema_version": 1, - "id": "pyvdisk.storage.fs", - "updated_at": "2026-09-23T07:23:37.275Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先看磁盘布局(超级块、inode 表、位图、多级块指针),再看目录与路径解析,然后是创建/写入/截断等文件操作,最后是加锁、挂载、格式化、fsck 与扩容。", - "en": "Start with the on-disk layout (superblock, inode table, bitmap, multi-level block pointers), then directories and path resolution, then create/write/truncate operations, and finally locking, mount, mkfs, fsck and growth." - }, - "order": [ - "pyvdisk.storage.fs.layout", - "pyvdisk.storage.fs.superblock", - "pyvdisk.storage.fs.inode", - "pyvdisk.storage.fs.inode-io", - "pyvdisk.storage.fs.bitmap", - "pyvdisk.storage.fs.block-alloc", - "pyvdisk.storage.fs.pointers", - "pyvdisk.storage.fs.dir", - "pyvdisk.storage.fs.dir-mutate", - "pyvdisk.storage.fs.names", - "pyvdisk.storage.fs.paths", - "pyvdisk.storage.fs.attrs", - "pyvdisk.storage.fs.stat", - "pyvdisk.storage.fs.query", - "pyvdisk.storage.fs.locking", - "pyvdisk.storage.fs.mount", - "pyvdisk.storage.fs.mkfs", - "pyvdisk.storage.fs.fsck", - "pyvdisk.storage.fs.grow", - "pyvdisk.storage.fs.create", - "pyvdisk.storage.fs.mutate", - "pyvdisk.storage.fs.readwrite", - "pyvdisk.storage.fs.truncate" - ], - "groups": [ - { - "id": "ondisk", - "title": { - "zh": "磁盘布局", - "en": "On-Disk Layout" - }, - "children": [ - "pyvdisk.storage.fs.layout", - "pyvdisk.storage.fs.superblock", - "pyvdisk.storage.fs.inode", - "pyvdisk.storage.fs.inode-io", - "pyvdisk.storage.fs.bitmap", - "pyvdisk.storage.fs.block-alloc", - "pyvdisk.storage.fs.pointers" - ] - }, - { - "id": "namespace", - "title": { - "zh": "目录与命名", - "en": "Directories and Naming" - }, - "children": [ - "pyvdisk.storage.fs.dir", - "pyvdisk.storage.fs.dir-mutate", - "pyvdisk.storage.fs.names", - "pyvdisk.storage.fs.paths", - "pyvdisk.storage.fs.attrs", - "pyvdisk.storage.fs.stat", - "pyvdisk.storage.fs.query" - ] - }, - { - "id": "ops", - "title": { - "zh": "文件操作", - "en": "File Operations" - }, - "children": [ - "pyvdisk.storage.fs.create", - "pyvdisk.storage.fs.mutate", - "pyvdisk.storage.fs.readwrite", - "pyvdisk.storage.fs.truncate" - ] - }, - { - "id": "lifecycle", - "title": { - "zh": "生命周期与维护", - "en": "Lifecycle and Maintenance" - }, - "children": [ - "pyvdisk.storage.fs.locking", - "pyvdisk.storage.fs.mount", - "pyvdisk.storage.fs.mkfs", - "pyvdisk.storage.fs.fsck", - "pyvdisk.storage.fs.grow" - ] - } - ] - }, - "pyvdisk.storage.fuse": { - "schema_version": 1, - "id": "pyvdisk.storage.fuse", - "updated_at": "2026-09-23T07:23:39.976Z", - "reading": { - "zh": "meta 与 data 分别实现元数据与数据回调,handlers 覆盖其余 FUSE 操作,mount 负责挂载与参数。", - "en": "meta and data implement the metadata and data callbacks, handlers covers the remaining FUSE operations, and mount performs the mount and argument handling." - }, - "order": [ - "pyvdisk.storage.fuse.meta", - "pyvdisk.storage.fuse.data", - "pyvdisk.storage.fuse.handlers", - "pyvdisk.storage.fuse.mount" - ] - }, - "pyvdisk.storage.identity": { - "schema_version": 1, - "id": "pyvdisk.storage.identity", - "updated_at": "2026-09-23T07:23:40.359Z", - "reading": { - "zh": "format 定义尾标的磁盘格式,model 是其内存模型,trailer 负责编码解码,probe 从任意宿主文件识别出 pyvdisk 镜像。", - "en": "format defines the on-disk trailer format, model is its in-memory shape, trailer encodes and decodes it, and probe recognises a pyvdisk image from an arbitrary host file." - }, - "order": [ - "pyvdisk.storage.identity.format", - "pyvdisk.storage.identity.model", - "pyvdisk.storage.identity.trailer", - "pyvdisk.storage.identity.probe" - ] - }, - "pyvdisk.storage.log": { - "schema_version": 1, - "id": "pyvdisk.storage.log", - "updated_at": "2026-09-23T07:24:01.803Z", - "reading": { - "zh": "先打开日志盘并管理流,再追加事件,随后经 query 与其过滤辅助读回,最后执行保留策略。", - "en": "Opens the log disk, manages streams, appends events, then reads them back through query and its filter helper, and finally applies retention." - }, - "order": [ - "pyvdisk.storage.log.open", - "pyvdisk.storage.log.streams", - "pyvdisk.storage.log.append", - "pyvdisk.storage.log.query", - "pyvdisk.storage.log.filter", - "pyvdisk.storage.log.retention" - ] - }, - "pyvdisk.storage.logging": { - "schema_version": 1, - "id": "pyvdisk.storage.logging", - "updated_at": "2026-09-23T07:24:02.119Z", - "reading": { - "zh": "先是事件记录,再是持久化它的 sink 与发出事件的 logger,之后是标准库 logging 桥接与上下文传递辅助。", - "en": "Event records first, then the sinks that persist them and the logger that emits, then the stdlib-logging bridge and the context propagation helpers." - }, - "order": [ - "pyvdisk.storage.logging.events", - "pyvdisk.storage.logging.sinks", - "pyvdisk.storage.logging.logger", - "pyvdisk.storage.logging.bridge", - "pyvdisk.storage.logging.context" - ] - }, - "pyvdisk.storage.rwlock": { - "schema_version": 1, - "id": "pyvdisk.storage.rwlock", - "updated_at": "2026-09-23T07:24:02.413Z", - "reading": { - "zh": "core 是读写锁本体(获取、释放、升级);ctx 把它包装成 with 语句可用的读/写上下文。", - "en": "core is the reader/writer lock itself (acquire, release, upgrade); ctx wraps it into with-statement read and write contexts." - }, - "order": [ - "pyvdisk.storage.rwlock.core", - "pyvdisk.storage.rwlock.ctx" - ] - }, - "pyvdisk.storage.vector": { - "schema_version": 1, - "id": "pyvdisk.storage.vector", - "updated_at": "2026-09-24T11:32:36.825Z", - "mode": "grid", - "max_columns": 3, - "reading": { - "zh": "先看集合簿记与记录,再看索引后端,最后是消费它的检索。", - "en": "Collection bookkeeping and records first, then the index backend, then the search that consumes it." - }, - "order": [ - "pyvdisk.storage.vector.open", - "pyvdisk.storage.vector.collections", - "pyvdisk.storage.vector.records", - "pyvdisk.storage.vector.flat-index", - "pyvdisk.storage.vector.search" - ] - }, - "pyvdisk.storage.vfs": { - "schema_version": 1, - "id": "pyvdisk.storage.vfs", - "updated_at": "2026-09-23T07:23:37.579Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "先看 VFS 如何打开镜像/卷并挂载(含 create),再沿着路径式接口读下去:权限检查、查询、目录、文件、删除、属性、宿主导入导出、遍历与空间;最后是 VFile 文件对象及其读写与上下文。", - "en": "First how the VFS opens an image or volume and mounts it (including create), then the path-based API: permission checks, query, directories, files, removal, attributes, host transfer, walking and space; finally the VFile object with its IO and context." - }, - "order": [ - "pyvdisk.storage.vfs.open", - "pyvdisk.storage.vfs.create", - "pyvdisk.storage.vfs.lifetime", - "pyvdisk.storage.vfs.permissions", - "pyvdisk.storage.vfs.query", - "pyvdisk.storage.vfs.dirs", - "pyvdisk.storage.vfs.files", - "pyvdisk.storage.vfs.remove", - "pyvdisk.storage.vfs.stat", - "pyvdisk.storage.vfs.attrs", - "pyvdisk.storage.vfs.hostio", - "pyvdisk.storage.vfs.walk", - "pyvdisk.storage.vfs.space", - "pyvdisk.storage.vfs.vfile", - "pyvdisk.storage.vfs.vfile-io", - "pyvdisk.storage.vfs.vfile-ctx" - ], - "groups": [ - { - "id": "lifecycle", - "title": { - "zh": "挂载与生命周期", - "en": "Mount and Lifetime" - }, - "children": [ - "pyvdisk.storage.vfs.open", - "pyvdisk.storage.vfs.create", - "pyvdisk.storage.vfs.lifetime" - ] - }, - { - "id": "namespace", - "title": { - "zh": "路径式文件系统接口", - "en": "Path-Based Filesystem API" - }, - "children": [ - "pyvdisk.storage.vfs.permissions", - "pyvdisk.storage.vfs.query", - "pyvdisk.storage.vfs.dirs", - "pyvdisk.storage.vfs.files", - "pyvdisk.storage.vfs.remove", - "pyvdisk.storage.vfs.stat", - "pyvdisk.storage.vfs.attrs", - "pyvdisk.storage.vfs.hostio", - "pyvdisk.storage.vfs.walk", - "pyvdisk.storage.vfs.space" - ] - }, - { - "id": "fileobj", - "title": { - "zh": "文件对象", - "en": "File Objects" - }, - "children": [ - "pyvdisk.storage.vfs.vfile", - "pyvdisk.storage.vfs.vfile-io", - "pyvdisk.storage.vfs.vfile-ctx" - ] - } - ] - }, - "pyvdisk.storage.volume": { - "schema_version": 1, - "id": "pyvdisk.storage.volume", - "updated_at": "2026-09-23T07:24:03.065Z", - "reading": { - "zh": "先是卷元数据与其模型,再是打开与创建,随后是把逻辑块映射到成员盘的 layout、使用它的块/字节 IO,最后是镜像修复与重同步。", - "en": "Volume metadata and its model, then open and create, then the layout that maps logical blocks onto members, the block and byte IO that use it, and finally mirror repair and resync." - }, - "order": [ - "pyvdisk.storage.volume.meta", - "pyvdisk.storage.volume.model", - "pyvdisk.storage.volume.open", - "pyvdisk.storage.volume.create", - "pyvdisk.storage.volume.layout", - "pyvdisk.storage.volume.blocks", - "pyvdisk.storage.volume.bytes", - "pyvdisk.storage.volume.repair" - ] - }, - "pyvdisk.storage.wal": { - "schema_version": 1, - "id": "pyvdisk.storage.wal", - "updated_at": "2026-09-23T07:24:03.371Z", - "reading": { - "zh": "journal 是 VFS 背衬的元数据日志,entries 是其事务动词与恢复重放,undo 是记录旧文件内容的宿主文件系统变体。", - "en": "journal is the VFS-backed metadata log, entries are its transaction verbs and recovery replay, and undo is the host-filesystem variant that records previous file bodies." - }, - "order": [ - "pyvdisk.storage.wal.journal", - "pyvdisk.storage.wal.entries", - "pyvdisk.storage.wal.undo" - ] - }, - "pyvdisk.tests": { - "schema_version": 1, - "id": "pyvdisk.tests", - "updated_at": "2026-09-24T11:39:19.907Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "按所验证的子系统分组:夹具、文件系统持久性与平台适配层、事务与崩溃、执行平面、队列与精确一次保证、VScript、治理与沙箱,最后是日志盘、CLI、打包与零依赖检查。", - "en": "Grouped by the subsystem each module validates: fixtures, filesystem durability and the platform layer, transactions and crashes, the execution plane, queue and exactly-once guarantees, VScript, governance and the sandbox, then log-disk, CLI, packaging and the zero-dependency check." - }, - "order": [ - "pyvdisk.tests.fixtures", - "pyvdisk.tests.vdisk", - "pyvdisk.tests.atomic-save", - "pyvdisk.tests.submit-conflict", - "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount", - "pyvdisk.tests.compat", - "pyvdisk.tests.tx-rollback", - "pyvdisk.tests.tx-idempotency", - "pyvdisk.tests.crash-matrix", - "pyvdisk.tests.checkpoint", - "pyvdisk.tests.participant-compensation", - "pyvdisk.tests.wal-checkpoint", - "pyvdisk.tests.execution", - "pyvdisk.tests.execution-queue", - "pyvdisk.tests.cancellation", - "pyvdisk.tests.e2e", - "pyvdisk.tests.queue", - "pyvdisk.tests.queue-backoff", - "pyvdisk.tests.queue-crossprocess", - "pyvdisk.tests.exactly-once-internal", - "pyvdisk.tests.exactly-once-operation", - "pyvdisk.tests.vscript", - "pyvdisk.tests.vscript-audit", - "pyvdisk.tests.audit-trail", - "pyvdisk.tests.vscript-host", - "pyvdisk.tests.vscript-optional", - "pyvdisk.tests.vscript-undo", - "pyvdisk.tests.vscript-cron", - "pyvdisk.tests.vscript-triggers", - "pyvdisk.tests.governance", - "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts", - "pyvdisk.tests.agent-sandbox", - "pyvdisk.tests.logdisk-compact", - "pyvdisk.tests.logdisk-retention", - "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging", - "pyvdisk.tests.no-dependency" - ], - "groups": [ - { - "id": "fs", - "title": { - "zh": "文件系统与持久性", - "en": "Filesystem and Durability" - }, - "children": [ - "pyvdisk.tests.fixtures", - "pyvdisk.tests.vdisk", - "pyvdisk.tests.atomic-save", - "pyvdisk.tests.submit-conflict", - "pyvdisk.tests.wal-recovery", - "pyvdisk.tests.fuse-mount", - "pyvdisk.tests.compat" - ] - }, - { - "id": "tx", - "title": { - "zh": "事务与崩溃", - "en": "Transaction and Crash" - }, - "children": [ - "pyvdisk.tests.tx-rollback", - "pyvdisk.tests.tx-idempotency", - "pyvdisk.tests.crash-matrix", - "pyvdisk.tests.checkpoint", - "pyvdisk.tests.participant-compensation", - "pyvdisk.tests.wal-checkpoint" - ] - }, - { - "id": "exec", - "title": { - "zh": "执行平面", - "en": "Execution Plane" - }, - "children": [ - "pyvdisk.tests.execution", - "pyvdisk.tests.execution-queue", - "pyvdisk.tests.cancellation", - "pyvdisk.tests.e2e" - ] - }, - { - "id": "queue", - "title": { - "zh": "队列与精确一次", - "en": "Queue and Exactly-Once" - }, - "children": [ - "pyvdisk.tests.queue", - "pyvdisk.tests.queue-backoff", - "pyvdisk.tests.queue-crossprocess", - "pyvdisk.tests.exactly-once-internal", - "pyvdisk.tests.exactly-once-operation" - ] - }, - { - "id": "vscript", - "title": { - "zh": "VScript", - "en": "VScript" - }, - "children": [ - "pyvdisk.tests.vscript", - "pyvdisk.tests.vscript-audit", - "pyvdisk.tests.audit-trail", - "pyvdisk.tests.vscript-host", - "pyvdisk.tests.vscript-optional", - "pyvdisk.tests.vscript-undo", - "pyvdisk.tests.vscript-cron", - "pyvdisk.tests.vscript-triggers" - ] - }, - { - "id": "gov", - "title": { - "zh": "治理与沙箱", - "en": "Governance and Sandbox" - }, - "children": [ - "pyvdisk.tests.governance", - "pyvdisk.tests.api-governance", - "pyvdisk.tests.contracts", - "pyvdisk.tests.agent-sandbox" - ] - }, - { - "id": "misc", - "title": { - "zh": "日志盘、CLI 与打包", - "en": "Log Disk, CLI and Packaging" - }, - "children": [ - "pyvdisk.tests.logdisk-compact", - "pyvdisk.tests.logdisk-retention", - "pyvdisk.tests.agentic-cli", - "pyvdisk.tests.packaging", - "pyvdisk.tests.no-dependency" - ] - } - ] - }, - "pyvdisk.tests.vdisk": { - "schema_version": 1, - "id": "pyvdisk.tests.vdisk", - "updated_at": "2026-09-23T07:24:46.362Z", - "max_columns": 4, - "reading": { - "zh": "这份 1650 行的存储测试模块按类顺序阅读:基础路径与大文件、命名与 IO、链接与属性、维护、裸设备访问、空间耗尽、四组卷模式、身份、磁盘管理器、并发、权限、向量盘、日志盘,最后是 CLI 契约。", - "en": "The single 1650-line storage test module, read in class order: basic paths and large files, naming and IO, links and attributes, maintenance, raw device access, space exhaustion, the four volume-mode groups, identity, the disk manager, concurrency, permissions, vector disk, log disk and finally the CLI contract." - }, - "order": [ - "pyvdisk.tests.vdisk.base", - "pyvdisk.tests.vdisk.large-files", - "pyvdisk.tests.vdisk.names", - "pyvdisk.tests.vdisk.io", - "pyvdisk.tests.vdisk.links", - "pyvdisk.tests.vdisk.maintenance", - "pyvdisk.tests.vdisk.raw-fs", - "pyvdisk.tests.vdisk.exhaustion", - "pyvdisk.tests.vdisk.volume", - "pyvdisk.tests.vdisk.volume-mirror", - "pyvdisk.tests.vdisk.volume-meta", - "pyvdisk.tests.vdisk.volume-detect", - "pyvdisk.tests.vdisk.identity", - "pyvdisk.tests.vdisk.disk-manager", - "pyvdisk.tests.vdisk.locking", - "pyvdisk.tests.vdisk.permissions", - "pyvdisk.tests.vdisk.vector", - "pyvdisk.tests.vdisk.log", - "pyvdisk.tests.vdisk.cli" - ] - }, - "pyvdisk.vscript": { - "schema_version": 1, - "id": "pyvdisk.vscript", - "updated_at": "2026-09-24T09:55:44.889Z", - "mode": "groups", - "max_columns": 4, - "reading": { - "zh": "跟随一个脚本穿过系统:前端完成词法与语法分析,策略与挂载/宿主层决定它能触及什么,标准库与运行时执行它,撤销记账让每处可撤销改动都能回滚,审计记录结果,触发器与 cron 安排后续运行,CLI 是用户的启动方式。", - "en": "Follow a script through the system: the front end lexes and parses, the policy and mount/host layers decide what it may touch, the stdlib and runtime execute it, the undo module keeps every reversible change rollback-able, audit records the outcome, triggers and cron schedule further runs, and the CLI is how a user starts one." - }, - "order": [ - "pyvdisk.vscript.frontend", - "pyvdisk.vscript.policy", - "pyvdisk.vscript.mounts", - "pyvdisk.vscript.host", - "pyvdisk.vscript.stdlib", - "pyvdisk.vscript.runtime", - "pyvdisk.vscript.undo", - "pyvdisk.vscript.audit", - "pyvdisk.vscript.triggers", - "pyvdisk.vscript.cron", - "pyvdisk.vscript.cli" - ], - "groups": [ - { - "id": "frontend", - "title": { - "zh": "语言前端", - "en": "Language Front End" - }, - "children": [ - "pyvdisk.vscript.frontend" - ] - }, - { - "id": "security", - "title": { - "zh": "沙箱与能力", - "en": "Sandbox and Capabilities" - }, - "children": [ - "pyvdisk.vscript.policy", - "pyvdisk.vscript.mounts", - "pyvdisk.vscript.host" - ] - }, - { - "id": "runtime", - "title": { - "zh": "运行时与审计", - "en": "Runtime and Audit" - }, - "children": [ - "pyvdisk.vscript.stdlib", - "pyvdisk.vscript.runtime", - "pyvdisk.vscript.undo", - "pyvdisk.vscript.audit" - ] - }, - { - "id": "events", - "title": { - "zh": "触发器与调度", - "en": "Triggers and Scheduling" - }, - "children": [ - "pyvdisk.vscript.triggers", - "pyvdisk.vscript.cron" - ] - }, - { - "id": "entry", - "title": { - "zh": "命令行", - "en": "CLI" - }, - "children": [ - "pyvdisk.vscript.cli" - ] - } - ] - }, - "pyvdisk.vscript.audit": { - "schema_version": 1, - "id": "pyvdisk.vscript.audit", - "updated_at": "2026-09-24T09:55:53.156Z", - "reading": { - "zh": "先是脚本与策略的内容哈希,再是由它们构成的记录形态、查询与保留辅助、负责持久化与校验的 sink,以及填充记录的 run id 与计时辅助。", - "en": "Content hashes of script and policy, then the record shape built from them, the query/retention helpers, the sinks that persist and verify records, and the run-id and timing helpers that fill them in." - }, - "order": [ - "pyvdisk.vscript.audit.hashing", - "pyvdisk.vscript.audit.record", - "pyvdisk.vscript.audit.query", - "pyvdisk.vscript.audit.sinks", - "pyvdisk.vscript.audit.clock" - ] - }, - "pyvdisk.vscript.cli": { - "schema_version": 1, - "id": "pyvdisk.vscript.cli", - "updated_at": "2026-09-23T07:25:08.831Z", - "reading": { - "zh": "先是把本接口挂到主 CLI 的解析器钩子,再是含挂载授权的 check/run 命令,最后是交互式 REPL。", - "en": "The parser hook that grafts this surface onto the main CLI, the check/run commands with mount authorization, and the interactive REPL." - }, - "order": [ - "pyvdisk.vscript.cli.parser", - "pyvdisk.vscript.cli.commands", - "pyvdisk.vscript.cli.repl" - ] - }, - "pyvdisk.vscript.frontend": { - "schema_version": 1, - "id": "pyvdisk.vscript.frontend", - "updated_at": "2026-09-23T07:25:09.231Z", - "reading": { - "zh": "按编译流水线顺序阅读:词法单元词表、词法器、AST 节点、语法解析器,以及前四者用于报告的的位置/诊断与错误类型。", - "en": "The compilation pipeline in order: token vocabulary, lexer, AST nodes, parser, and the span/diagnostic and error types the first four report through." - }, - "order": [ - "pyvdisk.vscript.frontend.tokens", - "pyvdisk.vscript.frontend.lexer", - "pyvdisk.vscript.frontend.ast", - "pyvdisk.vscript.frontend.parser", - "pyvdisk.vscript.frontend.span", - "pyvdisk.vscript.frontend.errors" - ] - }, - "pyvdisk.vscript.host": { - "schema_version": 1, - "id": "pyvdisk.vscript.host", - "updated_at": "2026-09-23T07:25:09.568Z", - "reading": { - "zh": "guard 是读写根白名单的强制执行;module 是面向脚本的读取、写入与传输入口,全部经它限权。", - "en": "guard is the allowlisted read/write root enforcement; module is the script-facing read/write/transfer entry points that all funnel through it." - }, - "order": [ - "pyvdisk.vscript.host.guard", - "pyvdisk.vscript.host.module" - ] - }, - "pyvdisk.vscript.policy": { - "schema_version": 1, - "id": "pyvdisk.vscript.policy", - "updated_at": "2026-09-23T07:25:09.885Z", - "reading": { - "zh": "budget 是声明式限额与强制限额的运行时计数器;capability 是脚本必须满足的逐句柄权限集。", - "en": "budget is the declarative limits plus the runtime counter that enforces them; capability is the per-handle permission set a script must satisfy." - }, - "order": [ - "pyvdisk.vscript.policy.budget", - "pyvdisk.vscript.policy.capability" - ] - }, - "pyvdisk.vscript.runtime": { - "schema_version": 1, - "id": "pyvdisk.vscript.runtime", - "updated_at": "2026-09-23T07:25:10.297Z", - "reading": { - "zh": "先是作用域与控制流,再是可调用对象与任务,随后是解释器核心及其两张分发表(语句与表达式)、模块加载,最后是带撤销日志的脚本事务。", - "en": "Scopes and control flow, then callables and tasks, then the interpreter core and its two dispatch tables (statements and expressions), module loading, and finally script transactions with their undo journal." - }, - "order": [ - "pyvdisk.vscript.runtime.env", - "pyvdisk.vscript.runtime.callables", - "pyvdisk.vscript.runtime.core", - "pyvdisk.vscript.runtime.statements", - "pyvdisk.vscript.runtime.expressions", - "pyvdisk.vscript.runtime.modules", - "pyvdisk.vscript.runtime.tx" - ] - }, - "pyvdisk.vscript.stdlib": { - "schema_version": 1, - "id": "pyvdisk.vscript.stdlib", - "updated_at": "2026-09-23T07:25:10.640Z", - "reading": { - "zh": "先是原生模块与 Handle 基础设施,再是每个原生函数都会调用的两个守卫,最后是组装 fs、vector、log 与 json 模块的工厂。", - "en": "Native module and Handle plumbing first, then the two guard helpers every native calls, and finally the factory that assembles the fs, vector, log and json modules." - }, - "order": [ - "pyvdisk.vscript.stdlib.native", - "pyvdisk.vscript.stdlib.guards", - "pyvdisk.vscript.stdlib.factory" - ] - }, - "pyvdisk.vscript.triggers": { - "schema_version": 1, - "id": "pyvdisk.vscript.triggers", - "updated_at": "2026-09-23T07:25:11.546Z", - "reading": { - "zh": "registry 声明并持久化应当触发什么;daemon 轮询文件与日志事件、经检查点去重并调用处理函数。", - "en": "registry declares and persists what should fire; daemon polls file and log events, dedups them through checkpoints and invokes handlers." - }, - "order": [ - "pyvdisk.vscript.triggers.registry", - "pyvdisk.vscript.triggers.daemon" - ] - } - }, - "policy": { - "schema_version": 1, - "updated_at": "2026-09-23T06:56:56.092Z", - "rules": [ - { - "id": "core-acyclic", - "type": "acyclic", - "severity": "error", - "includeCrossTree": true - }, - { - "id": "core-no-deprecated-target", - "type": "forbid-dependency", - "from": [ - "**" - ], - "to": [ - "**" - ], - "toState": "deprecated", - "severity": "warning" - } - ] - }, - "changes": [ - { - "id": "2026-09-24-compat-describe-live-impl", - "status": "verified", - "title": { - "en": "describe() reports the live implementation", - "zh": "describe() 报告生效的实现" - }, - "updated_at": "2026-09-24T11:51:43.517Z" - }, - { - "id": "2026-09-24-readme-agent-demo-fix", - "status": "verified", - "title": { - "en": "Fix the README agent demo", - "zh": "修正 README 的 Agent 对接 Demo" - }, - "updated_at": "2026-09-24T11:48:42.331Z" - }, - { - "id": "2026-09-24-readme-counts", - "status": "verified", - "title": { - "en": "Align the README counts with the rebuilt tree", - "zh": "README 计数与重建后的结构库对齐" - }, - "updated_at": "2026-09-24T10:00:54.385Z" - }, - { - "id": "2026-09-24-resync-issue1-fixes", - "status": "verified", - "title": { - "en": "Resync the module tree with the issue #1 fixes", - "zh": "结构库同步 issue #1 的修复" - }, - "updated_at": "2026-09-24T09:59:19.981Z" - }, - { - "id": "2026-09-24-zero-dep-windows-agentsandbox", - "status": "verified", - "title": { - "en": "Zero dependency, Windows compat layer and AgentSandbox", - "zh": "零依赖 + Windows 兼容层 + AgentSandbox" - }, - "updated_at": "2026-09-24T11:41:32.089Z" - } - ] -}