Skip to content

Latest commit

 

History

History
869 lines (727 loc) · 63.4 KB

File metadata and controls

869 lines (727 loc) · 63.4 KB

Changelog

All notable changes to the public surface are documented here. Exact version pins are the install contract, so a breaking change only lands where a pin is deliberately moved. Releases happen only on an explicit maintainer decision; the Unreleased section accumulates until then.

한국어 요약은 각 절 하단에 둔다.

Unreleased

소비자가 핀한 버전에 아직 없는 subpath 목록이다(위 주석이 기계 판독 정본). 출하 문서가 이 이름을 예시로 쓰면 미출하 표식이 함께 있어야 하고, tests/contracts/publicSurface.mjs가 그것을 문다.

0.0.25 - 2026-09-09

Added

  • Python checkpoints, Machine images and process clones preserve files, directories, hard links and open file positions together with interpreter memory. Unchanged engine files use the exact engine baseline. New checkpoint images require this reader; existing memory-only images remain readable.
  • Setup is a public first-hour contract. Both READMEs document Chromium and Edge, the two isolation headers, and Vite and Next snippets. checkEnvironment() points at the live #setup heading.
  • npx pyproc-playground serves the installed package graph with those headers and opens the first Python receipt path. Default boot() still loads only the core engine.
  • The second public example reopens a Machine image and reads back the recorded value.
  • Default Machines accept Python package requests. %pip install and python -m pip install use the attached package environment. Unsupported native wheels and subprocess pip stay readable failures and do not stop later Python execution.
  • Native Linux CPython is a second door, not the default kernel. createWebComputer().linuxPython runs python3 and python -m pip over linuxOs serial. Root boot() stays the owned WASI CPython 3.14.6 kernel. The guest interpreter on the python profile is CPython 3.12.13. inspect().interpreter reports that split. Receipt stdout is the serial transcript. Offline missing wheels fail through guest pip. The slim linux image still has no python3. The python guest is a digest-pinned project release, not an npm bundle. test:linux-python prepares that catalog consumer without an injected image path.

한국어 요약

  • 체크포인트, Machine image와 프로세스 복제가 파일·디렉터리·하드 링크·열린 파일 위치를 함께 보존한다. 변경 없는 엔진 파일은 같은 엔진의 기준 자산을 참조한다. 새 이미지는 이 판독기가 필요하고 기존 메모리 전용 이미지는 계속 읽을 수 있다.
  • Setup 절이 Chromium/Edge, 헤더 두 줄, Vite와 Next 스니펫을 공개하고, 환경 진단이 #setup으로 연결된다.
  • npx pyproc-playground가 설치 그래프를 COOP/COEP로 서빙해 첫 Python receipt를 연다. 기본 boot()는 core engine만 로드한다.
  • 두 번째 공개 예제가 Machine image를 다시 열어 기록한 값을 읽는다.
  • 기본 Machine에서 %pip installpython -m pip install로 패키지를 요청한다. 지원하지 않는 native wheel과 subprocess pip는 패키지 오류로 거절되고 이후 파이썬 실행은 계속된다.
  • 네이티브 Linux CPython은 두 번째 문이다. createWebComputer().linuxPythonlinuxOs serial로 python3python -m pip를 친다. 기본 boot()는 WASI 커널이다. 별도 Buildroot python profile이 CPython 3.12.13과 pip 25.2를 Node guest와 같은 재현/SBOM/oracle 계약으로 싣는다. slim linux image에는 여전히 python3가 없다. python guest는 npm이 아니라 digest-pinned project release다. test:linux-python은 그 catalog consumer만 받는다.

0.0.24 - 2026-08-16

Added

  • Web Machine Core v1 is a reviewable product protocol. The package now includes a normative protocol, requirement and surface locks, shared conformance vectors, a public product binding, a dependency-free minimal implementation, browser coverage, and a WPT-shaped test. Both implementations produce the same nine transcripts and reject malformed graphs, missing vectors, and inconsistent attachment lengths.
  • Full-page screenshot limits are measured before capture. Current CSS content bounds are preferred over the deprecated metric, and oversized dimensions, areas, origins, extents, and scales fail with a stable code, measured details, explicit limits, and a recovery boundary before the capture request is sent.
  • Pipeline cancellation preserves honest transport outcomes. Browser automation verification now accepts both a provably unsent read poll and an unknown result when cancellation crosses the send boundary, while preserving the completed effect prefix and forbidding unsafe effect retries.

한국어 요약

  • Web Machine Core v1은 규범 protocol, requirement와 surface lock, 공통 conformance vector, 공개 제품 binding, 무의존 최소 구현, 브라우저 gate, WPT 형태 검증을 한 package에 담는다. 두 구현은 9개 transcript가 같고 잘못된 graph, 누락 vector, attachment 길이 불일치를 거부한다.
  • 긴 full-page screenshot은 capture 전에 CSS content 크기를 측정하고 dimension, area, origin, extent, scale 한계를 넘으면 안정 code, 측정 detail, 한계와 복구 경계를 포함해 거부한다.
  • pipeline 취소가 send 경계를 가로지를 때 전송 전 거부와 결과 불명확을 모두 정직하게 보존하고, 완료된 effect prefix를 유지하며 effect 재시도를 막는다.

0.0.23 - 2026-08-16

Added

  • The installed package is now the default engine entrance. Root open() and boot(), createWebComputer, Control, and the package-owned engine catalog converge on one exact installed product without deep imports.
  • Browser eyes and hands now carry bounded proof through document change. Paged semantic inventory, durable locators, action convergence, occlusion handling, document replacement, 20-cycle resource cleanup, and a headed hardware receipt for compute and rendered pixels run through exact packed-product gates.
  • A reproducible data engine ships beside the default core engine. pyproc/wasi exposes its exact manifest and a profile-selected package-owned catalog. The static pyproc.data/2 module executes float64 SIMD oracles. NumPy 2.5.1 is built from its exact sdist as 13 static modules and survives process clone and Machine image revival. The build-sealed thread capability reports the actual worker-process boundary. SciPy, pandas, Polars, shared-memory threads, and arbitrary native wheels remain explicit absences.
  • Browser storage failures are explicit and recoverable where bytes still exist. Persistence receipts, quota rollback, eviction witnesses, and OPFS generation recovery distinguish best-effort durability from silent first boot while preserving the last valid state.
  • Source-pinned ripgrep and local Git are resident Machine tools. Isolated WASI workers run ripgrep 15.1.0 over bounded snapshots and libgit2 1.9.7 over compare-and-swap KernelVfs transactions. Main and cloned Python kernels call the same argv-only catalog through pyprocTools and receive the same receipts.
  • An optional source-pinned Node guest joins Python and Linux in one Web Computer. createWebComputer({ node }) creates nodeOs and nodeDisk, verifies Node source identity and every declared V86 boot asset before engine construction, and carries all configured guests in one signed .webmachine. The exact packed product runs Node crypto and filesystem work, rejects a changed boot image before active replacement, and restores all three guests. A separate reproducible Buildroot release carries the image, source, configuration, SBOM, complete legal material, and two-build byte-identity receipt.

