Skip to content

UIAP Discovery Mapper

FieldValue
StatusDraft
Version0.1
Date2026-03-27
Dependencies[UIAP-CORE], [UIAP-CAP], [UIAP-WEB], [UIAP-ACTION], [UIAP-POLICY]
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 Discovery Mapper Spec v0.1 defines how an application or a discovery tool explores a web application in a controlled manner, describes it in a structured way, and translates it into agentically usable artifacts.

The goal of the mapper is not to “understand everything” at user runtime, but rather to produce a reliable inventory in a controlled environment for:

  • Route catalogs
  • Scope and page models
  • Element and field lexicons
  • Action candidates
  • Transition graphs
  • Workflow candidates
  • Review and gap lists
  • Coverage reports

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
  • optionally UIAP Workflow Extension v0.1

This specification does not define:

  • LLM planning behavior,
  • production runtime control within the user session,
  • final workflow approval,
  • security policy of the target application beyond the discovery context.

  1. Discovery belongs primarily in staging, demo environments, or controlled test tenants, not in the live session of real users.
  2. Discovery is bounded exploration, not an infinite spider.
  3. Discovery is evidence-driven: every extracted assertion should have a provenance and a confidence value.
  4. Discovery is safe by default: no destructive or externally effective actions without explicit authorization.
  5. Discovery is semantics-first: annotations, registered actions, roles, names, and states take precedence over heuristics.
  6. Discovery produces candidates and findings, not automatically final truth.
  7. Discovery MUST correctly treat boundaries such as cross-origin and closed shadow DOM as actual boundaries, not as “it’ll probably work”. Humans like to hope that. Browsers less so.

The mapper can operate as a companion spec or optionally be exposed as a UIAP extension.

type ExtensionId = "uiap.discovery";
type ExtensionVersion = "0.1";

If the discovery function is offered as a UIAP extension, it MUST be declarable during the handshake:

{
"id": "uiap.discovery",
"versions": ["0.1"],
"required": false
}

A single controlled exploration execution against a specific target environment.

The target environment including URL, auth context, roles, locale, feature flags, and budget limits.

A starting point for discovery, e.g., route, URL, menu item, registered action, documentation hint, or known workflow.

An observed UI state consisting of a PageGraph, supplementary evidence, and a fingerprint.

A documented transition from one discovery state to another, triggered by an action.

An artifact proposed by the mapper, e.g., route, action, or workflow, that is not necessarily approved yet.

A machine- or human-reviewable finding about gaps, ambiguities, or uncertainties.


A conforming mapper SHOULD pursue at least these objectives:

  • identifying the navigable main areas of the application,
  • cataloging visible and relevant scopes,
  • extracting semantically important UI elements,
  • deriving safe and plausible action candidates,
  • capturing observable success signals,
  • documenting transitions between states,
  • deriving workflow candidates from transition chains,
  • explicitly marking uncertainty.

interface DiscoveryPackage {
modelVersion: "0.1";
spec: "uiap.discovery";
revision?: string;
run: DiscoveryRunSummary;
environment: DiscoveryEnvironment;
routeCatalog: RouteCatalog;
scopeCatalog: ScopeCatalog;
elementCatalog: ElementCatalog;
actionCatalog: ActionCatalog;
transitionGraph: TransitionGraph;
workflowCandidates?: WorkflowCandidateCatalog;
reviewQueue: ReviewQueue;
coverage: CoverageReport;
evidenceIndex?: EvidenceIndex;
metadata?: Record<string, unknown>;
}

interface RouteCatalog {
routes: DiscoveredRoute[];
}
interface DiscoveredRoute {
routeId: string;
urls?: string[];
titles?: string[];
scopes?: ScopeId[];
discoveredBy: EvidenceRef[];
confidence: Confidence;
entryActions?: string[];
exitSignals?: SuccessSignal[];
metadata?: Record<string, unknown>;
}

interface ScopeCatalog {
scopes: DiscoveredScope[];
}
interface DiscoveredScope {
scopeId: ScopeId;
kind: ScopeKind;
routeIds?: string[];
parentScopeId?: ScopeId;
names?: string[];
stableIds?: StableId[];
discoveredBy: EvidenceRef[];
confidence: Confidence;
metadata?: Record<string, unknown>;
}

