Prefix: store_.

Every run of the generator leaves a record of itself here: which module it captured, which files it read, what configuration it held in hand, and where it wrote. The rows answer bookkeeping questions rather than schema questions: what was this store built from, and which graph do these facts belong to. When two runs disagree, this family is where you look up what each of them actually saw.

Where to start

store_graph

A graph the store holds: the anchor of the graph_name partition dimension, one row per module ever captured into this store.

store_graph_source

The membership relation store_graph’s comment defers to: which sources are the joining graph’s.

store_stamp

What this store was built from.

How this family meets the others

Declared key edges
graphql_

7 foreign keys from that family’s rows into this one.

graphitron_

2 foreign keys from that family’s rows into this one.

sql_

3 foreign keys from that family’s rows into this one.

jvm_

1 foreign key from that family’s rows into this one.

javac_

1 foreign key from that family’s rows into this one.

walk_

1 foreign key from that family’s rows into this one.

intent_

24 foreign keys from that family’s rows into this one.

rejection_

1 foreign key from that family’s rows into this one.

lint_

1 foreign key from that family’s rows into this one.

build_warning_

1 foreign key from that family’s rows into this one.

Why the name is right

The store’s own record: what it read, what it was built from, and which graphs it holds. Its rows are never a reading of the consumer’s schema, database or classpath, which is what the transcription families are named for; the graph recipe rows are configuration the run held in hand, which is what keeps them in this family rather than making them a family of their own.

store_graph

A graph the store holds: the anchor of the graph_name partition dimension, one row per module ever captured into this store. Two discriminators keep the DDL’s FK conventions readable against this relation. First, why the SDL roots carry an FK here while the SDL-to-store_source FK was declined: the graph is ambient before the walk begins and NOT NULL on every row, while the source rows are a summary collected last and nullable at schema-level sites, so the FK doctrine admits one and not the other. Second: any derivation joining an SDL fact to a catalog or classpath fact (graphitron_service’s class name against jvm_class, graphitron_table’s table reference against sql_table) is underdetermined in a shared store until a membership relation says which sources are the joining graph’s; store_graph_source below is that relation, landed with its first consumer (the inferred claim view), and such a join scopes its catalog side through it.