Fixed

  • Successful Control startup now clears its timeout timer immediately, so a completed product lifecycle does not wait for an obsolete process timer.
  • Chromium profile cleanup now waits for stable absence after Windows pending deletion, and POSIX launches use an isolated process group that is terminated as a whole. A remaining exact profile becomes a structured failure.
  • Digest-locked Python wrapper sources are checked out as LF on every platform, so fresh Windows runners verify the same supply-chain bytes as Linux and repository builds.
  • The data engine builder copies target module sources before the native bootstrap but applies its SIMD Setup.local only to the WASI target build, keeping host GCC free of target-only flags.
  • V86 inspection reports readiness only after the engine event. A pre-ready timeout no longer calls unsafe partial-instance stop or destroy methods, while a ready instance retains the full drain, flush, and destroy path.
  • V86 verified asset descriptors are closed and type-exact. The default Node loader accepts only same-origin credential-free URLs, refuses redirects and unbounded response bodies, enforces declared lengths, hashes independent bytes, and returns WEB_MACHINE_ASSET_INTEGRITY on mismatch.
  • WebComputer.bootAll() now rolls every partial guest back to stopped when one configured guest fails. If cleanup also fails, an AggregateError retains the original boot failure and every cleanup failure.
  • The TypeScript V86 block mode now names the implemented ata and filesystem values rather than stale names.
  • V86 text display accepts the engine's transient 256-row boot geometry and reports only genuinely invalid updates as errors, so a normal Linux boot returns errors: 0 instead of accumulating clipped VGA cells.

Compatibility

  • The root remains exactly six exports and no package subpath or executable is added. The node option is additive on createWebComputer; WEB_COMPUTER_MACHINE_IDS now lists the optional nodeOs identifier.
  • The npm package retains zero runtime dependencies. V86, firmware, and optional guest images remain external, digest-pinned assets rather than bundled package bytes.
  • Existing Python-only and Python plus Linux Web Computers keep their machine IDs, device names, lifecycle, image format, and durability behavior.

한국어 요약: 설치 패키지를 엔진 기본 진입점으로 통일하고, 문서 교체와 가림을 다시 관찰해 안전하게 수렴하는 브라우저 눈과 팔, 실제 hardware 결과 영수증, 무잔류 수명주기를 제품화했다. 별도 재현 data engine과 NumPy 2.5.1, 정확한 thread 경계, 저장소 quota와 축출 영수증, 상주 ripgrep과 local Git 및 같은 Python 도구 영수증을 추가했다. 선택적 Node guest는 Python과 Linux 옆에서 같은 Web Computer, 독립 disk, 서명 image 계약을 쓰며 source와 boot asset을 실행 전에 검증한다. npm package는 계속 runtime 의존성 0이고 V86, firmware, guest image는 별도 digest-pinned 공급망으로 남는다.

0.0.22 - 2026-08-15

Added

  • The owned CPython WASI kernel now powers the default product and pyproc/wasi. bootCpythonWasiKernel opens a worker-owned CPython WASI kernel with Promise-first commands, ordered output events, retry identity, generation fences, structured terminal errors, hard interrupt truth, and idempotent close. Root boot(), WebComputer, and installed Control compose the same verified engine through KernelFactory and KernelMachine.
  • ValueEnvelope v1 removes live Python objects from the v2 value boundary. Finite scalars, bigint, bytes, lists, canonical string maps, verified artifact spill, and generation-bound application references cover kernel values and the v2 ASGI and IPC seams with explicit limits.
  • Kernel checkpoint v2 keeps reactive memory ownership inside the WASI worker. Engine and environment-bound descriptors seal opaque full or 64KiB page-delta artifacts, reject busy or incompatible boundaries before restore, compact at bounded depth, and fence generations.
  • KernelVfs v1 adds immutable roots and crash-consistent OPFS volumes to the owned kernel. Intent, marker, HEAD CAS, adoption recovery, owner epochs, typed devices, and checkpoint root pairing reject partial objects, stale writers, forbidden resources, and corrupt candidates.
  • Hostcall ABI v1 connects the static CPython module to an authority broker. A dedicated SAB record and worker-only atomic wait carry byte requests through /hostcall; stable receipts prevent duplicate external sends, preserve uncertain outcomes, bound streamed responses, and block unsafe checkpoints. Core no-op, clock, entropy, and terminal providers ship behind the same authority boundary.
  • Product host capability ports extend the owned kernel without browser handles in Python. Explicit HTTP credit streams, socket relay, process, GPU, clipboard, framebuffer, and ASGI opcodes share destination-aware authority, exact effect boundaries, receipt replay, cancellation truth, and checkpoint resource classification through injected adapters.
  • PyProc Eyes now returns task-conditioned situations. The existing automation.observe operation accepts representation: "apx.situation" and typed focus requirements. It returns a canonical SituationCapsule with explicit known, conflicted, unknown, and stale claims, bounded probes, and broker-issued affordances.
  • Proof-carrying actions bind authority to observed state. JavaScript and Python clients expose situate() and actAffordance(). An actionContext binds the capability to its session, situation, world, document epoch, action, risk, destination, expiry, and expected transition, and stale bindings fail before the effect.
  • Verified Change Loop turns repository experience into a replayable verdict. Strict Experience Contracts, exact environment observation, deterministic structural and behavioral rules, bounded perceptual review, atomic Evidence Packs, comparison, and effect-free replay are available through Control, MCP, JavaScript, Python, and CLI entrances.
  • Hibernating Machine Fleet bounds live execution owners. createMachineFleet in pyproc/machine registers durable Web Computers, issues owner-epoch leases, admits only within a hot limit, commits and verifies exact generations before terminating adapters, and cold-resumes in fresh Workers. WebComputer.suspend() and resume() expose the same single-computer lifecycle. Unsafe effects, stale leases, commit failures, environment drift, and cleanup failures fail closed.
  • Execution Memory makes exact execution state the handoff unit. An opt-in Control manifest adds immutable session revisions, compare-and-swap HEAD, real .pymachine capture, SituationCapsule and Automation Recording boundaries, Evidence Pack-gated completion, retention reachability, and signed handoff with separate permission approval. JavaScript, Python, MCP, and direct pyproc/control registry paths share the same revision digest.
  • Rehearse-Commit Transactions separate preparation from one-shot external effects. Exact intents, effect-free rehearsal receipts, externally signed approval grants, durable commit leases, terminal effect results, and Evidence Pack-gated receipts share one immutable revision chain. JavaScript, Python, MCP, Control, and CLI entrances use the same fail-closed coordinator and never resend after the durable sending boundary.
  • Transactional AppSpace pairs cooperative application state with the Python Machine. Exact app identity, fenced logical-state export, host-side canonical validation, immutable completion markers, in-process Machine checkpoints, paired restore, CAS adoption, rollback, and a no-send effect outbox share one Control lifecycle. JavaScript, Python, and MCP reopen the same durable pair digest from the packed product.
  • ReplayGraph Worlds make verified branches traversable without effects. Sealed recordings and exact Transactional AppSpace pairs become content-addressed state nodes and transition edges. Immutable CAS graph revisions, one-shot cursor capabilities, deterministic path evaluation, coverage, retention planning, and installed JavaScript, Python, MCP, and Control parity share one durable root.