interface ElementCatalog {
elements: DiscoveredElement[];
}
interface DiscoveredElement {
stableId?: StableId;
semanticKey: string;
routes?: string[];
scopes?: ScopeId[];
role: UIRole;
names?: string[];
meanings?: string[];
stateKeys?: UIStateKey[];
affordances?: UIAffordance[];
supportedActions?: ActionId[];
risk?: RiskDescriptor;
dataClasses?: DataClass[];
discoveredBy: EvidenceRef[];
confidence: Confidence;
reviewState?: "verified" | "candidate" | "needs_review";
metadata?: Record<string, unknown>;
}

semanticKey is the canonical mapper identity when no stable stableId exists yet.


interface ActionCatalog {
actions: DiscoveredAction[];
}
interface DiscoveredAction {
id: ActionId;
kind: "primitive" | "domain" | "candidate";
targetPatterns?: ActionTargetPattern[];
routes?: string[];
scopes?: ScopeId[];
args?: ActionArgDescriptor[];
risk?: RiskDescriptor;
sideEffectClass?: SideEffectClass;
successSignals?: SuccessSignal[];
prerequisites?: WorkflowCondition[];
discoveredBy: EvidenceRef[];
confidence: Confidence;
reviewState?: "verified" | "candidate" | "unsafe" | "needs_review";
metadata?: Record<string, unknown>;
}
interface ActionTargetPattern {
role?: UIRole;
stableId?: StableId;
meaning?: string;
scopeId?: ScopeId;
}

interface TransitionGraph {
states: DiscoveryStateNode[];
edges: DiscoveryTransition[];
}
interface DiscoveryStateNode {
stateId: string;
fingerprint: string;
routeId?: string;
scopeIds?: ScopeId[];
modalStack?: string[];
pageGraphRef?: string;
screenshotRef?: string;
discoveredBy: EvidenceRef[];
confidence: Confidence;
metadata?: Record<string, unknown>;
}
interface DiscoveryTransition {
transitionId: string;
fromStateId: string;
toStateId: string;
viaActionId: ActionId;
target?: TargetRef;
args?: Record<string, unknown>;
sideEffectClass?: SideEffectClass;
observedSignals?: SuccessSignal[];
confidence: Confidence;
discoveredBy: EvidenceRef[];
metadata?: Record<string, unknown>;
}

interface WorkflowCandidateCatalog {
workflows: DiscoveredWorkflowCandidate[];
}
interface DiscoveredWorkflowCandidate {
id: string;
title?: string;
category?: WorkflowCategory;
routeIds?: string[];
entryConditions?: WorkflowCondition[];
requiredInputs?: WorkflowParameter[];
stepSkeleton: WorkflowStepSkeleton[];
successSignals?: SuccessSignal[];
discoveredBy: EvidenceRef[];
confidence: Confidence;
reviewState?: "candidate" | "verified" | "needs_review";
metadata?: Record<string, unknown>;
}
interface WorkflowStepSkeleton {
type: "instruction" | "collect" | "action" | "ensure" | "branch" | "handoff" | "complete";
actionId?: ActionId;
target?: TargetRef;
parameterNames?: string[];
signals?: SuccessSignal[];
}

interface ReviewQueue {
items: ReviewItem[];
}
interface ReviewItem {
id: string;
severity: "low" | "medium" | "high";
kind:
| "missing_stable_id"
| "duplicate_name"
| "ambiguous_target"
| "opaque_frame"
| "closed_shadow"
| "missing_success_signal"
| "unsafe_action_candidate"
| "inferred_only"
| "coverage_gap"
| "workflow_uncertain"
| "custom";
routeId?: string;
scopeId?: ScopeId;
stableId?: StableId;
description: string;
evidence: EvidenceRef[];
remediation?: string;
}

interface CoverageReport {
seedsTotal: number;
seedsVisited: number;
routesDiscovered: number;
scopesDiscovered: number;
elementsDiscovered: number;
actionsDiscovered: number;
workflowCandidatesDiscovered: number;
opaqueRegions: number;
unresolvedTransitions: number;
reviewItems: number;
confidenceSummary?: {
high: number;
medium: number;
low: number;
};
}

Discovery must not merely say “I believe this is a button”. That is nice for demos, unpleasant for production operations.

type EvidenceSource =
| "annotation"
| "app_registry"
| "dom"
| "accessibility"
| "visible_text"
| "signal"
| "transition"
| "network"
| "screenshot"
| "vision"
| "documentation"
| "manual_review"
| "inferred";
interface EvidenceRef {
source: EvidenceSource;
refId: string;
note?: string;
}
type Confidence = "high" | "medium" | "low";
  • high: supported by annotation, app registry, or repeatedly observed transition with consistent signals
  • medium: supported by multiple semantic indicators or a single successful transition
  • low: supported only by heuristics, screenshots, or partial inference

