KURAL
Infrastructure

Database

Local snapshot persistence — schema, lifecycle, and serialization

All data lives on disk as SQLite databases under .kural-db/.

Directory Layout

.kural-db/
  <branch>/
    active.db                           # current snapshot
    advise.db                           # ephemeral clone for simulation
    history/
      <snapshot-id>.db                  # rotated snapshots (max 10)

Snapshot ID format: <timestamp>-<short-commit-hash> (e.g., 1711700400-a3f8b2c).

Schema

Six tables per snapshot database.

files

Source files with embeddings and import tracking.

ColumnTypeNotes
pathTEXT PKAbsolute file path
nameTEXT NOT NULLFile name
descriptionTEXTFrom KURAL.md or JSDoc
identity_embeddingBLOB NOT NULLFloat32 — name + description vector
leaf_embeddingBLOB NOT NULLFloat32 — name + description + structure vector
facet_hashTEXTSHA256 for cache invalidation
imports_internalTEXT NOT NULLJSON string array
imports_externalTEXT NOT NULLJSON string array
companionTEXT@kuralCompanion group ID
boundTEXT"inward" or "outward" — @kuralBound
residualsTEXT NOT NULLJSON ResidualEntry array

types

Type declarations (interfaces, classes, type aliases).

ColumnTypeNotes
pathTEXT NOT NULLPK with name
nameTEXT NOT NULLPK with path
descriptionTEXT
fieldsTEXT NOT NULLJSON Record<string, string>
exportedINTEGER NOT NULLBoolean (0/1)
refsTEXT NOT NULLJSON string array — cross-module type refs
utilINTEGER NOT NULLBoolean — utility helper
helperINTEGER NOT NULLBoolean — shared extraction helper
residualsTEXT NOT NULLJSON ResidualEntry array
identity_embeddingBLOB NOT NULLFloat32
leaf_embeddingBLOB NOT NULLFloat32
facet_hashTEXT
patternsTEXT@kuralPatterns group ID
boundTEXT"inward" or "outward" — @kuralBound

functions

Function declarations with call graph and purity info.

ColumnTypeNotes
pathTEXT NOT NULLPK with name
nameTEXT NOT NULLPK with path
descriptionTEXT
paramsTEXT NOT NULLJSON string array — parameter types
param_namesTEXT NOT NULLJSON string array — parameter names
returns_typeTEXT NOT NULLReturn type
exportedINTEGER NOT NULLBoolean
pureINTEGER NOT NULLBoolean — @kuralPure
utilINTEGER NOT NULLBoolean
helperINTEGER NOT NULLBoolean
residualsTEXT NOT NULLJSON ResidualEntry array
causesTEXTNon-type side effects description
callsTEXT NOT NULLJSON string array — outbound call graph
identity_embeddingBLOB NOT NULLFloat32
leaf_embeddingBLOB NOT NULLFloat32
facet_hashTEXT
patternsTEXT@kuralPatterns group ID
documented_paramsINTEGER NOT NULLCount of @param tags (default 0)
has_return_docINTEGER NOT NULLBoolean — has @returns tag (default 0)
boundTEXT"inward" or "outward" — @kuralBound

directories

Directory hierarchy with child references.

ColumnTypeNotes
pathTEXT PKAbsolute directory path
nameTEXT NOT NULLDirectory name
descriptionTEXTFrom KURAL.md
childrenTEXT NOT NULLJSON string array — child paths
identity_embeddingBLOB NOT NULLFloat32
leaf_embeddingBLOB NOT NULLFloat32
facet_hashTEXT
residualsTEXT NOT NULLJSON ResidualEntry array

scores

Structural health metrics for every node (types, functions, files, directories).

ColumnTypeNotes
keyTEXT PKUnique identifier
kindTEXT NOT NULL"function", "type", "file", or "directory"
nameTEXT NOT NULLDisplay name
fitREALContent-to-parent alignment (null for root or util containers)
uniquenessREAL NOT NULLMean distance to siblings (2.0 = N/A, fewer than 2 siblings)
scoreREALharmonicMean(fit, uniqueness). Null if fit is null
children_fitREALIdentity-to-content alignment (null for leaves)
children_uniquenessREALCV spread quality of children (null for leaves, 2.0 = N/A)
children_scoreREALharmonicMean(childrenFit, childrenUniqueness). Null for leaves
subtree_fitREALMean childrenFit of descendants (null for leaves)
subtree_uniquenessREALMean childrenUniqueness of descendants (null for leaves)
subtree_scoreREALharmonicMean(subtreeFit, subtreeUniqueness). Null for leaves
overall_scoreREALLeaf: score. Container: harmonicMean(score, subtreeScore)
worst_pairTEXTJSON — most similar child pair (null for leaves)
best_uncle_nameTEXTUncle node where this unit fits better
best_uncle_scoreREALUncle's fit score

metadata

Key-value store for snapshot configuration and computed data.

ColumnTypeNotes
keyTEXT PK
valueTEXT NOT NULL

Known keys:

KeyValuePurpose
created_atUnix timestamp (ms)When the snapshot was generated
commit_hashShort git commit hashSnapshot identity and provenance
model_idEmbedding model identifierCache invalidation across model changes
schema_versionIntegerSchema version for forward compatibility
axis:<id>JSON number arrayComputed semantic axis vector
axis-scores:<id>JSONDirectory scores on a semantic axis

Snapshot Lifecycle

Generate

  1. Parse target path into units (files, types, functions, directories)
  2. Load embedding cache from current active.db (if exists and model matches)
  3. Embed uncached units (7-pass faceted embedding)
  4. Rotate current active.db to history/kural-history-<snapshot-id>.db
  5. Create fresh active.db, write metadata, parsed units, and scores
  6. Evict oldest history snapshot if count exceeds 10

Cache

On subsequent runs, unchanged units (same facet_hash) reuse cached embeddings from the previous active.db. This makes incremental runs fast.

Cache key format:

  • Leaf units: type\0<path>\0<name> or func\0<path>\0<name>
  • Container units: file\0<path> or dir\0<path>

Cache is invalidated when:

  • facet_hash differs (content changed)
  • model_id differs (embedding model switched)
  • No previous active.db exists (first run)

Advise (clone-and-mutate)

  1. Copy active.db to advise.db
  2. Run simulation/analysis on the clone
  3. Delete advise.db when done

The original active.db is never modified by advise operations.

Serialization

TypeStorage format
BooleansINTEGER (0/1)
EmbeddingsBLOB (Float32Array binary)
String arraysJSON TEXT
Record typesJSON TEXT
ResidualEntry arraysJSON TEXT

Schema Versioning

  • schema_version is stored in metadata from day one
  • Default evolution is additive-only — new nullable columns, no removals or renames
  • Old snapshots have NULLs for new columns
  • Breaking changes (rare) require a one-time migration

On this page