Skip to content

UIAP Authoring/Manifest

FieldValue
StatusDraft
Version0.1
Date2026-03-27
Dependencies[UIAP-CORE], [UIAP-CAP], [UIAP-WEB], [UIAP-ACTION], [UIAP-POLICY], [UIAP-WORKFLOW]
EditorsPatrick

The key words MUST, MUST NOT, SHOULD, MAY in this document are to be interpreted as described in RFC 2119 and BCP 14, when and only when they appear in ALL CAPS.


UIAP Authoring/Manifest Spec v0.1 defines how UIAP artifacts for an application are structured, versioned, composed, validated, and published.

The specification governs in particular:

  • Package structure and package metadata
  • Manifest types for app, bindings, actions, policies, workflows, localization, and discovery import
  • Imports and reuse
  • Overlays and environment overrides
  • Review and provenance model
  • Versioning and compatibility
  • Build and release model

This specification builds on:

  • UIAP Core v0.1
  • UIAP Capability Model v0.1
  • UIAP Web Profile v0.1
  • UIAP Action Runtime Spec v0.1
  • UIAP Policy Extension v0.1
  • UIAP Workflow Extension v0.1
  • optionally UIAP Discovery Mapper Spec v0.1

It does not define the wire transport at runtime, but rather the authoritative source from which runtime bundles and releases are built.


  1. Authoring manifests are the source of truth for published UIAP packages.
  2. Discovery artifacts are input, but not automatically truth.
  3. Overlays and imports MUST be deterministically resolvable.
  4. Review status MUST be machine-readable.
  5. Build outputs MUST be normalized and reproducible.
  6. Runtime should not read loose authoring files but rather compiled bundles.
  7. Semantics and IDs must be stable. Humans love to “clean things up later”. Protocols less so.

Authoring documents use a common envelope format.

interface UIAPAuthoringDocument<TSpec = unknown, TStatus = unknown> {
apiVersion: "uiap.authoring/v0.1";
kind: AuthoringKind;
metadata: ManifestMetadata;
spec: TSpec;
status?: TStatus;
}
type AuthoringKind =
| "Package"
| "App"
| "Capabilities"
| "Bindings"
| "Actions"
| "PolicySet"
| "WorkflowCatalog"
| "LocalePack"
| "Overlay"
| "ReviewSet"
| "DiscoveryImport";
interface ManifestMetadata {
id: string; // unique within package
title?: string;
description?: string;
version?: string; // optional for sub-manifests, required for Package
packageId?: string;
labels?: Record<string, string>;
tags?: string[];
owners?: OwnerRef[];
source?: "manual" | "generated" | "mixed" | "imported";
reviewState?:
| "draft"
| "generated"
| "in_review"
| "approved"
| "rejected"
| "deprecated";
}
interface OwnerRef {
id: string;
role?: "owner" | "maintainer" | "reviewer" | "approver";
contact?: string;
}
  1. metadata.id MUST be unique within a package.
  2. Package manifests MUST set metadata.version.
  3. Sub-manifests MAY omit metadata.version if they inherit the package version.
  4. reviewState describes the domain-level approval status, not merely whether JSON is syntactically pretty.

A UIAP package is the smallest versioned and publishable unit.

interface PackageManifest {
packageId: string;
version: string; // semver-like
profile: string; // e.g. "[email protected]"
compatibility: CompatibilitySpec;
imports?: PackageImport[];
manifests: LocalManifestRef[];
build?: BuildSpec;
publish?: PublishSpec;
}
interface CompatibilitySpec {
uiapCore: string; // e.g. ">=0.1 <0.2"
profiles: string[]; // e.g. ["[email protected]"]
extensions?: Array<{
id: string;
range: string;
required?: boolean;
}>;
sdk?: {
web?: string;
};
appVersions?: string[]; // semver-like ranges or fixed strings
}
interface PackageImport {
packageId: string;
versionRange: string;
alias: string;
include?: {
kinds?: AuthoringKind[];
manifestIds?: string[];
};
}
interface LocalManifestRef {
id: string;
kind: Exclude<AuthoringKind, "Package">;
path: string;
required?: boolean;
}
  1. A package MUST have exactly one Package manifest.
  2. A package MUST provide exactly one App manifest, either directly or via import plus overlay.
  3. A package MAY contain multiple Bindings, Actions, PolicySet, WorkflowCatalog, and LocalePack manifests.
  4. Imported manifest IDs MUST be namespaced via alias:id.
  5. Local manifest IDs MUST NOT collide with imported fully qualified IDs.

