Skip to content

Commit 5d136f6

Browse files
phodalQoder-AI
andcommitted
feat(studio): add revision-bound artifact views
Refactors Artifact View around immutable revisions, adapters, snapshots, and renderer plugins. Adds cross-platform native PPTX rendering, grouped browsing, the Qoder Canvas bridge, and explicit Studio-private Walnut bootstrap controls. Implements docs/specs/2026-08-21-studio-artifact-view-model.md. Validated with 137 Studio tests, 17 Playwright scenarios, and 1,435 repository tests. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
1 parent 71e771e commit 5d136f6

28 files changed

Lines changed: 2878 additions & 223 deletions
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# Unify artifact revisions, adapters, and renderers in Studio
2+
3+
## Traceability
4+
5+
- Spec ID: studio-artifact-view-model
6+
- Status: Implemented
7+
8+
## Intent
9+
10+
Refactor Harness Studio's flat preview descriptor into a data-backed Artifact
11+
View lifecycle with explicit content revisions, data adapters, immutable
12+
snapshots, renderer providers, and user-facing browsing. Use that lifecycle to
13+
render PPTX files in Studio without treating Canvas as the universal Artifact
14+
abstraction or executing presentation bytes as code.
15+
16+
Canvas remains the name of the existing Qoder Canvas Viewer integration only.
17+
The Studio-owned abstraction is Artifact View:
18+
19+
```text
20+
Artifact Revision -> Data Adapter -> Data Snapshot -> Renderer -> View Host
21+
```
22+
23+
This increment implements the data-backed half of that model. Code project
24+
compilation, build snapshots, preview execution, cross-revision comparison, and
25+
Session trace addressing remain future work.
26+
27+
## Decisions
28+
29+
### D-1: Catalog V2 owns file identity and presentation references
30+
31+
`HarnessStudioArtifactCatalogV2` remains a read-only, browser-safe catalog. Each
32+
descriptor contains:
33+
34+
- a stable catalog-local thread id;
35+
- an exact revision id and SHA-256 digest;
36+
- the bounded content reference;
37+
- a data-backed family and format;
38+
- the selected adapter id/version/schema and snapshot URI;
39+
- the selected renderer id/provider/type/status;
40+
- renderer capabilities and an optional unavailable reason.
41+
42+
The catalog does not inline parsed Office payloads, absolute paths, runtime
43+
code, UI state, or Session claims. V1 is superseded rather than extended with a
44+
parallel optional-field vocabulary.
45+
46+
### D-2: ArtifactDataSnapshotV1 is immutable and format-specific
47+
48+
Every snapshot is bound to one artifact id and revision id. Its common envelope
49+
contains adapter provenance, summary, structure, semantic addresses, resources,
50+
diagnostics, and a discriminated payload. The first payloads are:
51+
52+
- `artifact/raw-v1`: exact content reference for direct text/image/SVG/JSON
53+
renderers;
54+
- `pptx/v1`: deck size, ordered slides, shapes, text runs, images, notes,
55+
addresses, and unsupported-feature diagnostics.
56+
57+
Snapshot generation is bounded by compressed input, expanded entry, entry
58+
count, text, media, and response limits. Artifact bytes never choose an adapter
59+
or local executable path.
60+
61+
### D-3: The plugin registry chooses Adapter and Renderer separately
62+
63+
The trusted registry resolves one data adapter and one renderer for each file.
64+
Resolution order is:
65+
66+
1. an operator-provisioned Qoder Canvas viewer with `overrideBuiltIn`;
67+
2. a Studio-native data-backed plugin;
68+
3. a matching non-overriding Qoder Canvas viewer;
69+
4. the raw adapter plus an honest unavailable renderer.
70+
71+
Qoder viewer `scripts/index.mjs` is wrapped as a
72+
`QoderViewerSidecarAdapter`; `index.canvas.tsx` is wrapped as a
73+
`QoderCanvasRenderer`. The existing opaque-origin iframe and runtime discovery
74+
remain the bridge implementation.
75+
76+
The current `esbuild-wasm` transform is a `TrustedRendererCompiler`. It compiles
77+
only provisioned renderer code and is not an Artifact compiler.
78+
79+
### D-4: PPTX has a cross-platform native baseline
80+
81+
`PptxArtifactDataAdapter` parses untrusted OOXML with pure JavaScript libraries
82+
inside the Studio server. It reads slide order, slide dimensions, positioned
83+
shapes, text runs, fills, images, and speaker-note presence into `pptx/v1`.
84+
85+
`NativePptxRenderer` renders the snapshot as a slide rail plus DOM stage. It
86+
supports navigation, zoom-to-fit, and semantic slide/shape addresses. Unsupported
87+
OOXML is reported in diagnostics; the baseline is observable coverage, not
88+
PowerPoint or Walnut pixel parity.
89+
90+
An installed ChatGPT Walnut runtime remains an explicit, Studio-private,
91+
experimental provider receipt. `harness-studio walnut probe|install|verify|remove`
92+
may provision reviewed assets only after consent, but no private ChatGPT API is
93+
treated as a parser contract. The native PPTX adapter is therefore the default
94+
portable fallback. A future reviewed Walnut adapter can implement the same
95+
snapshot schema without changing the catalog or renderer host.
96+
97+
### D-5: Artifact View uses a grouped Explorer
98+
99+
The left pane defaults to collapsible format families:
100+
101+
1. Documents;
102+
2. Images & diagrams;
103+
3. Data;
104+
4. Source & text;
105+
5. Other.
106+
107+
It provides filename search and a `Grouped | Flat` presentation switch. This is
108+
not a filesystem tree: the current catalog has no relative paths or directory
109+
nodes. Folder Tree becomes eligible only after a future catalog owns confined
110+
path hierarchy and recursive indexing.
111+
112+
Rows show a format icon, filename, human format, size, and an accessible
113+
unavailable indicator. The preview owns the selected filename, revision,
114+
adapter/renderer metadata, snapshot diagnostics, and document navigation.
115+
116+
At narrow width, Explorer and Preview become two view tabs so a long list cannot
117+
push the selected document below the fold.
118+
119+
## Acceptance Scenarios
120+
121+
- **AC-1:** `/api/artifacts` returns only a valid
122+
`HarnessStudioArtifactCatalogV2`; each artifact has an exact revision and
123+
content digest, adapter reference, snapshot URI, renderer reference, family,
124+
and capabilities. Absolute filesystem paths never reach the browser.
125+
- **AC-2:** `/api/artifacts/:id/snapshot` returns a valid
126+
`ArtifactDataSnapshotV1` bound to the descriptor revision. A changed source
127+
digest cannot reuse the prior snapshot.
128+
- **AC-3:** Direct code, diff, JSON, text, image, and SVG behavior remains inert
129+
and readable through native renderers. Arbitrary artifact TSX/JSX is never
130+
executed.
131+
- **AC-4:** A real PPTX produces ordered slides, dimensions, positioned text
132+
shapes, embedded images, notes presence, semantic addresses, and explicit
133+
diagnostics. Corrupt, oversized, path-traversing, or expansion-heavy OOXML
134+
fails closed without stopping other Studio routes.
135+
- **AC-5:** The native PPTX renderer opens the repository's
136+
`Better-Harness-one-page.pptx` in Studio, visibly renders its first slide,
137+
exposes slide navigation and adapter/renderer identity, and has no page or
138+
console errors.
139+
- **AC-6:** An overriding Qoder viewer still wins. A non-overriding viewer is a
140+
fallback when no native plugin exists. Qoder sidecar adaptation and renderer
141+
compilation retain timeout, size, temp cleanup, path scrubbing, CORS, CSP,
142+
and opaque-origin iframe boundaries.
143+
- **AC-7:** Walnut bootstrap remains explicit, content-addressed,
144+
receipt-verified, Studio-private, and absent from normal startup, npm package
145+
bytes, source control, and release claims. Missing or unreviewed Walnut builds
146+
do not disable native PPTX rendering.
147+
- **AC-8:** Grouped and Flat explorer modes preserve the selected revision;
148+
search matches filenames only; empty groups disappear; PPTX belongs to
149+
Documents regardless of renderer provider.
150+
- **AC-9:** At 1440x900, 1024x768, and 390x844, the explorer and PPTX stage have
151+
no document-level horizontal overflow, keyboard focus is visible, the preview
152+
remains reachable, and dark/light contrast remains accessible.
153+
- **AC-10:** Debugger and other catalog consumers use V2 descriptors without
154+
inventing retained artifacts or reconstructing content/snapshot URLs from
155+
ids.
156+
- **AC-11:** Package typecheck/build/tests, root tests, package audit, Markdown
157+
link graph, and preview health/runtime smoke checks pass or report an exact
158+
external Canvas-runtime prerequisite separately.
159+
160+
## Non-goals
161+
162+
- ArtifactThread persistence across renamed files or independent Sessions.
163+
- Parent revision chains, replay storage, compare mode, annotations, mutation,
164+
save-back, or Office round-trip editing.
165+
- XLSX, DOCX, PDF, GLB, Lottie, or Mermaid native adapters in this increment;
166+
the registry and snapshot contract make them additive follow-ups.
167+
- ArtifactCompileRuntime, project bundling, virtual filesystems, incremental
168+
rebuilds, WebContainer, Sandpack, or executable React artifacts.
169+
- Copying or distributing Walnut, ChatGPT hashed chunks, private protobufs,
170+
application IPC, or full `ArtifactTabContent` UI.
171+
- Claiming PowerPoint, Walnut, or Qoder Canvas pixel parity.
172+
173+
## Plan and Tasks
174+
175+
1. Replace the V1 catalog contract with browser-safe V2 revision, adapter,
176+
renderer, family, capability, and snapshot contracts.
177+
2. Introduce an Artifact plugin registry; adapt existing direct renderers and
178+
Qoder Canvas discovery behind separate adapter/renderer references.
179+
3. Rename the trusted Canvas TSX transform boundary to
180+
`TrustedRendererCompiler` and the host boundary to
181+
`QoderCanvasViewerBridge`, retaining compatibility re-exports only where
182+
focused tests still need them.
183+
4. Implement bounded OOXML ZIP/XML parsing, PPTX snapshots, snapshot/resource
184+
routes, cache identity by source digest plus adapter version, and behavioral
185+
malformed-input tests.
186+
5. Implement the grouped Artifact Explorer and native PPTX renderer with shared
187+
Studio tokens, semantic slide addresses, diagnostics, and responsive tabs.
188+
6. Keep and integrate the explicit Walnut bootstrap commands as provider
189+
capability evidence; do not make Studio startup mutate the cache.
190+
7. Validate direct renderer regressions, Qoder override/fallback behavior, the
191+
real repository PPTX, browser layouts, package/root gates, package contents,
192+
and diff hygiene.
193+
194+
## Test and Review Evidence
195+
196+
- AC-1/AC-2/AC-4/AC-10: 137 Studio tests passed across 21 files. Focused PPTX
197+
tests cover exact revision and snapshot binding, leading-zero text, positioned
198+
shapes, embedded resources, notes path redaction, semantic addresses, corrupt
199+
archives, unsafe ZIP paths, oversized expanded entries, and cache invalidation.
200+
- AC-3/AC-6: the V2 catalog, direct renderers, Qoder override/fallback registry,
201+
sidecar freshness, trusted renderer compilation, active-content CSP, SVG
202+
sandbox, and malformed route behavior all remain covered in that package run.
203+
- AC-5/AC-8/AC-9: all 17 Playwright scenarios passed. Native PPTX rendering,
204+
Grouped Explorer, wide 1440x900, compact 1024x768, narrow 390x844, automatic
205+
Preview navigation, keyboard focus, horizontal overflow, theme contrast, and
206+
browser errors are verified with screenshots. The live in-app browser also
207+
rendered `Better-Harness-one-page.pptx`: 19 shapes, one complete 1280x950
208+
image, preserved `01` text, no page overflow, and no console/page errors.
209+
- AC-7: eight focused Walnut bootstrap tests cover explicit consent,
210+
content-addressed install, verification, tamper detection, app-change
211+
invalidation, symlink rejection, removal, and cross-platform cache roots. A
212+
read-only real probe found ChatGPT 26.818.22352 and 34 reviewed assets for
213+
DOCX/PPTX/XLSX. Package dry-run contained 926 files and no ASAR/WASM or
214+
extracted ChatGPT asset.
215+
- AC-11: Studio typecheck/build/tests, full browser suite, 1,435 root tests,
216+
six Markdown link-graph tests, package dry-run, and `git diff --check` passed.
217+
The optional root Canvas preview smoke was not runnable because no Canvas SDK
218+
runtime was configured; native PPTX rendering does not use that runtime.
219+
220+
### Risks
221+
222+
- **Model overreach:** the attachment describes a larger future runtime. This
223+
increment freezes only data-backed contracts exercised by current consumers.
224+
- **PPTX fidelity:** fonts, themes, layout inheritance, charts, SmartArt,
225+
animation, cropping, and grouped transforms are complex. Diagnostics must
226+
preserve uncertainty rather than imply parity.
227+
- **Archive expansion:** OOXML is a ZIP container. Enforce compressed,
228+
expanded, entry-count, path, media, and snapshot limits independently.
229+
- **Plugin trust:** artifact bytes may select a format but never a plugin path.
230+
Only the operator-controlled registry and provisioned viewer roots execute.
231+
- **Cache staleness:** cache keys include artifact digest, adapter id/version,
232+
and schema id; mutable file metadata alone is not sufficient identity.
233+
- **UI density:** format groups improve findability only if search, selection,
234+
disclosure, and narrow Preview navigation remain distinct and keyboard-safe.

0 commit comments

Comments
 (0)