ADR-0020: Database-first observations and reviewed tracking proposals¶
Status: specified compiler/transport/CLI and Movies executable scope verified in hosted run 38115255813: eleven-project clean build, locked restore, 175 tooling tests and ten live database-first cases pass, including generated EF reads/updates/rollback and explicit ID backfill.
Database-first is optional authoring tooling. The driver inspector creates one explicitly selected-database read session and finite-timeout transaction, uses fixed read queries, then rolls back and disposes it. It never commits, deploys schema or backfills IDs. The supplied driver remains caller-owned. Read access mode is routing/transport intent, not a substitute for a restricted database account. Driver 6.3 operations have no cancellation-token overloads; cancellation is checked between awaited operations without abandoning in-flight work.
Inventory uses bounded db.labels(), db.relationshipTypes(), SHOW CONSTRAINTS and SHOW INDEXES results. Schema tokens retain empty constrained/indexed types. Each validated selected label/type is sampled with WITH ... LIMIT before property-type projection. The old conceptual aggregate queries in the sample specification were corrected: limiting aggregate results does not bound their input scan. We avoid the whole-graph property-distribution procedures, whose pinned implementation scans all graph elements. Neo4j 2026.09 inventory implementation, property schema calculator.
The versioned snapshot contains storage names, constraints/indexes, capability facts, directed endpoint labels and sampled property kinds. It contains no property values, connection addresses, credentials, timestamps or element IDs. Transient IDs deduplicate overlapping label observations and detect distinct parallel relationships within a sample; they never become EF keys or leave the inspector. Observations are read-committed, not a consistent schema/data snapshot. The first observed shape of a repeated node is retained. Absence of observed parallel edges proves no global cardinality. A present value's NOT NULL type suffix proves no requiredness.
Defaults cap samples at 32 per selected token, inventory at 64 tokens per kind, schema at 256 rows per kind, properties at 64 per element, labels at 16 per endpoint, and total raw samples at 2048. Fixed aggregate budgets additionally cap retained evidence at 65536 fields and 1 MiB of text characters before accumulating another row. Configured maxima remain finite. These limits bound client evidence, not server IO, eager metadata-list allocation, individual incoming driver-record allocation or transaction wall time beyond Neo4j's timeout enforcement. Oversized or malformed metadata fails without publishing a partial report; data samples intentionally remain partial. Graph Type reads are optional and capability-gated; Community continues with schema/sample evidence.
The offline compiler distinguishes unreviewed DTO browsing from reviewed tracked proposals. A tracked mapping requires an explicitly chosen application key, matching observed uniqueness/key constraint, and acknowledgement of stable identity/requiredness. Uniqueness without existence remains a warning even after review; missing sampled keys are errors. Bounded samples cannot prove all values exist or satisfy an explicit converter. elementId(), apparent unique names/titles, and ordinary indexes never become inferred keys. Use a separate reviewed validation/backfill migration when needed; compiling a policy never performs one. Constraint semantics.
Tracked relationship proposals require explicit directed endpoints and an independent application ID. No association identity or collection cardinality is inferred. Conflicting endpoint shapes, mixed incompatible property types, ambiguous overlapping tracked labels and unsupported payload fail. An explicit ignored payload decision emits a warning and preserves the native value through untracked DTO browsing; arrays such as Movies roles are never silently stringified. This does not add native array operators to the provider.
Snapshots and reviewed policies use strict versioned JSON, with duplicate/unknown fields, invalid enums, depth, count, aggregate metadata and 4 MiB input limits. JSON replaces the illustrative YAML/TOML override format for this workflow to share one bounded interchange codec; ontology policy remains YAML. inspect requires four explicit environment settings and publishes a new snapshot without overwriting existing files. scaffold runs offline and reuses protected artifact publication and byte checks. Generated EF source is actually compiled and its finalized model produces the storage fingerprint; DTO-only proposals produce no EF manifest. Schema output is an empty-target proposal, not a migration diff for the inspected database.
Optional tooling live tests run in a separate project on the same serialized disposable fixture. Adding tooling to the runtime integration project exposed Roslyn 5.9 versus upstream EF specification package Roslyn 5.0 constraints. Isolating the test dependency graphs fixed locked restore without version-warning suppression or changing either tested package pin. No second database/container is started by the test adapter.
Four inspector live tests verify graph/schema preservation, Community fallback, actual type/parallel-edge evidence, constraint-backed generated compilation, missing-key/mixed-type rejection and driver reuse after bounded/cancelled/invalid-database operations. Six Movies cases add fixture/schema guards, actual generated-model reads, native roles preservation, rollback and four explicit backfill scenarios. GB-014's specified sample scope is verified. Least-privilege deployment and Enterprise execution remain separate unverified profiles.
The Movies executable is being assembled from observations of the original authored fixture, rather than hand-authored snapshot facts. Its capture test filters actual schema metadata to the four sample-owned constraints/indexes before serializing, excluding unrelated test schema from committed generation inputs. The general inspector retains its full schema observation behavior. Hosted capture exports only these type/schema snapshots and generated artifacts; it does not export fixture credentials or raw database values.
The sample setup helper pins fixture inputs by normalized SHA-256, requires the disposable marker, and checks creation counts before committing. Explicit schema preparation preflights all four definitions before its first DDL, rejects conflicting names/shapes and checks committed ONLINE backing indexes in fresh transactions. Its stepwise schema operations do not initialize or reset the migration journal. The generated application depends only on the runtime provider; optional tooling remains in generation and the isolated tooling acceptance project.
The separate legacy-ID example uses a dedicated label, constrained legacy selector and one fixed reviewed application Guid. Preview and validation do not mutate; initialization, schema, seed and backfill are separate explicitly confirmed operations. Journal predecessor/checksum/ownership and current schema/data are checked before writes; completed history is not accepted as proof of unchanged current data. No inference from titles or element IDs, automatic recovery, reseed after drift, or journal reset is exposed by the executable. Serialize these sample commands: validation, seed and migration transactions are not one atomic operation. The generated query demo edits one supported payload in a transaction and rolls it back, verifying ignored roles and original payload in a fresh context. These paths pass the build/live gate in run 38115255813.
Hosted regeneration inside the assembled Movies test process exposed that TRUSTED_PLATFORM_ASSEMBLIES also contains host application dependencies. Importing that entire list caused generated types to conflict with their previously compiled application versions. Generated compilation now uses only shared-runtime assemblies and the dependency closure rooted at EF, the provider and the driver. Unrelated host/tooling assemblies are excluded; warnings remain errors. The isolated offline regression fails before this correction and passes afterward, alongside all 175 tooling tests. The corrected hosted run passes all four legacy-backfill cases and the generated Movies workflow.
This reference-resolution strategy supports the repository's framework-dependent tooling layout. Self-contained publication can place application DLLs beside the runtime, defeating directory isolation; single-file publication can remove required assembly file locations. Neither tooling deployment profile is supported or verified by this checkpoint. They require a separate reference resolver and acceptance before being advertised.