Metadata-Version: 2.4
Name: pgl-studio
Version: 0.1.1
Summary: PGL Studio MCP server — the Prometheus<->studio seam: production-ground ops and the Olive Drive Transit game face behind the vetted descriptor contract.
Author: E5 Enclave Inc.
License: Proprietary
Keywords: mcp,model-context-protocol,agentic-gaming,prometheus
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# pgl-studio

The PGL Studio MCP server — the Prometheus↔studio seam (P6). A small,
stdlib-only, loopback-bound server that exposes the agentic gaming
studio's production ground and its agent-playable game face to any
consumer that speaks the descriptor contract: vet before trust, a
pinned manifest hash, frozen effect classes, per-tool grants,
fail-closed on drift.

## The two numbers that print side by side

| Package version | Manifest pin (`descriptor.json` → `manifestSha256`) |
|---|---|
| 0.1.1 | `5ff1091bf04286e83118098c5d305987b4c93462069dfc13bbce0ef4a8af2eb4` |

The package version versions this distribution. The manifest pin is
the versioning law at runtime: a consumer registers the descriptor,
vets the server (initialize + tools/list + ping), and pins the
manifest hash; if the served manifest ever drifts from the pin, the
server compiles unavailable — fail-closed, with the reason on the
record. The same values are exposed programmatically from the
installed package: `pgl_studio.__version__` and
`pgl_studio.MANIFEST_SHA256`.

**The pin is recomputable, not just comparable (0.1.1).** The
compiler's canonicalization recipe ships inside the package:

```sh
python3 -m pgl_studio.manifest_check   # recompute + MATCH/MISMATCH
```

It recompiles the manifest from the installed server's own
initialize + tools/list and the shipped descriptor's declared
effects, hashes the canonical form, and compares against
`MANIFEST_SHA256`. Drift-checking is a computation, not a comparison
of copies.

## Run

```sh
pip install pgl-studio
pgl-studio            # serves http://127.0.0.1:8791/rpc, GET /health
```

Configuration is env-only; no credentials are carried in any file —
the consumer's descriptor names the bearer env var, never a value:

| Env | Default | Meaning |
|---|---|---|
| `PGL_MCP_PORT` | `8791` | Loopback port |
| `PGL_DONE_STATE` | house run-ops done-state path | Production-ground receipt the ground tools read |
| `PGL_RUNNER_CMD` | the studio tree's runner | Episode command for `ground_run_episode` |
| `PGL_WATCHDOG` | house run-ops watchdog | Advisory verdict source for status tools |
| `PGL_GAME_ADAPTER` | `odt` | `stub` selects the deterministic in-memory game adapter |

## Tools (10, grant = all 10 in the vetted descriptor)

Ground ops: `ground_run_episode` (write-local), `ground_run_status`,
`ground_lane_status`, `kernel_gate_states` (read-local).
Game face (Olive Drive Transit): `game_observe`, `game_legal_actions`,
`game_verify`, `game_snapshot` (read-local), `game_act`, `game_reset`
(write-local). Typed state only — pixels never cross this face.

## Dependency closure — measured, and the placed grant scoped

The import graph was measured, not assumed (Wisdom Council B2, Red
Team cure, 2026-11-07). The artifact's `tools/list` is byte-identical
to the vetted manifest — the pin binds the artifact's surface — but
the *backing machinery* differs by tool:

**The artifact alone serves:** the protocol face itself
(`initialize` / `tools/list` / `ping`, manifest self-consistency
against the pin), the ground read tools whose backing files are
env-pointed — `ground_run_status`, `ground_lane_status` (done-state
via `PGL_DONE_STATE`; the watchdog verdict via `PGL_WATCHDOG`,
degrading to UNAVAILABLE when unconfigured) — and, since 0.1.1, the
game contract through the stub adapter: the adapter contract module
(`adapters/contract.py`, the game face's one non-stdlib import)
ships inside this package, so `PGL_GAME_ADAPTER=stub` exercises all
six `game_*` tools deterministically from the bare artifact.

**Tree placement required** (the R10 seat beside the Prometheus core,
where the studio tree exists):

| Tools | Closure beyond this package |
|---|---|
| `ground_run_episode` | a runner command (`PGL_RUNNER_CMD`) in the tree |
| `kernel_gate_states` | the runner module in-process: `run_production_ground.py` → `kernel/`, `planner/` |
| `game_*` live (OdtAdapter) | the Node CDP sidecar (in-package) plus the game HTML (`studio/olive-drive-transit/index.html`, resolved tree-relative) and a Chromium |

Decision, on the record: the game HTML is **not** shipped in this
package — shipping it alone could not close the *live* game face
(the adapter resolves it by tree path and needs a browser besides).
The contract the game face is written against **is** shipped
(0.1.1 cure: in 0.1.0 its absence broke even the stub from the
artifact). **The placed grant is scoped here**: a bare pip install
is the contract + ground-read + stub-game face; the full 10-tool
live surface is the tree placement's. The descriptor remains the
primary package form; pip carries it to machines, the skill-file
kit carries it to agents, the MCP registry lists it for discovery,
git keeps it forever.