interface DiscoveryEnvironment {
environmentId: string;
baseUrl: string;
locale?: string;
viewport?: {
width: number;
height: number;
};
authMode?: "manual" | "seeded" | "session_reuse";
principalProfiles?: DiscoveryPrincipalProfile[];
featureFlags?: Record<string, boolean | string | number>;
budgets?: DiscoveryBudget;
safety?: DiscoverySafetyPolicy;
metadata?: Record<string, unknown>;
}
interface DiscoveryPrincipalProfile {
id: string;
roles?: string[];
grants?: PolicyGrant[];
description?: string;
}
interface DiscoveryBudget {
maxStates?: number;
maxTransitions?: number;
maxDepth?: number;
maxRuntimeMs?: number;
maxPerRoute?: number;
}
interface DiscoverySafetyPolicy {
defaultMode: "observe_only" | "safe_explore" | "sandbox_write";
allowExternalEffects?: boolean;
allowDestructiveActions?: boolean;
allowAuthFlows?: boolean;
allowPaymentFlows?: boolean;
}
  • observe_only MUST NOT execute any write or activating actions.
  • safe_explore MAY only execute reversible, non-destructive, and non-external actions.
  • sandbox_write MAY execute test/seed actions in controlled tenants.
  • Discovery MUST be conservative: unknown or unsafe actions SHOULD be treated as non-executable.

type DiscoverySeed =
| {
kind: "route";
routeId: string;
}
| {
kind: "url";
url: string;
}
| {
kind: "menu";
label: string;
}
| {
kind: "action";
actionId: ActionId;
}
| {
kind: "workflow";
workflowId: string;
}
| {
kind: "documentation";
ref: string;
};

A mapper SHOULD obtain seeds from multiple sources:

  • Static router/app manifests
  • Known UIAP annotations
  • Registered app actions
  • Navigation and menus
  • Product documentation
  • Previous discovery packages
  • Manual reviewer inputs

type DiscoveryRunStatus =
| "planning"
| "preparing"
| "seeding"
| "exploring"
| "extracting"
| "synthesizing"
| "reviewing"
| "completed"
| "failed"
| "cancelled";
interface DiscoveryRunSummary {
runId: string;
startedAt: string;
finishedAt?: string;
status: DiscoveryRunStatus;
environmentId: string;
profile?: string;
seeds?: DiscoverySeed[];
notes?: string[];
}

A conforming mapper MUST process a run in at least this order:

  1. Prepare environment
  2. Resolve seeds
  3. Capture initial states
  4. Perform safe exploration
  5. Extract artifacts
  6. Synthesize workflow candidates
  7. Generate review and coverage artifacts
  8. Finalize discovery package

The mapper MUST capture at minimum:

  • Target environment
  • Principal profile
  • Feature flags
  • Budgets
  • Safety policy
  • Available UIAP profiles/extensions
  • Seeds

If a UIAP SDK is present, the mapper SHOULD first read existing:

  • data-uiap-* annotations
  • Action registries
  • Capability documents
  • Policy documents
  • Workflow catalogs

For each seed, the mapper MUST produce an initial state.

A discovery state SHOULD contain:

interface DiscoveryStateSnapshot {
stateId: string;
pageGraph: PageGraph;
screenshotRef?: string;
evidence: EvidenceRef[];
fingerprint: string;
discoveredAt: string;
entrySeed?: DiscoverySeed;
}

The mapper SHOULD observe DOM and UI changes during exploration; MutationObserver is the standard instrument for this on the web platform. ([MDN Web Docs][2])

  • The mapper SHOULD prefer PageGraph from the UIAP Web Profile.
  • If available, an AX evidence record SHOULD additionally be stored.
  • For richer AX snapshots, the mapper MAY use CDP methods such as Accessibility.getFullAXTree or Accessibility.getPartialAXTree. ([chromedevtools.github.io][3])
  • Screenshots MAY be stored as supplementary evidence but not as the sole source for semantics.

The mapper MUST be able to deduplicate states.

A fingerprint SHOULD primarily be derived from these stable characteristics:

  • routeId or normalized URL
  • Visible scopes
  • Stable element IDs
  • Normalized roles and names of relevant controls
  • Modal/drawer/popover stack
  • Structured collection signatures
  • Focused primary element