The App manifest describes the target application as an authoring-side entity.

interface AppManifest {
appId: string;
displayName: string;
profile: string; // typically "[email protected]"
defaultLocale?: string;
supportedLocales?: string[];
environments?: AppEnvironment[];
principalProfiles?: AppPrincipalProfile[];
routing?: AppRoutingConfig;
sdk?: AppSDKConfig;
metadata?: Record<string, unknown>;
}
interface AppEnvironment {
id: string; // e.g. "dev", "staging", "prod"
baseUrls?: string[];
labels?: Record<string, string>;
}
interface AppPrincipalProfile {
id: string; // e.g. "workspace-admin"
roles?: string[];
grants?: string[];
description?: string;
}
interface AppRoutingConfig {
mode?: "history" | "hash" | "custom";
routeProviderRef?: string;
}
interface AppSDKConfig {
annotationPrefix?: string; // RECOMMENDED: "data-uiap-"
routeProviderRef?: string;
overlayEnabled?: boolean;
}

Wraps or supplements the formal Capability Model.

interface CapabilitiesManifest {
document: CapabilityDocument;
}
  • This manifest MAY be fully maintained manually or derived from actions/bindings.
  • Build systems SHOULD produce an error or at least a review warning when conflicts exist between Capabilities and Actions/Bindings.

Describes routes, scopes, and elements in authoritative form.

interface BindingsManifest {
routes?: RouteBinding[];
scopes?: ScopeBinding[];
elements?: ElementBinding[];
}
interface RouteBinding {
id: string;
match: RouteMatcher[];
title?: AuthoredText;
parentRouteId?: string;
successSignals?: SuccessSignal[];
metadata?: Record<string, unknown>;
}
type RouteMatcher =
| { kind: "routeId"; value: string }
| { kind: "path"; value: string }
| { kind: "urlPattern"; value: string }
| { kind: "title"; value: string }
| { kind: "signal"; value: string };
interface ScopeBinding {
id: string;
kind: ScopeKind;
routeIds?: string[];
parentScopeId?: ScopeId;
title?: AuthoredText;
stableIds?: StableId[];
metadata?: Record<string, unknown>;
}
interface ElementBinding {
id: StableId;
scopeId?: ScopeId;
routeIds?: string[];
role?: UIRole;
name?: AuthoredText;
meaning?: string;
match: ElementMatcher[];
risk?: RiskLevel;
dataClasses?: DataClass[];
defaultAction?: ActionId;
success?: SuccessSignal[];
metadata?: Record<string, unknown>;
}
type ElementMatcher =
| { by: "annotation"; attr: string; value: string }
| { by: "semantic"; role?: UIRole; name?: string; scopeId?: ScopeId }
| { by: "label"; text: string }
| { by: "text"; text: string }
| { by: "adapter"; id: string }
| { by: "runtimeHint"; css?: string; xpath?: string };
  1. annotation and semantic SHOULD be preferred over runtimeHint.
  2. runtimeHint.css and runtimeHint.xpath MAY be used, but SHOULD NOT be the only robust identity for critical targets.
  3. ElementBinding.id MUST remain stable even when DOM structures change.

Describes primitive and domain-specific actions plus implementation references.

interface ActionsManifest {
actions: AuthoredAction[];
}
interface AuthoredAction extends ActionDescriptor {
implementation?: ActionImplementationRef;
selectors?: ManifestSelector[];
}
interface ActionImplementationRef {
kind: "sdkHandler" | "serverAction" | "externalDriver" | "none";
ref?: string; // e.g. "app.actions.createVideo"
}
  1. ActionDescriptor.id MUST be unique within the package.
  2. Domain actions SHOULD reference an implementation.
  3. sdkHandler is the preferred form for direct app actions.
  4. none is only permissible for purely declarative or not-yet-implemented candidates with corresponding review status.

Describes one or more applicable policy documents.

interface PolicySetManifest {
policies: ScopedPolicyDocument[];
}
interface ScopedPolicyDocument {
id: string;
selector?: ManifestSelector;
document: PolicyDocument;
}
  • Multiple policies MAY coexist.
  • Selectors determine when they are active.
  • Conflicts MUST be resolved deterministically. Default rule: the stricter policy wins.

Contains versioned workflow definitions.

