downloads.fermihdi.io — SKILL.md

/ › skills › fermihdi-hd-schema-build

Download SKILL.mdView raw

name: fermihdi-hd-schema-build description: Build an HD dataset schema from an existing database's DDL (CREATE TABLE text, any dialect) or from a corpus of files (CSV, JSON, JSONL, Parquet, ORC, Avro, Protobuf, XML), using the hosted hd-schema-generator API, then check it for real ingestability against sample data before a real ingest is attempted. Use before fermihdi-hd-ingest or fermihdi-hd-migrate when no HD dataset schema exists yet.

Build and validate an HD dataset schema

Produces an HD dataset schema (schemas/hd_dataset_schema.json's format) from something that isn't one yet — another database's tables, or a pile of files nobody wrote a schema for — and checks it before it meets real data. Once a schema exists, hand off to fermihdi-hd-ingest (set up the pipe) or fermihdi-hd-migrate (a one-time bulk load).

What actually exists, and what doesn't

Step 1: pick the starting point

Starting point Path
An existing database (Postgres, MySQL, Cassandra/CQL, or generic ANSI SQL) 2a — DDL text
A corpus of files with no source database 2b — build a LogicalModel by hand

Step 2a: from an existing database's DDL

Get the CREATE TABLE text from the source — pg_dump --schema-only, MySQL SHOW CREATE TABLE, a CQL DESCRIBE TABLE, or hand-written ANSI SQL. Multiple tables in one call are fine.

curl -sX POST https://hd-schema-generator.fermihdi.io/v1/parse \
  -H 'Content-Type: application/json' \
  -d '{"dialect": "postgresql", "source": "<CREATE TABLE ...>"}'

dialect is one of ansi_sql, postgresql, mysql, cql. Returns a LogicalModel (columns, inferred types, key roles) plus findings for anything ambiguous. HTTP 422 means the DDL parsed but yielded zero columns — check the dialect and the DDL text, not the tool. Review the model with the user before continuing; a mis-inferred column type here becomes a wrong byte layout downstream.

Step 2b: from a corpus of files (no source DDL)

There is no endpoint for this — build a LogicalModel JSON object yourself from the corpus's own metadata, then skip straight to /v1/generate:

Name each column and give it the closest HD field type (§3) before calling /v1/generate.

Step 3: generate the HD schema

curl -sX POST https://hd-schema-generator.fermihdi.io/v1/generate \
  -H 'Content-Type: application/json' \
  -d '{"model": <LogicalModel from 2a or 2b>}'

Returns a candidate HD dataset schema with byte layout already assigned (the only layout strategy is declared-field-order packing — it does not reorder fields for you), plus proposals for HD-specific concepts it inferred: dataset_type, time_index_field, batch_id_field, compressed_time_fields, enum detection. Proposals are never auto-applied. Review each one with the user, then re-call with {"model": ..., "overrides": {...}, "confirmed": true} to lock them in.

HD field types, for judging the proposals: unsigned/signed integers (uint8..int256), float/double, boolean, numeric (numeric_precision ≤38 digits → 16 bytes, ≤76 → 32 bytes), string/bytes (caller-sized; string is UTF-32 by default — 4 bytes/char — unless string_encoding: ascii, 1 byte/char), blob (a 64-byte object-store key; requires the dataset to have a batch_id_field), ipv4/ipv6/timestamp/chess_move (semantic aliases over uint32/uint128/uint64), uuid (16 bytes, optional v6/v7 bit-relabelling), chess_fen (32 bytes packed), chess_move_cc (2 bytes, chess.com's own lookup code). An array object on a bytes field needs element_type, max_elements, element_width, count_bytes, and its total span must equal count_bytes + max_elements × element_width exactly.

batch_id_field — a dataset schema needs a way to group records into batches (a closed batch is never reopened by the storage cluster): a rounded time field (round_batch_id_field: true + time_index_interval/_unit, rounds down from epoch), a raw field's own value (records must already arrive grouped by it — no ingester-side sort happens for this form), or nothing at all (the ingester's own clock). This choice belongs in the proposals review, not left to the default.

There is no written schema-design-optimization guide in this codebase — no doc says when to prefer enum over a raw integer, how field order affects anything, or when array/blob beats a fixed-width field. The rules of thumb below are this skill's own judgment, not a cited platform doc — say so if the user asks where they come from:

Step 4: validate

curl -sX POST https://hd-schema-generator.fermihdi.io/v1/validate \
  -H 'Content-Type: application/json' \
  -d '{"schema": <the schema from step 3>}'

Always returns HTTP 200 — read the valid field and findings, don't trust the status code. This checks structure (against the published hd_dataset_schema.json meta-schema) and physical layout (byte-span overlaps/gaps, record_len arithmetic, type-width mismatches) only — it has not looked at a single real record yet.

Step 5: the check /v1/validate can't do — a dry run against real data

Use fermihdi-hd-dry-run: point the published ingester image's --dry-run mode at a copy of the real corpus (or the live source) with this schema — no lab, no sandbox, no DMS, no SCC, no licence. It reports mapping failures, dropped array elements, clamped values and unmapped enum codes as real counters, not silent drops, and a clean run is the closest thing this codebase has to "the schema validates against the corpus." Reach for a full fermihdi-hd-sandbox deployment only if the question moves past schema/source compatibility into real query or cluster behavior.

Handoff

Once the schema passes Step 5: fermihdi-hd-ingest to wire up an ongoing pipeline, or fermihdi-hd-migrate for a one-time bulk load. Registering the schema on a real (non-sandbox) deployment goes through DMS-Core's schema-update API — see fermihdi-hd-ingest §"Production schema registration" for the exact call and its data-destroying gotcha before changing a schema on a cluster that already holds data.

Download SKILL.mdView raw