Application
Overview
Section titled “Overview”An application in PCP is represented by an AppDescriptor. The daemon builds one for each detected application during the discovery pipeline, and the descriptor is what RegistryQuery::Apps returns to clients.
The descriptor carries the app’s identity, its detection metadata (how it was found, how confident the daemon is), the list of capability IDs it exposes, and an optional manifest for Tier 1 apps. It does not carry process-level details like PIDs or command lines. Those are implementation concerns of the detection adapters, not part of the protocol.
AppDescriptor JSON Schema
Section titled “AppDescriptor JSON Schema”{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "AppDescriptor", "type": "object", "required": ["app_id", "name", "capabilities", "detected_method", "detection_confidence"], "properties": { "app_id": { "type": "string", "description": "Reverse-DNS application identifier." }, "name": { "type": "string", "description": "Human-readable application name." }, "capabilities": { "type": "array", "items": { "type": "string" }, "description": "Fully qualified capability IDs this app exposes." }, "detected_method": { "type": "string", "enum": ["desktop", "atspi2", "wine", "simulated"], "description": "How the daemon discovered this application." }, "detection_confidence": { "type": "number", "minimum": 0.0, "maximum": 1.0, "description": "Confidence score from the detection adapter." }, "metadata": { "type": "object", "additionalProperties": true, "description": "Arbitrary metadata from the detection adapter." }, "manifest": { "type": ["object", "null"], "description": "Full CapabilityManifest for Tier 1 apps. Null for Tier 2 and Tier 3." } }}Detection Method
Section titled “Detection Method”The detected_method field indicates how the daemon found this application. The four values correspond to the detection priority chain:
| Method | Tier | Description |
|---|---|---|
desktop |
Tier 1 | Static discovery via desktop entry files, signed manifests, and binary probing |
atspi2 |
Tier 2 | Full accessibility-tree walk producing derived per-element capabilities |
wine |
Tier 2 | MSAA/UIA accessibility bridge for Windows applications |
simulated |
Tier 3 | Universal fallback using coordinate and input synthesis |
Tier 1 apps ship a manifest and implement the Tier 1 server trait, so they get typed parameters and structured return values. Tier 2 apps get capabilities derived automatically from the accessibility tree. Tier 3 apps receive only basic window-management capabilities via input simulation.
Domain
Section titled “Domain”The Domain enum defines three privilege levels. Every capability has a domain, and every caller has a domain. A caller can only reach capabilities at or below its own domain level.
pub enum Domain { App, // lowest -- app capabilities, registry reads, event subscriptions Compositor, // mid -- App plus surface and zone management System, // highest -- Compositor plus audio, network, filesystem, power}The privilege ordering is strict: App < Compositor < System. A capability in the System domain cannot be invoked by a caller at the App domain. This containment model prevents lower-privilege code from reaching system-level operations.
Intent
Section titled “Intent”An Intent represents a caller’s desire to perform an action. System Intelligence constructs intents from natural language or other input, and the daemon resolves them into concrete capability invocations.
pub struct Intent { pub action: String, // capability action to perform pub target_app: Option<String>, // resolved by the pipeline if absent pub parameters: serde_json::Value, // capability-specific parameters pub domain: Domain, // caller's domain pub priority: i32, // higher means more important}When target_app is None, the daemon runs target resolution to pick the right app based on session context, user defaults, and recent usage history. The priority field orders concurrent intents when System Intelligence issues multiple requests at once.
ExecutionResult
Section titled “ExecutionResult”Every capability invocation returns an ExecutionResult. It captures whether the invocation succeeded, what it produced, how long it took, and where it was audited.
pub struct ExecutionResult { pub success: bool, pub output: serde_json::Value, pub duration_ms: u64, pub audit_id: Option<u64>, pub error: Option<String>,}| Field | Description |
|---|---|
success |
True if the capability completed without error |
output |
Capability-specific return data |
duration_ms |
Wall-clock execution time in milliseconds |
audit_id |
Identifier in the audit journal, if the invocation was audited |
error |
Human-readable error description when success is false |
Example
Section titled “Example”{ "app_id": "com.example.present", "name": "Present", "capabilities": [ "app.com.example.present.slide.add", "app.com.example.present.slide.remove", "app.com.example.present.deck.list" ], "detected_method": "desktop", "detection_confidence": 1.0, "metadata": { "tier": "1", "display_target": "glasses" }, "manifest": null}This example shows a Tier 1 app discovered through desktop entry scanning. The detection_confidence of 1.0 means the detection adapter is fully certain. The capabilities list contains fully qualified IDs in domain.app.action format. The manifest field is null here, but a real Tier 1 response would include the full manifest object when the client queries individual app details.
For Tier 2 apps, detected_method would be "atspi2", the capabilities list would contain adapter-derived IDs (like app.com.example.mail.search), and the manifest would always be null.