interface WorkflowCatalogManifest {
workflows: AuthoredWorkflow[];
}
interface AuthoredWorkflow {
selector?: ManifestSelector;
review?: WorkflowReviewHints;
definition: WorkflowDefinition;
}
interface WorkflowReviewHints {
level?: "draft" | "candidate" | "approved";
highRisk?: boolean;
generatedFromDiscovery?: boolean;
}
  1. Workflow IDs MUST be unique within the package.
  2. Generated workflows SHOULD NOT automatically flow into production channels unless they have been reviewed or released via waiver.
  3. Workflows MAY be supplemented or restricted via overlays, but not silently reinterpreted semantically.

Defines reusable texts.

interface LocalePackManifest {
namespaces: Record<string, LocaleNamespace>;
}
interface LocaleNamespace {
messages: Record<string, LocaleMessage>;
}
interface LocaleMessage {
default: string;
byLocale?: Record<string, string>;
}

Authoring sources MAY use references instead of LocalizedText:

type AuthoredText =
| LocalizedText
| {
ref: string; // e.g. "workflow.video.first.title"
fallback?: string;
};
  1. Build systems MUST resolve AuthoredText into normal LocalizedText or string output.
  2. Missing locale keys SHOULD fall back to fallback or defaultLocale.
  3. Missing required texts MUST appear at minimum as a review warning.

Allows environment-, tenant-, channel-, or role-specific modifications.

interface OverlayManifest {
selector: ManifestSelector;
patches: ManifestPatch[];
}
interface ManifestSelector {
environments?: string[];
channels?: ReleaseChannel[];
locales?: string[];
tenantIds?: string[];
principalProfiles?: string[];
appVersionRanges?: string[];
}
type ManifestPatchOp =
| "replace"
| "merge"
| "append"
| "remove"
| "upsert";
interface ManifestPatch {
manifestId: string; // local or alias:id
path: string; // JSON Pointer
op: ManifestPatchOp;
matchKey?: string; // only for upsert
value?: unknown;
}
  • replace: replaces value at path
  • merge: deep-merge for objects
  • append: appends to arrays
  • remove: removes target
  • upsert: inserts into or updates arrays of objects by matchKey
  1. Overlays MUST be applied after imports and before the final build.
  2. When multiple overlays match, the order SHOULD be deterministic, by default following the manifest order within the package.
  3. Conflicts on the same path MUST either be resolved deterministically or flagged as a build error. Silent overwriting is the kind of “feature” that costs months later.

Carries review decisions, waivers, and approvals.

interface ReviewSetManifest {
decisions: ReviewDecision[];
waivers?: ReviewWaiver[];
}
interface ReviewDecision {
target: ReviewTarget;
state: "approved" | "rejected" | "needs_review";
by: string;
at: string;
comment?: string;
}
interface ReviewWaiver {
target: ReviewTarget;
reason: string;
by: string;
at: string;
expiresAt?: string;
}
interface ReviewTarget {
manifestId: string;
path?: string;
itemId?: string;
}
  1. ReviewSet does not alter domain content, only the approval status.
  2. Expired waivers MUST NOT count for production releases.
  3. Build pipelines SHOULD evaluate review gates from both ReviewSet and PublishSpec.

Brings discovery results into authoring in a controlled manner.

interface DiscoveryImportManifest {
source: {
runId?: string;
ref?: string; // file path, URI, or package ref
};
accept: DiscoveryAcceptanceRule[];
reject?: DiscoveryRejectionRule[];
}
interface DiscoveryAcceptanceRule {
kind:
| "route"
| "scope"
| "element"
| "action"
| "workflowCandidate"
| "reviewItem";
ids?: string[];
targetManifestId: string;
mode?: "copy" | "promote" | "link";
}
interface DiscoveryRejectionRule {
kind:
| "route"
| "scope"
| "element"
| "action"
| "workflowCandidate"
| "reviewItem";
ids?: string[];
reason?: string;
}
  1. Discovery imports MUST be explicit.
  2. Discovery artifacts MUST NOT automatically become productive without acceptance rules.
  3. promote means: discovery content is transferred into an authoritative manifest.
  4. link means: discovery remains evidence, not source.

Imported manifests are namespaced in the build with an alias:

<alias>:<manifestId>

Example:

base:actions.core
shared:workflow.onboarding.common
  1. alias MUST be unique within the package.
  2. Imported manifests MAY only be referenced via fully qualified IDs.
  3. Local manifests MUST NOT implicitly override imported content.
  4. Modifications to imported manifests occur only via Overlay or deliberate forking.

