Skip to content

fix(strict_provenance): gate update1 inside make() (target + key consistency)#1480

Open
dimitri-yatsenko wants to merge 1 commit into
masterfrom
fix/strict-update1-gate
Open

fix(strict_provenance): gate update1 inside make() (target + key consistency)#1480
dimitri-yatsenko wants to merge 1 commit into
masterfrom
fix/strict-update1-gate

Conversation

@dimitri-yatsenko

Copy link
Copy Markdown
Member

The 2.3 post-release audit of the make-integrity gates found update1() was a fully ungated write path under strict_provenance: inside make(), SideTable.update1({...}) silently mutated any table past the provenance boundary (empirically demonstrated — value changed 100→999 with no error), while the same write via insert is blocked. The asymmetry was unintended: the boundary is "write only to self (and Parts)," and update1 is a write.

Fix

update1 now runs the same two checks as insert, placed before the existence check so a provenance violation raises as such rather than as "no matching entry":

  • assert_write_allowed(self, verb="update1 on") — target must be the make() target or one of its Parts. Blocked-update message: strict_provenance=True: update1 on '<t>' is not permitted inside make() for '<target>'. Only the target table and its Part tables may be written.
  • assert_row_key_allowed(row, action="update") — key columns overlapping the current key must match: strict_provenance=True: updated row's '<k>'=<v> does not match the current make() key's '<k>'=<v>. Updates must be consistent with the key being populated.

Both gate functions gain wording parameters; the insert-path messages are byte-identical to before (spec-verbatim preserved). No-op outside make() / flag off — update1 outside strict mode is unchanged (pinned by test).

Tests (4 new; strict suite 12/12, test_update1 4/4, both green locally)

  • blocked update1 on another table, with the target row verified untouched
  • blocked key-mismatched update1 on self (raises the key-consistency error deterministically)
  • allowed key-consistent update1 on self (corrective update within the boundary)
  • default-off parity

Companion docs update (write-enforcement table rows + limits-list adjustments) rides in the datajoint-docs post-audit reconciliation PR. delete()/delete_quick() remain ungated by design and are being documented as a limit there, per the audit decision.

…istency)

The 2.3 post-release audit found update1 was a fully ungated write path under
strict_provenance: inside make(), SideTable.update1({...}) silently mutated any
table past the provenance boundary (empirically demonstrated) while the same
write via insert is blocked. The asymmetry was unintended: the boundary is
'write only to self (and Parts)', and update1 is a write.

update1 now runs the same two checks as insert, before the existence check so a
provenance violation raises as such:

- assert_write_allowed(self, verb='update1 on') — target must be the make()
  target or one of its Parts; blocked-update message reads 'update1 on <t> is
  not permitted inside make() for <target>...'.
- assert_row_key_allowed(row, action='update') — key columns overlapping the
  current make() key must match; mismatch message reads 'updated row's ...
  Updates must be consistent with the key being populated.'

Both gate functions gain wording parameters; the insert-path messages are
byte-identical to before. No-op outside make() or with the flag off — update1
behavior outside strict mode is unchanged (pinned by a new test).

Tests: blocked update1 on another table (value verified untouched), blocked
key-mismatched update1 on self, allowed key-consistent update1 on self, and
default-off parity. Full strict suite 12/12; test_update1 4/4.

Companion docs update (write-enforcement table + limits) rides in the
datajoint-docs post-audit reconciliation PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant