Skip to content

Commit f8b5b4a

Browse files
phodalAugment Agent (Grok 4.6)
andcommitted
docs(adrs): tighten external artifact provider boundaries
Clarify V2 Qoder wire compatibility, split adapter and hosted-surface trust profiles, and scope support to individual provider contributions. Document idempotent legacy activation, Walnut discovery limits, and retained authority terminology. Validated with the documentation link graph and diff checks. Co-authored-by: Augment Agent (Grok 4.6) <grok@x.ai>
1 parent c5fbc82 commit f8b5b4a

1 file changed

Lines changed: 96 additions & 47 deletions

File tree

docs/adrs/studio-artifact-runtime-and-providers.md

Lines changed: 96 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ its validation evidence.
6464
| Code lifecycle | TSX/JSX plus Studio-owned SVG and Mermaid virtual modules | One bounded compile/build/preview lifecycle for executable presentation |
6565
| Browser host | Ordered `ArtifactView` providers | Mount the exact server-selected surface; never reclassify by extension |
6666
| Qoder | Provider-specific discovery, sidecar, routes, and renderer type | Translate Qoder into a generic external provider contribution and hosted surface |
67-
| Walnut | Verified local bootstrap receipt; no Artifact execution | Register a verified provider with zero contributions until a reviewed adapter exists |
67+
| Walnut | Verified local bootstrap receipt; no Artifact execution | Register a receipt-verified, locally derived provider with zero contributions; any future contribution starts `experimental-local` |
6868
| Revision history | Current bytes are revision-bound but not retained | Retention, compare, and replay require a separate immutable Artifact authority |
6969
| Session trace | No canonical Artifact trace link | Add an evidence-backed manifest and trace projection in a later spec |
7070

@@ -95,6 +95,11 @@ Packaging outputs, checkpoint evidence, report attachments, and Studio Artifact
9595
revisions remain separate namespaces unless an explicit bridge records their
9696
identity and provenance.
9797

98+
An **authority scope** is the namespace and retention owner that can prove an
99+
Artifact identity: currently one live directory catalog, and later potentially
100+
one retained `SessionArtifactManifest`. Catalog-local and Session-stable Thread
101+
ids are distinct namespaces until an explicit provenance bridge relates them.
102+
98103
### Keep catalog authority on the server
99104

100105
The server owns discovery, format classification, revision hashing, plugin
@@ -154,20 +159,27 @@ interface ArtifactProviderBinding {
154159
providerId: string;
155160
contributionId: string;
156161
fingerprint: ArtifactDigest;
157-
support: "verified" | "experimental-local";
162+
contributionSupport: "reviewed" | "experimental-local";
158163
}
159164

