Skip to content

Deploying a tenant

Authored by the expert, 2026-10-09

The boundary

The carrier's platform team owns the infrastructure and creates the tenant databases during install. ElevateNow's side is a release folder with three entry points: a summary.json carrying a releasable flag, a code manifest, and one install command. Containerisation of the tools, workbenches and Curation Studio belongs to the deploy package; this page covers the data package, which is the knowledge a tenant runs on.

What ships

The data packager exports a bundle from ElevateNow's knowledge database under a manifest that classifies every collection and every record type with one of four verdicts.

Verdict Meaning
Ship A runtime tool reads it during a decision
Studio Only the Curation Studio reads it; ships for the curator
Init Created empty with its indexes, never seeded: tenant-local state such as the curation audit trail, extraction results and caches
Drop Nothing reads it, proven by search

The filter is an allowlist: a record type absent from the manifest is excluded, and a pre-seed check confirms no type exists outside it. Only active or approved records ship, never drafts. No carrier's records ship in another carrier's bundle; the filter is carrier_id: null by construction. The manifest's own hash is recorded in the bundle.

The source knowledge database holds about 26,500 documents; the base bundle ships 3,009. The difference is not loss. About 13,900 are ontology edges and entities, studio-optional and available as a patch seed; the rest are other carriers' demo records, drafts, and tenant-local history such as ElevateNow's own curation audit trail, which never leaves ElevateNow. Of the 3,009, roughly 350 are read by a runtime tool during a decision and the remainder are curation surface. Collections under the Init verdict (the curation audit, extraction results, caches) are created empty with their indexes so a tenant's governance trail starts with the tenant.

Load and verify

a360_export.py writes the bundle from the primary, cleaning the output directory first so stale files cannot poison the checksum. a360_load.py refuses a non-empty target and loads the bundle. a360_verify.py runs five checks: document counts, per-collection checksums re-exported byte-identically from the target, cross-reference resolution across the spec records, indexes, and carrier absence under a --permitted-carrier argument. Two full-text indexes cannot be recreated through the driver and ship as a mongosh script instead.

A parity harness then runs the two reference claims against source and tenant with the connection string as the only variable, diffing governance blocks, citations, three-state results and refusals, because verdict-level parity is not parity: a missing record produces a clean refusal, and a clean refusal renders as a reasonable brief.

Known limits

  • No in-place upgrade: the loader refuses a non-empty target, so changing the corpus means a fresh database. Upgrade in place needs its own design.
  • Studio authentication and tenant scoping are release blockers, because the carrier operates the Curation Studio.
  • The Reducto vendor adapter (EP-198) is not built; the reducto and databricks intake tracks are not production-ready. The carrier-structured track is.
  • WCBenefitCalculatorGKR carries the New York benefit schedule only; other states refuse by name.
  • CoverageAnalyzerGKR is not wired into the carrier pipeline, so complexity dimension 1 and the express-segment gate cannot resolve until it is. The full operating detail, including the environment variables and the harness commands, is in Seed bundle and tenant install.