Data • Analytics • Evaluated AI

From game records to checked answers

Explore the pipeline, its boundaries, and the code responsible for each stage.

Generated from maintained Markdown, contracts and recorded evidence. Repository guides

Follow a question through the system

Select a stage to inspect its role and code.

  1. Bounded ingestionRead a pinned archive or fixture; preserve exclusions, quarantine and source hashes.
  2. Checked snapshotsValidate immutable Parquet/DuckDB output before replacing its current pointer.
  3. Optional martsTransform a copy through dbt; record lineage, validation and recovery.
  4. Opening & clock metricsApply explicit cohorts, denominators, missingness and observed-prefix caveats.
  5. Checked analystAllowlisted read-only actions compute values and bind evidence IDs to the snapshot.
  6. Independent scoringCompare responses with frozen references and retain failures, repetitions and costs.
Bounded ingestion

Read a pinned archive or fixture; preserve exclusions, quarantine and source hashes.

Inspect bounded ingestion code
Checked snapshots

Validate immutable Parquet/DuckDB output before replacing its current pointer.

Inspect checked snapshots code
Optional marts

Transform a copy through dbt; record lineage, validation and recovery.

Inspect optional marts code
Opening & clock metrics

Apply explicit cohorts, denominators, missingness and observed-prefix caveats.

Inspect opening & clock metrics code
Checked analyst

Allowlisted read-only actions compute values and bind evidence IDs to the snapshot.

Inspect checked analyst code
Independent scoring

Compare responses with frozen references and retain failures, repetitions and costs.

Inspect independent scoring code

Architecture and boundaries

Chess Analytics Lab uses one Python/SQL repository and local DuckDB files. chesslab provides the foundation ingestion and two offline demos. The analytical source command is python -m chess_analytics.corpus; the checked analyst is python -m chess_analytics.analyst. These functional commands are the entry points while historical package and report names remain stable for source hashes.

Lichess fixed complete archive / fixed byte prefix / synthetic PGN
  → chess_analytics.ingest: caps, parser, normalization, dedup, quarantine
  → chess_analytics.warehouse: checked immutable snapshots + current pointer
  → chess_analytics.marts: local dbt copy, tests, published marts + recovery ledger
  → chess_analytics.corpus: selected moves, opening and clock definitions
  → chess_analytics.dashboard: parameterized analysis and Streamlit views
  → chess_analytics.analyst: allowlisted read-only tools, bounded plan, evidence IDs
  → frozen references + scorer + preserved attempts and costs

The single writer lock protects data-changing CLI operations. A candidate is validated before its current pointer is replaced. Foundation source manifests bind normalized output to source bytes, code and lock hashes; the analytical move publication also binds its extracted receipt to the checked source hash. Source order, sampling selection, coverage and exclusions are in manifests. The partial compressed prefix is hashed as retained bytes; it is never marked as a fully verified publisher archive.

The optional Dagster assets and Prefect tasks call the same stage/publish/verify functions and optional dbt mart transform. Neither is a production scheduler or cloud dependency; the orchestration guide gives the exact local commands and comparison evidence. Airflow remains a later option.

The analyst can list definitions, read coverage, query named metrics, compare openings and inspect clock buckets. query_metric reads the governed draw-rate, opening-usage, and opening-score metrics from the published mart when that mart's source snapshot and model hash match the analytical snapshot; any mismatch or semantic failure keeps the reviewed SQL. compare_openings calls query_metric, so it uses the same path. The analytical snapshot is not modified. It cannot execute free-form SQL, files, network access or extensions through its tool surface. Offline typed plans and recorded fixture plans run without a key. A live provider path exists but requires personal configuration, an explicit finite gross cap and named key; its requests/results are logged separately. Evidence IDs bind tool name, arguments, result and dataset ID. Scoring is external to the agent; historical M5–M7 rubrics remain frozen, portfolio fixture checks use portfolio-1.0, and engine-tool fixture checks use engine-1.0.

The dbt graph is drawn in dbt lineage. GitHub renders that Mermaid diagram from the committed manifest projection. The published catalog is the dbt docs for the tiny fixture. The Pages workflow generates it at deploy time. It is not the 2013 corpus.

The same allowlisted tools are available outside that planner through chesslab mcp, a stdio-only MCP server described in MCP. Each call is checked on its own. The planner's four-step limit and the M6/M7 scores belong to this repository's planner; they do not transfer to an outside client. Typed plans and that server can also score one position with a configured local engine and read observed White continuations from local opening data. Those scores are depth-limited evidence. The live provider prompt is unchanged. See ENGINE.

The full demo copies only required code/contracts into an ignored project under work/portfolio-demo/project, publishes a synthetic snapshot there and passes that path to Streamlit with CHESSLAB_PROJECT. It never replaces the real data/ pointers. The dashboard marks synthetic data on every view.