# Cohesix Python Support The `cohesix` Python package is a host-side, non-authoritative client for the existing Cohesix file and console contracts. It validates inputs, applies generated bounds, and offers typed helpers; it does not add protocol verbs, roles, paths, or authority. The package source is under [`tools/cohesix-py/`](../tools/cohesix-py/). REST semantics are defined in [API_GUIDELINES.md](API_GUIDELINES.md), control schemas in [INTERFACES.md](INTERFACES.md), and live topology in [HOST_TOOLS.md](HOST_TOOLS.md). The local `CohesixClient.peft_activate` and `peft_rollback` helpers update only the host registry and report `execution_location=host projection=pending`. They make no backend write to `/gpu/models/active`, which is read-only. Publish the same registry with the configured `gpu-bridge-host --registry --publish` workflow to update the target snapshot. Serialize publication with other publishers. A successful local call does not provide a Worker receipt, target publication proof, or inference reload. See the [Glossary](GLOSSARY.md) for Cohesix-specific role, namespace, and evidence terms. Python support consumes the compiler-owned [`host-integration-dependency/v1`](../configs/generated/host_integration_dependency.json) graph. Its `python-sdk-projection` row is release-required, while each external systemd, Docker, Kubernetes, GPU, or PEFT provider remains an independent row. The generated [support table](snippets/host_integration_dependency.md) is the shared vocabulary: a Python object, successful dry run, mock probe, or package install cannot create Worker READY, live-provider status, or use-case acceptance. ## Requirements and installation Python 3.11 or later is required. Use an isolated environment: ```bash # Created by either canonical host installer: # ./toolchain/setup_macos_arm64.sh # ./toolchain/setup_linux_arm64.sh source .venv/bin/activate ``` The installers populate `.venv` from the hash-locked host-test requirements and install `tools/cohesix-py` in editable mode without optional integrations. To create only that environment with an already installed Python 3.11 or later, run `./toolchain/setup_repo_venv.sh --python python3`. The editable path above is for a source checkout. From a release-bundle root, the runtime setup creates `.venv` and installs the bundle's exact wheel without resolving optional dependencies: ```bash ./scripts/setup_environment.sh source .venv/bin/activate ``` For a Python-only integration with Release A, install the [`1.1.0b1` distribution from PyPI](https://pypi.org/project/cohesix/1.1.0b1/) in an activated Python 3.11+ environment: ```bash python3 -m pip install 'cohesix==1.1.0b1' ``` This version uses the `1.1.0-beta` tagged SDK code with corrected Python package metadata. It installs the client, not the native host tools or target runtime; use the matching host bundle for those components. The sealed Release A archives retain their original bundled wheel. The M28g source selects `cohesix==1.2.0` and `cohesix-nemo-kit==1.2.0` for the unqualified `1.2.0` candidate. Both wheels are built from the compiler's exact source inventory and must be installed with the matching native host candidate for Release B testing. They do not replace the published Release A client until the assembled release qualifies and is approved for publication. Optional dependency groups are explicit: ```bash # Docker, Kubernetes, and NVML probes python3 -m pip install -e 'tools/cohesix-py[integrations]' # PEFT and Transformers probes python3 -m pip install -e 'tools/cohesix-py[ml]' # Package tests python3 -m pip install -e 'tools/cohesix-py[dev]' ``` The Python package versions are defined in [`tools/cohesix-py/pyproject.toml`](../tools/cohesix-py/pyproject.toml) and [`integrations/nemo-agent-toolkit/pyproject.toml`](../integrations/nemo-agent-toolkit/pyproject.toml). For M28g, both use the stable Release B version `1.2.0`. The installer requires both selected wheel versions to match that candidate identity. ## Backends | Backend | Connection | Intended use | Authority and concurrency | | --- | --- | --- | --- | | `RestBackend` | `hive-gateway` HTTP API | Concurrent live clients | Scoped delegated reads/writes, bounded by the gateway's upstream role/ticket | | `TcpBackend` | Target TCP console | One direct live client | Performs `AUTH` and `ATTACH`; owns the single console connection | | `FilesystemBackend` | Existing `coh mount` tree | File-oriented integrations | Inherits the authority of the process that created the mount | | `MockBackend` | Local deterministic directory tree | Unit tests, examples, dry runs | Persistent at the selected root; processes using the same root can share it; never live-system evidence | Use REST when Python must coexist with `cohsh`, SwarmUI, or continuous publishers. Do not open a `TcpBackend` while another direct client owns the target console. ### Explicit backend construction Use explicit construction when application configuration already selected one topology. These are the minimal constructors for all four public backends: ```python import os from cohesix import FilesystemBackend, MockBackend, RestBackend, TcpBackend mock = MockBackend(root="out/examples/mockfs") mounted = FilesystemBackend("/absolute/path/to/cohesix-mount") rest = RestBackend( base_url=os.environ["COH_REST_URL"], request_auth_token=os.environ.get("HIVE_GATEWAY_REQUEST_AUTH_TOKEN"), ) tcp = TcpBackend( host=os.environ.get("COH_TCP_HOST", "127.0.0.1"), port=int(os.environ.get("COH_TCP_PORT", "31337")), auth_token=os.environ["COH_AUTH_TOKEN"], role="queen", ticket=os.environ.get("COH_TICKET"), ) try: print(tcp.list_dir("/")) finally: tcp.close() ``` `FilesystemBackend` requires an already active `coh mount`; it neither creates nor owns that mount. `MockBackend` seeds a deterministic local tree and may reuse prior state at the selected root. When a `CohesixClient` binds a generated profile, future mock Worker observations use that profile's exact shard width. The REST and TCP constructors perform live operations and must follow the ownership rules in [HOST_TOOLS.md#choose-one-live-topology](HOST_TOOLS.md#choose-one-live-topology). ## Backend selection from the environment `CohesixOrchestrator.from_env()` selects the first configured backend in this order: 1. `COHESIX_MOCK=1`; optional root `COHESIX_MOCK_ROOT`. 2. `COHESIX_MOUNT_ROOT`. 3. `COH_REST_URL`, `HIVE_GATEWAY_URL`, or `COHESIX_REST_URL`. 4. Direct TCP using `COH_TCP_HOST`/`COHSH_TCP_HOST`, `COH_TCP_PORT`/`COHSH_TCP_PORT`, `COH_ROLE`/`COHSH_ROLE`, and optional `COH_TICKET`/`COHSH_TICKET`. The common request timeout is `COHESIX_TIMEOUT_S`; direct TCP retry count is `COHESIX_MAX_RETRIES`. Example read-only inspection through a configured backend: ```python from cohesix import CohesixOrchestrator with CohesixOrchestrator.from_env() as cohesix: entries = cohesix.backend.list_dir("/") snapshot = cohesix.read_proc_snapshot() print(entries) print(snapshot.schedule_summary) print(snapshot.lease_summary) ``` ## Authentication ### REST `cohesix.exchange_identity` performs one bounded, authenticated exchange using credential references and an independently enrolled provider graph digest. It returns an `IdentityTicket` for explicit `RestBackend` delegation. It follows no redirects and does not retry or refresh authority. `cohesix.local_subject` reads only the local kernel euid. See [identity mapping](IDENTITY_MAPPING.md). The SDK provides `QueenIntent` and `AdmissionCorrelation`, delegated REST write credentials, strict-intent and writer-epoch validation, and bounded authority/dedupe snapshots in evidence packs. Generated `cohesix-python-profile/v2` includes selected authority policy; consumers require a generated profile matching the selected target. Neither Python objects nor profile metadata constitute a VM admission grant. Missing production epoch/delegation fails before mutation, and REST writes have no automatic retry. See [M27a authority](M27A_AUTHORITY.md). `RestBackend` accepts an explicit `request_auth_token`. Otherwise it resolves, in order, `HIVE_GATEWAY_REQUEST_AUTH_TOKEN`, `COHSH_REST_AUTH_TOKEN`, then `COH_REST_AUTH_TOKEN`. The backend sends both accepted gateway headers for authenticated requests. Non-public reads, including gateway status and namespace reads, require request auth and a delegated `Read` or `ReadWrite` ticket through `delegated_ticket=` or `COH_REST_TICKET`; public classification is generated. They remain bounded by the gateway's upstream target authority. The explicit single-caller read-compatibility option is not enabled by default. See [read authentication](HOST_API.md#authentication-and-exposure). `RestBackend.submit_selected_job(binding, ticket)` posts the same versioned binding used by `coh job submit`. The retained admission id is the recovery key: `selected_job_status(id)` reads execution and independent result delivery; `reconcile_selected_job(id)` checks the target result without another effect; `request_selected_job_cancel(id)` only requests cancellation. An uncertain submission response requires status or reconcile with the original id, never a new ticket or idempotency key. `inspect_standing_scope(id)` and `revoke_standing_scope(id)` require a separate delegated admin ticket. Standing authority and native outcome remain gateway/agent contracts, not Python grants. `cohesix.workload.batch_edges_expected` and `verify_batch_edges` provide an independent bounded CPU verifier for the registered CUDA batch-edge example. The checked [preparation script](../tools/cohesix-py/examples/cuda_batch_edges.py) freezes package, input and expected output digests before a selected job is admitted. Its second dataset is an adaptation using the same installed package, without a Cohesix source change. `recovery_guidance(record)` explains the original job's execution and delivery states, retained uncertainty and lack of checkpoint resume; it cannot cancel, settle or authorize a restart. A successful pixel check remains host evidence until correlated with the root admission, native observation and signed terminal. See [registered CUDA workloads](https://lukeb-aidev.github.io/cohesix/docs/HOST_TOOLS.html#registered-cuda-workloads) for installation and recovery. ```python import os from cohesix import RestBackend backend = RestBackend( base_url=os.environ["COH_REST_URL"], request_auth_token=os.environ.get("HIVE_GATEWAY_REQUEST_AUTH_TOKEN"), ) print(backend.read_file("/proc/lifecycle/state", 128).decode("utf-8")) ``` ### Direct TCP `TcpBackend` requires a console auth token, role, and optional ticket: ```python import os from cohesix import TcpBackend backend = TcpBackend( host=os.environ.get("COH_TCP_HOST", "127.0.0.1"), port=int(os.environ.get("COH_TCP_PORT", "31337")), auth_token=os.environ["COH_AUTH_TOKEN"], role="queen", ticket=os.environ.get("COH_TICKET"), ) try: print(backend.list_dir("/")) finally: backend.close() ``` For checkout-based development, `resolve_tcp_auth_token()` can read a Queen ticket secret from an explicitly selected or default source manifest before it falls back to `COH_AUTH_TOKEN` and `COHSH_AUTH_TOKEN`. This is a local configuration convenience, not delegated identity. Production callers should pass the intended secret explicitly through their secret-management boundary so manifest discovery cannot select an unexpected credential. Missing, empty, and placeholder tokens are rejected. Never log tokens, embed them in source, or store populated credential files in the repository. ## Public API The provider helpers `cohesix.providers.registry`, `provider`, `action`, `profile`, `surface`, and `validate_target` resolve compiler-generated contracts and stable integration IDs, including admission, target grammar, exact host profiles and read visibility. Returned dictionaries are detached projections; changing them cannot alter admission policy or establish live provider support. The package exports these primary surfaces from `cohesix`: | Surface | Purpose | | --- | --- | | `CohesixClient` | GPU discovery and leases, telemetry push/pull, host-command operation reports, evidence packs, and PEFT lifecycle helpers | | `CohesixOrchestrator` | Typed approvals, scheduler records, leases, exports, host tickets, and `/proc` snapshots | | `ControlPlan` | Declarative collection of approval, schedule, lease, and export writes | | `ApprovalRequest` | Validated `/actions/queue` record | | `ScheduleRequest`, `ScheduleDequeue` | Validated producer and exact FIFO-consumer `/queen/schedule/ctl` records | | `LeaseRequest` | Validated `/queen/lease/ctl` record | | `ExportRequest` | Validated `/queen/export/ctl` record | | `HostTicketRequest`, `K8sRbacIntent` | Manifest-bounded host ticket records and Kubernetes intent conversion | | `CohesixAudit` | Bounded client-side acknowledgement and breadcrumb collection | | `TargetProfileContract`, `load_profile_contract` | Strict loader for one compiler-generated QEMU or Pi Python profile contract | | `WorkerClient` and `CohesixClient.worker_*` | Existing `/queen/ctl` and canonical `/shard` Heartbeat, GPU, and LoRA lifecycle projection | | `WorkerReceipt`, `CompatibilityReceipt`, `parse_receipt` | Version-1 compatibility and local-admitted version-2-correlated Worker receipt projection | | `WorkerAcceptanceAxes` | Keeps admission, READY, provider, receipt, artifact, proof, release, and use-case state separate | | `CohesixError` | Package error type for validation, transport, and server refusals | ## Target contracts and Worker API The wheel is target-neutral. Its generated `DEFAULTS` object contains bounded fallback expectations, `manifest_sha256=None`, and `execution_proof="none"`. It cannot identify a running target. Live Worker calls require one explicit, regular, non-symlink compiler output: - `configs/generated/cohesix_python_qemu_smp_production.json` for the selected `qemu_smp_production` Mac or `qemu_smp_kvm_production` Linux build; - `configs/generated/cohesix_python_pi4_production.json` for `pi4_production`. Both use `cohesix-python-profile/v2`, but each binds its own resolved-manifest hash. They are generated independently; one target contract must never be copied, renamed, or inferred from the other. A parsed in-memory mapping is useful for validation tests but is marked `source="mapping"` and does not establish target identity. ```python from cohesix import CohesixClient, MockBackend, load_profile_contract profile = load_profile_contract( "configs/generated/cohesix_python_qemu_smp_production.json", expected_target="qemu", ) client = CohesixClient( MockBackend("out/examples/worker-model"), profile_contract=profile, ) admission = client.worker_spawn("heartbeat", "heartbeat-1") assert admission.lifecycle == "queued" # the control write was admitted ready = client.worker_wait_ready("heartbeat", "heartbeat-1") assert ready.state.lifecycle == "ready" # separately observed telemetry client.worker_teardown("heartbeat", "heartbeat-1") ``` The mock in this example reports `execution_proof="host-model"`. It exercises the API but is never QEMU or Pi proof. The three executable roles are `worker-heartbeat`, `worker-gpu`, and `worker-lora`; their combined generated maximum is 256 simultaneous tasks for both QEMU and Pi 4 (1 Heartbeat, 127 GPU, and 128 LoRA). `worker-bus` remains model-only, and spawn or teardown returns a deterministic `CohesixError` before any backend write. Worker telemetry uses `/shard/