1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Location: ./crates/cpex-hosts-python/Cargo.toml
# Copyright 2026
# SPDX-License-Identifier: Apache-2.0
# Authors: Ted Habeck
#
# cpex-hosts-python — out-of-process host for existing Python CPEX
# plugins. Each plugin runs in its own cached virtualenv, driven by the
# Python framework's `worker.py` over a newline-delimited JSON stdio
# protocol. Registers under the `isolated_venv` plugin kind.
#
# Pure Rust plus a subprocess — no libpython link, so this crate is in
# `default-members` (unlike `bindings/python`, which links libpython).
[]
= "cpex-hosts-python"
= true
= true
= true
= true
= "CPEX host — runs Python plugins out-of-process in isolated virtualenvs."
= true
= true
= true
= true
= true
[]
= { = true }
= { = true }
# Expiry on a token a Python delegation plugin mints (`credential_payloads`).
= { = true }
= { = true }
= { = true }
= { = true }
= { = true }
# Version-pinned rather than workspace-inherited, matching how the rest of the
# tree declares it. Used by `venv`
# to fingerprint a requirement set into its cache directory name.
#
# No `zeroize` here, deliberately, even though this crate handles plaintext
# credentials. `praxis-policy-core` and the OAuth delegator hold a secret
# in memory for its lifetime, so `Zeroizing` there wipes the one authoritative
# copy. This host instead *forwards* the plaintext: `credentials` reads the
# token out of core's `Zeroizing` field and it is immediately copied into a
# `serde_json::Value`, then into the serialized request line, then into the
# pipe buffer, then into the worker's own address space. Zeroizing the DTO
# field would wipe one of those copies and leave the rest, which reads as a
# control that is not one. The real boundary is the worker process, and it is
# documented as such in `credentials`' "Residual exposure" note.
= "0.11"
# `process` and `io-util` are absent from the workspace tokio floor (the
# embedded library never spawns children). This host's whole job is a
# long-lived child spoken to over piped stdio, so it opts both in.
= { = true, = ["process", "io-util"] }
[]
# Exposes the `testing` module (temp dirs, python3 detection) to the
# integration tests under `tests/`, which cannot see a `cfg(test)` module.
# Not enabled by default — production builds carry none of it.
= []
[]
= { = true }
# The APL runtime, so `tests/acceptance_e2e.rs` can drive a route's
# `require(...)` and `delegate(...)` steps through the real engine. A dev-only
# edge: the facade depends on this crate, never the other way round.
= { = true }
= { = true, = ["process", "io-util", "macros", "rt", "rt-multi-thread"] }
# Self-dependency with the test-only feature on, so `tests/*.rs` see
# `cpex_hosts_python::testing`. Standard trick for cfg(test)-adjacent helpers.
= { = ".", = ["testing"] }
[]
= true