# Legal entities and cataloging switchover

This is a maintenance-window runbook. The database migration is transactional, but
rollback is exclusively a restore of the verified pre-maintenance backup. There is
no dual-read mode and the Worker must not process extraction jobs across the v1/v2
contract boundary.

## Preconditions

- A deployment package containing the API, Web, Worker, and migration
  `20260715200030_LegalEntitiesAndCataloging` has passed build and automated tests.
- `docs/hermes-documental-agent-instructions.md` has been installed in a staging
  `documental-agent` profile and returns `sibyla.extraction.v3.1` with instruction
  version `sibyla-documental/2.3`.
- The operator has `pg_dump`, `pg_restore`, service-control permissions, and the
  approved database connection material. Do not place credentials in this repo or
  in the command history.
- A restore rehearsal has succeeded against an isolated database using the same
  PostgreSQL major version and backup format that will be used in production.

## Preflight before the window

Run the collision query against production. It must return zero rows. Existing
collisions must be resolved and recorded in the audit trail before continuing.

```sql
SELECT "OriginalContentHashSha256", COUNT(*) AS document_count,
       ARRAY_AGG("Id" ORDER BY "RegisteredAt") AS document_ids
FROM "Documents"
WHERE "OriginalContentHashSha256" IS NOT NULL
GROUP BY "OriginalContentHashSha256"
HAVING COUNT(*) > 1;
```

Record counts for `Companies`, `Departments`, `Memberships`, and `Documents`, the
current migration, and the Worker queue depth. Verify that no integration operation
is in flight.

## Maintenance window

1. Stop and verify the Worker before changing the database or Hermes instructions.

   ```powershell
   Stop-Service -Name "Sibyla Worker"
   Get-Service -Name "Sibyla Worker"
   ```

2. Create the restoreable PostgreSQL backup immediately before deployment. Use the
   approved protected backup location and a custom-format dump.

   ```powershell
   pg_dump --format=custom --no-owner --no-privileges --file <protected-backup-path> <approved-connection>
   pg_restore --list <protected-backup-path>
   ```

3. Deploy the API and Web binaries while their application pools are stopped. Apply
   the reviewed EF migration. The migration performs its own global SHA-256
   preflight, copies companies to `BusinessEntities` with the same IDs, assigns the
   `InternalCompany` role, renames operational foreign keys, validates counts and
   orphans, and only then drops `Companies`.

   ```powershell
   dotnet ef database update 20260715200030_LegalEntitiesAndCataloging `
     --project src\Sibyla.Infrastructure\Sibyla.Infrastructure.csproj `
     --startup-project src\Sibyla.Infrastructure\Sibyla.Infrastructure.csproj
   ```

4. Validate the new schema before starting any application process.

   ```sql
   SELECT COUNT(*) FROM "BusinessEntities";
   SELECT COUNT(*) FROM "EntityRoleAssignments" WHERE "Role" = 'InternalCompany';
   SELECT COUNT(*) FROM "Departments" d
     LEFT JOIN "BusinessEntities" e ON e."Id" = d."InternalCompanyEntityId"
     WHERE e."Id" IS NULL;
   SELECT COUNT(*) FROM "Memberships" m
     LEFT JOIN "BusinessEntities" e ON e."Id" = m."InternalCompanyEntityId"
     WHERE e."Id" IS NULL;
   SELECT indexdef FROM pg_indexes
     WHERE indexname IN ('IX_Documents_OriginalContentHashSha256',
                         'IX_EntityTaxIdentifiers_CountryCode_IdentifierType_NormalizedV~');
   ```

5. Install the persistent `sibyla-documental/2.3` instructions in the restricted
   target-host `documental-agent` profile. Record the declared instruction version,
   profile, effective `HERMES_HOME`, actor, and timestamp. During the prototype,
   checksums are optional diagnostics and do not gate this handoff. Do not retain v1
   as a runtime fallback.

6. Start the API and Web only. Run the restricted acceptance set with representative
   Portuguese, English, and one other supported-language document. Verify exact v2
   output, v1 rejection, prompt-injection resistance, buyer/supplier evidence, and
   a document routed to human review.

7. Verify `/pt` and `/en`, optional upload overrides, entity authorization, the
   authenticated inline-original endpoint, and a complete human review. Confirm the
   audit records include thresholds, evidence, revision lineage, and actor.

8. Start the Worker and watch the first bounded extraction jobs through their
   postcondition before releasing the maintenance window.

   ```powershell
   Start-Service -Name "Sibyla Worker"
   Get-Service -Name "Sibyla Worker"
   ```

## Rollback

Do not run migration `Down`, rebuild `Companies` manually, or enable a dual read.
Stop API, Web, and Worker; restore the backup to the production database using the
approved recovery procedure; redeploy the matching pre-window binaries and v1 agent
instructions; then validate counts, migration history, and queue leases before
reopening traffic. Record the rollback reason and restored backup identifier in the
incident evidence.
