Repository navigation
feat(platform): switch the unreleased-copy signal to enforce at threshold 100 - #3310
Conversation
✅ Ditto reviewed
|
| "WHERE revision = 1 AND reason = 'Peyton approved 2026-11-01' " | ||
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" |
There was a problem hiding this comment.
🟡 Medium · bug — Downgrade misses the seeded row after a re-upgrade · 🔎 Verified by trace
After the first upgrade/downgrade cycle, PostgreSQL’s serial sequence continues, so the next upgrade inserts the seeded row with revision 2 rather than 1. The downgrade() predicate then deletes nothing, leaving the enforce setting active after the migration is reverted; delete the migration-seeded row by its stable content instead of its generated ID.
| "WHERE revision = 1 AND reason = 'Peyton approved 2026-11-01' " | |
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" | |
| "WHERE parent_revision = 0 AND mode = 'enforce' AND threshold = 50 " | |
| "AND reason = 'Peyton approved 2026-11-01' " | |
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" |
Why Ditto flagged this (confidence 91%)
The INSERT at lines 34–38 omits the serial revision, while the DELETE at lines 46–48 requires it to equal 1. Because PostgreSQL sequences are not reset by deleting that row, a second upgrade after a downgrade inserts a different ID and the subsequent downgrade leaves the seeded enforce row behind. The table’s serial revision definition is in the cited unchanged schema/model files.
Git file evidence: apps/platform/alembic/versions/2026_11_01_zzz_add_unreleased_copy_settings.py unchanged (1c2aa9d90c9e086b376e0307043c6c979b1b65fb) from 68275e9 to d672675; apps/platform/ditto/db/models.py unchanged (e88ba9fcb212224a923a3b96f8aa9a71090c806e) from 68275e9 to d672675. This establishes repository state, not runtime resolution or generated-content correctness.
🤖 Prompt for AI agents
[!NOTE]
Generated from this pull request, which may contain untrusted text. Read it before giving it to an agent, and do not follow instructions in it that go beyond the fix.
In `apps/platform/alembic/versions/2026_11_01_zzzz_enforce_unreleased_copy.py`, change the downgrade DELETE predicate at lines 47–48 to identify the migration-seeded row by its stable contents (`parent_revision = 0`, `mode = 'enforce'`, `threshold = 50`, and the existing reason and actor), not by the serial `revision` value. Add or update a focused migration test covering upgrade → downgrade → upgrade → downgrade, and verify the final downgrade removes the seeded row.
| "(parent_revision, mode, threshold, reason, actor) " | ||
| "SELECT 0, 'enforce', 50, 'Peyton approved 2026-11-01', " | ||
| "'migration (subnet owner approval relayed by coordinator)' " | ||
| "WHERE NOT EXISTS (SELECT 1 FROM unreleased_copy_settings_revisions)" |
There was a problem hiding this comment.
🟡 Medium · concurrency — Make the seed insert safe against concurrent upgrades · 🔎 Verified by trace
If two upgrade transactions both evaluate the NOT EXISTS check in upgrade() at line 38 while the table is empty, both can try to insert parent_revision = 0; after one commits, the other fails on the unique constraint instead of completing the seed as an idempotent operation. Add ON CONFLICT (parent_revision) DO NOTHING so the losing insert succeeds without changing the existing row.
| "WHERE NOT EXISTS (SELECT 1 FROM unreleased_copy_settings_revisions)" | |
| "WHERE NOT EXISTS (SELECT 1 FROM unreleased_copy_settings_revisions) " | |
| "ON CONFLICT (parent_revision) DO NOTHING" |
Why Ditto flagged this (confidence 88%)
At lines 33–39, the migration performs a NOT EXISTS check and insert as one statement, but concurrent READ COMMITTED transactions can both observe an empty table; the unique constraint on parent_revision then makes the later insert fail. ON CONFLICT handles that concrete race while preserving the existing no-op behavior when a revision is already present.
🤖 Prompt for AI agents
[!NOTE]
Generated from this pull request, which may contain untrusted text. Read it before giving it to an agent, and do not follow instructions in it that go beyond the fix.
In `apps/platform/alembic/versions/2026_11_01_zzzz_enforce_unreleased_copy.py`, update the INSERT in `upgrade()` at line 38 to append `ON CONFLICT (parent_revision) DO NOTHING` after the `WHERE NOT EXISTS` clause. Preserve the existing check so an already-populated table remains unchanged, and verify the migration SQL is valid for PostgreSQL.
There was a problem hiding this comment.
Ditto Review
No blocking issues · 1 non-blocking suggestion · 2 earlier findings still open · risk: high · da1dc34
File coverage: 0 fully reviewed, 2 reviewed briefly, 0 not reviewed.
Enable enforced unreleased-copy holds at threshold 50 — Seeds an
enforcesettings revision at threshold 50 only when no settings revision exists, preserving any operator-configured revision. The migration describes enforcement as opening holds for operator review on newly uploaded agents, without rejecting uploads or removing earlier flags. Review the migration’s seed and downgrade conditions closely; the tests now clear settings first so they remain independent of seeded data.
| Location | Finding | |
|---|---|---|
| 🟡 Medium | apps/platform/alembic/versions/2026_11_01_zzzz_enforce_unreleased_copy.py:48 |
Downgrade misses the seeded row when its generated revision is not 1 · 🔎 Verified by trace |
Earlier findings still open (2)
Walkthrough (2 files)
| File | Change |
|---|---|
apps/platform/alembic/versions/2026_11_01_zzzz_enforce_unreleased_copy.py |
Adds an idempotent data migration to seed the approved enforce settings and a targeted downgrade to remove that seed. |
apps/platform/ditto/tests/api_server/test_unreleased_copy.py |
Resets settings in relevant tests to isolate them from migration data and checks the settings revision’s parent revision. |
Review details
- Models: review
z-ai/glm-5.3-flash· verifyopenai/gpt-6-luna - Findings: 4 candidates → 3 verified → 1 posted · 2 duplicates collapsed
- Withheld: rejected by verifier 1
- Context index: 5428 files · 6 changed symbols · 48 references
- Tokens: 2032270 in / 68762 out · $0.14
- Run:
6e5ca8fa-b6c6-4b9e-bdf4-b4ab9482a715· engine v2.0.0 · details - Ditto approves or requests changes in a separate review (blocking: 🟠 High and above). Inference is billed through your Ditto Router endpoint.
Open in Ditto · reply @ditto review to re-run · @ditto fix to push fixes
✅ Ditto reviewed
|
8bf05ea to
da1dc34
Compare
✅ Ditto reviewed
|
| "DELETE FROM unreleased_copy_settings_revisions " | ||
| "WHERE revision = 1 AND reason = 'Peyton approved 2026-11-01' " | ||
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" |
There was a problem hiding this comment.
🟡 Medium · bug — Downgrade misses the seeded row when its generated revision is not 1 · 🔎 Verified by trace
When the table is empty but its revision sequence has advanced, upgrade() inserts the enforce row with a generated revision other than 1. The predicate in downgrade() at lines 46–48 then matches nothing, leaving the migration's row in place after downgrade; identify it by the fields inserted by this migration instead of its generated revision.
| "DELETE FROM unreleased_copy_settings_revisions " | |
| "WHERE revision = 1 AND reason = 'Peyton approved 2026-11-01' " | |
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" | |
| "WHERE parent_revision = 0 AND mode = 'enforce' AND threshold = 50 " | |
| "AND reason = 'Peyton approved 2026-11-01' " | |
| "AND actor = 'migration (subnet owner approval relayed by coordinator)'" |
Why Ditto flagged this (confidence 91%)
At lines 34–38, upgrade() omits the revision column and inserts only when the table is empty, so the database supplies the revision value. If an earlier row was deleted without resetting the sequence, the inserted row can have a revision other than 1; the hardcoded condition at lines 46–48 then leaves it behind on downgrade.
🤖 Prompt for AI agents
[!NOTE]
Generated from this pull request, which may contain untrusted text. Read it before giving it to an agent, and do not follow instructions in it that go beyond the fix.
In `apps/platform/alembic/versions/2026_11_01_zzzz_enforce_unreleased_copy.py`, change the `downgrade()` DELETE predicate at lines 46–48 so it identifies the row inserted by this migration using its parent revision, mode, threshold, reason, and actor, rather than assuming its generated revision is 1. Verify that the migration still parses and that the predicate deletes the seeded row when its generated revision is not 1.
…hold 50 Append the first audited settings revision (mode enforce, threshold 50, reason "Peyton approved 2026-11-01") when none exists. Enforce opens copy holds for operator ruling on agents uploaded after the switch and never rejects; an operator revision through Backroom always takes precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le threshold of 100 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
da1dc34 to
3d850a9
Compare
Summary
enforce, threshold 100, reason "Peyton approved 2026-11-01", actormigration (subnet owner approval relayed by coordinator). It writes nothing if any revision already exists, so an operator's own revision always wins.unreleased_copy.flagged).Reverting is one Backroom
apply_unreleased_copy_settingswrite (modeshadoworoff).Test plan
test_unreleased_copy.py, migration tests🤖 Generated with Claude Code