Skip to content

Add safe individual-block actions for Content databases - #2781

Open
3mdistal wants to merge 23 commits into
mainfrom
codex/content-feedback-block-actions
Open

Add safe individual-block actions for Content databases#2781
3mdistal wants to merge 23 commits into
mainfrom
codex/content-feedback-block-actions

Conversation

@3mdistal

@3mdistal 3mdistal commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Problem

Content could replace a whole Blocks field, but an agent could not safely address one stable block without risking sibling content, losing concurrent UI edits, or replaying a retry.

What changes

This PR adds two actions for one exact database membership row, row document, and Blocks property:

  • list-content-database-blocks returns stable block IDs, canonical values, order, supported operations, and schema, row, and field revisions.
  • mutate-content-database-block performs one typed insert, update, upsert, delete, or same-parent reorder where the live block-kind capability matrix permits it.

Sparse mutations preserve sibling blocks and other fields. Field and row compare-and-swap checks reject concurrent edits without clobbering them. Durable idempotency receipts replay the original result for an exact retry and reject reuse of a key with a different payload. Accepted mutations refresh the UI and return the row link, revisions, affected/deleted IDs, resulting order, and verified read-back. Unsupported kinds and structural operations fail explicitly.

The mutation schema remains object-shaped at the action boundary so both Content actions register as agent tools, while operation-specific validation stays discriminated and strict.

Dependency and base refresh

PRs #2778 and #2779 are merged on main. This branch was rebuilt from d916772e506b713c6f425bccc86d95bac13da5cc, with both merge commits present, and PR #2781 now targets main directly. Its independently reviewable artifact is 18 Content-only files.

Three dependency overlaps were reconciled without changing the frozen contract:

  • _database-row-mutation.ts keeps merged row-mutation semantics and exports the substrate used here.
  • shared/blocks-field-identity.ts keeps merged field-scoped collision and tombstone behavior while accepting caller-supplied preferred IDs for block actions.
  • parity/matrix.md was regenerated from the reconciled source matrix.

Current main through 429ae6c416d99ffa0c1c012cf9bfa5f806647843 is merged. The later Content intake work overlapped only the generated parity matrix and agent-card registration test: the resolution preserves both action sets, combines both registration assertions, and regenerates the matrix from its merged typed source. The resulting prospective merge tree is conflict-free.

Verification

At exact head ed6faff33f4a336c025672cb4fab748030acf5cd:

  • 156 coupled mutation, row-substrate, stable-identity, lifecycle, migration, and agent-registration tests pass across 9 files. Repair-focused mutation coverage passes 38/38 on SQLite, and the exact block-action integration suite passes 8/8 on PostgreSQL, including a deterministic direct-title-write race.
  • The current official Content database suite passes 227/227, with the block-action file bringing the exact-head run to 234 passing plus one PostgreSQL-only case; Content parity passes 115/115; Core action/error coverage passes 170/170.
  • Isolated PostgreSQL 17.11 passes release migrations 15/15, row-mutation concurrency 13/13, and block actions 8/8.
  • Content TypeScript, all 53 repository guards, formatting, git diff --check, Content product records 14/14, and product-impact tests 30/30 pass.
  • All nine required current-head checks pass, alongside typecheck, security guards, Content PostgreSQL locking, trusted acceptance, and the remaining branch-relevant CI lanes.

An authenticated local real-interface fixture exercised exact list, insert, update, existing/new upsert, delete, and reorder; retry/dedupe and key-reuse rejection; field/row CAS and no-clobber; sibling and other-field preservation; receipts/link/read-back; unsupported-kind and outside-scope denial; and UI visibility after reload. The task-owned database QpCpr3bVGzE2, page l75u94Wlxx3v, row document FE17mvlCyLm4, and both block fields were action-deleted, independently read back as absent, verified at zero rows across all relevant SQL tables, and the isolated database directory and browser session were removed.

A bounded independent review found one cross-field preferred-ID race: persistence could remap a raced caller ID while the receipt retained the requested ID. The repair rejects cross-field remapping, maps database uniqueness races to BLOCK_ID_ALREADY_USED, and asserts the inserted ID survives verified read-back. A later forge review identified five additional in-contract gaps: multi-database primary sidecars, leaf insertion parents, direct title-write row CAS, replay receipts after later drift, and ignored positioning on an existing-block upsert. The exact-head repair synchronizes every primary sidecar, rejects leaf parents before serialization, locks the row document before revision validation, re-verifies every replay, and atomically applies existing-upsert content and position while preserving its stable ID. Focused tests cover each path; the Yjs and container-descendant claims were independently rejected against the established action refresh/reconcile and identity algorithms, with an added descendant-ID regression test. No frozen-contract drift was required.

A broad Content sweep also exposed two pre-existing unrelated failures outside this 18-file artifact: an obsolete row-upsert fixture shape and a Node 26 localStorage test assumption. They are not counted as green and are not repaired here; all official branch-owned suites above pass.

Boundaries

