Dead release.* Schema — DROP Audit & Plan

Status: PROPOSAL — NOT WIRED. No migration file exists for this plan. Audit performed 2026-07-04 against working tree 04673987208e (follow-up to the deployment-capability audit + the 2026-07-04 live E2E pass, SPRINT_20260703_006). The DROP SQL in §5 is quarantined in this document only; it must NOT be copied into any Migrations/ directory (and therefore into the embedded-resource glob) until an operator explicitly approves it (§7).

1. Context — two parallel schemas

The platform database carries two parallel release data models:

Only the owning src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Program.cs runs the Environment migrations and stores against release.*. Platform and Concelier both stopped calling AddReleaseOrchestratorEnvironmentPostgresData and stopped applying the ReleaseOrchestrator.Environment startup migrations on 2026-07-11. Platform’s compatibility endpoints proxy the owning WebApi; the gateway’s topology-setup aliases route directly to it. In addition, DTC-7 (SPRINT_20260703_002) actively projects release.environments/targets/agents/regions into the release.topology_*_inventory read-model tables and mirrors regions/ environments into platform.context_regions / platform.context_environments (src/Platform/StellaOps.Platform.WebService/Program.cs:471-481, Services/TopologyInventorySynchronizer.cs:16-17, Services/PostgresTopologySourceReader.cs:29-53, Services/PostgresTopologyInventoryStore.cs, Services/PlatformContextService.cs).

So a blanket DROP SCHEMA release is not possible. This audit classifies every table and derives the safe DROP subset.

2. Method

Classifications

ClassMeaning
LIVE-USEDA wired store / live script reads or writes it, or it is an FK target of a live table (structural).
DTC-7-SYNCEDWritten/served by the DTC-7 topology-inventory sync in platform-web.
AMBIGUOUS-KEEPUsage is ambiguous (dormant store code exists, or shape/ownership is contested) — keep, do not drop.
DEADNo code references it beyond its own CREATE migration (and, at most, tests that assert the SQL text of the baseline, which do not touch the DB table).

3. Per-table classification

Baseline line numbers refer to src/Platform/__Libraries/StellaOps.Platform.Database/Migrations/Release/001_v1_platform_database_release_baseline.sql (P: prefix) and src/ReleaseOrchestrator/__Libraries/StellaOps.ReleaseOrchestrator.Environment/Migrations/001_v1_releaseorchestrator_environment_baseline.sql (E: prefix) unless stated otherwise.

3.1 Integration hub block

TableClassificationEvidence
release.integration_typesAMBIGUOUS-KEEPCreated P:152. No runtime reader/writer, but the Platform-shaped release.integrations (P:198) FKs it; which integrations shape exists on a given DB depends on IF NOT EXISTS creation order between the two baselines (§6.3). Dropping it can break the FK graph on Platform-bootstrapped DBs.
release.integrationsLIVE-USED (structural)Created P:198 and E:71 (different shapes). FK target of live release.infrastructure_bindings (E:241; live INSERT PostgresInfrastructureBindingStore.cs:77). Writer IntegrationHub/Store/IntegrationStore.cs:26 exists but is not wired in any host (no DI registration found).
release.integration_health_checksDEADCreated P:296. No references outside the baseline.
release.integration_feed_source_healthDEADCreated P:3726. Only ref: src/Platform/__Tests/StellaOps.Platform.WebService.Tests/IntegrationSourceHealthMigrationScriptTests.cs:14 (asserts baseline SQL text, not the DB table). No runtime reader/writer, no dynamic _source_health composition anywhere.
release.integration_vex_source_healthDEADCreated P:3758. Only ref: IntegrationSourceHealthMigrationScriptTests.cs:15.
release.integration_source_sync_watermarksDEADCreated P:3792. Only ref: IntegrationSourceHealthMigrationScriptTests.cs:16.

3.2 Environment / topology block (live)