Primary key: (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the graph’s configured name (the Maven <graphName> parameter, defaulting to the module’s artifactId); the value every partitioned key leads with

base_dir (CHARACTER VARYING, not null)

the capturing run’s base directory, absolute and normalized. NOT NULL and deliberately not grouped with the nullable build-identity pair: every run has a directory (RewriteContext requires basedir of every caller) even when it has no build file, and this column is what the ownership check reads when a run’s graph_name is already recorded against a different directory

build_file_path (CHARACTER VARYING, nullable)

the module’s build file (its pom), absolute and normalized; NULL on a programmatic run with no build file

build_file_stamp (CHARACTER VARYING, nullable)

content hash of the build file, the graph’s build identity: the remembered recipe is trusted only while the build file still hashes to this, and a mismatch marks the recipe possibly stale until the module’s own next build repairs it

last_captured (TIMESTAMP, not null)

when this graph’s own run last captured it; the age half of the age/currency distinction, and the bookkeeping a future eviction surface reads

store_graph_lint_disabled_rule

The <lint><disabledRules> half, one row per silenced rule id. Decomposed rather than rendered: a rendered block would be a string a later reader has to re-parse, which is the shape the recipe’s source names exist to remove, and permitting a rendered form per parameter would reintroduce the untyped default door. The two <lint> halves are a genuine conjunction (LintConfig is a plain record of both) but they are not the same shape, which is why they are two relations rather than one discriminated one: this half is a Set and takes no ordinal, its sibling is a List and takes one, and forcing them together would need a nullable ordinal.

Primary key: (graph_name, rule_id). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the owning graph’s partition, anchored by store_graph

rule_id (CHARACTER VARYING, not null)

the disabled rule’s id as configured; the value is the key, there being no position to record. An ordinal here would record the JVM’s iteration order over a Set and call it a position

store_graph_lint_excluded_type

The <lint><excludedTypes> half, one row per type-name glob excluded from the SDL lint engine. Ordinal-keyed because the configured value is a List and its order is the author’s, which is the grain rule’s "an ordinal only where the source is genuinely ordered".

Primary key: (graph_name, ordinal). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the owning graph’s partition, anchored by store_graph

ordinal (INTEGER, not null)

position in the configured list, document order

type_pattern (CHARACTER VARYING, not null)

the type-name glob as configured

store_graph_output

Where a generating run wrote: the three output coordinates travelling together, because they are present together on any generating run and jointly answer one question. A validate-only run has no row rather than a row carrying the inert package sentinel the validate goal substitutes to satisfy the context’s non-null contract: that sentinel is the run’s own admission that it had no output coordinates, and transcribing it would mint the derived fact that can disagree.

Primary key: (graph_name). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the owning graph’s partition, anchored by store_graph

output_package (CHARACTER VARYING, not null)

the root Java package generation wrote under, from <outputPackage>

jooq_package (CHARACTER VARYING, not null)

the root Java package of the consumer’s jOOQ-generated catalog, from <jooqPackage>; what every @table and @field was resolved against

output_directory (CHARACTER VARYING, not null)

the directory generation wrote sources into, absolute and normalized, from <outputDirectory> resolved against the base directory

store_graph_schema_extension

The recipe’s effective schema-file-extension filter, one row per accepted extension. A per-run set rather than a per-binding one, which is why it sits beside the bindings rather than under them.

Primary key: (graph_name, ordinal). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the owning graph’s partition, anchored by store_graph

ordinal (INTEGER, not null)

stable position in the resolved set, for faithful replay

extension (CHARACTER VARYING, not null)

an accepted schema-file extension including the leading dot, as configured

store_graph_schema_input

The graph’s SDL recipe, one row per resolved recipe entry: configuration the run held in hand, written fresh by every run, never a derivation over captured rows. It records what the read-set never can: how to find the graph’s schema files, including ones that do not exist yet, so a currency check can re-expand the globs over base_dir without building the module. One discriminated relation rather than one per kind, because the ordinal is the recipe’s spine and splitting the relations would shatter the one ordering key. A reader of another graph’s recipe rows is maintenance machinery and counts as such exactly while it writes no conclusions outside the store_ family; these rows never join the cross-graph consumer read surface, whose enumeration axis is store_graph and store_graph_supergraph and whose payload axis is the SDL-derived families only.

Primary key: (graph_name, ordinal). Foreign key: (graph_name) references store_graph (graph_name). Check: "KIND" IN('pattern', 'file', 'named').

Columns
graph_name (CHARACTER VARYING, not null)

the owning graph’s partition, anchored by store_graph

ordinal (INTEGER, not null)

entry position in the resolved configuration, document order

kind (CHARACTER VARYING, not null)

a closed taxonomy of what entry_value holds: a glob pattern a build resolved, a literal file a programmatic caller handed over, or a literal bare label. The two literal kinds transcribe which door the entry’s source came through, so a replay recovers the arm from the row instead of re-asking the filesystem a question about a stored string

entry_value (CHARACTER VARYING, not null)

the entry as configured: an include pattern in the recipe’s one glob dialect (SchemaRecipe owns the expansion) when kind is pattern, and the source’s canonical rendering when it is file or named

tag (CHARACTER VARYING, nullable)

the entry’s tag, when configured; not optional fidelity, since the tag applier runs above the capture cut and a replay without it would mint different rows than the graph’s own build

description_note (CHARACTER VARYING, nullable)

the entry’s description note, when configured; kept for the same replay-fidelity reason as tag

store_graph_session_mount

The <sessionState> <mount> reference: the consumer’s static Java method that mounts identity on each acquired connection, as authored. Row presence is the fact, per the family’s absence rule: no row means no identity is mounted. The primary key on graph_name alone makes "at most one mount per graph" structural. Only the authored string lands here; the reflected signature is a build-time model fact, never stored back into this provenance family.

Primary key: (graph_name). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the configuring graph’s partition, anchored by store_graph

mount_method (CHARACTER VARYING, not null)

the mounting method as authored, fqcn#method, from <mount>

store_graph_session_unmount

The optional <unmount> reference beside the mount. Row presence is the fact: no row means the supported mount-only configuration (the next request’s mount overwrites wholesale), which the reconciler admits without ceremony, and the foreign key to store_graph_session_mount is the "unmount without mount is a defect" rule made structural.

Primary key: (graph_name). Foreign key: (graph_name) references store_graph_session_mount (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the configuring graph’s partition, anchored by store_graph_session_mount

unmount_method (CHARACTER VARYING, not null)

the unmounting method as authored, fqcn#method, from <unmount>

store_graph_source

The membership relation store_graph’s comment defers to: which sources are the joining graph’s. One row per source the graph’s run actually read, every kind alike (schema files, jOOQ schema packages, classpath entries), because kind is an axis on store_source and a kind-filtered membership would make completeness a function of which consumers had shipped, leaving a reader unable to tell "not this graph’s" from "kind not captured yet". What the run read, not configuration: the recipe rows above hold patterns the run held in hand, including files that do not exist yet, while a row here names a source the walk met. Graph-keyed, so a warm capture clears and rewrites exactly its own graph’s rows. Any derivation joining a graph-keyed fact to a source-keyed one (the column-match claim view is the first) scopes its catalog side through this relation, which is what keeps one graph’s resolution from seeing a sibling module’s tables in a shared store.

Primary key: (graph_name, source_name). Foreign key: (graph_name) references store_graph (graph_name). Foreign key: (source_name) references store_source (source_name).

Columns
graph_name (CHARACTER VARYING, not null)

the member graph, anchored by store_graph

source_name (CHARACTER VARYING, not null)

a source the graph’s run read, anchored by store_source; the scan’s hand-built stand-ins record against the empty source name like their class rows do

store_graph_supergraph

Which supergraph a graph declared itself a subgraph of: the graph’s own declaration of its <supergraph> parameter, minted and cleared by the graph’s own run like every other graph-keyed row. What it asserts is grouping, not federation. Declaring membership does not make a graph federated and is not policed against the SDL’s opt-in, which graphitron_link already records as a predicate over the @link url; the grouping is deliberately usable before any federation SDL lands, since a subgraph under development may declare its home before its first @key is written. Only graphs with a declared supergraph are registered, so the row’s presence is the fact and a standalone graph has no row; a nullable column on the anchor would be the field every construction site may leave null, which this store spells structurally instead. Three absences collapse deliberately, because every reader’s safe answer is the same "not a peer": a graph whose author declared nothing, a programmatic run that was never asked, and a graph whose anchor a diagnostics preamble minted before capture ran. Deliberately not a supergraph entity relation of its own beside store_graph: no single run would mint or may clear such a row, and StoreRefresh derives the ownership-scoped clear set from the presence of a graph_name column, so the supergraph exists here as a value graphs declare and never as an entity anything owns. Single-valued by the (graph_name) key; if federation practice’s multi-supergraph publication ever has to be admitted, the widening is the key growing to (graph_name, supergraph_name), which costs a store-stamp roll rather than a data migration. This relation and store_graph are the whole of the cross-graph consumer read surface’s enumeration axis; nothing else configuration-shaped joins it, and what a surface reads about a peer stays SDL-derived.

Primary key: (graph_name). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the declaring graph’s partition, anchored by store_graph; also the key, which is where the single-valued claim is enforced structurally

supergraph_name (CHARACTER VARYING, not null)

the declared supergraph’s name, as the <supergraph> parameter spelled it, with an empty element collapsed to absent by the decode rather than stored blank. Paired with graph_name it is the store’s rendering of the addressing federation already uses, which is why <graphName>'s own documentation speaks of the subgraph’s published name. A graph’s peers are the graphs this relation joins to over this column, a self-join between non-null values, so two standalone graphs never group by accident and two supergraphs in one workspace store coexist mutually invisible

store_graph_tenant_column

The database-per-tenant column declaration, from <tenantColumn>. Single-valued, optional and run-owned, so its own graph-keyed relation whose row presence is the fact; a single-tenant build has no row. Deliberately not a column beside store_graph’s base_dir and last_captured, even though it is single-valued and run-owned too: it is generation payload rather than a fact about how the partition groups or where it lives, and beside the anchor it would be the first brick of the key-value bag.

Primary key: (graph_name). Foreign key: (graph_name) references store_graph (graph_name).

Columns
graph_name (CHARACTER VARYING, not null)

the declaring graph’s partition, anchored by store_graph

column_name (CHARACTER VARYING, not null)

the column name as configured; matched against catalog columns the way column lookups match, Java name first then SQL name, both case-insensitively

store_source

A source the store read, store-global rather than graph-keyed: it can say what a file hashed to, never which graph read it. Every base relation is partitionable by the source that produced it: a refresh deletes exactly the rows one source wrote and re-walks it, so a relation unreachable from a source row is one the store can only ever discard wholesale.

Primary key: (source_name). Check: "SOURCE_KIND" IN('SCHEMA_FILE', 'DIRECTORY', 'JAR', 'JOOQ_SCHEMA').

Columns
source_name (CHARACTER VARYING, not null)

the schema file path, the classpath entry path, or the generated package a jOOQ schema lives in, as the reader spelled it

source_kind (CHARACTER VARYING, not null)

a closed taxonomy: a schema file, a directory root, a jar, or a generated jOOQ schema package. The last names jOOQ deliberately, unlike the sql_ family: a family is named for whose vocabulary its rows are written in and jOOQ owns none of SQL’s, but a source is named for what it is, and a generated package is jOOQ’s artefact

stamp (CHARACTER VARYING, nullable)

content hash, so an unchanged source is read once and a currency check can re-hash a cold graph’s files without building its module. Schema files are stamped at capture time (one file re-read per schema file, priced against exactly that reader); NULL where nothing resolves to a regular file to hash: a directory root changes on every compile, the bundled directives.graphqls is a resource name, a programmatic caller may hand a bare name, and a jOOQ schema is a package spread across the classpath whose walk is cheap enough not to need one. Also NULL while the source’s rows are being written, and set only once they are all in, so a run that dies mid-load leaves a partition that is re-walked rather than one that claims to be complete

last_seen (TIMESTAMP, not null)

when a run last named this source in its input set; the age half of the age/currency distinction, and the bookkeeping a future eviction surface reads

store_stamp

What this store was built from. At most one row, stated structurally. A persisted store is never state of record: this row decides whether an existing file is intelligible at all. The same stamp names the store’s directory segment, so a mismatching file is normally never even opened; meeting one here means it was moved or damaged by hand, and the store falls back to an in-memory one and leaves the file alone.

Primary key: (singleton). Check: "SINGLETON" = 'X'.

Columns
singleton (CHARACTER, not null)

always 'X'; the CHECK plus the primary key is how a relation says "at most one row" in SQL

ddl_hash (CHARACTER VARYING, not null)

hash of the DDL resource the store was created from, so any schema edit at all invalidates a persisted file

generator_version (CHARACTER VARYING, not null)

the capturing generator’s implementation version, or a placeholder where the manifest declares none. It invalidates a persisted file across releases; within one, a capture change that alters row content without touching the DDL is not caught here, and deleting the store’s cache directory is the remedy