Fixed

  • Fatal MCP shutdown now resolves a held page long poll with CONTROL_BRIDGE_CLOSED before closing the HTTP server. Duplicate request IDs still produce one fatal terminal and the process no longer waits on an abandoned browser poll during Linux cleanup.
  • Native profile C sources and Setup.local inputs are pinned to LF checkout bytes. Their locked SHA-256 values now validate identically on Windows and Linux before the reproducible CPython WASI build starts.
  • Execution Memory import authority now compares canonical existing filesystem paths. Windows short and long aliases for the same approved root no longer reject Evidence Pack sealing, while missing paths and escapes remain outside the authority boundary.
  • The GitHub Pages demo now establishes cross-origin isolation through its versioned service-worker bootstrap before starting the owned kernel, while the no-header preflight continues to fail closed outside that entry.

Compatibility

  • apx.graph 1.0 remains compatible and the situation representation is opt-in. The root export, package subpath, and bin sets are unchanged. Control adds verification.audit, verification.verify, and verification.replay; browser-disabled profiles expose only the two effect-free operations.
  • The root remains exactly six exports. Machine Fleet is additive on the existing pyproc/machine subpath. Existing non-durable and save() Web Computer behavior remains unchanged.
  • Execution Memory is additive on the existing pyproc/control subpath and disabled by default. Enabling it adds machine.image.export and eight memory.* Control operations. It creates no new Machine image, evidence format, root export, subpath, or executable.
  • Rehearse-Commit is additive on the existing pyproc/control subpath and disabled by default. Enabling it adds seven effect.* Control operations and requires Execution Memory, acknowledged externalEffect authority, and an external Ed25519 approval authority. It does not claim remote exactly-once delivery or rollback.
  • Transactional AppSpace is additive on the existing pyproc/control subpath and disabled by default. Enabling it adds nine app.* Control operations and requires FrameSpace, Execution Memory, and Rehearse-Commit. It does not capture a renderer heap, cookies, arbitrary site state, or remote effects, and adds no root or subpath.
  • ReplayGraph is additive on the existing pyproc/control subpath and disabled by default. Enabling it adds twelve world.* operations and requires Execution Memory. It does not open a browser during traversal, invent missing transitions, authenticate authorship, persist an open cursor, or add a root export or package subpath.

한국어 요약: 기존 automation.observe에 opt-in apx.situation 표현을 추가했다. typed focus가 최소 충분 상황과 명시적 불확실성을 만들고, broker가 발급한 capability만 현재 world와 epoch에 묶여 effect에 쓰인다. strict Experience Contract와 exact 환경을 실제 browser에서 판정하고 canonical Evidence Pack으로 발행한다. Control, MCP, JavaScript, Python, CLI가 같은 audit, verify, replay 의미론을 공유한다. pyproc/machine에는 hot 수를 제한하고 safe generation을 commit한 뒤 Worker를 종료하는 Machine Fleet을 추가했다. cold는 pause가 아니며 exact HEAD, fresh owner, stale lease 거부로 다시 부활한다. Execution Memory는 실제 Machine, observation, recording, evidence, permission을 immutable revision으로 연결하고 CAS HEAD와 별도 permission 승인이 있는 signed handoff로 이어받는다. 기존 pyproc/control 안의 opt-in 기능이며 새 root, subpath, image format은 만들지 않는다. Rehearse-Commit Transactions는 exact intent, effect-free rehearsal, 외부 서명 승인, durable send lease, terminal result, Evidence Pack receipt를 하나의 immutable chain으로 묶는다. sending 경계 이후에는 자동으로 재전송하지 않으며, 원격 exactly-once나 rollback을 주장하지 않는다. Transactional AppSpace는 협력 app의 fenced logical state와 Python Machine checkpoint를 immutable pair로 묶는다. marker 없는 object는 후보가 아니며 stale adopt는 app, Machine, active HEAD를 함께 rollback한다. effect outbox staging은 live send를 0회 수행하고 기존 Rehearse-Commit transaction만 참조한다. ReplayGraph Worlds는 봉인된 recording과 exact AppSpace pair를 content-addressed node와 edge로 만든다. one-shot cursor와 pinned root에서 effect 없이 분기를 탐색하고 deterministic evaluation과 coverage를 공유한다. graph 밖 transition은 생성하지 않으며 digest를 작성자 신원으로 해석하지 않는다. MCP fatal 종료는 보류 중인 page long poll을 명시적으로 닫고, 네이티브 프로필의 C와 Setup 입력은 Windows와 Linux에서 같은 LF 바이트로 검증한다. GitHub Pages 데모는 versioned service worker로 cross-origin isolation을 확보한 뒤 소유 커널을 시작한다. Execution Memory는 Windows의 short path와 long path를 실제 파일시스템 경로로 정규화해 같은 승인 root로 판정하고, 존재하지 않는 경로와 root 밖 경로는 계속 거부한다.

0.0.21 - 2026-08-13

Added

  • A supported JavaScript control entrance. The pyproc/control stable subpath starts the installed product, exposes persistent Python, checkpoint recovery, provider-neutral browser lifecycle, APX query and action evidence, verified screenshot bytes, cancellation, and bounded shutdown through the same Control Protocol used by MCP and the Python SDK.

Compatibility

  • The root stays at six exports and no wire operation changes. The new subpath is additive and Node.js-only. Browser application code continues to use the root Machine entrance.

한국어 요약: pyproc/control 안정 subpath가 설치 제품의 JavaScript 사용 경로를 제공한다. 기존 Control Protocol의 취소, 결과, attachment 검증을 그대로 사용하며 root와 wire operation은 바뀌지 않는다.

0.0.20 - 2026-08-12

Fixed

  • Fatal MCP protocol errors now arm the five-second exit watchdog before waiting for the stdout flush callback. A stalled callback can no longer prevent process termination after the fatal terminal reaches the client.
  • The Native APX product gate now creates and loads its inspected target through the browser broker, removing a Chromium startup-tab race while preserving fail-closed origin checks.

Compatibility

  • This patch changes no operation, schema, result, export, or type signature. It supersedes the GitHub-only 0.0.18 and 0.0.19 releases, whose publish gates prevented npm publication.

한국어 요약: fatal MCP terminal의 stdout callback을 기다리기 전에 5초 종료 watchdog을 시작한다. callback이 지연돼도 프로세스 종료가 보장되며 공개 표면은 바뀌지 않는다.

0.0.19 - 2026-08-12

Fixed

  • MCP fatal protocol errors now start a five-second shutdown deadline before draining product resources. The fatal terminal is flushed first, duplicate request IDs still execute no second effect, and a delayed Chromium or server cleanup can no longer leave the stdio process alive without an exit code.

Compatibility

  • This patch changes no operation, schema, result, export, or type signature. It supersedes 0.0.18, whose publish gate exposed the shutdown race before npm publication.

한국어 요약: 중복 MCP request ID의 fatal terminal 뒤 제품 정리가 지연돼도 프로세스가 5초 안에 종료되도록 bounded shutdown을 추가했다. effect 및 wire 의미론과 공개 표면은 바뀌지 않는다.

0.0.18 - 2026-08-12

