# v0.93.0 — Graph Contracts & External Ownership

> **Status:** Implemented (v0.93 foundation; strict graph refresh remains v0.94)
> **Scope:** Large
> **User promise:** *"Coordinating extensions can treat pg_trickle as a versioned incremental component."*
> **Blocked by:** [v0.92.0](v0.92.0.md)
> **Delivery plan:** Phase 1 of
> [Proposal: V1 Composable Refresh and Durable Delta Contracts](../plans/PROPOSAL_V1_COMPOSABLE_REFRESH_AND_DELTA_CONTRACTS.md)

## Theme

Expose versioned capability discovery and canonical stream-table and graph
contracts for trusted PostgreSQL extensions. Add durable `EXTERNAL`
orchestration ownership without exposing private catalogs, capture buffers,
frontiers, generated columns, or Rust internals.

This release establishes the public contract and ownership foundation. Graph
V1 is not complete until strict transactional refresh passes the separate
[v0.94.0](v0.94.0.md) gate.

## Items

### GV1-1: Independent capability discovery

Add a constant-size discovery API for `external_graph_refresh` and
`output_delta_consumer`, with independent major and minor versions, lifecycle
state, source-class admission, bounds, and encoding information. During this
release, graph refresh remains experimental or disabled and output deltas
remain absent, experimental, or disabled.

### GV1-2: Canonical execution contracts

Add `stream_table_contract()` and `graph_contract()` over deterministic typed
encodings. Contracts include every result-affecting property, source identity,
dependency edge, rewrite and DVM contract version, orchestration mode, and
database-instance identity. Contract generations and digests change for every
tracked mutation and remain stable for operational tuning that cannot affect
results.

Graph closure, member order, lock order, and graph digest are canonical.
Unsupported cycles, source classes, temporary relations, cross-database
references, and malformed catalog state fail closed.

### GV1-3: Durable external orchestration

Add `MANAGED` and `EXTERNAL` orchestration modes plus an authorized
`set_orchestration_mode()` lifecycle operation. `EXTERNAL` members are excluded
from scheduler dispatch across process restart, failover, backup, restore,
clone activation, and extension upgrade. Operational pause remains separate
from durable ownership.

Create, bulk-create, alter, repair, drop, status, scheduler admission, dump,
restore, and upgrade paths must all honor the mode and the canonical lifecycle
lock protocol. Existing stream tables upgrade to `MANAGED`.

### GV1-4: Authorization and lifecycle integrity

Require the caller to own or hold explicit authority over every graph member
and source operation. Pin role dependencies through PostgreSQL shared
dependencies or an equivalent reuse-safe mechanism. Harden every function
against hostile `search_path`, RLS boundaries, guessed object identifiers, and
private-relation disclosure.

## Exit criteria

- [ ] A conformance extension discovers both capabilities independently and
      rejects unsupported versions without package-version inference
- [ ] Canonical contract fixtures pin encoding, generation changes, graph
      closure, member ordering, and digests
- [ ] Durable `EXTERNAL` ownership survives restart, backup and restore,
      failover, clone activation, and supported upgrade
- [ ] Scheduler, lifecycle, and dump paths cannot refresh or silently transfer
      ownership of an external graph
- [ ] Security tests cover unauthorized and mixed-owner graphs, hostile
      `search_path`, RLS sources, role drop and reuse, and malformed catalogs
- [ ] No public API exposes or requires private catalogs, buffers, frontiers,
      scheduler tables, generated columns, or a Rust ABI
