Skip to content

feat(metadata): draft/package lifecycle for publish-as-preview (overlay reads, teardown, discard, delete) - #1569

Merged
xuyushun441-sys merged 4 commits into
mainfrom
worktree-draft-overlay-preview
Jun 3, 2026
Merged

feat(metadata): draft/package lifecycle for publish-as-preview (overlay reads, teardown, discard, delete)#1569
xuyushun441-sys merged 4 commits into
mainfrom
worktree-draft-overlay-preview

Conversation

@xuyushun441-sys

@xuyushun441-sysxuyushun441-sys commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Backend for the draft/package lifecycle behind "publish-as-preview" (ADR-0033 review loop) — drafts as a first-class state for both humans and the AI. Five composable capabilities, each independently tested.

1. Draft-overlay reads (previewDrafts)

Render the console (or let the AI discover) pending drafts before publish. getMetaItems/getMetaItem overlay state='draft' on active (draft wins; draft-only surfaces; _draft:true tag); dispatcher threads ?preview=draft.

2. Storage teardown on delete (dropStorage)

Object storage was create-only — delete left an orphan table. engine.dropObjectSchema → driver dropTable; deleteMetaItem({dropStorage}) DESTRUCTIVE/opt-in, gated (object+active only, never sys_); DELETE /meta/:type/:name?dropStorage=true.

3. discardPackageDrafts — abandon edits, revert to baseline

NON-destructive: drops only draft rows. POST /packages/:id/discard-drafts. "Edited a while, it's worse — abandon all changes."

4. deletePackage — remove an unwanted package entirely

DESTRUCTIVE: all package rows + object tables (keepData=true preserves tables). DELETE /packages/:id now does this persisted removal (was registry-only). "Don't want this package anymore."

5. AI authoring is draft-aware + package-aware (Fix 4)

Found while verifying the process guardrail:

  • list_objects/list_metadata were active-only → the agent couldn't find an object it just drafted when authoring a flow for it. Now pass previewDrafts:true (reusing Add metamodel interfaces for ObjectQL/ObjectUI contract #1, the unifying mechanism).
  • apply_blueprint now surfaces a top-level packageId + bindingHint so the agent binds the follow-up flow to the app package instead of orphaning it.

Why this shape (design note)

True data preview of a brand-new draft object is hard (no table until publish; the platform had no drop-table teardown at all). Chosen approach: cheap draft-overlay for structural/AI discovery, and lean on publish (into a dev sandbox) for data-level confirmation — made safe by reversible item teardown + package discard/delete. Admin-gating ?preview=draft is a deliberate follow-up. See docs/notes/draft-overlay-preview-plan.md.

Tests

protocol-meta (overlay), protocol-publish-rollback (teardown), protocol-package-lifecycle (discard/delete), metadata-tools + blueprint-tools (Fix 4). Full objectql green (519); service-ai green (one pre-existing env-dependent embedder test aside). Dispatcher/rest typecheck clean.

Pairs with objectui#1472 (Discard/Delete buttons) and framework#1570 (process guardrail).

🤖 Generated with Claude Code

…review
ADR-0033's loop is build(draft) -> review -> publish, but review was only a
JSON diff; the rendered object page / kanban / form / nav that actually
confirms a change only existed AFTER publish. This adds a request-scoped
draft-overlay read mode so an (admin) reviewer can render the console off
pending drafts before publishing:
- getMetaItems({previewDrafts}) overlays state='draft' rows on active (draft
wins; draft-only surfaces; never hydrates the SchemaRegistry).
- getMetaItem({previewDrafts}) is non-strict: draft if present, else active
(vs strict state:'draft' which 404s no_draft).
- overlaid items tagged _draft:true for UI badging.
- dispatcher threads ?preview=draft on GET /metadata/:type[/:name].
Admin gating of the flag is a deliberate follow-up (step 2). The same overlay
also unblocks the AI agent referencing its own drafts (follow-up).
Tests: protocol-meta draft-overlay (draft wins, draft-only, _draft, getMetaItem
fallback) + full objectql sweep green (509).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 3, 2026 11:58am

Request Review

Object storage was create-only: publish creates a table, but deleteMetaItem
only tombstones the metadata row, leaving the physical table behind. That made
"publish an object just to preview it with data, then discard" leave residue.
- engine.dropObjectSchema(name): inverse of syncObjectSchema; calls the driver's
existing dropTable.
- deleteMetaItem({dropStorage}): opt-in, DESTRUCTIVE, guarded — object + active
only, never sys_; default false keeps delete non-destructive. Best-effort.
- REST: DELETE /meta/:type/:name?dropStorage=true.
Makes "publish to preview -> discard" cleanly reversible (the chosen approach:
lean on publish-into-dev for data confirmation, made safely undoable).
Tests: deleteMetaItem teardown (drops for object+active; not by default; not
sys_; not non-object) + objectql sweep green (513).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuyushun441-sysxuyushun441-sys changed the title feat(metadata): draft-overlay reads (previewDrafts) for pre-publish preview [PR1/backend]feat(metadata): draft-overlay reads + storage teardown (publish-as-preview backend)Jun 3, 2026
});

it('does not drop storage for a non-object type even with dropStorage', async () => {
const { engine, rows } = makeStubEngine();
…rd / delete)
Two distinct package-level operations on the per-item delete primitive:
- discardPackageDrafts(packageId): drop only pending DRAFT rows, revert to the
published baseline. NON-destructive (active metadata + tables untouched).
"I edited this app a while, it's worse than before — abandon all changes."
sys_metadata path (no metadata-service dep, unlike POST /packages/:id/revert).
REST: POST /packages/:id/discard-drafts.
- deletePackage(packageId): remove ALL package rows (active + draft) + tear down
each object's table by default (DESTRUCTIVE; keepData:true preserves tables,
sys_ guard still applies). "I don't want this package anymore."
DELETE /packages/:id now also does this persisted removal (previously only the
in-memory registry unregister, leaving AI-package rows + tables behind);
?keepData=true opts out of teardown.
Drafts deleted before active so each table is dropped once; per-item failures
collected without aborting. Tests: orchestration for both + objectql sweep (519).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuyushun441-sysxuyushun441-sys changed the title feat(metadata): draft-overlay reads + storage teardown (publish-as-preview backend)feat(metadata): draft/package lifecycle for publish-as-preview (overlay reads, teardown, discard, delete)Jun 3, 2026
…kageId (Fix 4)
Two gaps that broke the multi-step "build app -> author a flow for it" path
(found verifying the solution_design guardrail):
1. AI couldn't discover its own draft objects: list_objects/list_metadata read
getMetaItems active-only, so a just-drafted object was "not found" when the
agent then authored a flow against it. They now pass previewDrafts:true
(older runtimes ignore the flag -> stay active-only). describe was already
draft-first.
2. The auto-authored flow had no package to bind to: apply_blueprint now
surfaces a top-level packageId + bindingHint so the agent passes it to
create_metadata and the flow lands in the app package, not an orphan draft.
Makes the guardrail's "model data, then proactively draft the approval flow
bound to the app" executable end-to-end. service-ai suite green (ai-service
embedder test fails only locally — env-dependent, untouched).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuyushun441-sys
xuyushun441-sys merged commit ac1fc4c into mainJun 3, 2026
12 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the worktree-draft-overlay-preview branch June 3, 2026 14:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@xuyushun441-sys@github-advanced-security@os-zhuang