Added

  • PyProc Eyes adds the APX 1.0 perception contract. Opt-in automation.observe calls now return a bounded semantic, structural, spatial, and temporal graph with stable entity identity, short-lived locator capability, full or delta delivery, attention queries, explicit truncation, provenance, and canonical integrity. Native CDP fuses Accessibility and DOMSnapshot facts. FrameSpace provides the same envelope at its honest cooperative-page boundary.

  • Pixels are captured only when structured evidence is unresolved. Native CDP can attach verified overview and entity-crop artifacts for canvas, unlabelled images, and unlabelled controls. MIME type, byte length, SHA-256, quota, permission, and artifact lifetime remain under the existing product host.

  • External effects can carry Action Evidence. An action with verify captures before and after APX observations, sends the effect once, correlates broker-issued network request references, and separates confirmed, contradicted, ambiguous, notObserved, and outcomeUnknown from transport outcome.

  • Python receives a first-class perception entry point. client.perception(sessionRef) provides typed observe, query, single-match, actionability, delta, and evidence-backed action helpers over the same Control Protocol operations used by native and MCP clients. Recording and ReplaySpace preserve APX terminals and artifacts without repeating live effects.

Compatibility

  • This patch adds no npm root export, Control Protocol operation, or breaking JavaScript type signature. Legacy observations remain unchanged unless representation: "apx.graph" is requested. Native CDP reports live conformance level L4, FrameSpace reports L3 with APX visual mode off, and no provider claims inference.

한국어 요약: PyProc Eyes와 APX 1.0을 추가했다. 의미, 구조, 공간, 시간, 선택적 픽셀을 bounded graph로 결합하고 행동 전후의 DOM 및 network evidence를 한 번만 전송되는 effect와 묶는다. Native CDP, FrameSpace, MCP, Control, Replay, Python SDK가 같은 의미론을 사용하며 기존 관찰 형식은 opt-in 밖에서 그대로 유지된다.

0.0.17 - 2026-08-12

Fixed

  • Control clients preserve their wire safety boundaries under deadlines and reuse. Python request timeouts send a protocol cancel and wait for one canonical terminal. Pending EOF and partial request-write failures become non-retryable CONTROL_CONNECTION_LOST instead of raw transport exceptions. MCP duplicate JSON-RPC IDs close the connection without a second terminal. Attachment chunks obey the client receive limit, and request spaceId values are checked before provider dispatch. Version 1 advertises its actual events: false capability instead of exposing a schema-only promise. The machine bearer remains outside guest-readable storage, and a direct control-page reload fails closed instead of reusing authority in the guest realm.

  • Temporary browser profiles and Python SDK product fixtures now close their process streams and retry transient Windows file locks before cleanup. Installed wheel, source distribution, Native CDP, and FrameSpace journeys finish with a clean process exit.

Changed

  • The matching GitHub Release is the official Python distribution source until a PyPI trusted publisher is registered. Public examples use the exact-version wheel URL, and the release procedure requires both wheel and source distribution assets plus a clean-environment installation check.

Compatibility

  • This patch has no breaking JavaScript export or type-signature change. The existing version 1 frame schema remains valid; capability flags and request fences now match the behavior already promised by the protocol.

한국어 요약: Python timeout은 실제 cancel 뒤 canonical terminal에 수렴하고, MCP 중복 JSON-RPC ID는 terminal을 복제하지 않고 연결을 닫는다. attachment chunk 협상, spaceId fence, 정확한 event capability, Windows 종료 정리를 고정했다. control bearer는 guest-readable storage 밖에 머물고 page reload는 fail-closed 처리한다. Python SDK의 공식 설치 경로는 같은 버전 GitHub Release 자산이다.

0.0.16 - 2026-08-12

Added

  • One language-neutral product host for native clients and MCP. The installed pyproc-control command exposes strict versioned NDJSON with single-use request IDs, exactly one terminal per request, page-epoch fencing, queue removal on pre-delivery cancellation, honest post-delivery outcomeUnknown, and ordered SHA-256 verified binary attachments. The MCP adapter now uses the same operation catalog and host instead of owning separate execution semantics.

  • An official zero-runtime-dependency Python SDK. The pyproc-control wheel and source distribution on the matching GitHub Release start the npm product from PATH and expose persistent Python, checkpoint recovery, cancellable requests, browser lifecycle and actions, stable errors, artifacts, and verified screenshot bytes. Both distribution formats install in clean environments, and Chrome plus Edge execute the installed Python journey.

  • Cooperative frame automation without a DevTools port. FrameSpace runs an opted-in target inside a credentialless sandbox, authenticates a private MessageChannel, enforces exact origin and action policy, and returns verified PNG artifacts. It deliberately excludes arbitrary pages, signed-in storage, trusted native input, and compositor capture.

  • Deterministic automation recording and effect-free replay. RecordingSpace stores canonical operation terminals and screenshot sidecars behind an exclusive writer and bounded private files. ReplaySpace verifies recording identity, final digest, cursor, and prefix pins before reproducing the exact remaining operation sequence without opening a live browser provider.

Fixed

  • Timed out or cancelled queued page commands are removed before delivery instead of running later after the caller has already received failure. Duplicate MCP request IDs can no longer overwrite an active request and execute a second effect. Reloaded machine pages fence late results with a new page epoch.

  • Journal operations that share one Runtime and storage directory now share one coordinator. Commit, recover, branch adoption, pack, prune, and deletion are serialized against one storage epoch, and stale page-address hints are revalidated before reuse. Packing can no longer leave a tree that names a deleted state blob.

  • Automation recordings now fail closed before a live effect when their destination is not writable or another writer owns it. Post-effect persistence failure preserves the original outcome or becomes non-retryable outcomeUnknown. Generation sidecars, symlink confinement, strict byte limits, shutdown draining, and stale generation cleanup close secret-retention, memory, and partial-write paths.

Changed

  • Browser automation now enters through the provider-neutral AutomationSpace contract. Its router fixes authorization before execution, supported operations, idempotent close, opaque artifacts, and explicit Python-restore plus provider-replay boundaries. The current Chromium implementation retains its external behavior behind a single-use authority token.

  • The installed Chromium implementation is now composed as NativeCdpSpace. Inspection declares its DOM, network, target, storage, runtime, screenshot, and artifact capabilities plus the record-only replay boundary. The broker-owned endpoint, opaque references, and existing browser error contract are unchanged.

  • A formal v86 boundary probe now boots the available Linux and graphical guests and checks display, input, packet networking, PNG capture, snapshot, and restore. Neither candidate is promoted as an automation provider: the reproducible Linux image has no browser or GUI, while the graphical fixture has opaque provenance and lacks the required external-network and semantic-control contracts.

Compatibility

  • This release has no breaking JavaScript package-export or type-signature change. nativeCdp remains the default opt-in browser provider, and the Python-only default still opens no browser authority. The Python SDK is a separately installed distribution whose version must match the npm package.

