PCQ
# pcq
[](https://pypi.org/project/pcq/)
[](https://pypi.org/project/pcq/)
[](LICENSE)
[](https://github.com/playidea-lab/pcq/actions/workflows/ci.yml)
[](https://glama.ai/mcp/servers/playidea-lab/pcq)
> **pcq is the contract for agent-run ML experiments.**
> This repository hosts the contract specification under [`spec/`](spec/INDEX.md)
> and the reference Python implementation under [`src/pcq/`](src/pcq/).
> Install the reference impl: `uv add pcq` (Apache-2.0).
The contract turns a project with `cq.yaml` into a reproducible experiment
unit. The reference Python implementation loads config, resolves output
paths, captures metrics, writes standard artifacts, finalizes run evidence,
and exposes JSON/JSONL/MCP surfaces that coding agents, CI jobs, notebooks,
and services can consume. See [`spec/IMPLEMENTATIONS.md`](spec/IMPLEMENTATIONS.md)
for the registered implementation list (Python reference + CQ Go production
worker today) and the procedure for adding yours.
`pcq` is **not** a training framework, model zoo, adapter matrix, or CQ-only
client. Use PyTorch, Hugging Face Trainer, Lightning, sklearn, TabPFN, PyCaret,
XGBoost, shell scripts, remote jobs, or project-local research code. The
contract is the integration layer.
```text
pcq does not operate the model.
pcq operates the experiment boundary.
```
[SITE](https://playidea-lab.github.io/pcq/) |
[INTRODUCTION](docs/INTRODUCTION.md) |
[V4_DIRECTION](docs/V4_DIRECTION.md) |
[VISION](docs/VISION.md) |
[AGENT_OPERABILITY](docs/AGENT_OPERABILITY.md) |
[RUN_RECORD](docs/RUN_RECORD.md) |
[AGENT_OPERATING_GUIDE](docs/AGENT_OPERATING_GUIDE.md) |
[CHANGELOG](CHANGELOG.md)
Contract specification (single source of truth):
[spec/INDEX.md](spec/INDEX.md) |
[SPEC](spec/SPEC.md) |
[CQ_YAML_RUNTIME_CONTRACT](spec/CQ_YAML_RUNTIME_CONTRACT.md) |
[JSON_CONTRACTS](spec/JSON_CONTRACTS.md) |
[STRICTNESS](spec/STRICTNESS.md) |
[CQ_MCP_SPEC](spec/CQ_MCP_SPEC.md) |
[VERSIONING](spec/VERSIONING.md) |
[CONFORMANCE](spec/CONFORMANCE.md) |
[schemas/](spec/schemas/) (auto-exported via [`scripts/export_schemas.py`](scripts/export_schemas.py))
Case studies (external evidence):
[mnist-dogfood](docs/case-studies/mnist-dogfood-2026-05-08.md) |
[tabular-dogfood](docs/case-studies/tabular-dogfood-2026-05-09.md) |
[mcp-dogfood](docs/case-studies/mcp-dogfood-2026-05-10.md) |
[cq-worker-dogfood](docs/case-studies/cq-worker-dogfood-2026-05-10.md)
Agent-readable site files:
[llms.txt](site/llms.txt),
[llms-full.txt](site/llms-full.txt),
[agent-manifest.json](site/agent-manifest.json).
## Identity
```text
pcq = open-source experiment evidence/control library
cq = managed execution + orchestration + dashboard + agent loop
```
CQ service is one managed consumer of the contract. `pcq` remains useful without
CQ: locally, in CI, in notebooks, and inside third-party orchestrators.
## Why pcq
- **Framework-neutral** — keep the training stack that fits the problem.
- **Agent-readable** — use JSON/JSONL instead of terminal scraping.
- **Agent-verifiable** — validate source, config, environment, metrics,
artifacts, and run records.
- **Agent-operable** — run, observe, validate, describe, compare, lineage, and
iterate through stable commands.
- **Service-ready** — CQ can consume the same contract for managed execution and
automatic experiment loops.
## What's New (v4.4 – v4.6)
Three agent-fillable metadata fields were added to `run_record.json` across the
last three minor releases, making each run's evidence richer with zero extra
code in most cases.
| Field | Since | Captures | Auto-filled? |
|---|---|---|---|
| `attribution` | v4.4 | author / committer / operator — **who** ran the experiment | Yes (agent identity injected at runtime) |
| `worker_spec` | v4.5 | cpu / gpu / memory / os — **where** it ran | Yes (`pcq.worker_spec()` auto-detects hardware) |
| `fingerprint` | v4.6 | modality / task_kind / shape / PII-safe stats — **what** data | Semi-auto (`pcq.fingerprint(X, y)` detects most fields) |
### attribution — who
Records the human author, the AI committer, and the operator that launched the
run. Coding agents (Claude Code, Codex) fill this automatically from their
identity context.
```python
pcq.attribution(
author={"kind": "human", "id": "alice"},
committer={"kind": "agent", "id": "claude-code"},
operator="ci-runner-42",
)
```
Spec: [spec/SPEC.md § Attribution](spec/SPEC.md#attribution)
### worker_spec — where
Records CPU model, core count, GPU kind/VRAM, total memory, and OS. Called with
no arguments for a full auto-detection pass.
```python
pcq.worker_spec() # 자동 감지 — 인수 불필요
```
Spec: [spec/SPEC.md § Worker Spec](spec/SPEC.md#worker-spec)
### fingerprint — what
Records dataset modality, task kind, sample count, size class, domain, and
PII-safe summary statistics. Accepts a NumPy/pandas array or DataFrame and
infers most fields.
```python
pcq.fingerprint(X, y, modality="tabular")
```
Spec: [spec/SPEC.md § Fingerprint](spec/SPEC.md#fingerprint)
---
All three fields are **optional** — existing runs remain valid. When present
they appear as first-class evidence in `run_record.json` and are surfaced
through `pcq describe-run --json`.
## Reproducibility Substrate
3개의 선택적 필드로 독립 재현이 가능한 substrate를 `run_record.json`에 제공한다.
pcq는 검증하지 않는다 — 검증을 가능하게 만든다.
| Field | Captures |
|---|---|
| `code` | `{content_sha256, scope}` — 어떤 코드가 해시되었는지 |
| `seeds` | `{<name>: int \| str, ...}` — 재현에 필요한 난수 시드 |
| `data_ref` | `{uri, content_sha256, size_bytes}` — 데이터셋 식별자 및 콘텐츠 hash |
상세 스키마, PHI 게이트(R5), integrity 확장, R8 한계 문장:
[spec/SPEC.md § Reproducibility Pack](spec/SPEC.md#reproducibility-pack)
Note: code content sha proves WHAT code was recorded, not THAT it produced these outputs. See SPEC.md R8.
Note: pcq records claims, not judgments — `intent` is a recorded assertion (a fact about what was claimed), not a pcq verdict on success.
## Installation
```bash
uv add pcq
# Optional — to expose pcq as MCP tools to agent runtimes:
uv add 'pcq[mcp]'
```
`pyproject.toml`:
```toml
[project]
dependencies = ["pcq"] # core only
# or:
dependencies = ["pcq[mcp]"] # core + Model Context Protocol server
```
### Docker (MCP server only)
A minimal container image is also published; it packages
`pcq[mcp]` from PyPI and runs `pcq mcp serve` on stdio.
```bash
docker build -t pcq .
docker run -i --rm pcq # MCP client attaches to stdin/stdout
```
The image is intentionally scoped to the MCP server surface — for
`pcq run`, `pcq describe-run`, `pcq agent install` and other CLI
subcommands, install pcq directly with `uv add pcq` instead.
For a tag, branch, or private fork:
```toml
[tool.uv.sources]
pcq = { git = "https://github.com/playidea-lab/pcq.git", tag = "v4.1.0" }
```
The PyPI distribution, import name, CLI command, GitHub repository, runtime
workspace, and JSON contract namespace are all `pcq`. Runtime contract names
from CQ remain stable: `cq.yaml`, `CQ_CONFIG_JSON`, and `cq://`.
## Minimal Contract
`cq.yaml` declares the run:
```yaml
name: sklearn-baseline
cmd: uv run python train.py
configs:
output_dir: output
seed: 42
strictness: 3
monitor: eval_acc
mode: max
metrics:
- epoch
- eval_acc
artifacts:
- output/
inputs: {}
```
`train.py` can use any framework:
```python
import pickle
import pcq
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
cfg = pcq.config()
out = pcq.output_dir()
pcq.seed_everything(cfg.get("seed", 42))
x, y = load_iris(return_X_y=True)
x_train, x_eval, y_train, y_eval = train_test_split(
x,
y,
test_size=0.25,
random_state=int(cfg.get("seed", 42)),
stratify=y,
)
model = RandomForestClassifier(random_state=int(cfg.get("seed", 42)))
model.fit(x_train, y_train)
eval_acc = float(model.score(x_eval, y_eval))
with (out / "model.pkl").open("wb") as f:
pickle.dump(model, f)
history = [{"epoch": 0, "eval_acc": eval_acc}]
pcq.log(**history[-1])
pcq.save_all(history=history, artifacts={"model": "model.pkl"})
```
No sklearn adapter is required. The same pattern works for HF Trainer,
Lightning, XGBoost, TabPFN, PyCaret, shell commands, or custom code.
## Agent Command Surface
Read and validate the project:
```bash
pcq resolve --json
pcq inspect . --json
pcq validate . --strictness 2 --json
```
Run the project:
```bash
pcq run --path . --json
pcq run --path . --jsonl
pcq run --path . --events output/events.jsonl --json
```
Validate and summarize outputs:
```bash
pcq validate-run output --strictness 3 --json
pcq describe-run output --json
pcq compare-runs old_output new_output --json
pcq lineage output --json
```
Iterate:
```bash
pcq apply-plan experiment.plan.json --json
```
Agent rule: prefer JSON/JSONL surfaces over scraping human output. `pcq`
reports facts; the agent or service chooses policy.
## Standard Artifacts
A completed run should produce:
- `config.json`
- `metrics.json`
- `manifest.json`
- `run_summary.json`
- `run_record.json`
- `validation_report.json`
`run_record.json` is the canonical completion object. It combines execution,
source, environment, input identity, metric schema, artifact manifest, agent
provenance, validation, and summary evidence.
## Agent Runtime Assets
`pcq` can install its canonical agent instructions and skill into a project.
Package installation itself never mutates project agent files.
```bash
pcq agent install --target codex --path .
pcq agent install --target claude --path .
pcq agent install --target both --path . --dry-run --json
pcq agent status --target both --path . --json
```
To also wire the project for MCP-aware agents (Claude Code, Codex), install
`pcq[mcp]` and pass `--mcp`:
```bash
uv add 'pcq[mcp]'
pcq agent install --target claude --path . --mcp # writes .mcp.json
pcq mcp serve # stdio (default)
```
This exposes 14 `mcp__pcq__*` tools (`resolve_project`, `validate_run`,
`describe_run`, `compare_runs`, ...) so agents call pcq directly without
subprocess parsing. See [MCP Integration](docs/MCP_INTEGRATION.md).
Reusable assets:
- [templates/AGENTS.pcq.md](templates/AGENTS.pcq.md)
- [skills/pcq/SKILL.md](skills/pcq/SKILL.md)
## v4 Direction
v4 clarifies the product boundary:
- contract-first workflow, not a 3-tier training API
- project-local training code, not built-in production catalogs
- contract scripts, not framework adapters
- run evidence validation, not recipe ownership
- JSON/JSONL facts, not prose parsing
See [pcq v4 Direction](docs/V4_DIRECTION.md).
## Development
```bash
uv run ruff check src/ tests/ scripts/
uv run python -m compileall src/pcq
uv run pytest tests/ -q
bash scripts/release-smoke.sh
```
## License
Apache-2.0.
TDQS
Scored across 14 tools
Each tool targets a distinct phase or action: plan application, scaffolding, execution, finalization/validation, and run analysis. The read-only analysis tools (describe_run, compare_runs, lineage_chain) and project inspection tools (resolve_project, inspect_project, validate_project) are separated by clear semantic boundaries. There are no pairs that appear to do the same thing.
Most tools follow an imperative verb_noun pattern (run_experiment, validate_project, describe_run). A few deviate: agent_install and agent_status are noun-first, lineage_chain is a noun phrase, and apply_planset compresses plan_set into one word. These are minor and do not prevent readability.
At 14 tools, the surface is within the well-scoped range and each tool covers a discrete step in the CQ lifecycle. The grouping of scaffold/configure/run/finalize/validate/analyze plus agent asset helpers feels intentional, with no obvious dead weight.
The main lifecycle is well covered: init, plan application, run, finalize, validate, and analyze. Minor gaps exist around explicit discovery/cleanup (e.g., listing or removing plans/runs), but agents can work around these using inspect_project, finalize_run artifacts, or output directories.