Skip to content

feat(serenity): publish-after-populate finalize on the sub-workspace path (LLMO-5492)#2873

Open
andreeastroe96 wants to merge 1 commit into
mainfrom
feat/LLMO-5492-deferred-publish-subworkspace
Open

feat(serenity): publish-after-populate finalize on the sub-workspace path (LLMO-5492)#2873
andreeastroe96 wants to merge 1 commit into
mainfrom
feat/LLMO-5492-deferred-publish-subworkspace

Conversation

@andreeastroe96

Copy link
Copy Markdown

What & why

LLMO-5492 — publish-after-populate for Serenity projects.

This re-targets #2584 onto main's sub-workspace onboarding surface. #2584 was built against the flat-mode POST /llmo/onboard markets[] fan-out, which is superseded on main — Serenity onboarding now runs through brand-create / /serenity/activate / /serenity/markets (provisionBrandSubworkspacehandleCreateMarketSubworkspace), which already publishes inline after populate. The deferred-publish mechanism didn't exist on main; this PR ports it and wires it into the sub-workspace create path.

Scope

  • SERENITY_DEFER_PUBLISH flag (defer-publish-active.js, default OFF → behavior-preserving). When ON, provisionBrandSubworkspace uses publishMode: 'skip' so each project is left a draft for a later finalize step. Flag OFF preserves the existing require/best-effort logic byte-for-byte.
  • handlers/finalize.jsfinalizeSerenityProjects: push prompts (publish deferred) → set models per slice → publish each project once, with populate gates (noPrompts/noModels) so an empty project never goes live, and a bounded publish-status confirm within the Lambda budget.
  • handlers/publish-status.js: classifyPublishStatus + pollProjectPublished (bounded confirm; the unbounded ≤900s reconcile stays the DRS/worker's job). Enum aligns with the existing subworkspace-projects.js mapPublishStatus.
  • rest-transport.getProjectStatus for the publish-completion read.
  • handleCreatePrompts / handleUpdateModels gain a { publish } option so finalize can batch a single publish. Default true keeps the standalone-endpoint contract; syncModelsForProject already supported the switch.
  • ERROR_CODES.PUBLISH_QUOTA_EXHAUSTED for the disguised-405 no-quota rejection (classified via main's isMeteredQuota).

Deferred / out of scope

  • The DRS-completion trigger that calls finalizeSerenityProjects lives in a separate repo (audit-worker/DRS) — intentionally not wired here; this is the reusable mechanism it will call.
  • The unbounded reconcile poll — also the worker's job.

⚠️ One review item

rest-transport.getProjectStatus currently passes query: { draft: 'false', type: 'ai' } (mirroring the existing getProject). #2584's design note calls for the v1 default view to read a never-published draft's publish_status faithfully, and warns the live view can distort it. getProject defaults to draft: true. Please confirm the correct draft value against the Semrush project-read semantics before merge — this is the one behavior I couldn't verify from the code alone.

Tests

New/extended unit tests (all green; lint + type-check gates pass): finalize.test.js (12), publish-status.test.js (13), plus { publish: false } cases for handleCreatePrompts / handleUpdateModels, getProjectStatus transport, and PUBLISH_QUOTA_EXHAUSTED. Full serenity unit suite: 1028 passing.

🤖 Generated with Claude Code

…path (LLMO-5492)

Re-targets the #2584 deferred-publish work onto main's sub-workspace
onboarding surface (the flat-mode /llmo/onboard fan-out it was originally
built against is superseded by the sub-workspace model on main).

- SERENITY_DEFER_PUBLISH flag (default OFF, behavior-preserving): when ON,
  brand-provisioning leaves each project a draft (publishMode 'skip') for a
  later finalize step instead of publishing inline at create.
- handlers/finalize.js finalizeSerenityProjects: push prompts (publish
  deferred) -> set models per slice -> publish each project once, with
  populate gates (noPrompts/noModels) and a bounded publish-status confirm.
- handlers/publish-status.js: classifyPublishStatus + pollProjectPublished
  (bounded confirm; the unbounded reconcile stays the DRS/worker's job).
- rest-transport getProjectStatus for the publish-completion read.
- handleCreatePrompts / handleUpdateModels gain a { publish } option so the
  finalize step can batch a single publish (inline publish preserved by default).

The DRS-completion trigger that calls finalizeSerenityProjects lives in a
separate repo and is intentionally out of scope; this is the reusable
mechanism it will call.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.52000% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/support/serenity/handlers/finalize.js 99.11% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

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