What the witness watches
L2 (“Witnessed by Postgres”) can only speak about what the decoder can see. This page says exactly what that is for a Postgres connector, what it isn’t, and how to change it safely. The decoder is DECODER.md; the V0 design this replaces is v0/OBSERVATION_BOUNDARY.md.
What is watched
Section titled “What is watched”The publication deedglass_pub is the boundary. It contains:
deedglass.ledger, the rowbegin_actionwrites in every agent transaction;- every table in the connector’s
witness.watched_tables, which must include every table inwritable_tables(config validation refuses a writable table that isn’t watched, anddeedglass connector postgres checkfailswritable_watched).
It publishes inserts, updates, deletes and truncates, with no row filters and no column lists; the
decoder halts (publication_invalid) at start when that isn’t so, and treats any change to the
publication during a read as an evidence gap (publication_changed, publication_gap). Each
watched table has REPLICA IDENTITY FULL, so updates and deletes carry the whole old row.
For each committed transaction that touches a watched table or the ledger, the decoder keeps the tables, exact counts, the first 1,000 changes with old and new images, and a digest over all of them (DECODER.md).
What isn’t
Section titled “What isn’t”- Tables outside the publication. Their changes are skipped by Postgres before Deedglass sees
them. A trigger on a watched table that writes to an unwatched one is invisible (
checkwarns about triggers on watched tables). - Unlogged and temporary tables, sequences and large objects. Logical decoding doesn’t carry them.
- Schema changes. DDL shows only as a changed relation shape (
relation_changed:<table>) on the next change to that table. - Effects outside the WAL:
NOTIFY,pg_net, foreign tables, files, other databases. - Reads. The decoder sees writes only.
- What a REPLICATION role could read anyway.
deedglass_witnesscan decode every table in its database (spike S1(h)); Deedglass asks only for the publication and stores only what it returns. Treat thewitness_dsnas a read-everything credential.
Changing what is watched
Section titled “Changing what is watched”Add to the publication first, then to watched_tables:
- Add the table to the connector’s config file under
witness.watched_tables(and, if agents may write it,writable_tables). - Run
deedglass connector postgres init --connector <name>: it plansREPLICA IDENTITY FULLandALTER PUBLICATION deedglass_pub ADD TABLE …. Review the plan and apply it. - Update the connector (
PATCH /v1/connectors/{id}with the new config). The decoder picks the new table up on its next read; a change committed before step 2 isn’t in the stream.
Removing a table is the reverse: drop it from writable_tables and watched_tables first, then from
the publication. Changing the publication while the decoder reads is safe but leaves a mark: on
Postgres 18, a change in the window can be skipped (publication_gap); on 16 and 17, dropping the
publication altogether halts the decoder (publication_missing) until the slot is dropped.
What this page doesn’t do
Section titled “What this page doesn’t do”It doesn’t cover the Gate’s own boundary (which tools an agent may call: GATE.md and the policy pages) or databases other than Postgres.