← TinyGPT · docs · devlog · roadmap · speedup
source: docs/factory/run-schema.md · view on GitHub ↗

Factory Run Schema

Each real factory run should write a local run directory:

runs/<YYYY-MM-DD>-<target-slug>/
  config.json
  dataset.json
  train.log
  eval-baseline.json
  eval-candidate.json
  slice-metrics.json
  trace_review.md
  provenance.json
  report.md
  artifact.json
  decision.json

runs/ is ignored by git. Commit only small fixtures or final specialist package metadata.

The typed Swift representation lives in native-mac/Sources/TinyGPTIO/FactoryRun.swift. Keep this document and that type in sync; it is intentionally in the pure IO target so report/dashboard code can parse run metadata without loading MLX or a checkpoint.

Use the CLI wrapper to render or validate a folder:

tinygpt factory-run render \
  --config config.json \
  --dataset dataset.json \
  --baseline eval-baseline.json \
  --candidate eval-candidate.json \
  --decision decision.json \
  --artifact artifact.json \
  --out runs/<id>

tinygpt factory-run validate runs/<id>

config.json

{
  "run_id": "2026-07-02-pace-planner-sft-v1",
  "target": "pace-planner",
  "owner_goal": "Improve Pace planner action grounding without breadth regression.",
  "base_model": {
    "id": "Qwen/Qwen3-4B-Instruct-2507",
    "revision": "cdbee75f17c01a7cc42f958dc650907174af0554",
    "precision": "bf16"
  },
  "candidate": {
    "method": "sft-lora",
    "adapter_format": "tgla",
    "training_command": "tinygpt sft ..."
  },
  "eval": {
    "primary": "pace-v11-ship-gate",
    "regression": "bfcl-heldout-breadth",
    "threshold": {
      "primary_min": 0.95,
      "breadth_drop_max_pp": 3
    }
  }
}

dataset.json

{
  "dataset_id": "pace-planner-v11-sft",
  "sources": [
    {
      "kind": "trace",
      "path": "evals/...",
      "rows": 709
    }
  ],
  "processing": {
    "dedupe": true,
    "quality_filter": true,
    "heldout_split": "locked"
  },
  "counts": {
    "train_rows": 0,
    "heldout_rows": 0,
    "dropped_rows": 0
  }
}

eval-baseline.json and eval-candidate.json

Use the existing E0/eval-gate shape when possible. Add run metadata around it instead of inventing another scoring format.

Required fields:

slice-metrics.json

Reports the primary metric by meaningful task slice. For SQL, generate it with:

python3 scripts/score_sql_slices.py <eval-row-trace.jsonl> --out slice-metrics.json

Required fields:

Do not publish an overall-only win if the artifact is meant to be a specialist.

trace_review.md

Qualitative failure review. For SQL, generate it with:

python3 scripts/review_sql_trace.py --rows <rows-or-preds.jsonl> --out trace_review.md

Required checks:

Publish Check

Before publishing or releasing a run report, run:

tinygpt factory-run publish-check --allow-report-only runs/<id>

Before shipping a package, run without --allow-report-only:

tinygpt factory-run publish-check runs/<id>

See enforcement.md for the exact enforcement layers.

provenance.json

Machine-readable reproducibility metadata:

{
  "schema_version": 1,
  "renderer": "scripts/render_sql_factory_run.py",
  "renderer_command": "python3 scripts/render_sql_factory_run.py --out <run-dir>",
  "git": {
    "commit": "<sha>",
    "branch": "main",
    "dirty": true
  },
  "commands": {
    "baseline": "tinygpt generate ...",
    "candidate": "scripts/run_sql_routed_generate.py ...",
    "training": "tinygpt sft ...",
    "publish_check": "tinygpt factory-run publish-check --allow-report-only <run-dir>"
  },
  "datasets": [
    {
      "path": "evals/...",
      "rows": 50,
      "sha256": "<hash>"
    }
  ]
}

Required fields:

artifact.json

{
  "artifact_id": "pace-planner-sft-v1",
  "kind": "adapter",
  "path": "~/.cache/tinygpt/models/pace-planner-sft-v1",
  "base_model": "Qwen/Qwen3-4B-Instruct-2507",
  "format": "tgla",
  "package_dir": "specialists/pace-planner-sft-v1",
  "shipped": false
}

decision.json

{
  "decision": "ship",
  "reason": "Primary score cleared threshold with acceptable breadth retention.",
  "failure_reason": null,
  "failure_reason_confidence": "not-applicable",
  "lesson": "This recipe passed the frozen gates without hidden blockers.",
  "next_action": "Register specialist package and add model card.",
  "evidence_sources": [
    "report.md",
    "eval-candidate.json",
    "trace_review.md"
  ],
  "blocked_by": []
}

Allowed decisions:

failure_reason_confidence must be one of:

Non-ship decisions must include failure_reason, lesson, and at least one evidence_sources entry. ship decisions should use failure_reason_confidence: "not-applicable" and still include evidence sources for the positive claim.

report.md

Use the template in docs/factory/reports.md. Reports must include an ## Evidence / Exactness section matching decision.json.