한국어 요약: MCP와 native NDJSON이 하나의 ControlHost, operation, 취소, 오류, attachment 계약을 공유한다. 공식 Python SDK는 별도 JavaScript 코드 없이 영속 Python, checkpoint, browser action, screenshot byte를 사용하며 wheel과 source distribution 설치 여정으로 검증한다. 전달 전 취소된 명령의 지연 실행, 중복 request ID 효과, page reload 뒤 late result 혼입을 막았다. FrameSpace는 DevTools port 없는 cooperative 격리 자동화를 제공하고, RecordingSpace와 ReplaySpace는 외부 효과를 다시 보내지 않는 결정적 재현 경계를 제공한다. 저널 공유 저장소의 경쟁과 stale 주소 재사용을 차단했고, 기록 파일의 원자성, 크기, symlink, 종료 drain 경계를 강화했다. 공개 JavaScript export와 type signature에는 브레이킹 변경이 없다.

0.0.15 - 2026-08-12

Added

  • An installed browser automation product beside the persistent Python Machine. The package now ships pyproc-mcp, a manifest-driven stdio entrance that can open a broker-owned temporary Chrome, Chromium, or Edge profile without exposing its DevTools endpoint to Python or the caller. Exact origin, action, method, file, risk, and artifact policies fail closed before launch. Browser authority remains opt-in; disabling it preserves the existing Python-only tool surface.

  • Semantic observation and ordered interaction for autonomous work. Opaque target, session, locator, and artifact references replace browser internals. Focused accessibility observations retain actionable controls and live state before applying output bounds. Action pipelines cover navigation, readiness, pointer and keyboard input, trusted controlled-editor input, form state, drag, scrolling, uploads, cookies, storage, screenshots, and downloads. A failed pipeline reports its completed prefix, failure position, trace, and outcome instead of silently replaying an effect.

  • Product-grade visual artifacts. Viewport, full-page, and clipped PNG, JPEG, and WebP captures can be returned as native MCP image content or retained behind an opaque artifact reference. Digests, quotas, bounded reads, expiry, explicit deletion, and shutdown cleanup make large screenshots and downloads usable without revealing host paths.

Changed

  • Browser navigation now returns control at commit by default. Callers can request DOM-ready or load completion explicitly, so an application that intentionally keeps loading cannot hold the session indefinitely. Denied popup cleanup restores the opener capture surface, while an allowed popup keeps focus.

  • Durable command RPC has a documented deadline. If transport is lost after an effect was sent, the outcome is unknown and the command is never retried automatically. Python checkpoint restore remains intentionally separate from browser, network, storage, download, and popup effects.

한국어 요약: 브레이킹 없는 기능 릴리즈다. 설치 패키지에 manifest 기반 pyproc-mcp를 추가해 영속 Python Machine과 별도 권한의 Chromium 자동화 프로필을 한 세션에서 사용한다. 의미 기반 관찰, 불투명 참조, 순서가 보존되는 입력과 화면 캡처, 다운로드 아티팩트, 정확한 권한과 위험도, 감사 및 실패 결과 계약을 제품 경계로 고정했다. 기본 탐색 완료 경계는 commit이며 더 강한 대기는 명시적으로 선택한다. Python 복원은 이미 발생한 브라우저 외부 효과를 되돌린다고 주장하지 않는다.

0.0.14 - 2026-08-06

Added

  • Named durable branches with provenance, and an attempts verb for competing solutions. The journal already speaks git's object model (content-addressed blob/tree/commit, HEAD/PREV refs); this names the missing layer. history.branch(name, { dir, note }) commits the current state to a branch ref without touching HEAD, history.branches() lists them with their fork parents and notes, history.recoverBranch(name) materializes one, and history.adopt(name) makes a branch the machine state and the new HEAD - the adopting commit's parents point at the branch commit and its note records { adoptedFrom }. Heap states cannot be merged, so the consuming verb is adopt, not merge. Commits accept note (canonical JSON, 4 KB cap): what was tried and why a state was chosen lives in the same object as the state itself.

    In the volatile zone, history.attempts([codes]) runs candidates serially from one base, each attempt checkpointed as a sibling branch with the heap rewound in between, so a failing attempt cannot contaminate the next; adopt(i) restores the winner. Serial on purpose: restoreLive is cheap, while parallel attempts cost one heap each.

    The durable machine speaks the same verbs. open({ name }) handles carry branch / branches / adopt / deleteBranch through the election command pipeline, so exactly-once outcome recording, succession, and epoch fencing apply to branching exactly as they do to run. Adoption materializes the branch and commits it as the new HEAD in one command, which is why that handle has no recoverBranch: the leader never sits on a heap that diverges from HEAD.

    Daily milestones make "go back to yesterday" a verb. Opt in with milestones: { keep: N } (journal config, or the open({ name }) options): every HEAD commit updates the auto-<date> branch to point at it, so a day's milestone converges to that day's last state, and dates beyond keep are trimmed oldest-first. A milestone is one tiny ref file - the content-addressed commit already exists - so this costs no extra state. adopt("auto-2026-08-03") is the whole journey back.

    Compatibility: a journal carrying branches marks itself format version 2, and an older pyproc refuses to recover it (fail closed) rather than pruning branch data its live-set walk cannot see. Do not run an older pyproc's pack()/prune() directly against a branched journal. Deleting the last branch restores version 1. Journals without branches are unchanged.

한국어 요약: 브레이킹 없는 기능 릴리즈다. 실행 상태가 git의 동사를 얻는다: 이름 있는 내구 가지(commitBranch), 목록(branches), 물질화(recoverBranch), 채택(adopt - 힙 상태는 병합이 성립하지 않으므로 merge는 없다), provenance note(무엇을 시도했고 왜 채택했는지가 커밋 자체에 산다), 직렬 attempts(오염 없는 후보 경쟁), 일일 이정표(auto-<날짜> 가지, adopt 한 번이 어제로 돌아가기). 같은 동사가 선출 내구 머신에서도 정확히 한 번 파이프라인으로 돈다. 가지를 나르는 저널은 마커 v2가 되어 구 버전이 fail-closed로 거부한다(가지 없는 저널은 불변).

0.0.13 - 2026-08-03

Supersedes 0.0.12, which was tagged but never reached npm: the pre-publish gate refused it. The x86 CI lane did not fetch the self-hosted engine, so the probes that boot Python beside the Linux guest failed on a missing /vendor/pyodide/. That lane is fixed here, and a gate now asserts that any CI job which starts a browser provisions the engine in the same job, derived from the package scripts rather than a hand-written list.

The package contents are identical to what 0.0.12 would have shipped. Everything in the 0.0.12 section below is what this release delivers, including the breaking replay-boundary change and its migration. Pin 0.0.13.

한국어 요약: 0.0.12는 태그까지 나갔지만 게시 전 관문에서 막혀 npm에 도달하지 못했다. x86 CI 레인이 자체 호스팅 엔진을 안 받아 Python guest를 올리는 probe가 죽었고, 그 배관을 고치면서 "브라우저를 띄우는 job은 같은 job에서 엔진을 마련한다"를 게이트로 세웠다. 패키지 내용은 0.0.12가 냈을 것과 같다. 아래 0.0.12 절의 브레이킹과 이관 안내가 이 릴리즈의 내용이다.

0.0.12 - 2026-08-03

