Read-only SQLite access to rich lexical metadata in Crosseno language packs.
The PDO adapter implements the storage-neutral lexical catalog contract and adds lexeme, sense, clue, topic, and source lookups. It is deliberately not the backtracking solver index.
composer require crosseno/lexicon-sqlite$loaded = $loader->load('/srv/packs/crosseno-en');
$answer = $loaded->catalog->answer($stableAnswerKey);
$clues = $loaded->catalog->cluesForSense($stableSenseKey, $language);
$coverage = $loaded->catalog->clueCoverage();Loading validates the real pack root, rejects symlinked/out-of-root files, bounds and parses manifest.json, verifies catalog.sqlite and solver.idx lengths and SHA-256 hashes, checks SQLite magic/integrity/application/schema versions, requires lookup indexes, verifies the complete manifest/catalog/index tuple, and only then exposes queries.
Connections use SQLite read-only open flags where available, otherwise URI mode=ro; query_only, trusted_schema=OFF, bounded busy timeout, memory-only temporary storage, disabled memory mapping, and a small cache provide defense in depth. Filesystem permissions and trusted release signatures remain deployment responsibilities.
The SQL schema under resources/schema/ documents compiler output and test fixtures. The compiler—not this runtime package—owns schema creation and migration.
Catalog schema V1 stores definition clues, which are exposed explicitly as LexicalClueType::Definition. The catalog returns stable clue-ID order and aggregate covered-answer counts by language. It does not map records into clue-domain objects or own language matching, validation, scoring, selection, or assignment; crosseno/clues provides that adapter and policy layer.
Ordinal-space identity is validated against the manifest and index metadata during loading. Exact answer-key ordinals come from the runtime language pack/index API, not from SQLite row order. Ordinary applications should load their concrete runtime language package and pass its components to crosseno/builder.