TableClassificationEvidence
release.environmentsLIVE-USEDPostgresEnvironmentStore.cs:60 (Environment lib); DTC-7 source read PostgresTopologySourceReader.cs:38; wired by 3 hosts (§1).
release.targetsLIVE-USEDPostgresTargetStore.cs:69; DTC-12 sealed connection_config_encrypted (ReleaseOrchestrator.WebApi/Program.cs:389-395); DTC-7 source read PostgresTopologySourceReader.cs:46; Platform migration 006_v1_topology_inventory_target_types.sql:4.
release.agentsLIVE-USEDPostgresAgentStore.cs:40 (wired ReleaseOrchestrator.WebApi/Program.cs:212); PostgresTopologyAgentCatalog.cs:20; DTC-7 source read PostgresTopologySourceReader.cs:53; operator script devops/compose/scripts/launch-agent-core.ps1:158.
release.freeze_windowsLIVE-USEDPostgresFreezeWindowStore.cs:36 (registered Environment/Postgres/ServiceCollectionExtensions.cs:48).
release.regions (E-only)LIVE-USEDPostgresRegionStore.cs:44; DTC-7 source read PostgresTopologySourceReader.cs:29; mirrored into platform.context_regions.
release.infrastructure_bindings (E-only)LIVE-USEDPostgresInfrastructureBindingStore.cs:77 (INSERT), :96 (DELETE).
release.topology_point_status (E-only)LIVE-USEDPostgresTopologyPointStatusStore.cs:21.
release.pending_deletions (E-only)LIVE-USEDPostgresPendingDeletionStore.cs:70.
release.freeze_window_exemptions (E-only)LIVE-USEDPostgresFreezeWindowStore.cs:92-141; FKs release.freeze_windows and release.releases (E:364-365).
release.agent_registration_tokens (Agent-baseline-only)LIVE-USEDPostgresAgentStore.cs:418-504.

3.3 Release-management block (Platform shape — mostly dead)

TableClassificationEvidence
release.releasesLIVE-USED (structural)Rich shape P:689 / live stub E:183. FK target of live release.freeze_window_exemptions (E:365) and of release.promotions (E:192). Diagnostics read: devops/compose/scripts/compliance-setup.ps1:182, compliance-setup.sh:222-228. The authoritative release rows live in release_orchestrator.releases. Do not drop.
release.promotionsLIVE-USEDRich shape P:1079 / live stub E:192. Live delete-guard reads: PostgresEnvironmentStore.cs:163 (FROM release.promotions), PostgresTargetStore.cs:133 (JOIN release.promotions).
release.componentsDEADCreated P:611. All other matches are C#/TS property access (release.Components), e.g. ArtifactGenerator.cs:56, releases-list-page.component.ts:100 — not table usage. Live components live in release_orchestrator.components (:632).
release.component_versionsDEADCreated P:648. Live equivalent: release_orchestrator.component_versions (:661).
release.release_componentsDEADCreated P:768. Only other mention is a stale doc-comment in src/Policy/__Libraries/StellaOps.Policy.Persistence/Postgres/PolicyDbContextFactory.cs:16; Policy’s EF context maps only policy-schema tables. Live equivalent: release_orchestrator.release_components (:329).
release.release_tagsDEADCreated P:791. No references.
release.approvalsDEADCreated P:1149. Live approvals are release_orchestrator.approvals (:362).
release.gate_typesDEADCreated P:1177. Only FK’d by dead release.gate_results.
release.gate_resultsDEADCreated P:1207. Live gate decisions are release_orchestrator.gate_decisions (:381). (Matches on gate_results elsewhere are a JSONB column of release.policy_simulations, PostgresPolicySimulationStore.cs:56.)

3.4 Workflow block

TableClassificationEvidence
release.workflow_templatesDEADCreated P:899. StellaOps.ReleaseOrchestrator.Workflow has no Postgres persistence against these tables.
release.workflow_runsDEADCreated P:939. No references.
release.workflow_stepsDEADCreated P:977. No references.
release.workflow_step_logsDEADCreated P:1014. No references.