Breaking

  • The page-hash mixer splits each lane into two accumulator chains, so the replay boundary fingerprint (h0) changes. Every word still goes through the identical non-linear step; only the dependency chain is shorter, which lets the multiply latencies overlap. The digest values differ, so a journal or .pymachine image written by an earlier version is refused with PYPROC_REPLAY_MISMATCH rather than applied to a heap whose page identity is computed differently.

    Migration: export what you want to keep with the version that wrote it (history.export()), upgrade, then open() the exported bundle - the bundle carries its own boundary and is re-anchored on load. A journal that was only ever a crash-recovery cache can be dropped with history.forget(). There is no in-place conversion: the fingerprint is the identity of the boundary, not a field beside it.

    Cheaper mixers were measured and rejected. Prefix-sum families (Fletcher/Adler) do less work per word but are linear over Z_2^32, and flipping the top bit of two words carries nothing, so the delta is 2^31*(L_i+L_j) and vanishes whenever those weights have the same parity. The FNV lane cancels on the same pairs. The right shift in the second lane is the only thing that breaks that propagation, so per-word non-linearity is not negotiable. [해시 soundness] now asserts exactly that pair, and a linear mixer fails it.

Changed

  • /home is committed as one content-addressed blob per file. It used to be concatenated into a single pack, so one changed byte in one file changed the pack's address and the whole tree was re-read, re-hashed, and re-written on every commit. Now an unchanged file is already in the store and costs no write at all: a commit that changed nothing under /home writes zero home blobs, and a commit that changed one file writes one. journal.commit() reports that as home.wrote, which is now a count rather than a boolean.

    Older generations keep working - the v1 pack layout is still read, so upgrading does not lose a journal or an image. The new layout is not readable by older pyproc versions, so a .pymachine file exported after this change must be opened with this version or later; an older reader refuses it with PYPROC_MACHINE_FORMAT_INVALID rather than restoring a partial tree.

  • The Web Machine IndexedDB schema is now version 3, with a blob size index. Asking how much a store holds - inspectStorage(), and every recovery-window plan - used to require deserializing every blob value just to read its length, so the question cost a full read of the database. Sizes now live in their own small store and neither call reads a blob value at all. Opening an older database migrates it in the version-change transaction; that one pass replaces the full read that every later call was paying. A database already upgraded to v3 is refused by an older pyproc with WEB_MACHINE_SCHEMA_UPGRADE_BLOCKED rather than opened with a store it does not know.

  • A checkpoint node now stores hashes only for the pages it changed. The boundary keeps the full array, because it is what the replay fingerprint is computed from; every node above it keeps [page, a, b] triples and ReactiveController.hashesAt(j) folds the root-to-j chain when a consumer needs the whole array. Node cost stops tracking heap size and starts tracking churn, so stats().hashBytes on a long session reports a much smaller number than before - recalibrate any budget derived from it. hashesAt is new on the public surface; the hashes array itself was never part of it.

Added

  • setRetentionPolicy({ rebaseLinear: true }) reclaims memory on a linear history. Pruning only frees nodes off the root-to-live path, so a session that checkpoints per statement (the dominant shape) got zero bytes back no matter what limit was set: the policy observed the overrun and the memory stayed. Rebase folds the path itself into the base, so the same limit now holds.

    This moves the replay boundary, and that is breaking for anything written against the old one. hashes[0] becomes the rebased state, so a journal or image committed before the rebase is refused with PYPROC_REPLAY_MISMATCH, and time travel to any checkpoint before the new boundary is refused with PYPROC_CHECKPOINT_PRUNED. Both refusals are explicit, neither is silent. The flag is off by default for exactly this reason; turn it on when a long-lived session matters more than its past. ReactiveController.boundaryEpoch counts boundary moves so a consumer caching the fingerprint (the journal does) can drop its cache.

Fixed

  • The asset manifest now lists workerHostedGuestWorker (src/machine/composition/workerHostedGuestWorker.js). createWebComputer() has always spawned that module worker, but it was missing from getPyProcAssetManifest(), so a deployment that copied exactly the listed files left it out of the same-origin set and out of the assetIntegrity preflight. Deployment pipelines pick up one additional file; the manifest format is unchanged and PYPROC_ASSET_MANIFEST_VERSION stays 1.
  • WheelCache honours the patchScope it is given. bootSession({ wheelDir, packages }) deadlocked because the constructor dropped the re-entrant scope and the wheel fetch swap queued behind the boot window that was waiting for it.
  • Disposing a machine now reclaims journal watchers. machine.dispose() stops the idle watcher started by history.watch(), so the interval no longer holds the runtime and the reactive controller for the life of the tab.

한국어 요약: 리플레이 경계 지문(h0)이 바뀌는 브레이킹 릴리즈다. 페이지 해시 믹서가 레인마다 사슬 둘로 갈라지고, 체크포인트 노드는 바뀐 페이지의 해시만 담고, /home은 파일마다 내용주소 blob 하나로 커밋되고, Web Machine IndexedDB는 스키마 v3에 blob 크기 색인을 갖는다. 옛 저널과 이미지는 PYPROC_REPLAY_MISMATCH로 명시 거부되므로, 지키려는 상태는 이전 버전에서 history.export()로 내보낸 뒤 업그레이드하고 open()한다. 크래시 복구 캐시일 뿐인 저널은 history.forget()으로 버린다. setRetentionPolicy({ rebaseLinear: true })는 선형 역사에서 메모리 한계가 실제로 걸리게 하는 새 옵션이고, 경계를 옮기는 대가 때문에 기본값은 꺼짐이다.

0.0.11 - 2026-08-02

Breaking

  • The 0.0.9-era PYMACHINE2 reader is retired. open() accepts the PYBUNDLE1 format written by 0.0.10 and later. Open an older PYMACHINE2 file with the version that wrote it and export it again before upgrading. The error is PYPROC_MACHINE_FORMAT_INVALID.
  • history.save() and history.export() refuse heaps that hold JS handles with PYPROC_IMAGE_PROXY_SURFACE. Export before enabling a blocking host surface when possible. { allowHostProxies: true } explicitly accepts that the revived kernel keeps plain Python state but cannot use those surfaces again. Packet networking and the permission jail use value boundaries and remain portable.
  • MachineCommitCoordinator no longer takes idFactory (pyproc/machine). Generation identity is the content address produced by the commit itself; remove the unused constructor argument.
  • boot() now rejects unknown option keys immediately. Existing callers that mixed custom keys into boot options must move those values outside the boot option object.

Users upgrading directly from 0.0.9 must also apply the 0.0.10 migration from root boot() -> Runtime to root boot() -> PyprocMachine; the 0.0.10 section below is the migration map.

Added

  • A durable Web Computer lifecycle on the existing createWebComputer() handle. Opt into it with durability, then use initialize, save, exportImage, importImage, inspect, and dispose. Owner fencing, restore-or-boot, pause/snapshot/commit/resume, signed export, candidate preflight, and conflict-safe active-context replacement are one public composition contract. Additional guest factories can be installed through adapters without adding a root export.
  • Explicit journal deletion and eviction detection. machine.history.delete() leaves a deletion tombstone, while a committed marker with missing generations fails closed as PYPROC_JOURNAL_EVICTED. A fully origin-wide browser eviction remains indistinguishable from a first visit, so important state still needs an external signed export.
  • A project-built Linux guest. The reproducible i686 Buildroot image, exact source archive, complete legal material, CycloneDX inventory, build manifest, config, and independent-build receipt are published together in the buildroot-pyproc-i686-v2 asset release. The catalog pins the guest image by hash and the Web Computer can place it on the same packet switch as Python.
  • pyproc/runtime returns as a stable plumbing subpath with Runtime, bootRuntime, MemoryCapability, FileSystem, checkEnvironment, and engine/runtime contract assertions. The separate bootRuntime name keeps its return type distinct from the root machine boot.
  • The typed API subpaths pyproc/runtime, pyproc/history, pyproc/machine, and pyproc/assets now declare their type entry explicitly.
  • machine.dispose() terminates the process pool and releases reactive retention. machine.proc() is memoized per machine so a remount reuses the existing pool.