This PR does not add PR 4 routing/actor-history work, Slack or A2A behavior, provider calls, deployment, or production/canonical-data mutation.

Review focus

  • Stable identity and tombstone behavior across every supported operation.
  • Conflict/no-clobber behavior at row, field, and storage-target boundaries.
  • Truthfulness of retry receipts, resulting order, and verified read-back.
content_product_impact:
  lane: contract_fulfillment
  features:
    - content.feature.durable-foundations
  capabilities:
    - content.object.block
    - content.object.blocks-field
    - content.agent.action-parity
  record_change: included
  proof:
    - 156 coupled exact-head tests across mutation, identity, lifecycle, migration, and agent registration
    - official Content database 227/227 plus exact block-action coverage, Content parity 115/115, and Core action/error 170/170
    - isolated PostgreSQL migrations 15/15, row mutation concurrency 13/13, and block actions 8/8
    - authenticated disposable real-interface acceptance with independent cleanup proof
    - Content TypeScript, 53 repository guards, product records, product-impact tests, formatting, and exact-head CI
  rationale: This fulfills exact stable individual-block actions for Content database Blocks fields while preserving PR 4 routing and actor-history scope.

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@3mdistal
3mdistal changed the base branch from codex/content-feedback-block-actions-base to main August 14, 2026 16:58
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@3mdistal 3mdistal changed the title Add exact Content database block actions Add safe individual-block actions for Content databases Aug 14, 2026
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@3mdistal
3mdistal marked this pull request as ready for review August 14, 2026 17:37
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes and found 5 potential issues 🔴

Review Details

Code Review Summary

PR #2781 adds a substantial, well-scoped action surface for listing and mutating individual Blocks in an exact Content database row/property. The implementation has good foundations: typed operation discrimination, field/row/schema revisions, durable receipt storage, scope checks, stable identity reconciliation, and extensive SQLite/PostgreSQL-oriented tests. I classified this as standard risk because it introduces shared data-mutation and concurrency behavior, though it does not change authentication or payment paths.

Key Findings

  • 🔴 HIGH — Primary document-body mutations bypass the live collaboration document, allowing an open editor to remain stale and later overwrite the agent's committed change.
  • 🔴 HIGH — Mutating one document-backed primary Blocks property can leave sibling primary-field identity sidecars stale when the same document belongs to multiple databases.
  • 🟡 MEDIUM — Leaf blocks are accepted as insertion parents even though serialization cannot retain nested block children.
  • 🟡 MEDIUM — The advertised row revision check is only a pre-write read and is not protected by a CAS shared with other row writers.
  • 🟡 MEDIUM — Idempotent receipt replay bypasses current-state verification and can return stale data marked as verified.
  • 🟡 MEDIUM — Replacing a container can recreate unchanged descendant IDs, breaking stable references.

The overall action contract is thoughtfully explicit and the test coverage is unusually broad; the findings are concentrated at the boundary between SQL persistence, collaborative editor state, and identity/revision bookkeeping.

🧪 Browser testing: Will run after this review (PR touches UI code)

Comment thread templates/content/actions/_database-block-actions.ts Outdated
markdown: string,
now: string,
) {
if (loaded.storageTarget === "document_body") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Synchronize primary Blocks mutations with the live collaboration document

writeMarkdown updates documents.content directly for the primary Blocks field, but the Content editor uses a live Yjs document and does not observe raw SQL writes. An open editor can remain stale and later persist its old state over this successful, verified mutation; route the write through the collaboration-aware path or publish an equivalent post-commit synchronization update.

Additional Info
Found by 4/4 review agents; two classified this high and two medium, so severity normalized to medium per majority voting.

Fix in Builder

Comment thread templates/content/shared/database-block-mutations.ts
Comment thread templates/content/actions/_database-block-actions.ts
Comment thread templates/content/actions/_database-block-actions.ts Outdated
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

builder-io-integration[bot]

This comment was marked as outdated.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

builder-io-integration[bot]

This comment was marked as outdated.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes — no new findings

Review Details

Incremental Code Review Summary

The latest PR head expands the test coverage and repairs the previously reported existing-upsert positioning behavior. The new implementation also adds direct editor-race coverage, leaf-parent rejection coverage, and PostgreSQL title-write concurrency coverage. I reviewed the complete shuffled diff with four independent agents and found no new confirmed regressions beyond the already-open primary document-body collaboration issue, which was intentionally not reposted.

The earlier upsert-position comment was verified fixed and has been resolved. Focused mutation and identity suites report 38 passing tests with one PostgreSQL-only case skipped in some environments; one agent also noted that broader typecheck is environment-blocked by production configuration validation rather than a code diagnostic.

Risk remains standard because this is shared Content data-mutation and concurrency logic. Existing concerns around live collaboration synchronization remain visible to the author and are not duplicated here.

🧪 Browser testing: Will run after this review (PR touches UI code)

@3mdistal
3mdistal requested a review from steve8708 August 14, 2026 18:56
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