3.5 Deployment block

TableClassificationEvidence
release.deployment_jobsDEADCreated P:1315. Live jobs are release_orchestrator.deployment_jobs (:480). Doc-comment ExecuteCapabilityAgentTask.cs:9 explicitly states the agent-task path has “no release.deployment_jobs / release.deployment_tasks lifecycle”.
release.deployment_tasksDEADCreated P:1359. Same evidence.
release.deployment_artifactsDEADCreated P:1407. No references.
release.deployment_eventsDEADCreated P:1435. No references.

3.6 Agent history block (Platform shape)

TableClassificationEvidence
release.agent_capabilitiesDEADCreated P:1596. Live agent capabilities are a JSONB column on release.agents (E:99).
release.agent_heartbeatsDEADCreated P:1618 (PARTITION BY RANGE). Live heartbeat state is release.agents.last_heartbeat (E:102).
release.agent_heartbeats_defaultDEADP:1631 — PARTITION OF release.agent_heartbeats DEFAULT; dropped implicitly with its parent.
release.agent_tasksDEADCreated P:1643. The live task queue is release_orchestrator_agent.agent_tasks (AgentTaskDataSource.cs:16, unqualified SQL in PostgresAgentTaskStore.cs:29 under that schema’s search_path).

3.7 Evidence blocks

TableClassificationEvidence
release.evidence_packetsDEADCreated P:1770. Live evidence is release_orchestrator.release_evidence (:397).
release.evidence_exportsDEADCreated P:1843. No references.
release.evidence_export_packetsDEADCreated P:1873. No references.
release.evidence_threadsAMBIGUOUS-KEEPCreated P:2222. Full CRUD store exists (PostgresEvidenceThreadStore.cs:41-142) + integration-test fixture, but AddEvidenceThread (EvidenceThread/Extensions/ServiceCollectionExtensions.cs:33) is never called by any host — dormant feature, not provably abandoned.
release.evidence_nodesAMBIGUOUS-KEEPPostgresEvidenceThreadStore.cs:184-240; same dormant-store rationale.
release.evidence_linksAMBIGUOUS-KEEPPostgresEvidenceThreadStore.cs:288-314.
release.evidence_thread_exportsAMBIGUOUS-KEEPPostgresEvidenceThreadStore.cs:464-510.
release.evidence_transcriptsAMBIGUOUS-KEEPPostgresEvidenceThreadStore.cs:391-438.

3.8 Plugin registry block (Platform shape)

TableClassificationEvidence
release.plugin_typesDEADCreated P:2003. The live plugin registry migrates into the platform schema (PluginRegistryMigrationModulePlugin, MigrationModulePlugins.cs:159-166).
release.pluginsDEADCreated P:2066. No references.
release.plugin_versionsDEADCreated P:2104. No references.
release.plugin_instancesDEADCreated P:2135. No references.

3.9 Policy-gate block

TableClassificationEvidence
release.policy_profilesAMBIGUOUS-KEEPCreated P:2552. Store exists (PostgresPolicyProfileStore.cs:57) and is registered by PolicyGate/Extensions/ServiceCollectionExtensions.cs:40 — but AddPolicyGateServices is never called by any host. Dormant.
release.policy_simulationsAMBIGUOUS-KEEPPostgresPolicySimulationStore.cs:58; same dormant registration path (:45).
release.feed_freshnessAMBIGUOUS-KEEPCreated P:2646. PostgresFeedFreshnessStore.cs:47; same dormant registration path (:50).

3.10 Control-bundle / trust / read-model / run blocks

