MJ-CAT-21 — an EXISTING per-connection row has just been matched to a declaration. Rebase it, and record that it is now a declared row rather than one this connection merely found.
The second half is the load-bearing one. A field this connection discovered BEFORE the
connector declared it keeps MetadataSource = 'Discovered', and decidePKPromotion reads
exactly that to rule that a declared primary key cannot include it — so a rebase on its own
sets IsPrimaryKey and has it demoted again a few statements later, which is precisely how
PheedLoop 1.4.6's new eventCode key reached a connection's catalog as an ordinary column.
A row that now has a declaration is no longer merely discovered.
Not StampNewField: that one also clears IsSelected and resets FirstSeenAt, which would
deselect a table the customer chose and forget when the field first appeared.
Shared writers no-op — there the row IS the declaration, and writing provenance onto it would be writing it onto itself.
Lowercased ids of the given objects that already carry a primary key, from one two-column
scan per 200 owners. The classify stage used to load every object's fields as entity
objects just to ask some(IsPrimaryKey); the keyed majority needs nothing else.
Record that this row was seen — and optionally sampled — by the discovery now running.
Reset the connector-DECLARED columns of an existing row from the declared definition, before discovery overlays it.
plan.md: a refresh uses IO/IOF as the source of truth and REPLACES what is in CIO/CIOF, because the per-connection row is a projection, not an accumulator. Without this an open-app upgrade that changes a declared APIPath or page size never reaches a connection that has already discovered once. Shared writers no-op: there the row IS the declaration.
The field counterpart of StampNewObject.
Write the columns saying who a newly-created object belongs to and where its shape came from. A no-op on the shared catalog beyond the integration id, which is the only ownership it has.
Reads and creates for one catalog, scoped to whatever "this connector" means for it.
ObjectsInScopedeliberately returns rows of EVERY status. Disabled rows are load-bearing: an object the source dropped is disabled rather than deleted, and if it reappears the overlay must find and reactivate that row. Matching active rows only would attempt a second row with the same name and hit the unique constraint instead.These read straight from the database rather than the engine cache, deliberately. The cache is refreshed between discovery passes, not within one, so the write path must be able to see rows a previous pass of the SAME run just persisted. It is also what makes the per-connection catalog writable at all: its cached rows are read-only projections with no
Save().