# pcq [![PyPI version](https://img.shields.io/pypi/v/pcq.svg?label=PyPI&color=18794e)](https://pypi.org/project/pcq/) [![Downloads](https://img.shields.io/pypi/dm/pcq.svg?label=downloads&color=1f5eff)](https://pypi.org/project/pcq/) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![CI](https://img.shields.io/github/actions/workflow/status/playidea-lab/pcq/ci.yml?branch=main&label=CI)](https://github.com/playidea-lab/pcq/actions/workflows/ci.yml) [![pcq MCP server (Glama)](https://glama.ai/mcp/servers/playidea-lab/pcq/badges/score.svg)](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` | `{: 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.