TableClassificationEvidence
release.control_bundlesLIVE-USEDPostgresReleaseControlBundleStore.cs:90 — wired Platform/StellaOps.Platform.WebService/Program.cs:540; e2e seed src/Web/StellaOps.Web/e2e/helpers/seed-releases.ts:44; created by bootstrap fallback devops/compose/postgres-init/00-v1-baseline.sql.
release.control_bundle_versionsLIVE-USEDPostgresReleaseControlBundleStore.cs:93-166; seed-releases.ts:54.
release.control_bundle_componentsLIVE-USEDPostgresReleaseControlBundleStore.cs:469, 868.
release.control_bundle_materialization_runsLIVE-USEDPostgresReleaseControlBundleStore.cs:26-45, 588-726; seed-releases.ts:65.
release.trust_keysLIVE-USEDPostgresAdministrationTrustSigningStore.cs:51 — wired Program.cs:552; demo-seed cleanup Migrations/Release/002_v1_remove_demo_bootstrap_seed.sql:46.
release.trust_issuersLIVE-USEDPostgresAdministrationTrustSigningStore.cs:289; 002_…seed.sql:41.
release.trust_certificatesLIVE-USEDPostgresAdministrationTrustSigningStore.cs:521; 002_…seed.sql:36.
release.trust_transparency_configsLIVE-USEDPostgresAdministrationTrustSigningStore.cs:732; 002_…seed.sql:51.
release.release_read_modelDEADCreated P:3354. Only ref: ReleaseReadModelMigrationScriptTests.cs:14 (SQL-text assertion). The runtime ReleaseReadModelService (Program.cs:484) is not SQL-backed by this table.
release.release_activity_projectionDEADCreated P:3380. Only ref: ReleaseReadModelMigrationScriptTests.cs:15.
release.release_approvals_projectionDEADCreated P:3401. Only ref: ReleaseReadModelMigrationScriptTests.cs:16.
release.run_input_snapshotsDEADCreated P:3860. Only ref: RunInputSnapshotsMigrationScriptTests.cs:14.
release.run_gate_decision_ledgerDEADCreated P:3909. Only ref: RunGateDecisionLedgerMigrationScriptTests.cs:14.
release.run_approval_checkpointsDEADCreated P:3958. Only ref: RunApprovalCheckpointsMigrationScriptTests.cs:14.
release.run_deployment_timelineDEADCreated P:4004. Only ref: RunDeploymentTimelineMigrationScriptTests.cs:14.
release.run_capsule_replay_linkageDEADCreated P:4064. Only ref: RunCapsuleReplayLinkageMigrationScriptTests.cs:14.

3.11 Topology inventory read-model (DTC-7)

TableClassificationEvidence
release.topology_region_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:76-85, 381; sync wiring Program.cs:471-481.
release.topology_environment_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:71-113, 408.
release.topology_target_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:25, 146, 446; Platform migration 006_v1_topology_inventory_target_types.sql:12-15.
release.topology_host_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:26, 181, 479.
release.topology_agent_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:27, 210, 510.
release.topology_promotion_path_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:28, 241, 537.
release.topology_workflow_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:29, 273, 566.
release.topology_gate_profile_inventoryDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:30, 302, 594.
release.topology_sync_watermarksDTC-7-SYNCEDPostgresTopologyInventoryStore.cs:334, 637; ITopologyInventoryStore.cs:14.

Related (same DTC-7 flow, platform schema, NOT in scope of any DROP): platform.context_regions (P:3294) and platform.context_environments (P:3304), served by PlatformContextService.cs.

3.12 Federated telemetry

TableClassificationEvidence
release.federated_telemetry_bundlesLIVE-USEDCreated 004_v1_federated_telemetry_bundles.sql:29; PostgresFederatedBundleStore.cs:12-80 — wired Program.cs:545-546.

4. Confirmed-DEAD set (safe to DROP after approval)

37 tables (+1 partition dropped implicitly), all with zero runtime readers/writers:

