Marketing Operations composition
The data-only root describes implemented capabilities and required host ports.
./server exposes createMarketingOperationsServer and ./mcp exposes
registerMarketingMcpTools. Both use the same canonical operation registry.
./site-mcp owns the public marketing site MCP surface that the contractspec.io and CompanyOS hosts serve at /api/marketing-mcp. It binds the three Growth site operations (marketing.product.get, marketing.plans.compare, marketing.demo.book) from
lib.growth-spec to their lib.growth-runtime handlers, and exposes the framework-neutral JSON gateway (executeMarketingTool, bounded SlidingWindowRateLimiter), the MCP 2024-11-05 JSON-RPC dispatcher (handleMcpJsonRpc) and the embedded-agent config (createMarketingChatConfig). Product facts and plan comparison are public reads;
demo.book is default-deny without an authenticated user (UNAUTHENTICATED at the MCP transport gate, FORBIDDEN from the PDP) and limited to its contract rpm. Hosts keep the request body cap, trusted client IP, session lookup and feature flag. The
./site-mcp/marketing-agent-config, ./site-mcp/marketing-mcp and
./site-mcp/marketing-registry subpaths expose the individual modules. This
registerMarketingMcpTools takes a tool-context factory for the public site tools; the
./mcp export of the same name mounts the authenticated operations registry. The surface replaces the deprecated @lssm-tech/lib.contracts-runtime-server-mcp/marketing* subpaths with the same exports.
./ui/MarketingWorkspace exposes the localized goal-to-plan interface. It displays questions, assumptions and proposed actions, with host-owned detailed action review. It does not execute a model's suggestions. onPropose binds to authenticated host transport; the optional controlled proposal prop can be refreshed by the host.
Supply planning dependencies to the server to enable durable, contract-validated goal proposals at /marketing/plans/propose and /marketing/plans/get. Inference requires scoped approval and idempotent cost authorization. A proposal request ID is reserved before calling the model, so retries do not buy another generation. Every step must match a registered/allowed operation and pass host resource validation. The full composition now exposes 39 REST/MCP operations with every optional service configured.
scripts/preview.ts serves a synthetic browser QA fixture on loopback only. It is not a production deployment and never invokes a model or payment/ad provider.
Supply a durable MarketingExecutor, MarketingCopyGenerator, and an authorized brief loader through MarketingOperationsDependencies. The host context resolves the authenticated actor, tenant, workspace, PDP, and shared approval runtime. Execution and copy generation declare cost-bearing effects and require scoped approval receipts before their handlers run. The executor independently checks the plan digest, mandate, current rights, provider qualification, and provider state.
There is no default authority, credential, in-memory production store, or advertising provider. Hosts must mount this with the same isolation controls in managed and self-hosted deployments. This package is a server composition foundation; a complete standalone UI, creator migration, campaign-provider certification, and production deployment are not yet delivered.
The new API endpoints are declared in lib.growth-spec/marketing/operations:
POST /marketing/executions
POST /marketing/executions/reconcile
POST /marketing/executions/continue
POST /marketing/copy
Supply the optional editorial host dependency to bind ten standard operations under
/marketing/editorial: create, revise, submit, review, schedule, archive, publish, reconcile, get and due. Recovery is an additional operation when the store supports it. Their declarations live in
lib.growth-spec/marketing/editorial-operations. Editorial and advertising authority are independent. REST tests cover authentication, tenant/workspace substitution, storage effects and publication/copy approval gates.
Supply optional creators dependencies to bind eleven canonical creator operations under /creator-operations. This brings the combined registry to 24 operations. The creator store is transactional, agreements are immutable, and every settlement rail consumes the same wallet reservations. Runtime approval and provider evidence are still required; mounting the module does not enable production payouts.
See the repository Marketing Operations implementation status for remaining work.
./advertising composes Meta, Google and TikTok HTTP providers with the durable recipe executor and marketing reservation engine. Supply recipe/receipt stores, current request and recipe authority, a reviewed compiler and a read-only reconciler. No constructor sends requests or enables spend. Launch compilation supports typed Meta, Google Search/Display/Demand Gen/Performance Max and TikTok plans; campaign controls support pause/resume against a checked provider-state digest. The continuation operation reauthorizes pending work without reserving the same budget again.
The advertising compiler composition also supports reviewed budget adjustments and creative replacement. Configure AdvertisingCampaignCompiler with the launch, control, budget and creative compilers. The host loads immutable change documents and exact native resource mappings; the execution plan must reference their digests in reviewed evidence.
Utiliser createMarketingConversions from ./advertising to compose the conversion service with scoped providers, durable storage, current consent authority and read-only recovery. Supply it as the server's optional conversions dependency to mount three operations at
/marketing/conversions/deliver, /reconcile and /get. Delivery requires its own approval. The original registry remains unchanged when the optional service is absent.
createMarketingObservations from ./advertising composes native read providers with a required evidence store, current scope authority and immutable snapshot storage. Supply it as the optional observations server dependency for /marketing/observations/refresh
and /get. Results separate review/eligibility/configuration and include a stable state digest. Source mappings must verify each native resource belongs to the scoped campaign.
./social exports createMarketingSocialScheduling, which composes durable schedules with the existing social publication runtime. Its default remains draft-only. Configure SQL schedule/intent/lease ports, current signed grant verification, policy/audit ports, qualified LinkedIn/X providers and an explicit publication autonomy mode. Pass the result as optional socialScheduling to mount eight schedule operations. Register the worker with the existing lifecycle scheduler and persist each batch result.
Live LinkedIn/X publishing, account access and media formats still require qualification; the local scheduling tests use simulated provider effects.
Configure the optional scoped LinkedIn publisher under
publicationPorts.providersV2.linkedin. The SQL scheduling composition preserves its creation URN and confirms through tenant/account/author-bound reads. Hosts supply approved materialization, ready assets, qualified LinkedIn contexts and credentials. Provider qualification and media upload pipelines remain installation work.
Configure the scoped X publisher in publicationPorts.providersV2.x with a durable
SqlXPublicationStore, qualified materialization, current per-part grant/metering checks and exact-request recovery evidence. The scheduler reconciles uncertain thread parts before resuming only unsent work. Configure the native upload composition below for new media; live account qualification remains separate from mocked transport tests.
For X media, compose XNativeUploadProvider with SqlXUploadStore before materializing reviewed publication. The uploaded-asset projection returns the native ID/key only after processing succeeds and before expiry. SQL integration tests cover uploaded video through scheduling and native attachment confirmation. Live qualification remains host-owned.
LinkedIn image/video uploads can use LinkedInMediaJobRuntime, SqlLinkedInMediaJobStore
and LinkedInSecretSessionVault. Supply a versioned secret backend, exact native recovery receipts and authorized immutable asset reads. Project ready media into the existing publication materializer with current rights checks. Standalone worker wiring and live qualification remain separate requirements.
./installation exposes createMarketingOperationsInstallation for both deployment modes. Supply the canonical server, explicit worker mode and readiness checks. Concurrent starts/stops share lifecycle work, partial startup rolls back registrations, and failed cleanup can be retried. Public probes reveal only liveness/readiness. Mutations from a foreign browser origin are rejected; canonical operation approval checks remain intact.
./workers adapts the existing durable social scheduler into a registration that stops new callbacks and drains active batches. Registrations must clean up resources they create if startup fails before returning a stop handle. The thin app.marketing-operations shell binds HTTP before starting workers and loads trusted deployment composition from a module. A turnkey installation, standalone frontend and managed provisioning remain incomplete.
./ui/planning-client exposes createMarketingPlanningBrowserClient; use it with
./ui/ConnectedMarketingWorkspace. The host supplies an authenticated actor/scope/brand binding, same-origin fetch and an exact-input approval callback. The browser binding is a cache partition, never server authorization. No receipts or goal text are persisted in browser storage. Identical actor/intent/goal/context produces the same durable request ID, including after a lost response or client recreation. Set a new intentRef only for an explicitly separate generation.
Check progress calls the canonical read operation without inference approval. Responses must match the original request before rendering; switching scope remounts the workspace and clears previous visible results. Detailed review/execution remains host-owned. The standalone authenticated bootstrap and approval experience are not yet wired by default.
Supply optional workspace to register the authenticated /marketing/workspace query. Its brand selector is resolved against the current actor, tenant and workspace; the loader must authorize access and return the approved brand revision. Bootstrap returns no credentials or execution grants. The full optional composition exposes 40 operations.
BootstrappedMarketingWorkspace loads that query before creating the planning client. Change its sessionKey on login/logout or session changes to clear the previous view. The optional server approvalReceipt callback adapts transport evidence; the existing context approvalPort still decides whether that evidence authorizes execution.
PlanningApprovalReview displays a host-issued exact-input planning quote, maximum cost and expiry. Its controlled callback invokes the existing issuer; the component never mints receipts. Expired quotes cannot be approved, duplicate clicks are locked, and uncertain callback failures require status resolution rather than blind retry. The quote issuer and production approval workflow remain installation requirements.
ReviewedMarketingWorkspace composes authenticated bootstrap, planning and quote review. Provide a MarketingPlanningApprovalGateway backed by the existing server authority; quote/issue/status must bind the actor, exact input, maximum cost and expiry. Issuance must be idempotent by quote ID. The UI controller resumes the waiting planning call only with the returned receipt, rejects quote substitution and uses read-only status recovery after uncertain issuance. Change sessionKey on principal changes; unmount discards local waiting without claiming to revoke durable receipts. Production gateway routes and issuer configuration remain required.
Configure optional planningApproval to mount quote, issue and status operations at
/marketing/planning-approvals/* (43 operations with all optional services). The injected authority must authorize brand access, persist quotes, verify explicit human review and issue scoped receipts idempotently by quote ID. Authentication alone is insufficient.
createMarketingPlanningApprovalGateway implements the browser transport; supply host CSRF/step-up handling through its fetch callback. Issuance/status receipt outputs are marked transient and redacted by operation contracts. No permitting issuer is supplied.
The planningApproval host port can now use MarketingPlanningApprovalService with SqlPlanningApprovalStore. Configure pricing, brand authorization and explicit human review verification. Wire createOperationApprovalPort with the service's verifyEvidence and the SQL store as nonceStore; never use the verifier's permissive evidence default. Human authentication, quote pricing and reviewer evidence still require host integration.
Utiliser withMarketingPlanningApproval(host, {service, nonceStore}) from
./planning-approval-host to install the durable planning verifier and receipt decoder. It requires both persisted evidence and the supplied nonce store, rejects malformed or unrecognized receipt headers, and preserves existing approval handling for other operations. The resulting host can be passed directly to createMarketingOperationsServer.
Supply metricReports to expose /marketing/metrics/report and the matching MCP query. The loader must authorize brand/campaign access, authoritative source and freshness policy. The module rejects foreign tenant/workspace scope before loading observations. The complete optional registry now contains 44 operations. Missing periods remain unavailable in the returned report, with provenance and explicit reasons.
./optimization wraps the existing self-improvement lifecycle effect port for acquisition economics or creator performance. Configure the exact program and marketing scope plus an authorized immutable evidence loader. Promotion requires matching candidate artifact, program revision and experiment scope, then an eligible marketing assessment. Existing authority/gates still decide whether the effect may run. Inconclusive evidence and guardrail failure block promotion; rollback/kill behavior remains available. This does not qualify statistical methods or install autonomous provider effects by itself.
Marketing optimization composition also requires recordEvidence: persist the exact readout/assessment document idempotently and return its SHA-256 artifact reference. The wrapper verifies that reference before effects and appends it to the lifecycle receipt. A failed or mismatched evidence write blocks promotion.
Lifecycle integration tests drive acquisition and creator programs through shadow, canary, observation, an inconclusive promotion hold, qualified promotion, replay and regression rollback. Assessment artifacts use the SQL store; candidate lifecycle state and effects remain simulated. This is not live statistical or production qualification.
The optimization lifecycle scenarios now use SqlMarketingOptimizationLifecycleStore for candidate state/history and SqlMarketingOptimizationEvidenceStore for assessments. Both initial programs pass shadow/canary/observation/promotion/replay/rollback paths with durable SQL state. External effect transports remain simulated and require qualification.
createMarketingWithdrawalWorker from ./withdrawal-worker binds withdrawal processing to the installation worker lifecycle. Supply authorized durable pending-use discovery and a durable result observer; scope-bound scheduler IDs isolate installations. Batches are bounded, overlapping local ticks are skipped, and shutdown stops new work and drains active callbacks. The ContentWithdrawalWorker retains provider claims/reconciliation.
The scheduled withdrawal integration test now uses SqlContentWithdrawalQueue for both discovery and result tracking. Completed uses disappear from subsequent batches without manual queue edits, while unresolved items retain fair attempt ordering. Provider effects and installation authorization remain simulated in this test.
Supply contentRights to expose grant/use/revoke/get/withdraw operations at
/marketing/rights/*, bringing the full optional registry to 49 operations. Scope checks precede service access; grant recording and provider removal require operation approval. Rights service authorization and durable native withdrawal remain independently required.
withMarketingRightsPreflight wraps existing advertising authority with current rights checks for declared grants. The resolver must bind the exact reviewed plan/assets to registered-use IDs and the authorized actor. Every grant must be covered by an active use on the advertising channel with paid-amplification permission. Existing budget, provider-state and qualification checks still run. Pause remains available after revocation; this wrapper is not a lease over later provider dispatch.
Supply creatorTraining to mount /creator-operations/training/open and /update. The full optional registry now exposes 51 operations. The injected service owns course access, quiz evidence validation and transactional request replay; mounting does not migrate Hirly records or replace its current training writer.
Optional creatorTrainingProgress mounts the read-only training summary query at
/creator-operations/training/progress and MCP. Missing state returns not_started
without progress initialization. Full optional composition now has 52 operations.
Optional creatorQuizCompletion mounts /creator-operations/training/quiz/complete
and its MCP command. Input contains answers and expected training version, never a claimed score. Private-key authorization/scoring and durable progress replay remain in the injected completion service. Full optional composition now contains 53 operations.
Optional creatorQuizView mounts the authorized public quiz-read operation at
/creator-operations/training/quiz/get. Strict response validation rejects private answer-key fields and mismatched revisions. Full optional composition has 54 operations. The loader must enforce creator/course enrollment and requested locale.
createMarketingEditorialWorker invokes due discovery and publication through the canonical registry. Its host context callback supplies exact-input approval evidence for each publication; no background authority is inferred. Result observation is required, local overlapping ticks are suppressed, and shutdown drains the active batch. Unknown publication reconciliation remains a separate existing operation, not a blind retry.
Configure a separate editorial worker with mode: "reconcile" to discover and reconcile persisted unsettled publications. minimumAgeSeconds defaults to 60 (30–86400 allowed); publication remains the default worker mode. Recovery requires the optional store-backed recovery operation and current reconcile authority. Both modes drain on stop, and explicit stop closes dispatch before scheduler unregistration.
editorial-restart.test.ts rehearses interrupted terminal persistence and database reopening through the recovery scheduler. It preserves publication identity and provider receipt without redispatch; provider responses remain simulated.
createNativeEditorialGitCompiler adapts an existing strict native compiler and its application readiness function to the shared Git compiler port. Supply an authorized approved-source loader, compileNative, and publicationState. It binds the exact requested title/body/locale/canonical URL to one compiled edition, verifies the returned receipt against native edition digests and configured locales, then packages unchanged Markdown sources and the approved publication manifest. The Hirly rehearsal script exercises its current compiler and source-derived readiness projection without changing its deployment.
createGitEditorialModule from ./git-editorial composes the editorial publication service, durable Git publisher, native GitHub transport and HTTP deployment verifier. Assign its result to the marketing server’s optional editorial host field. Supply migrated editorial/Git stores, native compiler, IDs/clock, and separate domain/artifact/repository/deployment authorization functions; construction performs no network activity. The composition test uses both SQL stores and native GitHub/HTTP adapters with simulated HTTP responses, retaining unknown state until deployment readiness is confirmed.
Feed GitHubEditorialSourceLoader.load(record) into the native compiler’s approved-source callback, adding installation-native compiler options and its returned publicationManifest. The returned target preserves the reviewed sourceCommitSha. The Hirly rehearsal now covers the loader, native compiler and readiness projection together using simulated pinned GitHub reads.
The native compiler always receives the complete source snapshot. Optional approved commitPaths control only the emitted mutations, must include the requested edition, and cannot name unrelated files. Tests cover a 145-edition cohort, its initial 146-file artifact, and a six-file incremental artifact.
Git editorial installations expose editorial_resume_preparation through the canonical registry. Operators must approve the exact claim and expected revision; supported recovery preserves the claim and cannot repeat an existing Git dispatch.
The clean packed-consumer check now installs the complete marketing bundle dependency closure and runs on Bun and Node without source aliases. It exercises Git editorial composition, exact-input preparation-resume approval and durable compiler rejection. docs/evidence/marketing-operations/packed-consumer.json records the tested archive and projected-manifest fingerprints; this is not an npm publication claim.
Editorial-capable SQL installations expose paginated summary discovery. HTTP tests verify no-store responses, scope rejection and unavailable-capability behavior.
./ui/EditorialWorkspace provides a connected, read-only editorial workspace with contract-driven filters, cursor pagination and localized EN/FR/ES chrome. Supply an authorized scope, a non-secret sessionKey that changes with the actor session, and optionally onOpen for a custom host detail route. Fetching defaults to the same-origin API. Late responses are ignored after filters or sessions change; errors never masquerade as empty results. Keyboard pagination moves focus into newly loaded records. Schedules are explicitly displayed in UTC. EditorialWorkspaceView is available for controlled hosts.
loadEditorialRecord from ./ui/editorial-detail-client fetches the current revision through the canonical same-origin detail endpoint. It checks tenant/workspace/brand, record identity and the content digest before returning data; callers must still use the returned revision for subsequent mutations.
EditorialWorkspace now opens its verified read-only record panel by default; an optional onOpen callback preserves custom host navigation. Selection/session changes cancel prior detail requests. Opening focuses the record heading; returning preserves collection state and focuses the workspace heading. Loading and denied states hide prior content. EditorialRecordPanel and EditorialRecordView are separately available for host composition.
The clean-consumer probe includes current-record retrieval and French detail rendering from built exports, including the Markdown block-nesting regression check.
saveEditorialRevision submits one expected-revision edit attempt, verifies the returned draft/digest and invalidated approvals, and never retries uncertain writes. After an unknown outcome, load the current record before another save.
EditorialEditorController preserves local draft text during save conflicts and uncertain outcomes. It blocks another write until recovery reads current state and the operator explicitly adopts a conflicting revision. Disposal ignores late responses. The controller is not yet mounted in editor controls.
EditorialEditFields renders the canonical title/Markdown form through the design-system form renderer and EN/FR/ES translation context. It merges edited text with host-supplied verified provenance. Mount it only during editable controller phases; save/recovery controls remain host composition.
Editable record states now expose the integrated editor. Save/recovery phases preserve local text, show remote conflicts before explicit adoption, and block closing during active saves. Returning with unsaved text requires an explicit discard choice. Unknown saves recover via a verified read; the form never retries the write automatically.
Editor state guards also reject terminal publications when invoked directly. Recovery cannot reopen a record that became published elsewhere; local text remains available for comparison. A 375px browser rehearsal verified direct saving without overflow or console warnings.
Draft and changes-requested detail panels now offer Submit for review. The client sends the expected revision once, verifies the returned in_review state and unchanged content, and requires a refresh after an uncertain result. This action does not approve or publish content.
Submission qualification includes a REST/SQL concurrency test (one accepted revision, one conflict) and a browser lost-response rehearsal that recovers in_review via refresh without resubmitting.
recordEditorialReview records an explicit supplied review decision/evidence against the current in-review digest and revision. It never mints authority receipts, retries uncertain writes or treats a returned approval with altered evidence as success.
Pass optional prepareReview to EditorialWorkspace/EditorialRecordPanel to expose two-step review decisions. The installation supplies reviewer identity, digest-bound evidence and authority receipt; the UI displays those before an explicit confirmation. Preparing evidence performs no mutation. Unknown writes remain held until record refresh; installations without the callback do not expose review decisions.
Disposed review controllers now discard prepared evidence and refuse confirmation. Shared controller lifetime handling tolerates React StrictMode effect replay while disposing actual unmounts and replaced controllers.
Review REST/SQL qualification verifies denied evidence authority, mismatched reviewer identity and concurrent opposing decisions. One decision is persisted with its evidence; the competing request receives a revision conflict and no publication is created.
Review browser qualification covers prepare/cancel, explicit changes-requested/approval decisions, mobile evidence inspection and heading focus after the persisted revision changes. Test authority is synthetic; installations still supply production review evidence.
scheduleEditorialRecord schedules one approved revision through the canonical API, preserving review evidence and verifying exact destination/time in the response. The server owns clock and destination authority; unknown outcomes require read recovery rather than write retries.
Scheduling REST/SQL qualification verifies destination denial, server-clock rejection of past schedules, concurrent-request exclusion, review preservation and appearance in due discovery only at the scheduled time.
Supply optional loadDestinations to the workspace/panel to expose scheduling for approved records. The callback receives the verified record and returns authorized destination IDs/labels. The form rejects ambiguous local time strings and sends explicit UTC. Server time and current destination authority remain authoritative; uncertain saves require refresh.
Scheduling browser checks verify destination option labels, controlled initial fields and the exact saved UTC timestamp/destination in record details. The supplied destination label is mapped to the form renderer labelI18n property.
publishEditorialRecord requires an opaque exact-input approval receipt supplied by the installation. reconcileEditorialPublication uses the separate recovery endpoint without implying new publication authority. Both verify scope/content/claim/destination bindings; publication success requires provider receipt and public URL. Clients never retry writes automatically.
Publication-client qualification now exercises canonical REST approval validation and SQL claim persistence: unrecognized receipts fail before dispatch, a reused nonce permits one attempt, and a lost provider response recovers through reconciliation without publishing again.
Supply optional approvePublication to expose two-step publication on scheduled records. The installation receives the canonical operation/input plus the reviewed record, and returns an opaque execution receipt. The UI keeps the receipt out of rendered state, requires explicit confirmation and never retries an uncertain write. Publishing/unknown records expose reconciliation separately.
Publication browser qualification covers cancel-before-dispatch, explicit confirmation to an uncertain result, and separate reconciliation to visible provider proof. The preview uses synthetic state responses; real clock, approval and SQL dispatch checks are covered separately.
Publication response validation also requires lifecycle/claim-status agreement and definitive failure receipts. An unchanged revision may only return the identical record; contradictory or unversioned state changes remain uncertain.
createEditorialDraft requires a stable caller-owned ID and verified content/provenance input. It sends one create request and checks the returned initial draft. After uncertainty, read the same ID; repeated creation returns conflict rather than allocating another draft.
EditorialCreateController owns one immutable creation intent, coalesces creation attempts and resolves uncertainty with a read of the original ID. Recovery checks content and assignee before adopting the record; conflicting content remains a conflict and no automatic replacement ID is allocated.
Optional prepareDraft enables workspace creation. The installation returns a complete creation intent with stable ID and provenance. Operators inspect the title/body/ID before confirming. Uncertain creation remains attached to that ID with read recovery; opening is offered only after confirmed or matching recovered creation.
Creation browser qualification verifies prepared-content preview, original-ID retention after a lost response, read recovery and opening revision 1 with no console warnings. The preview backend is synthetic.
The clean-consumer probe now exercises create → revise → submit → review → schedule → approved publication → reconcile using public clients, the canonical REST handler, and SQL history. Bun and Node both finish at revision 8 with eight history rows, one provider dispatch and one recovery read.
archiveEditorialRecord retires an unpublished revision without deleting content/history. The client rejects published and uncertain publication states, validates schedule removal and retained review evidence, and never retries uncertain writes.
Eligible record details now offer archival with a separate confirm/cancel step explaining schedule removal and retained history. Published, publishing, uncertain and already archived records show no archive action. Unknown writes stay held until refresh.
Archive browser qualification confirms cancellation leaves the draft unchanged, confirmed archival preserves inspectable content, and editing/publication actions disappear in archived state. Focus returns to the record heading.
Returning from integrated record details refreshes the collection from its first cursor while preserving selected filters. Records changed by review/scheduling/archival no longer remain visible under stale filter membership.
loadEditorialHistory validates each historical revision, identity, digest and continuation cursor before returning it. Missing or skipped revisions are reported as unavailable rather than silently shown as complete history.
Record details include on-demand revision history. The history panel fetches bounded authorized pages and opens a clearly labeled read-only historical detail without mutation actions. It only selects revisions present in the fetched page and discards late responses after disposal.
History browser checks verify original content after edits, read-only inspection and focused historical headings. Revision rows use compound record/revision identities and record action/history sections have distinct React keys.
The additive content-generation.media.status v1 query exposes persisted generation state, revision, artifact references and expected output count through
POST /marketing/media/status and MCP media_generation_status. It never polls providers or dispatches generation. Installations supply an authorized reader; the marketing host mounts it only when configured. Tenant, workspace and generation ownership are checked before returning progress. Provider URLs, connection keys and payment reservation references stay private. Existing draft generation operations retain their behavior.