SDK adapter system
Current production third-party Component boundary
The current V1 installer, catalog, and executor observations below are internal/runtime audit facts, not permission for production third-party Component install admission or activation. There is no safe inactive quarantine. Exact ProjectScope { kind: "project", workspaceKey, projectKey } data-path isolation is implemented, but production third-party Component install admission and activation remain blocked until authenticated-principal authorization, execution-trust closure, and explicit production gates are implemented.
The future V2 Canvas uses only the host-owned component.declarative@2. Settings are declared through component-declared-settings@1, at most eight per declaration, and the host draws each control from its own registry; package JS, HTML, CSS, React, or iframe UI is not mounted. The Installed Component editor is the isolated surface component-rich-surface-declaration@1 (RFC-016) owns. This block does not change current Function or built-in/first-party paths.
An Adapter classifies an Extension contribution by functional category and versioned format. When it connects an external product or service, that Extension is an Integration. Neither becomes a core product area.
Component Nodes use a different path
A Python Component package/distribution may export one or more Component definitions. A placed Component follows the Component target path rather than an Adapter path. Separately, the portable Component container V1 reader accepts one closed-grammar-validated content/component.json declaration per container; its componentContractVersion is independent of the Python distribution version.
The portable V1 declaration owns the single classification: "flow-node", ports, executor, and presentation. The authoring ComponentDescriptor owns discovery under the closed primary task category (input, transform, calculate, review, deliver, control) and the publisher's own open subcategory beneath it, while .pxflow componentNode.settings owns placement-local instance values. Do not move members between these three authorities.
The current public SDK derives input and result ports from plain Python annotations. It exports no px.input, px.result, or px.setting symbols and defines no Component settings schema. flow.node(..., settings={...}) stores a schema-free object and the separately packaged executor receives it through execute(inputs, settings). No current build bridge turns the decorated callable body into that executor.
The portable V1 declaration carries integrity-measured declarative icon and summaryResultKeys, but the current production Flow reader does not connect them to component.signed@1. A design-system registry entry is not a live renderer for this reader. Categories remain open discovery metadata, and Node settings retain their current instance semantics; neither is an Adapter category.
The following installer, resolver, and worker description is a current V1 internal/runtime audit observation. The installer stores the measured release and closed-grammar-validated declaration. After install, product.component.resolve joins those records into the exact seven-field ComponentRef and judges it through the closed target grammar. The execution worker separately revalidates the pinned release and executor source digest. That join and the declaration-to-Flow-renderer bridge are both implemented. The presence of this storage and join path does not permit production third-party Component install admission or activation.
Without a trust authority, the current installer refuses a signed Component before recording it. An explicitly accepted unsigned Component is recorded only as absent / not-checked. Only a verified marketplace channel may call a release or declaration verified or signed after it performs and records signature verification. component.signed@1 is a registry identifier, not evidence of that verification. The current reader preserves exact target and settings plus usage-derived partial ports, not a last-verified full contract.
Current Component contribution storage, catalog, detail, and execution reads retain the exact Workspace and Project pair accepted by install, while the Python descriptor registry still uses process-wide (kind, key) identity. The resolver accepts scope plus componentKey, so multiple measured releases with the same key remain ambiguous. Data-path isolation is implemented; package-scoped collision-free authoring lookup and principal-to-Project authorization are not.
FUTURE V2: Component Node presentation and third-party UI and node-presentation-profile.v2.json describe a contract_only requiredContractVersion: 2 successor that carries multiple Component declarations in one portable container. Its Node projection starts a separate host-renderer version axis at the contract-only component.declarative@2, not a reuse of component.signed@1. Its value schema is component-declarative-node-value.v1.schema.json with schemaVersion: 1; that renderer version is independent of Component container contract V2, descriptor schema V2, and componentContractVersion. It is not registered in the current production design-system catalog and is not the current V1 container reader contract. The V2 Canvas draws only that host-owned projection; settings are declared through component-declared-settings@1, at most eight per declaration, and the host draws each control from its own registry. Package UI stays outside the Canvas, and the Installed Component editor is the isolated surface component-rich-surface-declaration@1 (RFC-016) owns.
Use AppSurfaceDescriptor only for an independently opened surface such as a Streamlit app or a PXFLOW App. Use data-source, artifact, and document-codec descriptors for their respective external boundaries. In V1, only pxflow_app and streamlit are registered formats. Data-source, artifact, and document-codec names in diagrams are category examples only; their format lists and closed configuration schemas are not yet registered.
Report authoring is part of the core
px.Report and Report Workbench are the code and screen authoring surfaces for the same independent .pxreport document. They map authored Report values to the public inputs of a saved Flow and map named Flow results back to Report positions. Those mappings belong to .pxreport. App Surface adapters and Component settings keep their own separate contracts.
Adding a Report mapping leaves the Flow's Python source and internal Canvas connections unchanged. See Report Workbench and Connect a Report to a Flow.
Common Adapter envelope
Every Adapter descriptor carries its category, format key, category and format contract versions, semantic key, title, description, signed source reference, host-capability ceiling, manual reference, and descriptor digest. Each category then supplies a closed typed payload; arbitrary config maps are not part of the contract.
AI discovery
AI discovery uses typed search followed by typed describe, but the exact public command names and signatures are not yet approved. Plan 23's adapter_* examples and Plan 24's app_surface_* examples therefore are not presented here as registered commands. AI discovers a Component through the Component catalog and opens its details through the same Node action as the user. Adapter discovery never bypasses Flow permissions or execution commands.