From 8fe0ca427923cb128c12a061bdc9c0a6e40cbd92 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Fri, 2 Oct 2026 17:29:10 -0500 Subject: [PATCH 1/2] fix(provenance): capture defaults to off `provenance.capture` shipped defaulting to True, so upgrading to 2.3.4 would have changed the DDL of every Entry table declared afterwards. That is a deployment's decision, not a library default, and it left 2.3.4 as the only release on the 2.3 line that alters what an unchanged schema declares. It also makes the pair consistent: `jobs.add_job_metadata` already defaults to False for the same reason, and both add a hidden column at declaration. The platform turns capture on per project through the usual channels -- `DJ_PROVENANCE_CAPTURE`, the config file, or the secrets directory. Nothing else changes: a table declared with capture on still records on insert, and `deploy.add_prov_column` still retrofits one declared without it. --- src/datajoint/settings.py | 6 ++++-- tests/unit/test_provenance.py | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/datajoint/settings.py b/src/datajoint/settings.py index d99b2d8f7..9a185f821 100644 --- a/src/datajoint/settings.py +++ b/src/datajoint/settings.py @@ -323,9 +323,11 @@ class ProvenanceSettings(BaseSettings): ) capture: bool = Field( - default=True, + default=False, description="Add the hidden `_prov` attribute to Entry (dj.Manual) tables at declaration " - "and fill it on insert. Tables declared while this is False never receive the column; " + "and fill it on insert. Off by default, matching jobs.add_job_metadata: enabling it changes " + "the DDL of every Entry table declared afterwards, which is a deployment's decision rather " + "than a library default. Tables declared while this is False never receive the column; " "use datajoint.deploy.add_prov_column to add it to an existing table.", ) source: dict[str, Any] = Field( diff --git a/tests/unit/test_provenance.py b/tests/unit/test_provenance.py index c2c250fa6..c6b733ea0 100644 --- a/tests/unit/test_provenance.py +++ b/tests/unit/test_provenance.py @@ -120,9 +120,14 @@ def test_payload_survives_unserializable_key_values(config): assert rendered["context"]["key"]["who"] == "12345678-1234-5678-1234-567812345678" -def test_settings_defaults_to_capturing(): - """A slot nobody can rely on is a slot nobody codes against.""" - assert Config().provenance.capture is True +def test_settings_default_to_not_capturing(): + """Off by default, like `jobs.add_job_metadata`. + + Capture changes the DDL of every Entry table declared afterwards. A library + default that does that would make an upgrade to 2.3.4 alter what a schema + declares, so the deployment turns it on. + """ + assert Config().provenance.capture is False assert Config().provenance.source == {} From 5d30b16a3cceaa0da2b1380b54554ff66cfe1de4 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Fri, 2 Oct 2026 17:30:33 -0500 Subject: [PATCH 2/2] docs(deploy): add_prov_column's docstring assumed capture was on It said tables declared from 2.3.4 onward already carry the slot. With capture off by default the reverse holds: a table has the column only if it was declared while a deployment had capture on, which is what makes this function the normal path rather than a migration. --- src/datajoint/deploy.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/datajoint/deploy.py b/src/datajoint/deploy.py index 3aff87710..cf8189b92 100644 --- a/src/datajoint/deploy.py +++ b/src/datajoint/deploy.py @@ -190,10 +190,10 @@ def add_prov_column(target: "TargetType", dry_run: bool = True) -> dict: """ Add the hidden ``_prov`` attribute to Entry (``dj.Manual``) tables that lack it. - Capture defaults on, so tables declared from 2.3.4 onward already carry the - slot. Two populations do not: tables declared before 2.3.4, and tables - declared while ``config.provenance.capture`` was off. Inserts into those - record nothing, silently, and this brings them in line. + Capture defaults off, so a table carries the slot only if it was declared + while ``config.provenance.capture`` was on. Every other table -- declared + before 2.3.4, or before the deployment enabled capture -- records nothing on + insert, silently, and this brings it in line. It belongs here rather than in :mod:`datajoint.migrate` because it is not a one-shot correction of legacy state. It is idempotent — a table that already