A fingerprint SHOULD not primarily depend on ephemeral values such as:

  • Timestamps
  • Toaster IDs
  • Random React/DOM IDs
  • Scroll positions without layout relevance
  • Transient loading indicators
interface StateFingerprintPolicy {
includeTextValues?: boolean;
includeCollections?: boolean;
ignoreTransientToasts?: boolean;
ignoreSpinners?: boolean;
}

From each discovery state, the mapper SHOULD extract:

  • Route candidates
  • Scope candidates
  • Element candidates
  • Field meanings
  • Risk and sensitivity hints
  • Success signal candidates
  1. App annotations
  2. Action registry / Capability Model
  3. Native HTML + ARIA
  4. Visible text and label association
  5. AX evidence
  6. Heuristics
  7. Vision fallback

The mapper SHOULD only execute actions from a state that:

  • are permitted by the safety policy,
  • do not produce prohibited side effects,
  • meaningfully expand the target,
  • are within budget.
  1. Known, safe appActions
  2. Semantic navigation
  3. Opening tabs, accordions, menus, drawers, dialogs
  4. Navigation to main areas
  5. Selection in safe filters or tabs
  6. Form drafts only in sandbox contexts
  7. Visual or external fallbacks only when documented necessity exists

A mapper SHOULD resolve targets in order of priority via:

  • Stable IDs / agent IDs
  • Role
  • Name / text
  • Scope context

In practice, test/agent IDs are often more robust than text or CSS, and Playwright prioritizes role, text, and test IDs over CSS/XPath for resilient locators. ([Playwright][4])

Before every exploration action, the mapper SHOULD at minimum verify that:

  • Target is attached
  • Visible
  • Enabled
  • Not blocked
  • Sufficiently stable
  • In viewport or scrollable into it

Playwright’s actionability checks and auto-waiting serve as a good reference model for this. ([Playwright][5])

Every executed action SHOULD be documented as a transition with:

  • Source state
  • Target resolution
  • Chosen action
  • Arguments
  • Observed signals
  • Target state
  • Confidence

If an action leads to no clearly distinguishable target state, a review item SHOULD be generated.

11.7 Phase G: Workflow Candidate Synthesis

Section titled “11.7 Phase G: Workflow Candidate Synthesis”

The mapper SHOULD derive workflow candidates from transition chains.

A workflow candidate is plausible when:

  • a recognizable domain-level goal is present,
  • the step sequence is not purely random,
  • inputs are identifiable,
  • success signals are observable,
  • policy/risk situations are known or at least conservatively derivable.

Preferred sources for workflow synthesis:

  1. Existing workflow/action catalogs
  2. Repeatedly observed transition chains
  3. Documentation and UI texts
  4. Semantic form/dialog structures
  5. Manually marked high-value flows

The same-origin policy restricts direct interaction with documents of other origins, and ShadowRoot.mode distinguishes between open and closed, where closed makes internal structures inaccessible to JavaScript from outside. The mapper MUST correctly model these boundaries. ([MDN Web Docs][6])

MAY be explored directly.

MUST be treated as opaque. Only container or frame metadata MAY be captured.

MAY be treated as a separate discovery context with its own document and evidence space.

MAY be explored.

MUST be treated as opaque unless the host publishes explicit UIAP bindings or adapters.

SHOULD be marked as vision-assisted and receive low confidence by default if no additional semantics or registry is available.


13. Safety and Policy in the Discovery Context

Section titled “13. Safety and Policy in the Discovery Context”

Discovery MUST make a discovery safety decision before every action.

interface DiscoveryActionPolicyDecision {
effect: "allow" | "skip" | "review" | "deny";
reason:
| "safe"
| "unknown_side_effect"
| "destructive"
| "external_effect"
| "credential"
| "payment"
| "security_sensitive"
| "budget_exceeded"
| "opaque_boundary"
| "manual_only";
}
  • destructive, billing_change, security_change, irreversible SHOULD default to deny.
  • Credential, secret, and payment areas SHOULD default to review or deny.
  • Unclear actions without a safe side-effect classification SHOULD NOT be executed autonomously.
  • Workflow synthesis MAY be based on observation without actually executing risky actions.

If the mapper is exposed as a UIAP extension, at minimum the following message types SHOULD be supported.