160165
type ArtifactSurfaceBinding =
161166
| { kind: "native"; rendererId: string }
162167
| { kind: "studio-sandbox"; rendererId: string; runtimeId: string }
163-
| { kind: "external-hosted"; rendererId: string; runtimeId: string }
168+
| {
169+
kind: "external-hosted";
170+
rendererId: string;
171+
runtimeId: string;
172+
securityProfileId: "opaque-web-v1";
173+
}
164174
| { kind: "unavailable"; reason: string };
165175
```
166176

167-
These shapes describe ownership; they are not a new public package API. The
168-
current V2 catalog may continue to project them through `backing`, `build`, and
169-
`renderer`. A later wire-format revision is justified only when a client needs
170-
information that cannot be represented safely and additively.
177+
All TypeScript shapes in this ADR are conceptual ownership contracts until a
178+
dated implementation spec freezes their internal names and validators; they are
179+
not a new public package API. The current V2 catalog may continue to project
180+
them through `backing`, `build`, and `renderer`. A later wire-format revision is
181+
justified only when a client needs information that cannot be represented
182+
safely and additively.
171183

172184
The V2 compatibility projection is explicit:
173185

@@ -182,9 +194,13 @@ New Studio code normalizes that legacy wire value at the protocol edge and then
182194
uses the generic surface mount. A Qoder provider migration removes
183195
`qoderViewer` and the Canvas-typed plugin context from the generic internal
184196
binding, but it continues to emit `renderer.type: "qoder-canvas"` and the
185-
provider-owned `qoder-canvas/v1` payload schema to V2 clients. Removing those
186-
wire aliases requires a dated V3 or negotiated compatibility spec; it is not an
187-
additive V2 change.
197+
provider-owned `payload.kind: "qoder-canvas/v1"` discriminator to V2 clients.
198+
For every migrated viewer it also preserves the current
199+
`adapter.schemaId: "qoder-canvas/<viewer-id>/v1"`; a provider refactor alone
200+
cannot rename or generalize that value. A new Qoder adapter schema requires a
201+
new versioned schema id and compatibility negotiation rather than silently
202+
replacing the selected V2 contract. Removing any of these wire aliases requires
203+
a dated V3 or negotiated compatibility spec; it is not an additive V2 change.
188204

189205
Renderer implementations compose under `ArtifactView`; they do not inherit from
190206
PPTX, Canvas, or another concrete View. `ArtifactCodeView` is the shared source
@@ -297,7 +313,7 @@ interface ExternalArtifactProvider {
297313
id: string;
298314
label: string;
299315
version: string;
300-
support: "verified" | "experimental-local";
316+
acquisition: "operator-provisioned" | "local-derived-experimental";
301317
fingerprint: ArtifactDigest;
302318
receipt: VerifiedExternalProviderReceiptV1;
303319
contributions: readonly ExternalAdapterContribution[];
@@ -307,7 +323,7 @@ interface VerifiedExternalProviderReceiptV1 {
307323
kind: "HarnessStudioExternalArtifactProviderReceiptV1";
308324
providerId: string;
309325
providerVersion: string;
310-
manifestDigest: ArtifactDigest;
326+
providerDescriptorDigest: ArtifactDigest;
311327
assets: readonly {
312328
relativePath: string;
313329
role: string;
@@ -332,10 +348,10 @@ interface ExternalAdapterContribution {
332348
surface: ArtifactSurfaceBinding;
333349
outputSchemaId: string;
334350
capabilities: readonly ArtifactCapability[];
335-
executionProfile:
351+
support: "reviewed" | "experimental-local";
352+
adapterExecutionProfile?:
336353
| "trusted-local-process"
337-
| "confined-wasm"
338-
| "opaque-web";
354+
| "confined-wasm";
339355
}
340356
```
341357

@@ -344,6 +360,10 @@ replacement for source-specific evidence. The existing Walnut receipt remains
344360
the source receipt and is referenced by digest; Qoder gains an equivalent
345361
source receipt during migration. The provider fingerprint is derived from the
346362
canonical normalized receipt, every asset digest, and selected driver versions.
363+
For Qoder, `providerDescriptorDigest` covers its normalized manifest. A
364+
manifestless source such as Walnut uses a Studio-generated canonical provider
365+
descriptor derived from the verified source receipt; implementations do not
366+
invent an empty or synthetic manifest digest.
347367

348368
External matchers are declarative. At least one selector is required; a match
349369
occurs when any declared normalized format, lowercase extension, or portable
@@ -352,9 +372,15 @@ or a content probe. A Studio-owned built-in plugin may use a separately
352372
registered bounded inspector, but Artifact bytes still cannot select its module
353373
or permissions.
354374

355-
An installed and verified provider may contribute zero adapters. Installation
356-
proves asset identity, not a supported invocation contract, safe output schema,
357-
or rendering capability.
375+
Receipt verification proves provider asset identity. Support belongs to each
376+
adapter contribution because one provider can expose several schemas, drivers,
377+
and trust profiles at different maturity levels. `reviewed` means that specific
378+
invocation and output contract has passed its implementation and validation
379+
gate; `experimental-local` remains explicitly local and unsupported for release
380+
claims. A provider may therefore be receipt-verified and contribute zero
381+
adapters. The selected contribution's support level is copied into
382+
`ArtifactProviderBinding.contributionSupport`; the provider as a whole is never
383+
upgraded by one reviewed contribution.
358384

359385
#### Qoder Canvas mapping
360386

@@ -365,35 +391,48 @@ identity. The translation layer preserves the current request-scoped artifact
365391
copy, payload validation, size limits, timeout, path redaction, and cleanup.
366392

367393
The current sidecar is trusted local Node code in a bounded child process; it is
368-
not an operating-system sandbox. Its execution profile must say so. Separating
369-
the process and limiting request input/output do not justify claims that the
370-
sidecar cannot inspect the host filesystem or use the network.
394+
not an operating-system sandbox. Its `adapterExecutionProfile` must say so.
395+
Separating the process and limiting request input/output do not justify claims
396+
that the sidecar cannot inspect the host filesystem or use the network.
371397

