ph-runtime-guest 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/PKG-INFO +2 -2
  2. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/README.md +1 -1
  3. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/pyproject.toml +1 -1
  4. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/cell.py +1 -1
  5. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/protocol.py +26 -8
  6. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/runner.py +1 -1
  7. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/tests/test_snapshot_paths.py +1 -1
  8. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/.gitignore +0 -0
  9. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/LICENSE +0 -0
  10. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/__init__.py +0 -0
  11. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/__main__.py +0 -0
  12. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/_json.py +0 -0
  13. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/channel.py +0 -0
  14. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/errors.py +0 -0
  15. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/lifecycle.py +0 -0
  16. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/limits.py +0 -0
  17. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/proxies.py +0 -0
  18. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/py.typed +0 -0
  19. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/skill.py +0 -0
  20. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/src/ph_runtime/snapshot.py +0 -0
  21. {ph_runtime_guest-0.1.0 → ph_runtime_guest-0.2.0}/tests/test_cell_bindings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ph-runtime-guest
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: The guest half of pH's code runtime: the fd-3 protocol, the run loop, and the binding proxies a cell awaits.
5
5
  Project-URL: Homepage, https://github.com/chastabor/pH
6
6
  Project-URL: Repository, https://github.com/chastabor/pH
@@ -130,7 +130,7 @@ The host's orphan journal is the backstop for all three.
130
130
 
131
131
  Nothing here is configured directly. Every knob belongs to `ph-rlm`'s
132
132
  `code-runtime-python` row, which spawns this package and sends the `boot` frame
133
- that parameterises it — and the **host owns every default**, because there are
133
+ that parameterizes it — and the **host owns every default**, because there are
134
134
  two definitions of the protocol across the two sides and exactly one owner of
135
135
  each value. `boot` carries every limit as a required field, so a guest has
136
136
  nothing to guess and a changed default cannot mean two things at once.
@@ -104,7 +104,7 @@ The host's orphan journal is the backstop for all three.
104
104
 
105
105
  Nothing here is configured directly. Every knob belongs to `ph-rlm`'s
106
106
  `code-runtime-python` row, which spawns this package and sends the `boot` frame
107
- that parameterises it — and the **host owns every default**, because there are
107
+ that parameterizes it — and the **host owns every default**, because there are
108
108
  two definitions of the protocol across the two sides and exactly one owner of
109
109
  each value. `boot` carries every limit as a required field, so a guest has
110
110
  nothing to guess and a changed default cannot mean two things at once.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ph-runtime-guest"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "The guest half of pH's code runtime: the fd-3 protocol, the run loop, and the binding proxies a cell awaits."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -60,7 +60,7 @@ MAGIC_HINT = (
60
60
  The magic was the bypass — one shell command per cell that no `tools/pre-execute`
61
61
  listener, no approval and no sandbox `confine()` ever saw. Removing the
62
62
  mechanism closes the hole, so the error explains the governed route rather than
63
- apologising for a missing feature.
63
+ apologizing for a missing feature.
64
64
  """
65
65
 
66
66
 
@@ -1,12 +1,23 @@
1
1
  """The fd-3 frame vocabulary, guest side.
2
2
 
3
- **This module is written twice on purpose.** Its twin is
4
- `ph_rlm.kernel.protocol`, and neither imports the other: the guest runs in
5
- `$PH_CACHE/runtime-venv` with almost nothing installed, and making it import the
6
- host package would put the harness inside the process boundary that exists to keep
7
- the harness out. What keeps the two in step is `test_protocol_mirror.py`, which
8
- compares `PROTOCOL_VERSION`, every frame's required and optional field set, and
9
- the truncation marker byte for byte (D7, D4).
3
+ **This module is written twice on purpose — but not all of it, and the
4
+ asymmetry is the point.** Its twin is `ph_rlm.kernel.protocol`.
5
+
6
+ The four constants below are declared *here* and **imported** by the host. That
7
+ direction is the only one available: the guest runs in `$PH_CACHE/runtime-venv`
8
+ with almost nothing installed, and making it import the host package would put
9
+ the harness inside the process boundary that exists to keep the harness out. The
10
+ host is under no such restriction — it already depends on this package — so for
11
+ anything that is plain data with no typing to lose, one declaration beats two
12
+ held equal by a test.
13
+
14
+ Everything else is genuinely twinned, and `test_protocol_mirror.py` is what keeps
15
+ it honest (D7, D4). Two things, for two different reasons: every frame's required
16
+ and optional field set, because the host *derives* its own from `TypedDict`s for
17
+ mypy and a `TypedDict` cannot be derived from a runtime table; and the truncation
18
+ marker byte for byte, because the host re-exports ph-core's copy and this side may
19
+ not import ph-core at all — two implementations, which is the one thing a shared
20
+ declaration could never have reconciled.
10
21
 
11
22
  **`FRAME_FIELDS` is the *only* declaration of the vocabulary on this side** — a
12
23
  second one that no test compares is a copy that drifts, and one already had.
@@ -62,7 +73,14 @@ is dropped and a missing one takes its default.
62
73
 
63
74
  **Not a cache key**, though `venv._marker` digests it and a bump does force a
64
75
  warm guest venv to rebuild. Reaching for it to ship an edit is how a number that
65
- means "compatibility" ends up meaning "some byte changed"."""
76
+ means "compatibility" ends up meaning "some byte changed".
77
+
78
+ **Sharing this declaration with the host does not make the two agree at
79
+ runtime**, and nothing about the import should be read as if it did: host and
80
+ guest import from *different* venvs, so they are two installations that can hold
81
+ different versions. What covers that is unchanged and lives elsewhere —
82
+ `kernel/venv.py`'s staleness marker rebuilds a venv whose protocol or guest
83
+ version moved, and `boot-ack` refuses a pairing that still disagrees."""
66
84
 
67
85
  PROTOCOL_FD: Final = 3
68
86
  """Where the channel is by default. fd 0/1/2 stay the program's own, so a cell's
@@ -324,7 +324,7 @@ class Runner:
324
324
  cell = self.globals.pop(CELL_FUNCTION)
325
325
  value = await cell()
326
326
  except asyncio.CancelledError:
327
- error = {"kind": "aborted", "message": "the run was cancelled"}
327
+ error = {"kind": "aborted", "message": "the run was canceled"}
328
328
  except KeyboardInterrupt:
329
329
  error = {"kind": "aborted", "message": "the run was interrupted"}
330
330
  except CpuBudgetExceeded as exceeded:
@@ -2,7 +2,7 @@
2
2
 
3
3
  `NamespaceSnapshotter.changed` is called after every cell, and what it emits is
4
4
  the only account the host gets of a variable's fate. Two of its branches are
5
- about *not* saying things, which is exactly the kind of behaviour a test has to
5
+ about *not* saying things, which is exactly the kind of behavior a test has to
6
6
  pin because nothing downstream fails when it breaks:
7
7
 
8
8
  * a variable that cannot be pickled is reported once and then stays quiet, so a