interface DiscoveryPlanPayload {
environment: DiscoveryEnvironment;
seeds?: DiscoverySeed[];
}
interface DiscoveryPlannedPayload {
runId: string;
estimatedSeedCount?: number;
acceptedSeeds?: DiscoverySeed[];
rejectedSeeds?: Array<{
seed: DiscoverySeed;
reason: string;
}>;
}

interface DiscoveryStartPayload {
runId: string;
}
interface DiscoveryStartedPayload {
runId: string;
status: "preparing" | "seeding" | "exploring";
}

interface DiscoveryProgressPayload {
runId: string;
status: DiscoveryRunStatus;
currentSeed?: DiscoverySeed;
currentRouteId?: string;
currentStateId?: string;
visitedStates?: number;
visitedTransitions?: number;
discoveredRoutes?: number;
discoveredActions?: number;
discoveredWorkflowCandidates?: number;
note?: string;
}

interface DiscoveryPausePayload {
runId: string;
reason?: string;
}
interface DiscoveryPausedPayload {
runId: string;
status: "paused";
}

interface DiscoveryResumePayload {
runId: string;
}
interface DiscoveryResumedPayload {
runId: string;
status: DiscoveryRunStatus;
}

interface DiscoveryCancelPayload {
runId: string;
reason?: string;
}
interface DiscoveryCancelledPayload {
runId: string;
status: "cancelled";
}

interface DiscoveryResultPayload {
runId: string;
status: "completed" | "failed" | "cancelled";
package: DiscoveryPackage;
}

interface DiscoveryPackageGetPayload {
runId: string;
}
interface DiscoveryPackagePayload {
package: DiscoveryPackage;
}

A route candidate SHOULD be generated when at least one of the following applies:

  • A unique router or app route is present
  • Stable URL/path structure exists
  • Navigation reproducibly leads to a distinguishable state
  • Route is marked by annotation or app registry

A scope candidate SHOULD be generated for:

  • Forms
  • Dialogs
  • Drawers
  • Menus
  • Popovers
  • Tab panels
  • Larger regions with their own interaction context

An element candidate SHOULD be generated when the object:

  • is interactive, or
  • signals success/failure/state, or
  • is relevant as a parameter source.

An action candidate SHOULD be generated when:

  • a registered app action is present, or
  • a primitive UI affordance is present, or
  • a repeatedly observed transition appears domain-stable.
  • button + activate -> ui.activate
  • editable field -> ui.enterText, ui.clearText
  • checkbox / switch -> ui.toggle
  • combobox / listbox -> ui.choose
  • submittable scope -> ui.submit
  • route-capable target -> nav.navigate

A success signal SHOULD be derived from:

  • Route change
  • Dialog opens/closes
  • Toast/status message
  • Validation status
  • Collection count or entity change
  • Declared app signal source

If no observable signal exists, a review item missing_success_signal MUST be generated.


A mapper MUST generate a review item at minimum when:

  • Multiple equally plausible targets exist
  • An important action was identified only through heuristics
  • A cross-origin or closed-shadow area blocks discovery
  • A workflow candidate lacks clean success signals
  • A route was found without stable identity
  • A security- or billing-adjacent flow was touched
  • Semantics and observed behavior are contradictory

A conforming Discovery Mapper v0.1 MUST:

  • Be able to plan and execute controlled runs
  • Generate at least one PageGraph per seed
  • Be able to deduplicate states
  • Generate route, scope, element, and action candidates
  • Document transitions
  • Generate a review queue and coverage report
  • Correctly mark opaque boundaries

A conforming mapper SHOULD:

  • Be able to use AX evidence
  • Support multiple principal profiles
  • Be able to synthesize workflow candidates
  • Efficiently manage deltas or repeated state captures
  • Be able to compare historical discovery packages