372398
The hosted Canvas document remains an opaque-origin iframe. Generic hosted-view
373399
routes serve the selected contribution; the browser and common server path do
374400
not branch on `qoder-canvas` after the V2 protocol edge has normalized the
375-
compatibility alias.
401+
compatibility alias. One Qoder contribution therefore binds two explicit trust
402+
layers: `adapterExecutionProfile: "trusted-local-process"` for its sidecar and
403+
`securityProfileId: "opaque-web-v1"` for its external-hosted surface. Activation
404+
records the complete adapter-plus-surface combination rather than one ambiguous
405+
execution profile.
406+
407+
Migrated Qoder contributions start with `support: "experimental-local"`.
408+
Promotion to `reviewed` requires the receipt/fingerprint migration tests,
409+
bounded sidecar and hosted-surface security tests, cross-platform portable-path
410+
tests, a real provisioned-runtime browser smoke, and explicit maintainer
411+
approval. Existing operational behavior alone does not make a release support
412+
claim.
376413

377414
During migration, an existing Qoder manifest's `overrideBuiltIn` or
378415
`overridesBuiltIn` value may be imported once into a Studio-private activation
379-
record. That compatibility import binds the verified provider fingerprint,
416+
record. That compatibility import binds the receipt-covered provider fingerprint,
380417
contribution id, declared format/path scope, and `external-override` lane. After
381418
the import, changing or adding the manifest flag cannot grant precedence; a new
382419
fingerprint requires explicit operator approval. This preserves already
383420
provisioned behavior without leaving precedence under manifest control. Only
384421
Studio-declared data-backed formats are imported; a legacy override flag that
385422
matches protected TSX/JSX, SVG, or Mermaid is ignored with a provider
386-
diagnostic.
423+
diagnostic. The first provider spec must persist an atomic migration marker with
424+
an import version and source fingerprint. Restart, partial failure, or a later
425+
manifest change cannot import the flag again or grant new precedence.
387426

388427
#### GPT Walnut mapping
389428

390-
Walnut currently contributes a verified, content-addressed provider receipt and
391-
no Artifact adapter:
429+
Walnut currently contributes a receipt-verified, content-addressed provider
430+
receipt and no Artifact adapter:
392431