A build MUST handle these steps in exactly this order:

  1. Load package
  2. Resolve imports
  3. Load local manifests
  4. Apply discovery imports
  5. Apply overlays
  6. Resolve locale references
  7. Apply review status
  8. Validate references
  9. Generate normalized bundle
  10. Check publish gates
  • Exactly one effective App document after merge
  • Objects deep-merge
  • Lists deduplicated by stable identity
  • routes, scopes, elements merged by id or stableId
  • Conflicts in match definitions SHOULD require review
  • Merged by action.id
  • Incompatible implementation refs MUST produce an error or review warning
  • Policies consolidated
  • Selection and prioritization remain a policy concern
  • Merged by definition.id
  • Same ID + different structure = conflict, unless an overlay explicitly addresses it
  • Merged by namespace + message key + locale
  • Decisions applied to targets
  • Later decisions MAY override earlier ones but SHOULD be audited

interface BuildContext {
environment?: string;
channel?: ReleaseChannel;
locale?: string;
tenantId?: string;
principalProfile?: string;
appVersion?: string;
}

A build MUST always be resolved against an explicit or implicit context.


type ReleaseChannel =
| "dev"
| "staging"
| "canary"
| "prod"
| "deprecated";
interface PublishSpec {
defaultChannel?: ReleaseChannel;
channels: ReleaseChannelSpec[];
}
interface ReleaseChannelSpec {
name: ReleaseChannel;
selectors?: ManifestSelector[];
requiredReviewState?: "approved" | "in_review" | "draft";
allowWaivers?: boolean;
forbidGeneratedOnly?: boolean;
requireDigest?: boolean;
}
  1. prod SHOULD require requiredReviewState = "approved".
  2. prod SHOULD use forbidGeneratedOnly = true.
  3. canary and staging MAY have more lenient review gates.
  4. The publish specification MUST be checked before bundle output.

status is optional, but practically unavoidable for real teams.

interface ManifestStatus {
provenance?: ProvenanceRecord[];
warnings?: string[];
digest?: string;
}
interface ProvenanceRecord {
source: "manual" | "discovery" | "import" | "generated" | "runtime-trace";
ref?: string;
note?: string;
at?: string;
}
  • Authoritative content SHOULD include provenance.
  • Discovery-based fields SHOULD traceably reference a run, evidence, or import.
  • Build systems SHOULD be able to derive review obligations from provenance.

Package.spec.version MUST be semver-like.

A major bump SHOULD occur when:

  • IDs are changed incompatibly
  • Workflow or action semantics become incompatible
  • Policy behavior changes in stricter or more lenient ways with relevant runtime impact
  • App or profile compatibility breaks

A minor bump SHOULD occur when:

  • New workflows, bindings, actions, or policies are added additively
  • New localizations are added
  • Overlays are additively extended

A patch SHOULD occur when:

  • Only texts, review metadata, or harmless corrections are adjusted
  • No wire or runtime semantics are materially changed

Runtime and SDK SHOULD consume a compiled bundle.

interface UIAPCompiledBundle {
packageId: string;
version: string;
profile: string;
buildContext: BuildContext;
compatibility: CompatibilitySpec;
app: AppManifest["spec"];
capabilities?: CapabilityDocument;
bindings?: BindingsManifest["spec"];
actions?: AuthoredAction[];
policies?: ScopedPolicyDocument[];
workflows?: WorkflowDefinition[];
locales?: Record<string, string>;
manifestIndex?: string[];
digest?: string;
}
  1. The bundle MUST be free of unresolved imports and overlays.
  2. Locale references MUST be resolved.
  3. Only content valid for the build context MAY be included.
  4. Review gates MUST have been passed before bundle creation or at the latest before publish.

A conforming uiap.authoring/v0.1 implementation MUST:

  • Support the common document model
  • Understand Package, App, Bindings, Actions, PolicySet, WorkflowCatalog, Overlay, and ReviewSet
  • Deterministically resolve imports and overlays
  • Validate IDs
  • Be able to generate a normalized bundle
  • Be able to evaluate review gates

It SHOULD additionally:

  • Support Capabilities and LocalePack
  • Support DiscoveryImport
  • Store provenance
  • Generate build digests
  • Support publish channels

uiap/
package.uiap.yaml
app.uiap.yaml
capabilities/
core.uiap.yaml
bindings/
routes.uiap.yaml
elements.uiap.yaml
actions/
core.uiap.yaml
billing.uiap.yaml
policies/
default.uiap.yaml
admin.uiap.yaml
workflows/
onboarding.uiap.yaml
support.uiap.yaml
locales/
common.uiap.yaml
overlays/
staging.uiap.yaml
prod.uiap.yaml
tenant-acme.uiap.yaml
reviews/
approvals.uiap.yaml
discovery/
staging-admin.discovery.json
promoted.uiap.yaml

