Stamped on every row this run touches, so "when did we last see this" is answerable.
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.
Copy the declared columns back over this connection's row so discovery overlays a CURRENT declaration rather than its own previous output. Returns the columns that actually moved, for the merge log. A row with no declared match (an object that exists only for this connection) has nothing to rebase from and is left alone.
DISABLE, never delete — unlike the object above.
The delete rule is dictated for TABLES and only tables: plan.md says "for tables only, if its not there after discovery algorithm, just removes it", and again "columns that are in MJC already never get removed, tables maybe if discovery objects doesnt find them, NEVER columns".
The reason is in everything.txt: "sometimes, a column may be missing. If that is the case, then it doesnt automatically conclude the column no longer exist ... typically just may mean there is no more values". A column absent from one sample is absent from a SAMPLE, not from the source. Deleting the row destroys what only this connection knows about it — the observed width, the provenance, the selection state — so the next sample that does see it starts from nothing instead of reactivating. Disabling keeps all of it and reverses itself on rediscovery, which is what the shared catalog has always done.
A field DOES get deleted when its OBJECT is removed; that cascade lives in RetireObject and is the table rule, not this one.
Delete, not disable — see the interface comment.
Order matters and there is no ON DELETE CASCADE in the migration (deletes are deliberately explicit, so nothing disappears as a side effect of an unrelated write):
RelatedCompanyIntegrationObjectID is self-
referencing, so another object's field may point at this one; deleting underneath it
would violate that FK and abort the whole persist. Nulling drops the edge and keeps the
referencing field alive, which is right — the field still exists in the source, only
the thing it pointed at is gone.The field counterpart of StampNewObject.
A new per-connection object records the connection it belongs to, the declared row it was matched to (null when the object exists only for this connection — the case the shared catalog cannot represent at all), where its shape came from, and when it was first seen.
IsSelected starts FALSE. Catalog membership is not sync selection, and keeping them apart
is the point of the table: conflating them is why a newly-discovered object arriving disabled
disappeared from schema introspection, key inference and migration, with no error anywhere.
One connection's own catalog.