393432
```ts
394433
{
395434
id: "chatgpt-walnut",
396-
support: "experimental-local",
435+
acquisition: "local-derived-experimental",
397436
receipt: verifiedReceipt,
398437
contributions: [],
399438
}
@@ -411,20 +450,26 @@ unreviewed, inactive, or tampered Walnut assets never disable it. Walnut may
411450
override a built-in adapter only after explicit per-format activation binds an
412451
exact provider fingerprint.
413452

453+
Current real ChatGPT/Walnut application discovery is macOS-only. Windows and
454+
Linux evidence covers portable receipt, cache, and path semantics; it does not
455+
claim native ChatGPT application discovery on those platforms.
456+
414457
#### External execution profiles
415458

416459
External manifests describe relative, receipt-covered assets and select only a
417460
core-known driver id. They cannot contain an arbitrary shell command or grant
418-
themselves permissions. The activation policy selects one honest execution
419-
profile, for example:
461+
themselves permissions. The activation policy binds the selected adapter
462+
execution profile and surface security profile. Adapter execution profiles are:
420463

421464
- `trusted-local-process`: explicit operator trust, a separate process, bounded
422465
request input/output, timeout, diagnostics, and cleanup, but no claim of OS
423466
filesystem or network isolation;
424467
- `confined-wasm`: only verified modules and supplied buffers, with no host
425-
filesystem or network access exposed by the driver; or
426-
- `opaque-web`: browser execution in an opaque-origin iframe under a
427-
core-selected CSP and message protocol.
468+
filesystem or network access exposed by the driver.
469+
470+
An `external-hosted` surface separately and necessarily binds the core-owned
471+
`opaque-web-v1` profile: an opaque-origin iframe, core-selected CSP, and generic
472+
message protocol. A native surface has no external browser execution profile.
428473

429474
Environment variables are allowlisted per driver. Provider and artifact paths
430475
are never accepted from browser input. Diagnostics are bounded and scrubbed.
@@ -459,10 +504,11 @@ stealing precedence from a format activation.
459504

460505
The activation record is Studio-private, server-owned operator configuration;
461506
it is not part of the browser catalog or an external manifest. It records
462-
provider id, contribution id, fingerprint, scope, lane, execution profile, and
463-
user consent. The first external-provider implementation spec must select its
464-
portable persistence location and atomic update contract. A provider update
465-
invalidates the activation until the new fingerprint is verified and approved.
507+
provider id, contribution id, fingerprint, contribution support, scope, lane,
508+
adapter execution profile, surface security profile, and user consent. The
509+
first external-provider implementation spec must select its portable
510+
persistence location and atomic update contract. A provider update invalidates
511+
the activation until the new fingerprint is receipt-verified and approved.
466512

467513
Provider verification failure removes its contributions before resolution, so
468514
the next catalog can select the native or another fallback plugin. A runtime
@@ -552,14 +598,15 @@ format-specific control flow inside catalog projection, generic routes, or the
552598
- SVG and Beautiful Mermaid can share the React/esbuild preview lifecycle
553599
without making arbitrary document bytes executable in Studio origin.
554600
- Qoder compatibility remains available but no longer defines the host model.
555-
- Walnut can be discovered and verified honestly before it has a supported
601+
- Walnut can be discovered and receipt-verified honestly before it has a supported
556602
Adapter; capability follows reviewed contributions rather than installation.
557603
- Adding a format requires a plugin contribution, schemas, renderer surface,
558604
limits, and tests. It may add declarative classification and composition
559605
entries, but it should not require a new control-flow branch in the catalog,
560606
server router, or `ArtifactView` host.
561-
- Provider receipts, fingerprint-aware catalog revisions, activation state, and
562-
execution profiles add implementation and operational complexity.
607+
- Provider receipts, fingerprint-aware catalog revisions, activation state,
608+
adapter execution profiles, and surface security profiles add implementation
609+
and operational complexity.
563610
- The current Qoder trusted-process boundary remains weaker than a true sandbox
564611
and must stay labeled accordingly until a stronger driver is implemented.
565612
- Session trace, retention, compare, and replay remain unavailable until their
@@ -574,7 +621,7 @@ format-specific control flow inside catalog projection, generic routes, or the
574621
class hierarchy.
575622
- **Let the browser choose by extension or payload kind.** Rejected because it
576623
duplicates server policy and permits selection/execution drift.
577-
- **Treat a verified Walnut installation as a working Adapter.** Rejected
624+
- **Treat a receipt-verified Walnut installation as a working Adapter.** Rejected
578625
because asset identity does not prove an invocation or output contract.
579626
- **Allow external manifests to run arbitrary commands.** Rejected because the
580627
manifest would become a self-authorizing code execution API.
@@ -599,9 +646,10 @@ review evidence.
599646
existing data-format override flags once into fingerprint-bound activation,
600647
and preserve fallback/browser behavior. Protected Studio code-backed formats
601648
are not override-eligible.
602-
3. Project a verified Walnut installation as an external provider with zero
603-
contributions. Expose installed, verified, inactive, and unavailable states
604-
without weakening native PPTX.
649+
3. Project a receipt-verified Walnut installation as a locally derived external
650+
provider with zero contributions. Expose installed, receipt-verified,
651+
inactive, and unavailable states without weakening native PPTX. Any future
652+
Walnut contribution starts with `support: "experimental-local"`.
605653
4. Add a Walnut format contribution only after its invocation, output schema,
606654
execution profile, licensing boundary, and cross-platform evidence have been
607655
reviewed.
@@ -626,13 +674,14 @@ review evidence.
626674
- Qoder migration tests preserve explicit override, native-before-fallback,
627675
request-scoped copies, bounded sidecar behavior, path scrubbing, iframe
628676
isolation, legacy V2 wire behavior, one-time override import, protected
629-
code-backed formats, and real provisioned-runtime smoke coverage where
630-
available.
677+
code-backed formats, initial `experimental-local` contribution support, and
678+
real provisioned-runtime smoke coverage where available.
631679
- Provider tests prove receipt portability on Windows, macOS, and Linux;
632680
relative-path confinement; full asset fingerprinting; tamper invalidation;
633681
explicit activation; and catalog revision movement.
634-
- Walnut tests prove that a verified installation with zero contributions does
635-
not advertise a renderer and cannot displace the native PPTX adapter.
682+
- Walnut tests prove that a receipt-verified installation with zero
683+
contributions does not advertise a renderer and cannot displace the native
684+
PPTX adapter.
636685
- Session trace tests, when that slice exists, prove exact retained revision and
637686
event/tool evidence identity and explicitly reject current-worktree inference.
638687
- Visual verification covers wide, compact, and narrow Artifact surfaces,

0 commit comments

Comments
 (0)