Changed

  • Durable RPC now has one normative retry boundary. A direct durable controller may resend the same request id once only when it can prove a proxy-free session. A normal follower, a live timeout, a vanished caller, or an unportable heap returns non-retryable PYPROC_RPC_OUTCOME_UNKNOWN instead of guessing and replaying a possibly completed command.
  • Agent and MCP sandbox examples install both the cooperative net: false jail and a browser CSP wall after trusted engine/package preparation. Local execution alone is no longer described as a no-exfiltration guarantee.
  • Consumer-facing diagnostics and capability preflight errors use English on the public surface. IPC and WASI paths report their cross-origin-isolation requirement before allocating shared memory.
  • GitHub Actions, TypeScript, and the publishing npm CLI are exact-version pinned. Chrome and Edge run independent release lanes, and npm Trusted Publishing grants OIDC only to the publish job.
  • The internal mainPlan archive was removed. Persistent product, contract, and operating policy remains under docs/; implementation evidence remains in automated tests and git history.

Fixed

  • Consumer docs now name the shipped porcelain machine verbs and current signature helpers.
  • Durable image import preserves the running machine set and HEAD when trust validation or commit conflicts fail.
  • A serial timeout includes the Linux console tail, making a failed guest boot actionable.
  • The project Buildroot guest mounts the v86 host9p volume at /mnt/web and starts both serial and VGA shells, so Linux disk, display, and keyboard state cross save and cold-restore boundaries.

한국어 요약: 기존 root 6-export를 유지하면서 Web Computer의 내구 저장·복원·서명 이동 수명주기를 공개 핸들에 완성했다. OPFS 삭제와 축출을 분리하고 Python과 재현 가능한 Buildroot Linux를 실제 packet network와 cold restore로 묶었다. pyproc/runtime은 안정 subpath로 출하한다. 0.0.9 시대 PYMACHINE2, JS handle을 가진 heap 저장, MachineCommitCoordinator.idFactory, 알 수 없는 boot option에는 위 Breaking 절의 이관이 필요하다.

0.0.10 - 2026-07-19

Breaking

  • Root surface reshaped to a porcelain machine handle (37 exports -> 6). The root now exports exactly boot, open, createWebComputer, checkEnvironment, PyProcError, and PYPROC_ERROR_CODES. boot resolves to a PyprocMachine handle whose namespaces are the model's vocabulary: run / runAsync (execute), fs (files), term (terminal), proc (worker process pool), history (checkpoint/restore volatile, commit/recover/export durable), plus the runtime escape hatch for capability detail (enableSyscallBridge, enableAsgiServer, enableDeviceFs, ...). Root class exports are gone; the classes remain as typed contracts reached through the handle.

  • open is the one revival verb. Its trust contract follows the source instead of flattening semantics: open(bundleBlob, trustOpts) verifies envelope integrity and signature before touching the heap (replaces openMachine), open({ dir, name }) revives an OPFS session save by manifest replay plus delta (replaces bootSession().load(...)), and open({ persistent }) opens the multi-tab persistent machine and returns a KernelElection handle (replaces openPersistentMachine).

  • Deterministic boot is an explicit opt-in. boot({ deterministic: true, ...manifest }) replaces bootSession(manifest). PYTHONHASHSEED=0 and the entropy stub change guest-visible semantics, so they are never the default; the choice is recorded in the environment fingerprint of every durable commit, and history.export / history.save exist only in this mode (a non-deterministic state has no replay guarantee).

  • Subpaths reshaped. New: pyproc/history, the state kernel's contract surface (sha256 address law, object model, StateStore contract, commitState / openState protocol, signed tags, PYBUNDLE1 bundle codec, PAGE_SIZE). Removed: pyproc/runtime, pyproc/reactive, pyproc/syscall-bridge, pyproc/process-os (their capabilities moved onto the handle, see the migration map). Remaining: pyproc/machine, pyproc/worker, pyproc/assets, and the demoted pyproc/gpu / pyproc/socket / pyproc/wasi.

  • One bundle format (PYBUNDLE1). machine.history.export() writes a single signed, content-addressed envelope; open reads it. The layout is authoritative in skills/reference-pyproc-api/references/bundle-format.md. The legacy .pymachine envelopes (meta v2/v3) are still readable through a format-detecting reader, and that legacy reader sunsets at the next breaking release: re-export machines you intend to keep.

  • State kernel (src/state) refounds the journal. Durable commits are now content-addressed objects with HEAD/PREV generations, verify-on-read (PYPROC_STATE_CORRUPT, with PREV fallback) and owner fencing (PYPROC_STATE_FENCE_STALE protects HEAD from a superseded writer). Existing journals are migrated automatically on first recover; no consumer action is needed.

  • Machine crypto injection. pyproc/machine persistence and image constructors now require a provider from createMachineCryptoProvider(crypto?) instead of a bare Crypto object, so digest/signature law lives in one place (the state kernel).

  • Removed SharedKernel (and its SharedWorker host asset). It was documented as a non-canonical auxiliary path; KernelElection / openPersistentMachine is the canonical multi-tab lane and keeps document-level crossOriginIsolated (SharedWorker cannot). Migration: replace new SharedKernel(...) with openPersistentMachine({ name, manifest }).

  • Moved GPU surface (GpuCompute, GpuArray, GpuBridge) from the root export to the pyproc/gpu subpath, and removed Runtime.enableGpu(). GPU needs a real adapter and a windowed session, so it cannot be covered by the headless CI gate that guards the root surface. Migration: import { GpuCompute } from "pyproc/gpu" and construct directly.

  • Moved SocketBridge from the root export to the pyproc/socket subpath, and removed Runtime.enableSocketBridge(). It requires an external WS to TCP relay that pyproc does not ship. Migration: import { SocketBridge } from "pyproc/socket"; new SocketBridge(rt, cfg).

  • Moved bootWasi / WasiSession from the root export to the pyproc/wasi subpath. The WASI lane is a research preview that proves the engine-independent core; the production Python surface is the Pyodide lane. Migration: import from pyproc/wasi.

  • Removed alias methods that duplicated one behavior under two names: ReactiveController.timeTravel(...) (use restoreLive(...) or cp.restore()), PyProc.interrupt(pid) (use signal(pid, SIGNAL.INT)), PyProc.mapSerial(fnSrc, args) (a benchmark baseline, not a product surface; run tasks through exec(pid, ...) sequentially if you need a serial reference).

Migration map (old import -> new path)