apiVersion: uiap.authoring/v0.1
kind: Package
metadata:
id: package.videoland
version: 0.1.0
title: Videoland UIAP Pack
reviewState: approved
spec:
packageId: videoland.uiap
version: 0.1.0
compatibility:
uiapCore: ">=0.1 <0.2"
profiles: ["[email protected]"]
extensions:
- id: uiap.policy
range: ">=0.1 <0.2"
required: true
- id: uiap.workflow
range: ">=0.1 <0.2"
required: true
sdk:
web: ">=0.1 <0.2"
imports:
- packageId: uiap.shared.base
versionRange: "^0.1.0"
alias: base
manifests:
- id: app.core
kind: App
path: app.uiap.yaml
- id: bindings.routes
kind: Bindings
path: bindings/routes.uiap.yaml
- id: bindings.elements
kind: Bindings
path: bindings/elements.uiap.yaml
- id: actions.core
kind: Actions
path: actions/core.uiap.yaml
- id: policies.default
kind: PolicySet
path: policies/default.uiap.yaml
- id: workflows.onboarding
kind: WorkflowCatalog
path: workflows/onboarding.uiap.yaml
- id: locales.common
kind: LocalePack
path: locales/common.uiap.yaml
- id: overlays.prod
kind: Overlay
path: overlays/prod.uiap.yaml
- id: reviews.approvals
kind: ReviewSet
path: reviews/approvals.uiap.yaml
publish:
defaultChannel: staging
channels:
- name: staging
requiredReviewState: in_review
allowWaivers: true
- name: prod
requiredReviewState: approved
allowWaivers: false
forbidGeneratedOnly: true
requireDigest: true
apiVersion: uiap.authoring/v0.1
kind: WorkflowCatalog
metadata:
id: workflows.onboarding
title: Onboarding Workflows
source: mixed
reviewState: in_review
spec:
workflows:
- review:
level: approved
highRisk: false
definition:
id: video.create_first_video
version: 0.1.0
title:
ref: workflow.video.first.title
fallback: Erstes Video erstellen
category: onboarding
startMode: suggested
interactionModes: [guide, assist, auto]
initialStepId: intro
steps:
- id: intro
type: instruction
text:
ref: workflow.video.first.intro
fallback: Ich helfe dir beim ersten Video.
next: done
- id: done
type: complete
apiVersion: uiap.authoring/v0.1
kind: Overlay
metadata:
id: overlays.prod
reviewState: approved
spec:
selector:
channels: [prod]
patches:
- manifestId: policies.default
path: /spec/policies/0/document/defaults/onUnknownAction
op: replace
value: deny
- manifestId: workflows.onboarding
path: /spec/workflows
op: upsert
matchKey: definition.id
value:
review:
level: approved
definition:
id: video.create_first_video
version: 0.1.1
title:
default: Erstes Video erstellen
category: onboarding
startMode: suggested
interactionModes: [guide, assist]
initialStepId: intro
steps:
- id: intro
type: instruction
text: Ich helfe dir beim ersten Video.
next: done
- id: done
type: complete
apiVersion: uiap.authoring/v0.1
kind: ReviewSet
metadata:
id: reviews.approvals
reviewState: approved
spec:
decisions:
- target:
manifestId: workflows.onboarding
itemId: video.create_first_video
state: approved
by: patrick
at: "2026-03-26T17:00:00Z"
comment: Freigegeben für Staging und Prod.
waivers: []

After this spec, the next logical building block is clearly UIAP Conformance Suite v0.1. Now there is finally something that can actually be tested consistently: manifest validation, import resolution, overlay conflicts, review gates, bundle compilation, and the delightful question of whether someone is “UIAP-compatible” or merely particularly convinced of it.


  • [UIAP-CORE] UIAP Core v0.1
  • [UIAP-CAP] UIAP Capability Model v0.1
  • [UIAP-WEB] UIAP Web Profile v0.1
  • [UIAP-ACTION] UIAP Action Runtime v0.1
  • [UIAP-POLICY] UIAP Policy Extension v0.1
  • [UIAP-WORKFLOW] UIAP Workflow Extension v0.1
  • [RFC2119] Key words for use in RFCs to Indicate Requirement Levels, BCP 14
  • Manifest files MAY reference credential locations or API endpoints; they SHOULD NOT be committed to public repositories without redaction.
  • Schema validation MUST be performed before loading manifests to prevent injection attacks via manipulated YAML/JSON files.
  • Authoring tools SHOULD access the target application only with minimal permissions.
VersionDateChanges
0.12026-03-27Initial draft