← All frames
Flow 3 · Creator ownership · Frame (e) · app detail (/apps/:appId)

Owner & creator

“Org-held, user-originated.” The block always leads with the owner — the organization — because that never changes when people do. Below it, the creator: name and contact while they're a current member of the owning org, or just “former member” once they've left. It is information, not a permission: nothing in this block grants or shows authority.

(e1) Org app, creator is a current member — name + contact

Ownership

Owner
Acme CorpOrganization · owns this app
Creator
Dana Levi Created this app · contact for questions about it
Contact
dana.levi@acme.example
(e2) Creator left the org — “former member”, no name, no contact; the app stays with the org

Ownership

Owner
Acme CorpOrganization · owns this app
Creator
Former member The person who created this app is no longer in Acme Corp.
Contact
Contact an Acme Corp admin.
(e3) Personal app — the viewer is owner and creator

Ownership

Owner
Your personal workspaceOnly you can see and manage it
Creator
You
(e4) creator: null — registered before attribution, or by a service — owner only

Ownership

Owner
Acme CorpOrganization · owns this app
Creator
Not recorded
(e5) Flag OFF — creator fields absent from the DTO, so the block is not rendered

App detail renders without an Ownership section. No placeholder, no “unknown creator” — absence of createdBy/creator in the response means the capability isn't on, not that the creator is missing.

(e6) Loading — part of the app-detail fetch

Data. App.organizationId → owner (resolved to a name from the caller's organization list; a personal org renders as “Your personal workspace”). App.creator (AppCreator): isCurrentMember: true → displayName + contact; false → “Former member”, and the UI must not render any name or contact even if one were present. creator: null → “Not recorded”. The block shows only while fuzefront.apps.creator-ownership is ON and the response carries the creator key.
Contract gap — commissioned by approval. AppCreator in app-registry 1.2.0 carries displayName but no contact channel. Frame (e1)'s Contact row needs an additive AppCreator.contactEmail (returned under the same rule as displayName: only while isCurrentMember). Until contract-designer lands it (1.3.0, minor), the UI renders the name and omits the Contact row — never a guessed address.
Not authority. Who can edit/activate/publish comes from Permit (App#creator, org roles) and governs which controls render elsewhere. This block never shows roles and never offers transfer — a contact change is an admin role grant, out of scope for these frames.
Test hooks: [data-frame='05-creator-ownership'] · [data-panel='app-ownership'] · [data-field='owner'] · [data-creator-state='current-member'] · [data-field='creator-name'] · [data-action='contact-creator'] · [data-creator-state='former-member'] · [data-field='creator-former'] · [data-creator-state='self'] · [data-creator-state='none'] · [data-flag-state='off'] · [data-state='loading'].

← Outcomes & errorsPublish to marketplace →
Review · app-builder approve or reject each flow ↓
build-entrypendingApproveReject
build-sessionpendingApproveReject
creator-ownershippendingApproveReject
marketplace-publishpendingApproveReject