{
"uiap": "0.1",
"kind": "request",
"type": "uiap.discovery.plan",
"id": "msg_501",
"sessionId": "sess_mapper",
"ts": "2026-03-26T16:00:00.000Z",
"source": { "role": "agent", "id": "uiap-discovery" },
"payload": {
"environment": {
"environmentId": "staging-admin",
"baseUrl": "https://staging.app.example.com",
"locale": "de-CH",
"viewport": { "width": 1440, "height": 900 },
"authMode": "seeded",
"principalProfiles": [
{
"id": "workspace-admin",
"roles": ["admin"],
"grants": ["observe", "guide", "draft", "act", "admin"]
}
],
"budgets": {
"maxStates": 500,
"maxTransitions": 1200,
"maxDepth": 8,
"maxRuntimeMs": 1800000
},
"safety": {
"defaultMode": "safe_explore",
"allowExternalEffects": false,
"allowDestructiveActions": false,
"allowAuthFlows": true,
"allowPaymentFlows": false
}
},
"seeds": [
{ "kind": "route", "routeId": "dashboard" },
{ "kind": "route", "routeId": "videos" },
{ "kind": "route", "routeId": "settings" }
]
}
}
{
"modelVersion": "0.1",
"spec": "uiap.discovery",
"run": {
"runId": "disc_77",
"startedAt": "2026-03-26T16:00:00.000Z",
"finishedAt": "2026-03-26T16:11:22.000Z",
"status": "completed",
"environmentId": "staging-admin"
},
"routeCatalog": {
"routes": [
{
"routeId": "videos.new",
"urls": ["https://staging.app.example.com/videos/new"],
"titles": ["Neues Video"],
"confidence": "high",
"discoveredBy": [
{ "source": "annotation", "refId": "route:videos.new" },
{ "source": "transition", "refId": "tr_18" }
]
}
]
},
"actionCatalog": {
"actions": [
{
"id": "video.create",
"kind": "domain",
"routes": ["videos.new"],
"targetPatterns": [
{ "stableId": "video.submit", "role": "button", "scopeId": "video.create.form" }
],
"risk": { "level": "confirm", "tags": ["external_effect"] },
"successSignals": [
{ "kind": "route.changed", "pattern": "/videos/:id" },
{ "kind": "toast.contains", "text": "erstellt" }
],
"confidence": "high",
"reviewState": "candidate",
"discoveredBy": [
{ "source": "app_registry", "refId": "action:video.create" },
{ "source": "transition", "refId": "tr_33" }
]
}
]
},
"workflowCandidates": {
"workflows": [
{
"id": "candidate.video.create_first_video",
"title": "Erstes Video erstellen",
"category": "onboarding",
"routeIds": ["dashboard", "videos", "videos.new"],
"requiredInputs": [
{ "name": "title", "type": "string", "required": true }
],
"stepSkeleton": [
{ "type": "action", "actionId": "nav.navigate" },
{ "type": "action", "actionId": "ui.enterText", "parameterNames": ["title"] },
{ "type": "action", "actionId": "video.create" },
{ "type": "ensure", "signals": [{ "kind": "route.changed", "pattern": "/videos/:id" }] },
{ "type": "complete" }
],
"confidence": "medium",
"reviewState": "needs_review",
"discoveredBy": [
{ "source": "transition", "refId": "chain_9" },
{ "source": "documentation", "refId": "doc_3" }
]
}
]
},
"reviewQueue": {
"items": [
{
"id": "rev_19",
"severity": "medium",
"kind": "missing_success_signal",
"routeId": "videos.new",
"description": "Für ui.enterText auf video.use_case wurde kein verlässliches Erfolgs-Signal gefunden.",
"evidence": [
{ "source": "transition", "refId": "tr_29" }
],
"remediation": "Explizites success signal oder field binding ergänzen."
}
]
},
"coverage": {
"seedsTotal": 3,
"seedsVisited": 3,
"routesDiscovered": 12,
"scopesDiscovered": 31,
"elementsDiscovered": 186,
"actionsDiscovered": 44,
"workflowCandidatesDiscovered": 8,
"opaqueRegions": 2,
"unresolvedTransitions": 5,
"reviewItems": 17,
"confidenceSummary": {
"high": 122,
"medium": 104,
"low": 17
}
}
}

The mapper should not attempt to freely and blindly “spider” the entire app. The efficient path is:

  • Seeds + app semantics + UIAP annotations first,
  • then controlled exploration with budgets,
  • then transition graph + candidate synthesis,
  • then human review for high-value or high-risk flows.

This saves costs, reduces hallucination noise, and leads to discovery packages that can actually be reused in workflow and runtime specs, instead of being ceremoniously discarded afterwards.


  • [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
  • [RFC2119] Key words for use in RFCs to Indicate Requirement Levels, BCP 14
  • Discovery MUST NOT be executed on pages for which no authorization exists.
  • Crawled content MAY contain sensitive data; discovery results SHOULD be redacted before persistence.
  • LLM-assisted review modes MUST ensure that no sensitive DOM content is sent to external model APIs unless explicitly authorized.
  • Discovery results are suggestions, not binding configurations; they MUST be manually reviewed before production use.
VersionDateChanges
0.12026-03-27Initial draft