workflow_step_logs, workflow_steps, workflow_runs, workflow_templates, gate_results, gate_types, approvals, evidence_export_packets, evidence_exports, evidence_packets, deployment_events, deployment_artifacts, deployment_tasks, deployment_jobs, agent_capabilities, agent_heartbeats (+ agent_heartbeats_default partition), agent_tasks, release_components, component_versions, components, release_tags, plugin_instances, plugin_versions, plugins, plugin_types, integration_health_checks, release_read_model, release_activity_projection, release_approvals_projection, run_gate_decision_ledger, run_input_snapshots, run_approval_checkpoints, run_deployment_timeline, run_capsule_replay_linkage, integration_feed_source_health, integration_vex_source_health, integration_source_sync_watermarks

Explicitly NOT in the DROP set: everything classified LIVE-USED, DTC-7-SYNCED, or AMBIGUOUS-KEEP above — in particular releases, promotions, integrations, integration_types, the policy-gate trio, and the evidence-thread block.

The migration-script tests that mention dead tables (ReleaseReadModelMigrationScriptTests, Run*MigrationScriptTests, IntegrationSourceHealthMigrationScriptTests) assert the baseline SQL text, which the DROP migration does not modify (forward-only: the baseline file is never edited) — they stay green.

5. Quarantined DROP migration (proposal — do NOT create as a file yet)

Forward-only, children-before-parents per the FK graph extracted from the Platform baseline. Written as a release-category migration (100+ numeric prefix ⇒ requires explicit stella system migrations-run, never auto-applied at startup) — but again: this SQL lives only in this document until approved.

-- PROPOSED: src/Platform/__Libraries/StellaOps.Platform.Database/Migrations/Release/100_v1_drop_dead_release_parallel_model.sql
-- Category: Release (100+ prefix => NEVER auto-applied; operator runs it explicitly).
-- Forward-only per ADR-004. Requires a PostgreSQL snapshot first
-- (docs/runbooks/migration-recovery.md, "Snapshot Before Upgrade").
--
-- Drops the confirmed-DEAD subset of the legacy release.* parallel model.
-- Audit: docs/modules/release-orchestrator/data-model/dead-schema-drop-plan.md
-- (2026-07-04, working tree 04673987208e). Every table below has zero runtime
-- readers/writers in src/ and devops/; live data lives in release_orchestrator.*,
-- release_orchestrator_agent.*, or the LIVE-USED release.* tables (kept).
--
-- Ordering: FK children before parents (no CASCADE, so an unexpected dependent
-- object fails loudly instead of being silently destroyed).

-- Workflow block (steps -> runs -> templates)
DROP TABLE IF EXISTS release.workflow_step_logs;
DROP TABLE IF EXISTS release.workflow_steps;
DROP TABLE IF EXISTS release.workflow_runs;
DROP TABLE IF EXISTS release.workflow_templates;

-- Gate block (results FK gate_types + promotions[KEPT])
DROP TABLE IF EXISTS release.gate_results;
DROP TABLE IF EXISTS release.gate_types;

-- Approvals (FK promotions[KEPT]; live approvals = release_orchestrator.approvals)
DROP TABLE IF EXISTS release.approvals;

-- Evidence-packet block (export_packets FK exports + packets; packets FK deployment_jobs)
DROP TABLE IF EXISTS release.evidence_export_packets;
DROP TABLE IF EXISTS release.evidence_exports;
DROP TABLE IF EXISTS release.evidence_packets;

-- Deployment block (events FK jobs+tasks; artifacts FK jobs; tasks FK jobs+targets[KEPT];
-- jobs FK self + environments[KEPT] + promotions[KEPT])
DROP TABLE IF EXISTS release.deployment_events;
DROP TABLE IF EXISTS release.deployment_artifacts;
DROP TABLE IF EXISTS release.deployment_tasks;
DROP TABLE IF EXISTS release.deployment_jobs;

-- Agent history block (children of release.agents[KEPT]; heartbeats is partitioned —
-- dropping the parent drops the agent_heartbeats_default partition)
DROP TABLE IF EXISTS release.agent_capabilities;
DROP TABLE IF EXISTS release.agent_heartbeats;
DROP TABLE IF EXISTS release.agent_tasks;

