/** * @copyright Sister Software * @license AGPL-3.0 * @author Teffen Ellis, et al. * * Typed schema for the spatial-layer contract — the two tables EVERY layer database embeds, * regardless of tier: `layer_manifest` (single-row identity/provenance/licensing record) and * `layer_coverage` (per-H3-cell survey completeness). The contract is what lets shipped, * build-local, and private layers share one query surface. Spec: * docs/superpowers/specs/2026-07-18-spatial-layers-and-poi-design.md §2.1. * * Coverage carries the meaning-of-zero rule: a MISSING coverage row means "unmapped/unknown", * never "surveyed and empty". Consumers must treat absence as absence of evidence. */ import { type Kysely } from "kysely"; /** * Distribution tier of a layer. Shipped = permissive-license, published by us. */ export declare const LayerTier: { readonly Shipped: "shipped"; /** * Share-alike sources (ODbL): we ship the builder CLI, the user builds locally. */ readonly BuildLocal: "build-local"; /** * The user's own data, conforming to the contract, never distributed. */ readonly Private: "private"; }; export type LayerTier = (typeof LayerTier)[keyof typeof LayerTier]; /** * How a layer is kept current. */ export declare const LayerFreshnessPolicy: { /** * Immutable artifact; updates are full rebuilds (the gazetteer discipline). */ readonly Sealed: "sealed"; /** * Periodically re-issued under the same name (e.g. registries of people/programs). */ readonly VersionedRefresh: "versioned-refresh"; }; export type LayerFreshnessPolicy = (typeof LayerFreshnessPolicy)[keyof typeof LayerFreshnessPolicy]; /** * The single-row layer identity record. See {@link LayerManifest} for the parsed form. */ export interface LayerManifestTable { name: string; version: string; schema_version: number; /** * One of {@link LayerTier}. */ tier: string; /** * SPDX-ish license expression, e.g. `CDLA-Permissive-2.0`, `ODbL-1.0`. */ license: string; attribution: string | null; source: string; source_vintage: string; build_cmd: string; build_sha: string; /** * One of {@link LayerFreshnessPolicy}. */ freshness_policy: string; /** * JSON-encoded spine-key declaration (see `SpineKeys` in `manifest.ts`). */ spine_keys: string; /** * ISO-8601, supplied by the build script (never generated in-library). */ created_at: string; } /** * Per-cell survey completeness. Missing row = unknown, NOT zero. */ /** * What a `completeness` value RESTS ON. The magnitude alone cannot be acted on: a cell recorded at `1.0` because an * authority designates the set complete, and a cell recorded at `1.0` because the source happened to return rows there, * license entirely different conclusions. * * Only {@link CoverageBasis.Designated} and {@link CoverageBasis.Surveyed} can support an EXCLUSION — "the thing you * asked for is not here". {@link CoverageBasis.SourcePresent} supports presence and nothing else: the source looked, * which is not the same as the source found everything. */ export declare const CoverageBasis: { /** * An authority declares the set complete for this cell — BAN holding every address in a commune. A miss inside a * designated cell IS evidence of absence. */ readonly Designated: "designated"; /** * We measured completeness ourselves against an independent reference, and `completeness` carries that measurement. A * miss is evidence of absence in proportion to the value. */ readonly Surveyed: "surveyed"; /** * The source returned rows in this cell and we recorded that. Says nothing about what the source missed. A miss here * is UNKNOWN, never absence. */ readonly SourcePresent: "source_present"; }; export type CoverageBasis = (typeof CoverageBasis)[keyof typeof CoverageBasis]; export interface LayerCoverageTable { /** * 48-bit short H3 cell at the resolution declared by the manifest's spine keys. */ h3_cell: number; /** * Estimated completeness of the source survey in this cell, 0..1. * * Never read this without reading {@link LayerCoverageTable.basis} — see {@link CoverageBasis}. */ completeness: number; /** * What the `completeness` value rests on. One of {@link CoverageBasis}. * * NULL means the row predates this column, and must be read as {@link CoverageBasis.SourcePresent} — the weakest * reading, because that is what every layer built before the column was writing. */ basis: CoverageBasis | null; /** * Rows this layer actually holds in the cell. */ observed_rows: number; } /** * Pass to `new DatabaseClient(...)` (or intersect into a layer's own schema). */ export interface LayerContractDatabase { layer_manifest: LayerManifestTable; layer_coverage: LayerCoverageTable; } /** * The slice of a Kysely handle the contract helpers touch — the parameter type every one of them takes. * * Kysely is invariant in its schema parameter, so a `Kysely` is NOT assignable to * `Kysely` even when `POIDatabase extends LayerContractDatabase`. The incompatibility is in * `transaction()` and `with()`, which the contract never calls. Naming only the members it does call lets a layer pass * its own handle directly. The alternative — a cast at every call site — does not merely skip one check: it disarms * every column-level guarantee these two tables carry, including any added later. */ export type LayerContractHandle = Pick, "insertInto" | "schema" | "selectFrom">; /** * Create `layer_manifest`. Single row enforced by `name` PK + the writer's insert-once discipline. */ export declare function createLayerManifestTable(db: LayerContractHandle): Promise; /** * Create `layer_coverage` — small fixed-width rows probed by PK, the WITHOUT ROWID sweet spot. */ export declare function createLayerCoverageTable(db: LayerContractHandle): Promise; //# sourceMappingURL=schema.d.ts.map