Before After
boot() -> Runtime boot() -> PyprocMachine; the runtime is machine.runtime
bootSession(manifest) boot({ deterministic: true, ...manifest })
openMachine(blob, trustOpts) open(blob, trustOpts)
session.exportImage(opts) machine.history.export(opts)
session.save(dir, name) / session.load(dir, name) machine.history.save(dir, name) / open({ dir, name })
openPersistentMachine(opts) open({ persistent: opts })
rt.enableReactive() checkpoint/restore machine.history.checkpoint() / restore() / tree() / prune() (raw controller stays at machine.runtime.enableReactive())
rt.enableJournal(cfg) commit/recover/pack machine.history.commit / recover / watch / pack with { dir, ... }
new PyProc(opts) + pool.boot(n) await machine.proc({ lanes: n, ...opts })
rt.enableTerminal(cfg) machine.term(cfg)
createMachineKeyPair / exportMachinePublicKey / fingerprintMachinePublicKey createStateKeyPair / exportStatePublicKey / fingerprintStatePublicKey from pyproc/history
bootEnv(manifest, dirs) / runScript(rt, src) boot manifest options (packages, env, setup, wheelDir)
import { Runtime } from "pyproc/runtime" root boot() + machine.runtime (types via index.d.ts)
bare Crypto into machine persistence/image constructors createMachineCryptoProvider(crypto) from pyproc/machine

Added

  • PyProc.forkMany(srcPid, dstPids): the speculative-exploration primitive. A parent's delta is one value, so a fan-out harvests it once and broadcasts over a SharedArrayBuffer instead of re-harvesting per lane: O(heap + N x delta) rather than O(N x heap). Lanes stay isolated and candidate results are byte-identical to a serial run. fork is now a 1:1 delegation (name and return shape unchanged). An agent loop is three calls: fan out, run candidates, fork(winner, main) to adopt.
  • PyProcError and PYPROC_ERROR_CODES: one error contract for the whole surface. Every error thrown by pyproc now carries code (programmatic branching axis), retryable, and optional context (worker Python exceptions arrive with context.pyExcType, e.g. "KeyboardInterrupt"). Worker boundaries preserve codes.
  • Checkpoint handles: reactive.checkpoint() now returns { ..., sp, restore() }, so a restore is one call (cp.restore()) instead of carrying stackSave plus an index. restore/restoreLive accept omitted savedSP (the node-stored value is used).
  • ReactiveController.collectDelta(fromIdx?, toIdx?, opts?): the shared primitive behind session save, journal commit, and machine image export.
  • ReactiveController.markDirty(): report heap mutations that bypass execSeq (live PyProxy calls) so the next restoreLive upgrades to the rehash path.
  • ReactiveController.pruneTo(j) / dispose(): memory valves for the checkpoint tree.
  • Runtime.noteStateMutation() and boundary-recording restores: a restore now counts as a state mutation, so observers such as the journal idle watcher commit restored state.
  • Runtime.enableReactive() is memoized (one controller per runtime): two controllers could silently corrupt each other's live-diff restores.
  • MachineJournal cfg.onStatus (observe idle-commit success/failure; failures carry PYPROC_JOURNAL_IO) and cfg.pruneAfterCommit (tree pruning after each commit).
  • PyProc.respawn(pid) and JobControl.killHard(jobId): forced lane recovery that keeps fork symmetry (replay reboot).
  • PyProc.map no longer leaves silent undefined holes when every lane dies; unrun tasks resolve to { error: "pool exhausted: ..." }.
  • Nested machine containers now route run/heapLen/kill/spawn through an explicit path router at any depth, and a dead container rejects immediately instead of hanging.
  • PyProc.bootInfo: the last boot() result ({ workers, avgBootMs, forked }) is kept on the pool, so paths that do not consume the return value directly (such as machine.proc()) still have an observation point.
  • Asset provenance policy v2: the engine boot set (pyodide.js / pyodide.mjs / pyodide.asm.mjs / pyodide.asm.wasm / python_stdlib.zip / pyodide-lock.json, bytes cross-verified between the GitHub release and the jsdelivr CDN) is now described in the single asset catalog with a second distribution vocabulary, upstream-cdn-runtime-reference (referencing upstream's own distribution point at runtime is not redistribution). Both Web Computer guests now carry the same described provenance in signed envelopes; the "undescribed guest" marker is retired.

한국어 요약

  • 루트 37개 -> 6개(porcelain 머신 핸들): boot/open/createWebComputer/ checkEnvironment/PyProcError/PYPROC_ERROR_CODES만 남는다. boot가 돌려주는 머신 핸들의 어휘(run/fs/term/proc/history)가 표면이고, 능력 상세는 machine.runtime 탈출구로 연다.
  • open 통합: 외부 bundle(무결성+서명 선검증), { dir, name } 세션 저장(리플레이+델타), { persistent } 멀티탭(KernelElection 반환, 구 openPersistentMachine)을 부활 동사 하나로 통합. 결정적 부팅은 boot({ deterministic: true }) opt-in이고 history.export/save는 그 모드 전용.
  • subpath 재편: pyproc/history 신설(상태 커널 계약: 주소 법, 오브젝트 모델, store, 서명 tag, bundle 코덱). pyproc/runtime/reactive/syscall-bridge/process-os 소멸 (핸들 동사로 이동, 위 마이그레이션 표 참조).
  • 단일 bundle 포맷 PYBUNDLE1: 구 .pymachine v2/v3 reader는 다음 브레이킹 릴리즈에 일몰 예고(보관할 머신은 재내보내기).
  • 상태 커널(src/state) 신설과 저널 재기초: content-addressed HEAD/PREV 세대, verify-on-read(PYPROC_STATE_CORRUPT), fence(PYPROC_STATE_FENCE_STALE). 구 저널은 첫 recover에서 자동 이관.
  • machine 암호 주입: persistence/image 생성자는 맨 Crypto가 아니라 createMachineCryptoProvider가 만든 provider를 요구한다.
  • forkMany: 부모 델타를 한 번만 수확해 N 레인에 방송하므로 팬아웃 비용이 O(heap + N x delta)다(O(N x heap) 아님). fork는 1:1 위임으로 이름과 반환 계약 불변.
  • SharedKernel 삭제(정본은 openPersistentMachine), GPU/Socket/WASI는 subpath로 강등, 별칭 3종(timeTravel/interrupt/mapSerial) 절삭.
  • PyProcError 단일 오류 계약(코드/재시도 가능성/파이썬 예외 타입이 워커 경계를 건너온다).
  • 체크포인트 핸들(cp.restore() 한 호출), collectDelta/markDirty/pruneTo/dispose, 복원의 경계 기록, 컨트롤러 memoize, 저널 onStatus/pruneAfterCommit, respawn/killHard, map 부분 실패 정직화, 컨테이너 중첩 라우팅과 사망 즉시 거부.
  • PyProc.bootInfo: 마지막 boot() 결과를 풀에 보관(반환을 직접 받지 않는 machine.proc() 경로의 관측 지점).
  • 자산 provenance 정책 v2: 엔진 부팅 집합 6파일을 단일 catalog가 기술(두 유통 경로 바이트 교차 검증), 배포 어휘 upstream-cdn-runtime-reference 신설(상류 배포 지점 런타임 참조는 재배포가 아니다). 두 guest가 같은 기술된 출처를 봉투에 나르고 미기술 게스트 표식은 은퇴.