Applies to every coding agent (Cursor, Claude Code, Codex, Gemini, Copilot / GHCP, Grok, others). Prefer this file over tool-specific defaults on process conflicts.
Every harness enforces the same laws. python -m scripts.verify_agent_surfaces
owns the obligation × surface matrix and fails CI when one surface drops a law;
current coverage and known differences are in
docs/design/agent-harness-parity-audit.md.
@RTK.md
Experiment-first OpenUI layout SLMs:
- Honest models — TwoTower / grammar-diffusion that clear multi-suite
--ship-gates, not fixture memorizers (docs/design/adversarial-review.md). - Measurable progress — every train / eval / bench / matrix run leaves
durable evidence under
docs/design/. - Research → code → results — specs cite papers; harnesses implement levers; docs record what ran and whether gates passed.
- Ship vs demo — fixture demos are wiring-only; production claims need full
scoreboards (full
rico_held/ HF / DESIGN.md when claimed). - Durable checkpoints — real full HF-context trains upload checkpoints to
the OpenUI HF Bucket
(
docs/design/checkpoint-bucket.md). - Model cards — every new/promoted checkpoint updates
docs/MODEL_CARD.mdand the README “Model card (summary)” section. - Standard evals — every evaluation run emits AgentEvals JSONL and is
executed/published with the pinned AgentV SDK; domain metrics and honest ship
gates remain authoritative (
docs/design/agentv-evaluation.md).
This repo is not training a natural-language LLM. It trains a
grammar-constrained symbolic diffusion model that outputs templated
grammars (scaffolded structure + structural reasoning). Templated /
natural-language content is deferred to a real external LLM (symbol-only output
contract, dsl/language_contract.py, OUTPUT_CONTRACT_VERSION=2). Everything
below is a goal invariant: it constrains every model, harness, lever,
experiment, doc, and agent action here — past, present, and future. Canonical
expansion with file pointers, current status, and open goals:
docs/design/decode-invariants.md.
Ids below are the canonical I* ids from
docs/design/decode-invariants.md. Cite
them, never a file-local number — every agent surface uses the same ids so
"I13" means one thing everywhere.
- I6 — Never output invalid grammar. Every production decode path is
grammar-constrained end to end. Unconstrained arms
(
--unconstrained-control, HTTPgrammar_constrained=false, evalrawarms) are diagnostic controls only — never production defaults, never serving paths, and their output is never shipped, certified, or gated on. - I6 — Fail closed. Production configs must not set
allow_unconstrained_fallback=True, must run finalize validation, and must raise (not return uncertified text) when certification fails — in every backend, ONNX included. An empty legal domain is a constrained dead end, never a full-vocabulary fallback. This extends past decode: no load-bearing contract may silently widen when a dependency is unavailable. - I6 — No lever, experiment, or skill may remove or weaken deterministic /
constrained decoding. Levers may change how legal symbols are chosen
(ranking, speculation technique, batching) — never whether output is
legal. Weakening levers are registered in
levers.CONSTRAINT_WEAKENING_LEVERSand CI-blocked from production configs.
- I1 — Deterministic completion paths bypass inference wherever a deterministic answer exists. Authoritative deterministic decode proofs always outrank learned, semantic, confidence, or preference scores.
- I2 — Forced bypass on singletons: when the scope-aware symbol table (DFA
domain /
CompletionDomainV1/ choice-codec state) shows exactly one valid next symbol, that symbol is committed without any neural forward or ranking, in every decode path and every backend. Never downgrade certainty into a soft preference. New decode paths ship with a bypass test (theforwards_count == 0pattern) or they do not merge. - I3 — Speculative completion from forward-calculated symbol tables: symbol
tables are computed before the model; at non-singleton branch points, rank
legal symbols with a deterministic scorer
(
dsl/grammar/fastpath/speculative_rank.py, committed train-only n-gram table atresources/decode/speculative_ngram_v1.json) and speculatively commit multi-token spans that stay inside the certified domain (lookahead-then- verify, arXiv:2602.00612; intersection-witness completions, arXiv:2508.10111). I5 — the technique is a lever, swappable by preregistered experiment, but speculation always verifies against the grammar oracle before commit. - I4 — Symbol tables schedule compute: use them to plan subsequent prefills —
compact ambiguous rows into minimal forwards, place prefill boundaries at
grammar checkpoints proven by
common_forced_run(what the grammar forces after every legal candidate is determined before the model picks), route by detected device (runtime/decode_schedule.py). Record scheduled-prefill and forwards-avoided counters inDecodeStats; utilization regressions are measured, never vibes.
- I9 — Output = scaffolded grammar. Targets contain only grammar/AST literals and placeholder symbols. Natural-language vocab is optional fluff — optimizable later, never load-bearing, never a ship blocker.
- I10 — Use-case ladder (in order, no skipping): AST-2-AST → grammar-2-AST →
grammar+ops-2-AST → simplified-NL-2-AST → complex-NL-2-AST. Each rung is
certified before the next opens (
CERT_CAP*gates stay). Current position and blockers:docs/MODEL_CARD.md+docs/design/decode-invariants.md. - I10b — Calculator/solver enhanced with inference — not a chat model. Inference fills ambiguity; it never authors structure a deterministic solver can derive.
- I13 — The encoder vocabulary MUST reserve a compute-ops vocabulary —
AST/graph/set/topology operations — known and shared by the decoder
vocabulary. That vocabulary is
dsl/ops_vocab.py: derived from the live operator registries (an op cannot be in it without an implementation, or implemented without being in it), reserved in the versionedopstoken-id namespace, and exposed through the singleshared_token_ids()mapping both towers call. Grammar symbols layer on top viaassert_layering; NL sits above and is strictly optional. Adding, removing, or reclassifying an operator changes the fingerprint and failsverify_decode_invariantsuntilresources/ops_vocab_registry.jsonis rebuilt andops.vocabis bumped. e803 rejected decoder-target op tokens and says nothing about encoder-side sharing; that campaign is the open rung. The output tokenizer layout is likewise a frozen, checkpoint-bound contract (resources/tokenizer_layout_registry.json) — never re-derived from whichever grammar backend happens to be live. - I11 — Multi-turn = CRDT event store. Append-only, content-addressed events
over the conversation AST (
ConversationTraceV1). Turn inputs are ops on that AST; ops include copy/undo/redo. Merge must converge (CRDT semantics) — the conflict-rejecting merge is a documented interim state, not the goal. The AST artifact is a materialization of the entire conversation history (full replay, no hidden cursors). - I12 — Patch/diff outputs across turns. Turns emit operation patches/diffs, not full rewrites, wherever the edit space can reach the target (reachability-certified). Full-AST output is the bootstrap mode, not the end state; reachability blockers are open goals, not closed questions.
- The deliverable is the smartest output at the smallest model. Quality
rises with capacity on its own, so a quality win from a larger model is
not evidence about the change under test. Model size is a budget that is
spent and charged, never a free knob. Capacity levers are registered in
levers.CAPACITY_SCALING_LEVERSwith their baseline value. - Growth must pay for itself. Parameters are a first-class cost axis
(
scaling_fit.CostKeyincludesparams). A candidate with more trainable parameters than its baseline is promotable only with a size-normalized gain —EG_paramsLCB ≥ 1 (PromotionCriteria.eg_params_lcb_min). Unmeasured growth fails closed: wall-time parity is not a size budget, because a wider model can hold its latency and still buy its loss. - Promote the smallest sufficient model. Selecting the lowest loss over
a ladder that spans widths promotes the widest rung by construction. Rank
by loss, then take the smallest model within the noise band
(
promotion_engine.select_smallest_sufficient). - Scaling is a diagnostic control arm, never a default lever. Arms
compared to attribute a quality delta must be size-matched
(
levers.require_size_matched_arms) or charge the difference. Growing the model to green a gate is the size-analogue of weakening a gate, and is equally forbidden. A capacity deviation is legal only when it is the declared subject of a preregistered experiment.
- I14 — Goals are non-negotiable; approaches are disposable. A rejected
experiment closes an approach, never a goal. Every rejected approach to
an invariant above must file its successor approach (or an explicit, dated,
documented waiver) in the same measured-results doc. Labels like
"rejected" / "unavailable" /
nl_available=False/reachable_fraction=0.0describe current approach state and may never be cited as reason the invariant does not apply. - I7 — Every agent surface carries the law. Each configured harness reads a
different instruction file, so a law stated only here reaches only some
agents.
python -m scripts.verify_agent_surfacesowns the obligation × surface matrix and certifies every law on every surface. Seedocs/design/agent-harness-parity-audit.md. - I15 — Everything is documented. These invariants live canonically in
docs/design/decode-invariants.md, are linked from README, MODEL_CARD, and the decode/vocab/conversation design docs, and are regenerated into OpenWiki. Changing one requires editing that doc, bumping thedecode.invariantscomponent inresources/versions.json, and passingpython -m scripts.verify_decode_invariantsin CI — a silent weakening is a regression and blocks merge.
Every train, eval, benchmark, profile, telemetry, matrix, reproduction, and
supporting shell command must obey the canonical cap in
src/slm_training/levers.py. Use its derived interrupt and kill-grace values;
training, campaign, and CI harnesses must not exceed its MAX_RUN_MINUTES.
Change that one constant, then run
python -m scripts.repo_policy --sync-run-policy to regenerate the GitHub and
Vercel adapters. Prefer local compute;
remote CI and managed jobs are last-resort convenience surfaces. A timed
out, interrupted, or killed run is never evidence.
Start: README.md, docs/MODEL_CARD.md, docs/design/openui-twotower.md,
docs/design/reverse-mathematics-computability.md (revmath owners; verify_revmath_owners),
docs/design/quality-experiment-matrix.md,
docs/design/perf-experiment-matrix.md, docs/design/research-lineage.md,
docs/design/checkpoint-bucket.md, docs/repository-organization.md.
Canonical: .agents/skills/<name>/SKILL.md. Mirrored for discovery under
.claude/skills/, .cursor/skills/, and .grok/skills/ with symlinks. Edit
only the canonical copy; Codex and GitHub Copilot discover .agents/skills/
directly (never create .codex/skills/).
If a skill might apply (~1%), open and follow it before acting.
| Skill | Use when |
|---|---|
documenting-experiment-results |
After any train / eval / bench / profile / matrix / telemetry run |
honest-ship-eval |
Eval, gates, readiness claims, metric changes, demo vs ship |
running-experiment-matrices |
Running or extending E* / X* / PQR / phase matrices |
openui-autoresearch |
Evidence-grounded campaigns, data/researcher repair, telemetry persistence, and RL readiness |
revmath |
Reverse-mathematics / computability profile discoverability (reasoning/revmath); owners, hermetic fixture runs, labeling honesty |
improve-openui-harnesses |
Enhancing canonical research, data, model, eval, preference, distill, promotion, annotation, quality, or RL harnesses without parallel paths or artifact sprawl |
improve-lean-optimums |
Diagnosing or improving Lean4-calculated metric bands and out-of-band autotraining feedback |
autotrain |
Running any training pipeline phase (train/test data, SFT, eval, distill, preference, RL, experiments, checkpoints, annotations, bench, autoresearch self-improvement + hypothesis loop) — per-phase references load on demand |
autoresearch |
Knowledge-driven research orchestration: read/update repo + personal brains (OpenWiki / OKF / Obsidian), run the prior-work discovery loop, drive the autotrain hypothesis loop, and file ideas/experiments as Linear issues/milestones/projects — per-stage references load on demand |
ponytail (+ -review / -audit / …) |
Any coding task — write the minimum that works (YAGNI ladder) |
organize-repository |
Creating, moving, renaming, deleting, or duplicating tracked paths; adding modules/docs/src/apps/skills; repository-sprawl review |
sdlc |
Multi-step delivery: subagents + incremental check-ins, official gh stack stacked PRs, Scalar/sparse worktrees, bottom-up rubber-duck adversarial closeout (comments, CI, squash-merge) |
caveman (+ -commit / -review / …) |
Opt-in terse chat / short commits / one-line review comments |
headroom |
Large tool outputs, logs, greps, or context pressure |
rtk |
Verbose shell output — prefer rtk <cmd> when installed (RTK.md) |
hf-cli |
Hub models/datasets/spaces, auth, cache, HF jobs, buckets, downloads |
huggingface-* / hf-* / trl-training / … |
Other huggingface/skills workflows (papers, datasets viewer, trainers, Spaces, memory estimate, …) |
playwright-cli |
Browser automation or playground e2e |
synthesis-feedback |
After any training-data build/synthesis: read quality_report.json + rejected.jsonl + synthesis_feedback.json, fix the synthesis harness (never the gates), file the emitted experiment candidates |
frontier-describe |
Fill train-only frozen frontier artifacts and validate leakage/coverage |
dashboard-openui-parity |
Editing a dashboard page (src/apps/dashboard/src/pages/*.tsx) — keep its interpreted-mode static/openui/*.openui program at parity |
Multi-phase, multi-layer, or multi-task work uses the sdlc skill
(.agents/skills/sdlc/). Activation is automatic for landable engineering
work — not only when the user types sdlc.
- Parent agent plans layers and owns official GitHub Stacked PRs
(
gh stack/gsfromgithub/gh-stack), or one PR for single-concern work. - Subagents implement layers with incremental check-ins (small commits on the layer branch).
- Push is not done. After the last intended commit, open/update PRs in the same turn. Do not ask “want me to open a PR?” — open it.
- Closeout is mandatory and bottom-up: rubber-duck + adversarial review of each PR (post notes on the PR), address all comments and review feedback, fix all relevant status checks (billing/budget exceeded is the only allowed CI pause), then squash-merge every PR the parent opened unless the human explicitly said not to merge.
The GitHub connector is the authority for remote Git operations and delivery:
use it for branch/ref creation or updates, commits/trees, pull requests,
reviews, checks, and squash merges. Local git is for inspection, tests, and
working-tree edits only. Do not use shell git push, git merge, git commit,
or manual ref surgery to work around shared-worktree metadata, hooks, or a
read-only .git surface.
When a loop or delivery step reports dirty-tree protection, diagnose the exact paths and owner first. Do not classify GitHub/metadata friction as a product failure and do not “self-heal” by creating local commits or merging stale branches. Remediation is: preserve the worktree, use the GitHub connector to publish the intended commit/branch/PR, wait for connector-reported checks and merge state, then refresh the local checkout and rerun the exact blocked step. If the connector is unavailable, report the delivery blocker explicitly rather than substituting shell Git mutations. A training/eval loop may proceed only after its canonical status confirms a new cycle; a generated artifact or local commit alone is not cycle evidence.
- Workspaces:
scalar registerfor scale Git settings (sparse-checkout, partial clones on new clones, background maintenance); prefer dedicated worktrees + cone sparse-checkout per task so agents do not collide.
Single-file hotfixes may stay one PR; everything larger follows sdlc.
Installed into .agents/skills/ and discovered by Claude Code
(.claude/skills/), Cursor (.cursor/skills/), Grok (.grok/skills/), and
Codex / GitHub Copilot (project .agents/skills/ directly), with Cursor rule
files under .cursor/rules/ and GHCP under
.github/copilot-instructions.md.
| Layer | What it saves | Default |
|---|---|---|
| ponytail | Less code written | Always on for coding (skills + Cursor rules) |
| caveman | Shorter agent prose | Opt-in (/caveman or “talk like caveman”) |
| headroom | Smaller pasted tool results | When outputs are large / context is tight |
| rtk | Smaller shell command output | Prefer rtk when binary available |
Refresh / reinstall: .agents/skills/README.md is
the single owner of those commands. Do not copy them here — the two lists had
already diverged, and the marketplace installers need cleanup steps
(--copy leaves real directories where repo_policy requires symlinks) that
only the README carries.
Optional plugin installs (Claude Code / Codex / Copilot CLI) when you want host lifecycle hooks beyond skills:
# Claude Code
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytail
/plugin marketplace add JuliusBrussee/caveman
/plugin install caveman@caveman
# Codex CLI
codex plugin marketplace add DietrichGebert/ponytail && codex plugin add ponytail@ponytail
# GitHub Copilot CLI (ghcp)
copilot plugin marketplace add DietrichGebert/ponytail
copilot plugin install ponytail@ponytail
Optional full Headroom proxy (heavier than the portable skill):
uv tool install "headroom-ai[all]" then headroom wrap claude|codex|copilot|cursor.
Source: huggingface/skills (Cursor:
marketplace installs hf-cli; additional skills via hf skills add).
Already installed under .agents/skills/ and symlinked for Claude/Cursor/Grok.
Refresh commands and their cleanup steps live in
.agents/skills/README.md — the single owner.
Cursor also loads MCP from .cursor/mcp.json (Playwright +
Hugging Face Hub MCP + Serena). Optional UI install:
Cursor marketplace — Hugging Face.
Skills are identical everywhere; MCP servers are not. Check before assuming a
server is available, and fall back to the CLI (hf, npx playwright) when it
is not.
| Server | Claude Code | Cursor | VS Code / Copilot Chat | Codex |
|---|---|---|---|---|
| Serena | ✅ .mcp.json |
✅ | ✅ .vscode/mcp.json |
✅ .codex/config.toml |
Linear (autoresearch issue filing) |
✅ | — | — | — |
Playwright (playwright-cli) |
— | ✅ | — | — |
| Hugging Face Hub | — | ✅ | — | — |
Linear is Claude-only because autoresearch issue/milestone filing runs there;
Playwright and the HF Hub server are Cursor-only because both have first-class
CLIs (npx playwright, hf) that every other harness uses instead.
Serena provides IDE-like symbolic tools (find symbol / references / rename / replace body) via MCP. Do not install from MCP marketplaces — use the official quick start:
# prerequisite: uv (https://docs.astral.sh/uv/)
uv tool install -p 3.13 serena-agent
serena init
cd /path/to/slm-training
serena project create --language python --language typescript --index
# health: serena project health-checkProject config: .serena/project.yml (committed). Cache /
local overrides stay gitignored under .serena/.
| Client | Config in this repo |
|---|---|
| Cursor | .cursor/mcp.json (--context ide --project .) |
| Claude Code | .mcp.json + hooks in .claude/settings.json |
| VS Code / Copilot Chat | .vscode/mcp.json |
| Codex | .codex/config.toml (committed) + hooks in .codex/hooks.json; older builds need .codex/serena.config.toml.example → ~/.codex/config.toml (or serena setup codex) |
| Copilot CLI | /mcp add → serena start-mcp-server --context=copilot-cli --project-from-cwd; hooks in .github/hooks/ |
Prefer Serena symbolic tools over raw grep/read when navigating src/ /
scripts/. Docs: https://oraios.github.io/serena/
Prefer hf over deprecated huggingface-cli. Auth: hf auth login /
hf auth whoami. CLI docs:
https://huggingface.co/docs/huggingface_hub/guides/cli
Bucket: hf://buckets/TKendrick/OpenUI →
https://huggingface.co/buckets/TKendrick/OpenUI
| Run kind | Checkpoints |
|---|---|
Full HF-context train (train_model / hf_jobs_train / remote_train) |
Sync to bucket under checkpoints/<run_id>/ |
| Scratch matrix / CI / fixture demo | Local outputs/ only (--no-sync-checkpoints) |
GPU host: Prefer HF Jobs
(python -m scripts.hf_jobs_train --dry-run) or pods (remote_train). Do not
use Spaces ZeroGPU for full trains (short quotas, no torch.compile).
export HF_TOKEN=hf_... # required for write; never commit
python -m scripts.train_model --train-dir outputs/data/train/v1 \
--context-backend hf --run-id twotower_v1 --steps 200 --fast-train
# Managed GPU Job (A10G+):
python -m scripts.hf_jobs_train --run-id twotower_v1 --steps 200 --branch main
# Manual / rescue sync:
python -m scripts.sync_checkpoints --run-dir outputs/runs/twotower_v1 --ensure-bucketAgents must not treat a full HF train as done until
train_summary.json contains checkpoint_bucket with a successful remote URI
(or an explicit documented --no-sync-checkpoints / scratch reason). Use
hf-cli / bucket skills for inspection (hf buckets list TKendrick/OpenUI -R).
Whenever a checkpoint is created, synced, bootstrapped, or promoted:
- Update
docs/MODEL_CARD.md— roster row, eval table (suiten+ metrics + pass/fail), recipe (device/steps/backend/honesty), bucket URI or local path, and append Checkpoint history. - Refresh README → “Model card (summary)” — short table only; link to the full card for detail. Do not let the README diverge from the card.
- Keep claims honest (fixture / scratch matrix ≠ production HF ship).
Triggers include: train_model, hf_jobs_train, remote_train, bootstrap_playground,
sync_checkpoints, matrix runs that designate a reusable champion, preference /
RL stages that write a new serving *.pt, and --register-promoted.
A checkpoint without a model-card + README summary update is incomplete work
(same bar as missing docs/design/ measured-results).
The dashboard renders every page two ways, switchable by the sidebar
◈ Compiled / ◇ Interpreted toggle: hand-written React
(src/apps/dashboard/src/pages/*.tsx, compiled) and a committed OpenUI Lang
program (src/slm_training/web/static/openui/<slug>.openui, interpreted) run live
through the official @openuidev <Renderer> with the dashboard's hybrid library +
/api tool provider (src/apps/dashboard/src/interpret/). They must stay at parity.
Whenever you change a page (pages/*.tsx), its shared components
(components.tsx), or add/remove a route (main.tsx): update the matching .openui
program (and any library.tsx component / toolProvider.ts query it needs), then run
python scripts/validate_page_dsl.py (rewrites static/openui/MANIFEST.json). A page
change that leaves interpreted mode wrong is incomplete work. Full loop + gotchas:
REQUIRED SKILL: dashboard-openui-parity. These programs use the full OpenUI Lang
(not the placeholder training subset) — validate with validate_page_dsl.py, never the
training bridge; training data + ship-gates are untouched.
NO TRAIN / EVAL / BENCH / PROFILE / TELEMETRY / MATRIX / REPRO
WITHOUT UPDATING DOCS
AP-007+ experiment runners and every promotion candidate use the canonical
ExperimentCampaignV1 contract in
src/slm_training/autoresearch/experiment_campaign.py. Lock the manifest in
the campaign event chain before execution; bind plans, outcomes, and promotion
evidence to that digest. Deviations are append-only and exploratory. Never
replace the locked confirmatory endpoint, arms, seeds, stopping rule, family,
or gates after outcomes are visible. Meaning-v2 becomes the default primary
only after a hash-verified AP-001 certified artifact; otherwise use the
binder/reference F1 fallback. See
docs/design/experiment-campaign-governance.md.
Numbers only in outputs/, chat, or a PR comment = incomplete work.
Triggers (complete, whether invoked directly or via the slm wrapper):
train_model, train_rl, train_preference,
remote_train, hf_jobs_train, evaluate_model, evaluate_loss_suites, diagnose_eval,
run_quality_matrix, run_grammar_matrix, run_perf_matrix,
run_phase_pipeline, reproduce_baseline, run_scaling_ladder,
run_mixture_search, bench_* (incl. telemetry/accel), profile_generate,
or any ad-hoc run whose scoreboard / gates / latency inform a decision.
Required each time:
- AgentEvals JSONL plus an AgentV SDK result bundle for every eval run. New
eval entrypoints use
src/slm_training/evals/agentv.py; no alternate run envelope. - JSON under
docs/design/(scripts often mirror; verify it matches this run). - Matching markdown measured-results / notes updated (not JSON-only).
- Recipe metadata: device, steps, backend, matrix set, suite
n, honesty mode. - Honest pass/fail vs
--ship-gatesor perf guardrails. - If a checkpoint was written/promoted: update
docs/MODEL_CARD.mdand README “Model card (summary)”. - Commit docs with the experiment — no “docs later” TODO.
- Result JSON carries a
version_stamp(schemaversion_stamp/v1; canonical writers emit it). If you changed any metric, gate, harness, matrix, or data-builder file watched bysrc/slm_training/resources/versions.json, bump that component (or append ano-bump: <reason>history note) in the same change —python -m scripts.verify_version_stamps --checkenforces it.
Doc homes: quality/ship → quality-experiment-matrix.md (+ adversarial
review on policy changes); perf → perf-experiment-matrix.md /
runtime-performance.md; checkpoints → MODEL_CARD.md + README summary +
checkpoint-bucket.md; lever-specific → that design doc.
This repository has 2,227 repo-owned source files and 737,447 lines, 531 of
them (23.8%) over the 400-line module budget. At that size a budget held by
convention is a budget nobody holds, so it is machine-enforced as a ratchet:
python -m scripts.verify_code_quality (CI python-static, and the local
merge gate) measures four dimensions and compares each against
src/slm_training/resources/code_quality_baseline.json.
| Dimension | Budget |
|---|---|
| Module size | 400 physical lines |
| Complexity / SRP | ruff C901 (mccabe 10), PLR0911/0912/0913/0915 |
| Package principles | Martin's ADP (no cycles), SDP, SAP over the import graph |
| Component size | 20,000 lines (Common Closure Principle) |
Rules:
- Any increase fails. A module that grows past its recorded ceiling, a new oversized file, another dependency cycle — all red.
- Any decrease must be recorded. Run
python -m scripts.verify_code_quality --updateso the ceiling drops permanently. A win cannot be spent twice. - Never hand-raise a baseline number to land a change. Split the module, simplify the function, or break the cycle. The baseline is a record of debt already incurred, not a budget to spend. Re-freezing is legitimate only when the base moved (a merge bringing in pre-gate commits) and the commit says which numbers shifted and why.
- Complexity counts are ruff-version-scoped. The baseline records the ruff build they came from; a bump moves many counts at once and is re-frozen in its own commit, not treated as code regressions.
Canonical expansion: docs/design/code-quality-contract.md.
NO DATA BUILD WITHOUT READING ITS QUALITY REPORT —
FIX THE SYNTHESIS HARNESS, NEVER THE GATES
build_train_data runs strict-by-default (fuzzy + semantic dedup, tier floor,
n-gram decontamination vs eval suites, exposure caps) and every build emits
quality_report.json, rejected.jsonl (nothing dropped silently), and
synthesis_feedback.json (per-family/synthesizer yields, recommendations,
autoresearch-shaped experiment candidates). After any build: read the
feedback, act on the named producer/synthesizer, file the experiment
candidates — REQUIRED SKILL: synthesis-feedback. --profile permissive
is a diagnostic escape hatch, never a fix; gate/threshold changes go through
honest-ship-eval. Cross-snapshot overlap is audited with
scripts/audit_data_corpora.py (durable results in
docs/design/data-corpus-audit.*); exclude covered pairs with
--dedup-against. Runs bind to their exact dataset (data_manifest_sha ↔
lineage DataSnapshot); derived curation uses --derive-from,
--difficulty-from (record NLL evidence), and
scripts/mine_rejected_preferences.py.
| Excuse | Reality |
|---|---|
| "outputs/ is enough" | Reviewers read docs/design/. |
| "JSON written; markdown later" | Headline tables are the scoreboard. |
| "Failed/partial — skip docs" | Document failure + recipe. |
| "It's in the PR body" | PR text is ephemeral. |
| "Bucket URI is enough; skip the model card" | Card + README summary are how humans find the checkpoint. |
| "The code SHA is enough" | Component versions are what make results comparable and retestable. |
REQUIRED SKILL: documenting-experiment-results.
The eval/smoke/checkpoint stack is self-improving, so every result must say
which revision of the constraints produced it. Contract:
docs/design/version-stamp-contract.md.
- Registry:
src/slm_training/resources/versions.jsonmaps component ids (harness.model_build.eval,evals.meaningful_program,gates.ship,matrix.quality, …) to their current version, watchedpaths, and an append-onlyhistory(newest first). - Stamp: canonical writers embed a
version_stampenvelope (stamp_schema: version_stamp/v1— code commit, dirty flag, component versions, timestamp) in every eval/scoreboard/gates/matrix/bench/train payload viaslm_training.versioning.build_version_stamp. - Bump rule: changing a watched file requires touching that component's
registry entry in the same change — a version bump (new ids use monotonic
v1, v2, …) or a same-version history entry whose note starts withno-bump:for behavior-neutral edits. Enforced bypython -m scripts.verify_version_stamps --check(CI, pre-commit, agent hooks). - Re-test discovery: after a bump,
python -m scripts.verify_version_stamps --stale [--component <id>] [--include-outputs]lists results produced under older constraints — the candidates worth re-running. Experiments that ran against since-fixed constraints stay valuable; keep them discoverable, never silently comparable.
- JSON-shaped pytest cases live in mirrored
src/slm_training/resources/test_cases/<test path>.jsonfiles. Agents change inputs there and refresh snapshots withpython -m scripts.refresh_test_cases <test-or-resource>; ordinary tests and CI are read-only. Before finishing, runpython -m scripts.extract_test_casesandpython -m scripts.refresh_test_cases --check --changed. Runtime eval/gate policy belongs undersrc/slm_training/resources/evals/; never weaken ship gates or edit a frozen eval version in place. - Prefer harness/script changes over one-off notebooks.
- Preserve train/test isolation and structural leakage checks.
- Never reintroduce silent
gold.placeholderschannels underhonest_slot_contract=True. - Authoritative deterministic decode proofs always outrank learned, semantic, confidence, or preference scores. Commit an exact legal singleton before any neural ranking and never downgrade certainty into a soft preference.
- New production generation/decoder paths must project model-facing symbol identity to stable opaque request-local ordinals. External names, template-marker spellings, and alias-derived text, hashes, or embeddings are codec/realization data and must not become scoring or legal authority. Typed role/type metadata may be supplied separately as declared authority; restore caller names only after verified decode. Historical default-off name-aware experiment modes may remain for checkpoint and evidence compatibility, but must not become a production default or new authority.
- Say fixture-demo vs ship. Do not weaken ship gates to green CI.
- Do not grow the model to green a gate. Report trainable parameters beside
every quality number, size-match compared arms, and charge capacity growth
with
EG_params(goal invariant VI). - Match existing style; no unrelated drive-by refactors.
- Before adding or relocating tracked paths, use
organize-repository, followdocs/repository-organization.md, and usegit mvrather thanmvfor moves. - Frozen DSL-agnostic harness machinery (version stamping, lineage records,
checkpoint references, the gate/promotion engines, scaling math, eval
bookkeeping) lives in
src/slm_training/harness_core/and never imports the DSL/model/eval/harness layers; DSL specifics enter via callbacks. Old import paths are stable shims. Changes there bump theharness.corecomponent (seedocs/design/harness-core.md).
docs/MODEL_CARD.md # checkpoint roster + eval (keep README summary in sync)
docs/design/ # matrices + measured results (source of truth)
scripts/ # train / eval / matrix / bench CLIs
src/slm_training/ # implementation (harness_core/ = frozen DSL-agnostic core)
.agents/skills/ # canonical skills for all tools
This repository uses OpenWiki for recurring code documentation. Start with docs/openwiki/quickstart.md, then follow its links to architecture, workflows, domain concepts, operations, integrations, testing guidance, repository organization, and source maps.
The scheduled OpenWiki GitHub Actions workflow refreshes the repository wiki. Do not hand-edit generated OpenWiki pages unless explicitly asked; prefer updating source code/docs and letting OpenWiki regenerate.