# Store SQL Ownership Inventory and Ratchet

> Canonical path: `specs/storage/sql-ownership-inventory.md`
> Status: current
> Related spec: [`specs/storage/store-domain-transaction-api.md`](./store-domain-transaction-api.md)

## Purpose

Lock a durable, machine-readable inventory for where runtime SQL currently
lives while the store `Store` / `TxStore` migration proceeds. The inventory is
not a permission slip to spread SQL into upper layers; it is a shrink-only
ratchet that makes every non-canonical owner explicit.

## Canonical inventory sources

- `guardrails/store/sql-ownership-inventory.json` — machine-readable inventory
  for migrated `TxStore` packages, canonical SQL-owning directories,
  test/harness SQL directories, and exact temporary production exceptions.
- `guardrails/store/check-store-sql-ownership.sh` — executable inventory and
  ratchet check for SQL-owning Go / SQL files.
- `guardrails/store/check-store-txstore-pattern.sh` — structural `Store` /
  `TxStore` checker for the packages listed in `migratedTxStorePackages`.

Refresh the guardrail output when a PR touches SQL ownership. Do not treat old
thread notes or review comments as the canonical inventory.

## Canonical production SQL owners

Production SQL literals, query builders, and migration DDL belong only in:

- `internal/store/**`
- `internal/coredb/**`
- `internal/tidb/**`
- `internal/migrations/**`
- `internal/database/**`

Why these directories are allowed:

- `internal/store/**` owns domain data access and domain-local invariants.
- `internal/coredb/**` owns shared DB adapter/query-builder primitives used by
  store domains.
- `internal/tidb/**` and `internal/migrations/**` own bootstrap, admin, and
  migration plumbing.
- `internal/database/**` owns MeshX's domain-local database bootstrap and
  migration plumbing.

## Test and harness SQL owners

The following directories may own SQL for fixtures, bootstrap helpers, or
end-to-end harness setup, but they remain non-production code paths:

- `cmd/agentteam-e2e-server/**`
- `dev/**`
- `internal/api/testkit/**`
- `internal/coredb/testkit/**`
- `internal/store/testkit/**`

Production packages must not reach into these directories for runtime data
access.

## Temporary production exceptions (shrink-only)

The following exact files are the only allowed production SQL owners outside the
canonical directories above:

| Path | Why it still owns SQL |
| --- | --- |
| `internal/schedule/manage/manage_mutation.go` | Schedule mutation validation materializes relative times against the database clock before writing canonical schedule definitions. |
| `internal/schedule/manage/manage_schedule.go` | Schedule management owns bounded activation and canonical schedule-list queries used by the stable Trigger-shaped facade. |
| `internal/schedule/manage/manage_target.go` | Schedule target validation reads workspace membership and target scope facts. |
| `internal/schedule/manage/manage_view_validation.go` | Schedule view validation loads the authenticated workspace owner and validates canonical targets. |

These are exact-file exceptions, not prefix exceptions. If one of these files
stops owning SQL, remove it from the JSON inventory in the same PR. If a new
out-of-bound owner appears, the guardrail must fail until a dedicated planning
PR updates the spec and inventory.

## Ratchet policy

1. `check-store-sql-ownership.sh` inventories every SQL-owning Go / SQL file
   and fails on unexpected production owners outside the canonical directories,
   test/harness directories, and exact temporary exception list.
2. `temporaryProductionSQLExceptions` is exact, not package-wide. Splitting one
   exception file into more files requires an explicit inventory update.
3. `migratedTxStorePackages` is the canonical package list for
   `check-store-txstore-pattern.sh`.
4. When a domain migrates to `Store` / `TxStore`, update the JSON inventory,
   rerun both guardrails, and delete temporary `...InTx` bridges only in the
   owning package migration PR.
5. Do not add new production SQL to `internal/api`, `internal/service`,
   `internal/service`, or other upper layers. Introduce or reuse a domain store
   port instead.

## Review expectations

PRs touching SQL ownership should include:

- `./guardrails/store/check-store-sql-ownership.sh`
- `./guardrails/store/check-store-txstore-pattern.sh` when migrated package
  inventory or `Store` / `TxStore` structure changes
- targeted `go test` for touched store / trigger / service packages
