You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mainPlan은 이니셔티브이지 영구 문서가 아니고, 끝난 덩어리는 폴더를 지우고 지속 계약만
남기는 것이 그 README가 스스로 세운 규칙이다. 01부터 11까지 전부 끝나 폴더째 회수한다.
무엇을 했는지는 git 이력이 정본이고, 지속 계약은 코드 주석과 게이트와 CHANGELOG에 산다.
계약 실태 표의 리액티브 메모리 줄이 "라이브 경로의 자동 rebase는 아직 없다"고 적고 있었는데
이제 rebaseLinear가 그것이다. 대신 남은 것을 정확히 적었다: 기본값을 켤 수 없는 이유는
경계 이동을 되돌릴 방법이 없다는 것이고, 기존 저널을 새 경계에 다시 앵커하는 수단이 없으면
기본값 켜기는 메모리 상한을 저널 상실과 맞바꾸는 거래다.
검증: npm test 3364 passed 0 failed, test:types 0, test:package ok, test:contracts 7 suites.
Copy file name to clipboardExpand all lines: docs/operations/contractReality.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ It is consulted whenever the engine version moves or a capability changes.
14
14
| The global patch window costs boot concurrency | Two machines boot independently | The default boot always carries a core trust anchor, so it always opens the core-asset cache window, and that window is a single tab-wide chain because it swaps `globalThis.fetch`. Two concurrent `boot()` calls therefore overlap only partially: the browser gate measures 1.59x the single-boot wall clock for two at once (2.0x would be fully serial, 1.0x fully parallel). The window is not removable as-is - it exists because two concurrent global swaps restore each other's patch - so the cost is a property of the fetch-interception design, not a defect to patch away | Either intercept core-asset fetches without a global swap (an engine-level loader hook), or accept the cost and keep it measured. The gate records the ratio on every run so a regression toward 2.0x is visible |
15
15
| The legacy journal generation reader | The journal writes one on-disk format | The writer has been single since the state-kernel rebase, and the old root `HEAD.json` v2/v3 path is read-only. It now lives alone in `src/capabilities/journal/journalLegacyGeneration.js` so retiring it is one file deletion, but it is not dead weight yet: `pack`/`prune` compute live keys as the **union** of kernel and legacy generations, so an un-migrated journal still depends on it. Removing that branch deletes live blobs, which the browser gate now proves by refusing to recover | Retire the file once an un-migrated journal can no longer plausibly exist in the field. That judgement needs a release boundary, so it belongs to the next breaking release rather than a refactor |
16
16
| Implicit FFI/fetch assumptions | Survives an engine swap or update | Direct `toJs` is isolated to PyodideEngine alone, and the host contract is `proxyMode`/`fallback`. EngineContract validates version, kind, and capabilities at construction, and WASI and Pyodide share a minimum RuntimeContract | A new engine must pass both `tests/contracts/runtimeContract.mjs` and browser measurement |
17
-
| Reactive and %undo memory | Safe even in long sessions | A resident base is a foundational premise. `history.stats()` and the retention budget observe base, delta, hash, and node pressure, and off-path branches can be auto-pruned. There is still no automatic rebase of the live path | Collect pressure events from real long-lived workloads and judge a safe-rebase design as its own initiative|
17
+
| Reactive and %undo memory | Safe even in long sessions | A resident base is a foundational premise. `history.stats()` and the retention budget observe base, delta, hash, and node pressure, and off-path branches can be auto-pruned. A node now stores hashes only for the pages it changed, so node cost tracks churn rather than heap size. The live path can be folded into the base with `rebaseLinear`, which is what makes a limit hold on a linear history - but it is off by default because folding moves the replay boundary, and a session that has journaled or exported cannot take it back | Judge whether a consumer can be given a safe default. That needs pressure events from real long-lived workloads plus a way to re-anchor an existing journal at the new boundary; without the second half, on-by-default would trade a memory limit for a lost journal|
18
18
| The GPU subpath has no headless execution gate | Every shipped public surface has the strongest automated evidence the runner can provide | Edge headless still returns `null` from `requestAdapter()` with the repository's SwiftShader switches, so CI verifies every registered WGSL kernel and the exact shader bytes handed to WebGPU but cannot verify GPU result values. The socket subpath no longer shares this debt: `test:socket` starts the in-repo relay and local TCP origin hermetically in CI | Keep GPU under the Experimental freeze and the evidence ceiling explicit until a runner with a real adapter is available |
19
19
| Handles that enter the heap without `setGlobal`| The image-portability refusal sees every JS handle in the heap | The count sits on the engine's `globals.set`, which is where the shipped wrapper mints one, and a structure gate now fixes the set of places that may call it (the engine itself, plus the worker kernel that has no `Runtime` wrapper and writes no image). Two paths remain outside any count and cannot be brought inside: guest Python can `import js` itself, and `rt.raw` hands out the engine by design for `deviceFs`-class uses. So the refusal is a floor for shipped surfaces, not a proof about arbitrary guest code | State that boundary wherever the guarantee is quoted. Closing it entirely needs engine-level accounting of handle allocation, which is upstream work |
20
20
| A portable image and a blocking surface | `snapshotScope: "portable"` means a machine image revives and keeps working | A JS handle is interpreter-local and cannot cross an image: measured across thirteen bisected cases, a kernel revived from an image whose seed installed one traps on every proxy path, including handles the revived kernel mints itself. The packet port and the permission jail were moved to value boundaries (pure Python plus bytes and literals through `run()`), so they cross intact. What cannot move is a **blocking** surface - the syscall bridge behind `input()`, sockets, GPU - because blocking Python on a JS answer needs a handle by construction. `exportImage` and `save` now refuse such a heap with `PYPROC_IMAGE_PROXY_SURFACE` and name the surfaces, and `{ allowHostProxies: true }` is the explicit acknowledgement: the revived kernel keeps its plain Python state and loses those surfaces | Either an engine-level way to rebind handles after materialisation, or a blocking mechanism that needs no handle. Until one exists the refusal is the contract, and the browser gate holds both directions (refused by default, and the acknowledged path still works) |
0 commit comments