-- Component block (release_components FK component_versions + releases[KEPT];
-- component_versions FK components; components FK integrations[KEPT])
DROP TABLE IF EXISTS release.release_components;
DROP TABLE IF EXISTS release.component_versions;
DROP TABLE IF EXISTS release.components;

-- Release tags (FK environments[KEPT] + releases[KEPT])
DROP TABLE IF EXISTS release.release_tags;

-- Plugin block (instances -> versions -> plugins -> plugin_types)
DROP TABLE IF EXISTS release.plugin_instances;
DROP TABLE IF EXISTS release.plugin_versions;
DROP TABLE IF EXISTS release.plugins;
DROP TABLE IF EXISTS release.plugin_types;

-- Integration health checks (FK integrations[KEPT])
DROP TABLE IF EXISTS release.integration_health_checks;

-- Read-model projections (children of control_bundle*[KEPT])
DROP TABLE IF EXISTS release.release_read_model;
DROP TABLE IF EXISTS release.release_activity_projection;
DROP TABLE IF EXISTS release.release_approvals_projection;

-- Run-evidence block (ledger FK run_input_snapshots; all FK control_bundle*[KEPT])
DROP TABLE IF EXISTS release.run_gate_decision_ledger;
DROP TABLE IF EXISTS release.run_input_snapshots;
DROP TABLE IF EXISTS release.run_approval_checkpoints;
DROP TABLE IF EXISTS release.run_deployment_timeline;
DROP TABLE IF EXISTS release.run_capsule_replay_linkage;

-- Integration source-health block (no dependents)
DROP TABLE IF EXISTS release.integration_feed_source_health;
DROP TABLE IF EXISTS release.integration_vex_source_health;
DROP TABLE IF EXISTS release.integration_source_sync_watermarks;

Notes on the ordering:

6. RISK

  1. This DROPs data on the shared live PostgreSQL instance. Even “dead” tables may contain rows written by pre-consolidation builds. The migration is irreversible (forward-only, ADR-004). It therefore requires:
  2. Must NOT be wired into the embedded-migration glob until approved. The persistence csproj embeds Migrations\**\*.sql (StellaOps.Platform.Database.csproj); the moment this file lands in Migrations/Release/, every platform-web image build carries it. Numbering it 100_* keeps it out of startup auto-apply (release category requires stella system migrations-run --module Platform --category release), but the file must still not exist in the tree until the go-ahead.
  3. Row-count preflight is mandatory. Before running, the operator must verify the DEAD tables are empty or that their contents are confirmed disposable:
    SELECT relname, n_live_tup
    FROM pg_stat_user_tables
    WHERE schemaname = 'release'
      AND relname IN ('workflow_runs','evidence_packets','deployment_jobs', /* … full §4 list … */ 'agent_heartbeats')
    ORDER BY n_live_tup DESC;
    
    (n_live_tup is an estimate — for a non-zero result, confirm with SELECT count(*).) Any unexpectedly populated table ⇒ STOP and reclassify before dropping.
  4. Dual-owner shape hazard (standing risk, not introduced by this plan): seven tables (integrations, agents, environments, targets, freeze_windows, releases, promotions) are created with different shapes by both the Platform baseline and the RO-Environment baseline under IF NOT EXISTS — whichever host migrates first on a fresh DB wins. The DROP plan deliberately keeps all of them; unifying ownership is a separate follow-up (recommended: RO-Environment becomes the single owner and the Platform baseline’s copies are retired from the next pre-release re-baseline, with the checksum-recovery procedure in mind).
  5. AMBIGUOUS-KEEP tables need a product decision, not a DROP: the dormant PolicyGate (policy_profiles, policy_simulations, feed_freshness), EvidenceThread (5 tables), and IntegrationHub (integrations writer path) stores are complete, tested code that no host wires. Either wire them or delete the store code first; only then can their tables be reclassified.

7. Approval checklist (all boxes required before the migration file is created)