stillmade-sdk 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/.claude/settings.json +15 -0
  2. package/.cursor/hooks.json +11 -0
  3. package/.gitignore +2 -0
  4. package/.stillmade/sdk-baseline.json +65 -0
  5. package/AGENTS.md +29 -7
  6. package/AGENT_CONTROL.md +2 -1
  7. package/BROWSER_APPLICATIONS.md +128 -3
  8. package/GITHUB_APPLICATIONS.md +184 -1
  9. package/NATIVE_APPLICATION_ADAPTATION.md +565 -0
  10. package/NATIVE_MCP.md +3 -2
  11. package/PASTE_TO_LLM.md +29 -10
  12. package/PORTABLE.md +5 -4
  13. package/REMIX.md +16 -10
  14. package/SDK.md +511 -46
  15. package/UI_AESTHETIC.md +37 -6
  16. package/api-index.json +90 -0
  17. package/blocks/connected-app/versions/{1.2.0 → 1.5.0}/task-selection.js +5 -3
  18. package/blocks/connected-app/versions/{1.4.0 → 1.5.0}/view.js +4 -2
  19. package/blocks/native/sm.ai-decide/versions/1.0.0/package.js +149 -0
  20. package/blocks/native/sm.ai-write/versions/1.0.0/package.js +147 -0
  21. package/blocks/native/sm.connect-app/versions/1.0.0/package.js +55 -0
  22. package/blocks/native/sm.contact-fields/versions/1.0.0/package.js +197 -0
  23. package/blocks/native/sm.continue-if/versions/1.0.0/package.js +168 -0
  24. package/blocks/native/sm.generate-image/versions/2.1.0/package.js +101 -0
  25. package/blocks/native/sm.meta-creative/versions/1.0.0/package.js +206 -0
  26. package/blocks/native/sm.new-items/versions/1.0.0/package.js +191 -0
  27. package/blocks/native/sm.voiceover/versions/2.1.5/package.js +179 -0
  28. package/blocks/native/sm.voiceover/versions/2.1.6/package.js +179 -0
  29. package/blocks/native/sm.when/versions/1.0.0/package.js +129 -0
  30. package/blocks/native/sm.write-summary/versions/1.0.0/package.js +133 -0
  31. package/blocks/occasion-story/package.js +1 -1
  32. package/blocks/occasion-story/versions/1.0.2/package.js +1682 -0
  33. package/blocks/photo-reel-composer/versions/1.0.1/package.js +3026 -0
  34. package/blocks/release-visuals/package.js +1 -1
  35. package/blocks/release-visuals/versions/1.0.2/package.js +1500 -0
  36. package/blocks/short-form-finish/package.js +1 -1
  37. package/blocks/short-form-finish/versions/1.0.3/package.js +1026 -0
  38. package/examples/original-photo-editor.stillmade-block +0 -0
  39. package/examples/portable-regexp.stillmade-block +0 -0
  40. package/package.json +1 -1
  41. package/packages/block-cli/cli.js +16 -1
  42. package/packages/block-cli/format.js +2 -0
  43. package/packages/block-cli/ready-gate.js +164 -0
  44. package/packages/block-platform/block-readiness.js +3 -2
  45. package/packages/block-platform/canvas.js +1 -1
  46. package/packages/block-platform/catalog.js +6 -4
  47. package/packages/block-platform/chat-requirements.js +8 -3
  48. package/packages/block-platform/collaboration.js +5 -5
  49. package/packages/block-platform/first-revenue-project-types.js +2 -2
  50. package/packages/block-platform/flow-inspection.js +2 -2
  51. package/packages/block-platform/native-application-validation-context.js +20 -0
  52. package/packages/block-platform/plain-descriptions.js +67 -0
  53. package/packages/block-platform/product-ad-variants-project-type.js +6 -3
  54. package/packages/block-platform/project-context.js +4 -4
  55. package/packages/block-platform/project-type-composer.js +21 -12
  56. package/packages/block-platform/project-type-draft.js +2 -2
  57. package/packages/block-platform/project-type-recommendations.js +1 -1
  58. package/packages/block-platform/project-types.js +9 -4
  59. package/packages/block-platform/revenue-review-project-types.js +6 -5
  60. package/packages/block-platform/segment-runner.js +35 -11
  61. package/packages/block-platform/step-groups.js +78 -0
  62. package/packages/block-platform/steps.js +12 -8
  63. package/packages/block-platform/type-workspace.js +4 -4
  64. package/packages/block-platform/workflow-loop.js +4 -0
  65. package/packages/block-platform/workspace-input-readset.js +18 -4
  66. package/packages/block-sdk/admission.js +5 -17
  67. package/packages/block-sdk/agent-inputs.js +2 -0
  68. package/packages/block-sdk/agent-inspection.js +4 -2
  69. package/packages/block-sdk/browser-application-artifacts.js +1 -1
  70. package/packages/block-sdk/browser-application-execution.d.ts +2 -2
  71. package/packages/block-sdk/browser-application-execution.js +30 -12
  72. package/packages/block-sdk/browser-application-guest.d.ts +2 -0
  73. package/packages/block-sdk/browser-application-guest.js +16 -9
  74. package/packages/block-sdk/browser-application.d.ts +12 -4
  75. package/packages/block-sdk/browser-application.js +27 -13
  76. package/packages/block-sdk/builder-contract.js +25 -17
  77. package/packages/block-sdk/capabilities.js +38 -19
  78. package/packages/block-sdk/connected-app.js +26 -6
  79. package/packages/block-sdk/connection-adapters.js +19 -2
  80. package/packages/block-sdk/contracts-core.js +8 -0
  81. package/packages/block-sdk/contracts.js +9 -5
  82. package/packages/block-sdk/document-drafts.js +7 -1
  83. package/packages/block-sdk/document-store-binding.js +2 -1
  84. package/packages/block-sdk/file-bundle.js +4 -1
  85. package/packages/block-sdk/first-party-packages.js +18 -2
  86. package/packages/block-sdk/generation-catalog.js +3 -2
  87. package/packages/block-sdk/index.d.ts +20 -1
  88. package/packages/block-sdk/index.js +1 -0
  89. package/packages/block-sdk/native-application-package.d.ts +22 -0
  90. package/packages/block-sdk/native-application-package.js +77 -0
  91. package/packages/block-sdk/native_adapter.py +76 -0
  92. package/packages/block-sdk/package.json +1 -0
  93. package/packages/block-sdk/pipeline-runtime-host.d.ts +2 -0
  94. package/packages/block-sdk/project-flow-contract.js +2 -0
  95. package/packages/block-sdk/remix-policy.js +3 -1
  96. package/packages/block-sdk/resolver-admission.js +17 -0
  97. package/packages/block-sdk/runtime.js +4 -1
  98. package/packages/block-sdk/schema-fields.js +34 -2
  99. package/packages/block-sdk/semantic-relationships.js +14 -0
  100. package/packages/block-sdk/shared-controls.js +3 -1
  101. package/packages/block-sdk/shared-view.js +6 -1
  102. package/packages/block-sdk/source-rights.js +6 -5
  103. package/packages/block-sdk/testing.js +3 -0
  104. package/packages/design-system/theme.css +12 -3
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "Stop": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "node \"$CLAUDE_PROJECT_DIR/packages/block-cli/ready-gate.js\" --claude",
9
+ "timeout": 600
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "stop": [
5
+ {
6
+ "command": "node packages/block-cli/ready-gate.js --cursor",
7
+ "timeout": 600
8
+ }
9
+ ]
10
+ }
11
+ }
package/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .stillmade/ready-cache.json
2
+ .stillmade/gate-state.json
@@ -0,0 +1,65 @@
1
+ {
2
+ "version": 1,
3
+ "packages": {
4
+ "examples/asset-metadata.stillmade.json": "eb47dbde4d3d6857c829c223d56de9f76a3b1af5dffeff2f0ca433ba4678089b",
5
+ "examples/camera-recorder.stillmade.json": "6300bee739f4ebe1ca23ae43e3f412e9100a048df0df1f65db32eb0365658f27",
6
+ "examples/caption-from-text.stillmade.json": "3731a15b59043fbebee98416f2474800ef0154aa7873fb494934874ddcd2c705",
7
+ "examples/captions.stillmade-block": "b0fde32dddaf866f3e540018309aaa00ae56b0e74a53a498fbaf1553ce200bd6",
8
+ "examples/check-clip.stillmade.json": "cf83af5a3317cd714282939f6cd40cd0c459fb5af97e97e5148f1ca81b4b1b87",
9
+ "examples/clean-text.stillmade.json": "1d0ab95c652b201540fec45918651cdcffa7a70ea7909a17f8c1ad80345797e2",
10
+ "examples/comfy-invert.stillmade.json": "126bd3a8a88e14c08ae11c62a441ed099d83e16830e2062f936e14e56cb297eb",
11
+ "examples/comfy-text-to-image.stillmade.json": "957a616887115984c1888cf9c0eee2fe771dcbf041166ad112fb6c3feb7ad4dd",
12
+ "examples/custom-interface.stillmade.json": "e824f14f61b21d747a668faae55ad4f8afca9c2942a48436baefaa6925eb5a1b",
13
+ "examples/describe-image.stillmade.json": "1cf5985eaf7c27150815887c2f4550b3c5c716e9f2badda22ace606c082ac7cd",
14
+ "examples/docs-only-campfire-narrator.stillmade.json": "87c6a3b643b1ee007487e162aeced6f6302648f4c4a58b015e7df2ab9f2959be",
15
+ "examples/docs-only-custom-ui.stillmade.json": "4602fd6b9576d364e16b79d2f08b196a251a8e98cf3149576686a96680a5dfe6",
16
+ "examples/docs-only-gentle-trailer.stillmade.json": "ec081cc8aad654728dcd51257cb69603ec87fcc973ed2b1c5ea3d60a84c4c436",
17
+ "examples/docs-only-grayscale-original.stillmade.json": "9d04e6187d96ea49bdbdc20a257ccd25c2f3c20fa2359f1bf2de4664d32edf92",
18
+ "examples/docs-only-grayscale.stillmade.json": "c0453244cae4c7c07b632e420848e9a7f5de2bfc08b5b7350be917f81f4cfe48",
19
+ "examples/docs-only-image-studio.stillmade.json": "cbcaaa2ed1ff96c2f5310281afe5430215463381e48f36d7cc3b7fbf35f86f44",
20
+ "examples/docs-only-retained-versions.stillmade.json": "78b84f0e843887c2078ac3271d9c69ea779c31f94aee8d49f7465b8bbafef640",
21
+ "examples/docs-only-storybook-cover.stillmade.json": "7c94639d9bec5a673fe33f3c8c9b98e1119bea58a2fc8d0a7a98dabf73cc9a35",
22
+ "examples/export-timeline.stillmade-block": "7d3221dc3ec1491f420773edb0ad8612c650755111e1e8561510b68508976199",
23
+ "examples/foley-cue.stillmade.json": "5d274b5b646af166e0fc79e3b60004b4cce6ee82b58428dab542537794850df1",
24
+ "examples/generate-image.stillmade.json": "85c0b68f03535d30c1aacb857197135fc4384c0de50cc777ae02333b34e0d8e2",
25
+ "examples/generate-video.stillmade.json": "26c3d392ec8ee14ce805078eee4868cdcf53a6c885daa4135bd52fd9bf8caa4b",
26
+ "examples/grayscale.stillmade.json": "8c901790c25d2544f284a6a43341f72aa6b7e9211bef272b2e1d53c92b9e5faf",
27
+ "examples/import-media.stillmade-block": "e9642e203080f1a145bec81871525a670f98dd1c8763862f81ab876fb15a656b",
28
+ "examples/javascript-cloze-quiz": "b36a370c8b53250b9bb04783591661268ec674052bc13bf8cc8910fa27151f83",
29
+ "examples/javascript-invoice": "853f1464393563ac6e330f4d90cd97f6768d753cbd26b3191bb0838506530ffd",
30
+ "examples/microphone-recorder.stillmade.json": "ee6d420ab37ccffca42dcea737422e8fd13fe2ead65023740a2e7f7e50459141",
31
+ "examples/module-action-items": "ba6026bddb7efbd5fc3ccbab994fab435917723e2668a395feb5c98f5a68b1d1",
32
+ "examples/module-audio-extract": "5afc1ef4a5d6594e312acdaf7e171307a56ad60a20ca28b7cfa25dfc579cc8ab",
33
+ "examples/module-brand-kit": "cff0dd8b86f8a63a2ff52f192be275fa77794d8e0a6546b0923f31cec4e0ddbd",
34
+ "examples/module-csv-summary": "0303ea851d3512def907b75f297f11279cc862db8069abed7f9069304155a3cd",
35
+ "examples/module-notion-to-airtable": "5bc6f3696618e94d3ede339a567bfaea1bd95e84df940f49b7075192502a18cf",
36
+ "examples/module-opencv": "6e809a597f3ea40877bcf0669b22b0a4e59fe0602a9bbcb77c90ea43bc670330",
37
+ "examples/module-pdf-shot-list": "b372674aae8ef3392cc679cbfca25a76afcbf2271d5577e4055d2097d8a9ff24",
38
+ "examples/module-silence-trimmer": "baeb12ae028122d1bd05312c6b0680c33f95c7ea8c176675678a1c4ff005fa86",
39
+ "examples/module-tempo": "d2b842114e12b50de57f46ff004d6213022120c8dd7908fb7cb3648cd0e1d29a",
40
+ "examples/module-word-stats": "d89eacc4395bb7eae69f25509454659798946178fdccc5748e383392c370927f",
41
+ "examples/narrate-script.stillmade.json": "ce88242a4ac699443a8e002856182da2e70dd71e52ba62a9142f0a8fa0c848da",
42
+ "examples/numbered-takes.stillmade.json": "e4eef4f065f0458ab43413b1a584f887203f5208e83556a7f99c5927383f5d99",
43
+ "examples/original-photo-editor": "12e88abd9cdeea6eba983699aa81fe8f29aca06bd8cb6d61dece9fb951dd702f",
44
+ "examples/original-photo-editor.stillmade-block": "32af42f5ac9ce2d27e731984511f71313f1e011ad88318440b91eed838f0c05f",
45
+ "examples/portable-regexp.stillmade-block": "538930eb4546ac2c0860025dbfc4717317e1d867e66b926c49ecd91dcf3b0666",
46
+ "examples/portable-regexp.stillmade.json": "fd769d584a6437e2a37c7e4101a031c0fef740afc76ef91f2337e2956fb08a1a",
47
+ "examples/quieter-clips.stillmade.json": "23b026b267e5da522cc6a3a6af51e166a64fcc1d5391e855704fe1e1f243401b",
48
+ "examples/research-topic.stillmade.json": "8cfed5313c073db959c2d468ce470bd47ec5e8de4b4ec2def13591b9bf2f723e",
49
+ "examples/saas-product-launch-reviewed-source.stillmade.json": "2ec264a160faba338f3924965f935ce92c3fdad1fb69719921d7561353b010ab",
50
+ "examples/saas-product-launch.stillmade.json": "aabec7d8680ef6687980296ab170bbb002c0dc81bc15edebdf9db9750e43eddb",
51
+ "examples/scene-shots.stillmade.json": "d10a0aebb42ff090035410dc92ab708ffaf50b579edac4aa2f2cf6150b3ef537",
52
+ "examples/score-a-scene.stillmade.json": "ecc05642d82d2507803389350c7ea574c4c3f761dd629289e0c1c8fa28713292",
53
+ "examples/screen-recorder.stillmade.json": "86a6c935253c3b06d727ded8295fb3f025ff2ceb4fdb9be72b2118516fbb62ce",
54
+ "examples/script-draft.stillmade.json": "6c62787353c361ed2e9e255eb03047093ebdc4d678cfeb8be97b8b36e27b4102",
55
+ "examples/shot-readiness.stillmade.json": "ed73fe9038afaed7c12435368e90001f0bd3cebd8f0e6fe06508c1bb80c8cb7e",
56
+ "examples/summarize-page.stillmade.json": "fe2956a76d99d5cb10de69b763649064991ac9ac00a8e216db852a725be3e65e",
57
+ "examples/text-workflow.stillmade.json": "0d53e7498fb47702055e206b75e0111bb1cdcca1b086931e4628e0a3c79e70dc",
58
+ "examples/thicken-lines.stillmade.json": "7948c6d686de61cd32234a00f12c22229d601360093f50966d50b4e8a4ee759c",
59
+ "examples/timeline-mixer.stillmade.json": "93220984a88ca553dcf7102ce82b23d16eadda07809a89222a8589506743b5f8",
60
+ "examples/timeline-polish.stillmade.json": "ababd22681cbd640a4e28469f428161fe739dfca007b87b7563c39c214597997",
61
+ "examples/transcribe-audio.stillmade.json": "75754c5389dd49ed5b3c784f5ee5b17926c02afbf0c94fb9c0d1fb8830f64c57",
62
+ "examples/view-react-chart": "a0e7ef5148e386b34e405187761d23f1739809c3d72c68c7c6b4e2193747218e",
63
+ "examples/word-count.stillmade.json": "6731ab355c4d5918e0b106481a0486303653a6bd19696e52bb21aaac38118d53"
64
+ }
65
+ }
package/AGENTS.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # Building StillMade Blocks in this folder
2
2
 
3
- This folder is the StillMade Block SDK. Read this file before writing code; it is the same contract StillMade's own AI and importers follow. Scaffold with `node packages/block-cli/cli.js create my-block javascript`, then iterate with `validate my-block` and `test my-block`, check admission with `pack my-block /tmp/my-block.stillmade-block --original`, and finish with `ready my-block`, the same readiness check StillMade runs before a release. `SDK.md` is the complete reference and `PASTE_TO_LLM.md` the detailed authoring guide.
3
+ This folder is the StillMade Block SDK. Read this file before writing code; it is the same contract StillMade's own AI and importers follow. Scaffold with `node packages/block-cli/cli.js create my-block javascript`, then iterate with `validate my-block` and `test my-block`, check admission with `pack my-block /tmp/my-block.stillmade-block --original`, and finish with `ready my-block`, the same readiness check StillMade runs before an install or a release. `SDK.md` is the complete reference and `PASTE_TO_LLM.md` the detailed authoring guide.
4
4
 
5
- Contract `stillmade.block-builder@1.0.0`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
5
+ ## Readiness gate
6
+
7
+ Do not tell the user a Block is ready, done or working until `node packages/block-cli/cli.js gate .` passes after your last edit, and report the exact status it prints. In this folder Claude Code (`.claude/settings.json`) and Cursor (`.cursor/hooks.json`) run the gate when you finish a turn and send any failures back to you, but only in a session started in this folder: if you downloaded the SDK during the current session, run the gate yourself. Other agents must also run it themselves. If you cannot fix a failure, say plainly that the Block is not ready and list the failing checks.
8
+
9
+ Contract `stillmade.block-builder@1.3.0`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
6
10
 
7
11
  ## Source of truth
8
12
 
@@ -12,13 +16,27 @@ Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` con
12
16
 
13
17
  Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
14
18
 
19
+ ## One job per Step
20
+
21
+ A Step is one job: the work between two moments where a person or the outside world must see the result. Start a new Step only at one of three points; everything else is a part of the neighboring Step.
22
+
23
+ 1. **A person works with the result**: reads, edits, picks or approves it (a workspace Block such as a script, a Canvas or an Editor, or an approval). That is why Chat, Bible, Canvas and Editor are four Steps.
24
+ 2. **Finding new things turns into handling each one**: the trigger (a schedule or an app event), the app read, its filter and "only new" are the first job; what is done with each item is the next job. A trigger is a setting of the first job, never a Step of its own.
25
+ 3. **The result leaves StillMade**: it is sent, posted, published, paid or written into another app. Consecutive writes to the same app, with the glue that shapes data for them, are one job.
26
+
27
+ A part that only runs in the desktop app cannot share a Step with cloud parts. Before adding a Step, name which of the three reasons makes it separate; if none applies, make it a part of a neighbor. A Step nobody would ever open must not exist on its own. Prefer an app task's own filter (a Gmail query such as `has:attachment filename:png`) to an AI check, and use AI decide only for judgement.
28
+
29
+ Inside one job, each capability stays its own part: a capability Block performs exactly one hosted operation and a connector one app task, so every part keeps its own permission, approval and credit rules, and StillMade groups the parts of one job into one Step (`groups` in the Project Type). Never invent a combined runtime. When one Block can do the whole job with documented primitives (a JavaScript Block doing several local transforms, a workspace owning its whole document), build it as one Block.
30
+
31
+ Examples: "every new email with an image becomes a generated image" is two Steps, "Gmail · New emails with images" (When, fetch with an image filter, only new) and "Image from email" (AI write, Generate image); listing When, Fetch, Only new, AI decide, Continue only if, AI write and Generate image as seven Steps splits one job into its parts. "A new Meta lead goes to HubSpot" is three Steps: "Meta Ads · New leads", "Qualify lead" and "HubSpot · Add contact".
32
+
15
33
  ## Define the capability first
16
34
 
17
- Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.
35
+ Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible (few required inputs, one primary output) and keep implementation details out of it; small means a small interface, never a fragment of a job. A Block that generates images, video or speech declares only its prompt and output: every Step that runs it gets the host’s generation settings (model, quality, length and resolution, voice, speed, how many), saved with the Step, changed on its page or by Chat, and shown with their cost before each run.
18
36
 
19
37
  ## Blocks compose
20
38
 
21
- A Block is not a mini-app. Its outputs become other Blocks' inputs and its inputs come from other Blocks, project context or the user. Use the typed port system: shared StillMade types (`image`, `video`, `audio`, `asset`, `script`, `shot[]`, ...), a `semantic` meaning on every port, `required` and a short `description`. Mark exactly one primary input and one primary output so Project Type Steps connect automatically, and use `kind: "task"`: a `workspace` Block owns a project document and is never connected automatically. Inputs marked `context` read the project and cannot receive a connection from another Step. Output reusable StillMade values: media references (`{kind,assetId,versionId,url}`) and structured production values with `schemaVersion: 1`, preserving provenance, versions and relationships downstream Blocks need. Never make ordinary users wire JSON, copy IDs, understand internal paths or translate one Block's output into another: `createUniversalResolver()` (the same engine as the Project Type composer) resolves inputs from compatible upstream outputs, permitted project context and, for optional non-context inputs, `StillMade.requestFromUser`.
39
+ A Block is one job: not a mini-app of many jobs and not a fragment of one. Its outputs become other Blocks' inputs and its inputs come from other Blocks, project context or the user. Use the typed port system: shared StillMade types (`image`, `video`, `audio`, `asset`, `script`, `shot[]`, ...), a `semantic` meaning on every port, `required` and a short `description`. Mark exactly one primary input and one primary output so Project Type Steps connect automatically, and use `kind: "task"`: a `workspace` Block owns a project document and is never connected automatically. Inputs marked `context` read the project and cannot receive a connection from another Step. Output reusable StillMade values: media references (`{kind,assetId,versionId,url}`) and structured production values with `schemaVersion: 1`, preserving provenance, versions and relationships downstream Blocks need. Never make ordinary users wire JSON, copy IDs, understand internal paths or translate one Block's output into another: `createUniversalResolver()` (the same engine as the Project Type composer) resolves inputs from compatible upstream outputs, permitted project context and, for optional non-context inputs, `StillMade.requestFromUser`.
22
40
 
23
41
  ## Use platform primitives
24
42
 
@@ -28,9 +46,13 @@ Prefer, in order: an SDK capability; a documented host capability (the hosted op
28
46
 
29
47
  Never make a Block look functional through hard-coded local paths, developer-machine dependencies, undocumented environment variables, admin or database access, hidden core modifications, direct database writes, fake or mocked production results, hand-prepared test assets that hide incompatibilities, credentials in code, or assumptions about one user's machine. The finished Block must work through the same interfaces available to any installed Block; `permissions.network`, `permissions.filesystem` and `permissions.secrets` must be empty arrays.
30
48
 
49
+ ## Name it briefly
50
+
51
+ Give the Block a short, plain name of 40 characters or fewer that says what it does ("Captioned Clip", not "Captioned Business Clip Generator With Review"). The name appears in step bars, Project Type cards and pickers, so put the detail in the description instead. New releases with a longer name do not pass readiness.
52
+
31
53
  ## Interface
32
54
 
33
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Expose the capability, not the implementation: meaningful controls, sensible defaults, preview, direct manipulation, progress, clear errors and visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. Follow the host appearance (Light, Dark and White) and the mobile layout contract: one interface for every screen size that fits a 320 CSS-pixel phone without horizontal scrolling.
55
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Expose the capability, not the implementation: meaningful controls, sensible defaults, preview, direct manipulation, progress, clear errors and visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and the mobile layout contract: one interface for every screen size that fits a 320 CSS-pixel phone without horizontal scrolling.
34
56
 
35
57
  ## Shared editing
36
58
 
@@ -66,11 +88,11 @@ StillMade runs the readiness check on every Block it admits: manifest and contra
66
88
 
67
89
  ## Project Types
68
90
 
69
- A Project Type is an ordered production workflow. Each Step's primary output must be a compatible input for the next Step, secondary values come from permitted project context, and every member Block obeys this contract. Install Blocks into a realistic Project Type: project chat must understand each Step, inputs must resolve intuitively, outputs and execution state must be visible, failures must be diagnosable, and the user must be able to continue through the workflow.
91
+ A Project Type is an ordered production workflow. Each Step's primary output must be a compatible input for the next Step, secondary values come from permitted project context, and every member Block obeys this contract. Install Blocks into a realistic Project Type: project chat must understand each Step, inputs must resolve intuitively, outputs and execution state must be visible, failures must be diagnosable, and the user must be able to continue through the workflow. Group the parts of one job into one Step instead of listing helper parts as Steps; most automations are two to four Steps.
70
92
 
71
93
  ## Readiness report
72
94
 
73
- Finish with a Block Readiness Report: capability, contract (inputs, outputs, permissions, dependencies), platform APIs used, tests actually performed and their results, the composition test (upstream, Block, downstream), known limitations, unsupported requirements and any platform gap with its smallest general primitive. Choose exactly one status: PRODUCTION READY (every applicable check passed), READY WITH DOCUMENTED LIMITATIONS (works reliably within stated boundaries), BLOCKED BY PLATFORM CAPABILITY (needs a missing generic primitive) or FAILED. Never label a Block production ready to satisfy a request, and never claim a check ran when it did not.
95
+ Finish with a Block Readiness Report: capability, contract (inputs, outputs, permissions, dependencies), platform APIs used, tests actually performed and their results, the composition test (upstream, Block, downstream), known limitations, unsupported requirements and any platform gap with its smallest general primitive. Report exactly one status, the one StillMade's readiness check returned (`ready` in the SDK CLI, `check_block_readiness` over MCP), never one you chose: PRODUCTION READY (every applicable check passed), READY WITH DOCUMENTED LIMITATIONS (works reliably within stated boundaries), BLOCKED BY PLATFORM CAPABILITY (needs a missing generic primitive) or FAILED. Never label a Block production ready to satisfy a request, and never claim a check ran when it did not.
74
96
 
75
97
  ## Definition of done
76
98
 
package/AGENT_CONTROL.md CHANGED
@@ -106,7 +106,8 @@ Import `inspectAgentBlock`, `inspectAgentPorts`, `inspectAgentDocument`,
106
106
  presence paths; omitted children are explicit, and text/media contents stay out.
107
107
  `agentInputChoices(manifest, locked)` describes supported editable ports and UI
108
108
  choices. `parseAgentInput(manifest, {field, value}, {locked, busy, disabled})` checks
109
- types, numeric limits, choices and size before returning a copied value. This
109
+ types, numeric limits, choices and size before returning a copied value. A script
110
+ or brief input also accepts plain text, returned as `{schemaVersion:1, text}`. This
110
111
  helper does not grant permission, save a change, or authorize execution.
111
112
 
112
113
  Trusted native modules can use `defineNativeAgentAdapter` and
@@ -35,6 +35,32 @@ automatic permission. Arbitrary development servers, native Node modules,
35
35
  service workers, threaded WASM and full-stack backends need distinct profiles
36
36
  and verified host capabilities. Existing SDK restrictions are not removed.
37
37
 
38
+ The separately identified `desktop-browser-application/2` bundle may declare
39
+ `features: {wasm:false, srcdocFrames:true}`. A trusted stage and runtime use this
40
+ exact declaration to enable at most eight simultaneous direct `about:srcdoc`
41
+ frames (32 over the page lifetime), with inline script needed for a preview
42
+ document. Other frame URLs, nested frames, popups and local web workers remain
43
+ denied. The trusted controller bootstrap runs only in the top document. This
44
+ profile does not authorize ambient network requests or installation; exact
45
+ source review, isolated execution and output review still apply. An authoring
46
+ model can request it, but it cannot enable it by changing a prompt or manifest.
47
+
48
+ `desktop-browser-application/3` adds `localWorkers:true` (and an explicit
49
+ `srcdocFrames` boolean). It permits only dedicated workers whose script URL
50
+ exactly names a bundled JavaScript asset on the application asset server. The
51
+ target policy binds each worker to the exact parent page and browser context,
52
+ requires a paused attachment, installs recursive target monitoring before
53
+ resume, limits active and lifetime workers, and fails the session on an unknown
54
+ target or unconfirmed detach. The host-controlled CSP permits same-origin
55
+ workers and same-origin connections; the asset server serves only verified
56
+ bundled files. The isolated job's private network namespace remains required.
57
+ Chrome does not expose `Fetch.enable` on worker CDP sessions, so worker egress
58
+ is enforced by the host CSP, exact local asset server and private network
59
+ boundary, not by a worker-session Fetch interceptor. Blob, remote, shared and
60
+ service workers remain denied. A local Chromium probe exercises the target
61
+ policy and asset server, including a denied second loopback origin. A
62
+ provisioned StillMade worker run and application-level review remain required.
63
+
38
64
  Inspect compiled dependencies as well as asset extensions. For example, a
39
65
  checked-in editor bundle may contain base64 WebAssembly or dynamically create
40
66
  workers without shipping any `.wasm` file. The current asset/declaration check
@@ -42,7 +68,8 @@ does not prove those paths are absent. Admission must record which paths are
42
68
  needed, and the selected runtime must enforce its CSP, target and resource
43
69
  policy when code executes. A dead or explicitly unavailable feature is different
44
70
  from a verified fallback. The current development Linux worker rejects declared
45
- WASM and blocks worker creation; it does not establish general WASM support.
71
+ WASM; the new worker profile has not been provisioned or admitted for an
72
+ installed Block.
46
73
 
47
74
  ## Adapter lifecycle and completion
48
75
 
@@ -52,6 +79,47 @@ original application APIs and controls. Keep autosave separate from explicit
52
79
  completion; mounting a UI or retaining the original input is not evidence of
53
80
  the requested transformation.
54
81
 
82
+ For compiled applications, inspect where the original UI owns its live state.
83
+ If that state is private to a bundled module, a bounded source edit may expose
84
+ a data-only bridge for the Block-owned adapter. The edit must target an exact
85
+ inspected pinned file and be rebuilt under the sealed source identity. The
86
+ adapter should seed inputs and restore checkpoints through the original state
87
+ path, then export the state changed by real UI actions. A global store bridge
88
+ is not itself host storage or permission authority. Include binary project
89
+ files or fail explicitly; silently dropping them makes saved state and export
90
+ incomplete. Declare structured output meaning and schema so Revolver can
91
+ distinguish a website-source project from arbitrary JSON. Browser-downloaded
92
+ ZIP bytes are not a connected artifact until a trusted host materializer owns
93
+ and validates them; a JSON/base64 field must not be presented as a ZIP.
94
+
95
+ The candidate reviewer can perturb a primary `plain_text` input, or insert a
96
+ valid HTML comment into a primary `html_document` input, in a fresh isolated
97
+ session. It compares only declared text or schema-bearing structured output
98
+ ports for the same export operation. A fixed JSON project now fails this check
99
+ even when its original UI and save/reopen path appear to work. An arbitrary
100
+ custom text format does not receive a guessed mutation. This diagnostic checks
101
+ that output responds to changed input; it does not establish that the result
102
+ has the correct application-specific meaning.
103
+
104
+ When a Block receives an upstream value and also stores user edits, checkpoint
105
+ both the editable document and the upstream value that seeded it. Reopen edits
106
+ only when the mounted upstream value still matches; otherwise apply the new
107
+ upstream value and rerun the original application's render path. A model must
108
+ not treat the application's `localStorage` as the host's project or placement
109
+ state. If rendering is debounced or asynchronous, `mount` must wait for the
110
+ new result (or a real error) before acknowledging success, and `execute` must
111
+ read the completed original result rather than an old preview. Runtime review
112
+ should vary the input after a saved edit to catch stale-result replay.
113
+
114
+ Exercise original export buttons under the exact runtime CSP as well as the
115
+ declared adapter operations. Displaying SVG is weaker evidence than exporting
116
+ PNG: embedded XHTML `foreignObject` labels can taint the canvas when that SVG
117
+ is rasterized. An adapter may repair the original action with a bounded,
118
+ reviewed conversion, but must compare the visible result and downloaded bytes.
119
+ An operation that succeeds while the corresponding original control fails does
120
+ not establish a preserved application interface. Clipboard actions require a
121
+ separate approved capability and behavioral review.
122
+
55
123
  `prepareBrowserApplicationMount` binds a mount request to the exact package,
56
124
  bundle, input and state revision. A mount acknowledgement carries no outputs and
57
125
  cannot pass execution validation.
@@ -64,21 +132,70 @@ current permission/state checks. `validateBrowserApplicationExecutionResult`
64
132
  and the saved-record validator check those bindings; their result explicitly
65
133
  keeps `independentlyVerified:false`. Arbitrary callers can fabricate JSON, so
66
134
  these pure helpers do not authenticate evidence or authorize adoption.
135
+ An application package must declare at least one typed output, and each
136
+ completed operation must actually return at least one declared output even if
137
+ the port is optional. A nonempty value can still be semantically wrong; review
138
+ must compare representative saved and exported results with the original app.
67
139
 
68
140
  `runBrowserApplication` requires an explicitly supplied trusted executor. It
69
141
  never falls back to evaluating source in the host or treating a mounted page as
70
142
  success. Cancellation and timeout signal the executor; actual process/resource
71
143
  termination is the executor's responsibility and needs independent verification.
72
144
 
145
+ ### Media output candidates
146
+
147
+ An adapter exporting an `image` port returns actual PNG bytes as
148
+ `{encoding:"base64",mimeType:"image/png",data:"..."}`. It must never return an
149
+ `assetId`, `versionId`, URL or receipt of its own. The worker checks the shape
150
+ and keeps the result an **untrusted candidate**. The host-side
151
+ `materializeBrowserApplicationOutputs` boundary decodes and checks the image,
152
+ writes it through trusted storage, reads back the exact bytes, checks the current
153
+ execution revision again, and only then creates the typed image reference that
154
+ Revolver can carry. Other media types still require materializers. The local
155
+ worker, browser-control pipe and guest output envelope now each accept a
156
+ bounded 4 MiB PNG after base64 encoding inside an 8 MiB frame; the session
157
+ traffic cap is 32 MiB. Inputs and saved state retain their smaller limits.
158
+ Large candidate transport was checked offline across those layers, while
159
+ miniPaint's real PNG was separately decoded and materialized. A durable S3
160
+ output adapter exists but is not wired into installed production execution.
161
+ Installed image executions now reserve an 8 MiB aggregate maximum in the
162
+ server-owned ledger before dispatch, under the account-wide lock. The
163
+ reservation is compared with the account's storage-plan allotment and remains
164
+ charged if dispatch becomes uncertain. A reservation proven never dispatched
165
+ can be closed without consuming capacity. A completed run records verified
166
+ stored bytes. This ledger measures application outputs separately from other
167
+ project media; output deletion and plan-wide reconciliation still need the
168
+ production lifecycle before enabling installed image exports.
169
+ The desktop session now accepts a host-only `store.materializeOutputs` callback
170
+ between isolated execution and completion. It rejects guest-minted image asset
171
+ IDs before that callback, supplies the exact request and current authority
172
+ binding, rechecks access afterward, and accepts only a valid typed result.
173
+ The manager forwards this callback from trusted main-process composition; a
174
+ real PNG was tested through decode, write, readback and receipt validation,
175
+ including revocation after storage read. The installed HTTP host does not yet
176
+ supply a media store, so this is a supported host boundary, not a production
177
+ image export claim. Candidate review also lacks that store today.
178
+
73
179
  ## Guest registration
74
180
 
75
- `installBrowserApplicationGuest({target,operations,messageBytes})` is the
181
+ `installBrowserApplicationGuest({target,operations,messageBytes,outputBytes})` is the
76
182
  framework-neutral lifecycle dispatcher for a trusted bootstrap. It installs only
77
183
  `target.stillmadeApplication.register(adapter)` and returns a separate controller
78
- to that bootstrap. It does not install a runtime or grant host access.
184
+ to that bootstrap. The host may select a larger output-only envelope up to
185
+ 8 MiB; the ordinary message limit still applies to inputs and saved state.
186
+ It does not install a runtime or grant host access.
79
187
 
80
188
  The Block-owned adapter registers exactly these four methods once:
81
189
 
190
+ For a new application with several export choices, each bundle operation maps
191
+ to the output ports it actually produces, for example
192
+ `{id:"png.export",kind:"export",outputs:["png"]}`. Ports absent from some
193
+ operations must declare `required:false` in the shared manifest. The host
194
+ requires every mapped operation to return exactly its listed ports before
195
+ materializing media or committing a completion. Older bundles with only
196
+ `{id,kind}` retain their original contract; the new mapping is additive and
197
+ does not change published package bytes.
198
+
82
199
  | Method | Adapter result |
83
200
  | --- | --- |
84
201
  | `mount({inputs,state,signal})` | Restore the original UI and return exactly `{mounted:true}`. |
@@ -122,6 +239,14 @@ Method Draw is being used to study the first complete static editor route.
122
239
  Its remote fonts, global localStorage and SVG import behavior require explicit
123
240
  adaptation; an original-page baseline is not a completed Block integration.
124
241
 
242
+ The worker now has a separate **candidate-review** stage identity for an
243
+ unlisted, digest-verified browser package. Its driver and unit entry are selected
244
+ by trusted code, while the installed supervisor and runner retain the exact
245
+ reviewed-source registry. This is the source boundary needed to test generated
246
+ adapters without editing a per-repository allowlist. A root-owned review
247
+ supervisor, complete behavior gate, and admission-to-install handoff are still
248
+ missing; staging a candidate does not run or install it.
249
+
125
250
  ## Reproduce the reviewed package outside the repository
126
251
 
127
252
  The downloadable SDK zip includes `packages/block-sdk/browser-application.js`
@@ -17,8 +17,98 @@ The in-app full-application inspection pins source and retains an inventory of
17
17
  code, binary assets, dependency manifests, lockfiles, symlinks and submodules.
18
18
  It returns `not-built`, including unfinished feature and runtime checks. A complete
19
19
  file inventory is neither a complete dependency checkout nor a successful build.
20
- Inspection uses public unauthenticated GitHub APIs; it does not authorize private
20
+ Inspection first uses public unauthenticated GitHub APIs; it does not authorize private
21
21
  repository access, install dependencies, execute scripts or charge model credits.
22
+ An exact commit's complete, verified public tree and Git-blob-checked source
23
+ bytes may be reused from a 15-minute, 24 MiB process-local cache across the
24
+ inspection, build and source-recheck phases. Branch/HEAD resolution, partial
25
+ trees, failed reads and unverified bytes are not cached. Source review reports
26
+ `pinned-cache` when it uses that evidence instead of claiming a fresh API read.
27
+ The cache avoids repeated anonymous requests for one pin; a cold repository
28
+ still depends on GitHub availability and its rate limit, and another server
29
+ process has its own cache. It is not a substitute for an authenticated or
30
+ archive-backed source acquisition route at larger scale.
31
+ When the public REST API is rate-limited, the application import can instead
32
+ resolve the public branch or tag through bounded Git protocol v2 HTTP and inspect a
33
+ GitHub codeload archive at the resulting commit. The host checks the archive's
34
+ commit marker, tar structure and paths, computes Git blob identities from
35
+ actual bytes, rejects sensitive or oversized selected files, and labels this
36
+ evidence `pinned-github-archive`. A named ref uses two bounded Git HTTP requests
37
+ before the archive request; an exact commit needs only the archive request.
38
+ This fallback is capped at 12 MB compressed and 40 MB expanded, requires no
39
+ Git executable on the server, and refuses repositories with
40
+ submodules because the archive omits their Git identities. Larger archives
41
+ must use the Git tree route or a future bounded acquisition worker. Archive
42
+ inspection is source evidence only; it does not approve execution or install.
43
+ The REST and fallback phases use the same caller-owned HTTP transport when one
44
+ is provided. Reported request use includes both phases. Reported byte use
45
+ includes REST and archive bodies; the two Git-ref responses have separate
46
+ 64 KiB limits and are not included in that aggregate byte figure.
47
+ For a complete Git tree containing submodules, inspection reads the pinned
48
+ `.gitmodules` blob, accepts only canonical or relative GitHub repositories,
49
+ and follows each exact Gitlink commit (including nested modules) within one
50
+ 48-request, 32 MB metadata and 24-placement bound. It reports each dependency
51
+ commit separately. This verifies dependency identities and file inventories;
52
+ the isolated builder must still acquire and hash the actual dependency bytes
53
+ before running their code. Missing mappings, outside hosts, incomplete trees
54
+ and exhausted bounds fail with a specific source-graph reason.
55
+ The larger isolated-build acquisition profile can verify a complete archive
56
+ against that Git tree, including ordinary files and symlink identities. GitHub
57
+ codeload can omit files under `export-ignore` or transform exported text; those
58
+ paths must be restored from exact-commit raw transport and independently
59
+ rehashed to their pinned Git blobs. The raw route is limited to 64 files and
60
+ 8 MB, denies sensitive paths, uses no credentials or redirects, and cannot
61
+ grant execution. All archive and recovered bytes are checked before a trusted
62
+ staging callback receives any file. This profile has not yet been connected
63
+ to a complete native build or installation workflow.
64
+ The inspection `readable` flag controls what the LLM can request as source
65
+ text. It is not a build-file filter. A separately checked `stageable` flag
66
+ allows oversized but bounded files and inert symlink-target blobs into the
67
+ private build-source quarantine; sensitive paths remain excluded. Symlink
68
+ targets are stored as bytes, not followed or created as active filesystem
69
+ links. A later materializer must validate every link target before use.
70
+ The isolated-worker source-closure orchestrator groups identical pinned
71
+ repositories across submodule placements, rechecks each exact commit, and
72
+ hands verified bytes to a trusted quarantined staging callback under one
73
+ request, network-byte, file, staged-byte and deadline budget. Its receipt is
74
+ `execution:not-run` and `installable:false`; a partial stage has no activation
75
+ authority. The connected private staging writer uses content-addressed inert
76
+ blobs and rereads each file before sealing it. A complete closure produces a
77
+ read-only manifest bound to a host-retained digest; reopening the quarantine
78
+ audits every blob against its Git identity. Partial stages cannot be sealed.
79
+ The inert tree planner checks file/directory namespace collisions and resolves
80
+ symlink targets only within the exact staged closure, without expanding source
81
+ paths on the host filesystem. A bounded transfer format then packs each
82
+ audited Git blob once and binds its canonical namespace, modes, link targets,
83
+ source digest and sealed-manifest digest into a SHA-256 bundle. The Linux
84
+ materializer independently verifies the bundle and Git hashes, creates files
85
+ through private directory descriptors, creates links only after file writes,
86
+ and audits the final tree. A synthetic tree with an executable and links ran
87
+ in the isolated VM; a changed bundle was rejected before staging. Natron's
88
+ allowed exact closure also materialized there: 6,445 files and 654 directories.
89
+ This development path is not yet a trusted install or execution admission:
90
+ the stage owner can still change its read-only modes, and build recipes,
91
+ dependencies, GUI sessions and result contracts need separate host control.
92
+ For an npm browser candidate, inspection also reads the pinned `package.json` and
93
+ `package-lock.json` through the same bounded source verifier. It checks that root
94
+ dependency declarations agree and distinguishes integrity-pinned npm tarballs,
95
+ exact-commit GitHub dependencies and unresolved sources. This is a build plan,
96
+ not dependency acquisition or build admission. The pinned miniPaint case has
97
+ 517 npm tarballs and one exact-commit GitHub dependency; an isolated builder
98
+ must acquire and verify both kinds before executing its Webpack build.
99
+ Before rebuilding, the importer checks whether the pinned repository already
100
+ contains an HTML entry referencing a checked-in local browser bundle. It selects
101
+ the referenced scripts/styles and bounded local media resources, then verifies
102
+ every selected byte against the Git tree. This can preserve a real original UI
103
+ without executing a package script. It is still only a candidate: dynamic
104
+ resource requests, operations, state and output must pass isolated review.
105
+ miniPaint's checked-in bundle passed a separate local browser probe with a real
106
+ brush stroke, changed PNG bytes and exact document restore in a second page.
107
+ That probe is not an installed Block or a host-enforced multiplayer result.
108
+ The local acquisition module also re-read miniPaint's exact pinned lockfile and
109
+ verified all 518 dependencies (about 18.2 MB) against registry SHA-512 or Git
110
+ blob identities. Those bytes were discarded after the probe. A managed stage,
111
+ isolated framework rebuild and reviewed execution admission are still missing.
22
112
 
23
113
  Use the exported `defineRepositoryApplication` contract to record the requested
24
114
  scope, interface, versioned route and source-backed feature ledger. Use
@@ -28,6 +118,80 @@ verification. The assessor always reports `executionPerformed:false` and
28
118
  `independentlyVerified:false`. A model cannot certify its own integration by
29
119
  filling in that object.
30
120
 
121
+ For a generated browser application, put the exact GitHub repository URL,
122
+ 40-character commit and application folder in
123
+ `manifest.provenance.githubSource`. The SDK checks its shape and the source
124
+ reviewer independently matches it to the pinned Git tree and every bundled
125
+ original asset. This field travels with the versioned package; it is source
126
+ identity, not permission, a license decision or evidence that the adapter ran.
127
+ Older uninstalled candidates without the embedded pin can still undergo
128
+ source review, but must not be promoted to production solely from that legacy
129
+ shape.
130
+
131
+ For a framework application built from pinned source, the unreviewed candidate
132
+ also carries `manifest.provenance.browserBuild`: the verified source-closure
133
+ digest, build-script digest, output directory and digest of every original
134
+ compiled file. A model may author the lifecycle adapter, but cannot supply the
135
+ build result or certify it. A trusted host must independently rederive the
136
+ Git source closure, verify the exact isolated build and reconstruct the full
137
+ application bundle before running the ordinary interface, state and output
138
+ review. The current SDK handoff and internal verifier implement these checks;
139
+ the production build supervisor and review issuer are not yet connected to the
140
+ GitHub button. A build or source receipt alone does not make a Block installable.
141
+ An internal npm job now composes the sealed source bundle, Linux materializer,
142
+ integrity-pinned registry and exact-commit GitHub package stages, and the
143
+ network-denied build runner. It checks each identity again between stages and
144
+ returns compiled bytes with no installation authority. The Linux npm profile
145
+ now caps selected packages at 768, verified expanded package bytes at 256 MiB,
146
+ and package files at 18,000. It caps compiled files at 16 MiB total, each
147
+ file at 8 MiB, and the encoded build report at 24 MiB, with a root `dist`,
148
+ `build` or `out` entry. It
149
+ omits a lockfile package only when that package is explicitly optional and
150
+ incompatible with the worker's OS, CPU or libc; the root launcher rechecks
151
+ that selection against the pinned lock before execution. It has not run
152
+ miniPaint's build, and still needs the durable supervisor lease and cleanup
153
+ needed for a production
154
+ button. The stage-order tests are offline; no real framework repository has
155
+ passed this composed job. The worker also exposes a trusted rebuild callback
156
+ for the compiled-candidate source verifier; the caller must run it under the
157
+ same host-owned supervisor rather than accepting a browser-supplied report.
158
+
159
+ A successful framework build does not prove that all runtime assets are local.
160
+ For example, CanvasCode compiled from its pinned source but loaded Monaco from
161
+ a CDN; the isolated network-denied browser showed its preview while the editor
162
+ remained unavailable. Manually bundling the already pinned Monaco dependency
163
+ restored the editor and real ZIP export in an offline development VM. The
164
+ internal compiled-authoring path can now ask a model for complete replacements
165
+ or unique exact-text edits of inspected source files, each bound to its
166
+ original Git SHA-256. The host derives full replacement bytes for an edit. A root-owned
167
+ stage checks and seals replacement bytes separately from the immutable Git
168
+ source; the network-denied build applies them in scratch space. Patch identity
169
+ must match in the compiled candidate and an independent rebuild. Package
170
+ manifests and lockfiles cannot be patched in this profile. The root-owned patch
171
+ stage, service connection, automatic runtime-failure repair and full behavior
172
+ review remain unverified. A model-suggested CDN exception is not equivalent to
173
+ localizing and verifying those assets.
174
+ CanvasCode also requires a `srcDoc` preview frame and local Monaco language
175
+ workers. The original browser-application profile declares only single-thread
176
+ WASM; its CSP and target guard deny frames and workers. A successful ordinary
177
+ Chromium smoke therefore cannot establish host-runtime compatibility.
178
+
179
+ The new browser-application v2 source profile now supports a declared, bounded
180
+ direct `srcdoc` frame. The compiled authorer can request that feature, and
181
+ independent source verification reconstructs the exact profile from the pinned
182
+ build. A local Chromium probe confirmed that the v2 CSP runs an inline preview
183
+ script, reports the expected direct child frame, and keeps the top-only trusted
184
+ bootstrap out of the child. The existing v1 CSP and frame guard remain closed.
185
+ This is development-browser evidence, not a provisioned StillMade worker run.
186
+ CanvasCode also needs local Monaco language workers. Browser application v3
187
+ now declares exact bundled dedicated worker scripts, and the trusted target
188
+ policy admits them only when paused under the original page and context. A
189
+ local Chrome probe ran a worker through that policy and the hashed asset
190
+ server, while CSP denied a second loopback origin. The original v1 and v2
191
+ profiles still deny workers. This is not a provisioned StillMade worker test,
192
+ CanvasCode's own worker behavior has not passed runtime review, and its full
193
+ application import remains uninstalled.
194
+
31
195
  ## Choose an actual runtime
32
196
 
33
197
  | Source | Current boundary |
@@ -45,6 +209,18 @@ adapter. The exact reviewed Method Draw source has a private desktop install,
45
209
  editing and SVG export path. Other applications require separate source,
46
210
  runtime and result review; package validation alone is insufficient.
47
211
 
212
+ The separate Natron ARM64 development build (repository evidence `artifacts/repository-acceptance/natron-native-gui-dev-build-2026-09-29.json`)
213
+ shows that a Qt5/PySide2 native GUI can compile and open in a local VM after
214
+ architecture and Python-home adaptation. Its source tree is not yet the
215
+ complete sealed Git closure, and its OCIO configs and OpenFX plugins are
216
+ missing. This is runtime feasibility evidence, not approval to install a
217
+ GitHub-authored Block or a replacement for the full application.
218
+ The later exact-source-to-GUI check (repository evidence `artifacts/repository-acceptance/natron-exact-tree-to-gui-2026-09-29.json`)
219
+ replaced that archive input with the verified allowed Git closure and compiled
220
+ a separate copy carrying only the recorded ARM64 patch. The GUI opened; the
221
+ same binary also saved and reopened a native `.ntp` project. The missing
222
+ plugins, color config and host-enforced Block contracts remain.
223
+
48
224
  ## Keep the original appearance
49
225
 
50
226
  For an eligible restricted view, place this option in `src/view.json`:
@@ -77,6 +253,13 @@ contract and the complete runtime message limits. Large or referenced media
77
253
  still needs the host's authenticated asset resolution and materialization path;
78
254
  a guest-local data/blob URL is not a durable shared asset.
79
255
 
256
+ For browser applications with several export actions, declare which output
257
+ ports each action produces. An SVG export can map to `svg` and a PNG export to
258
+ `png`; mark each shared-manifest port `required:false` when another action
259
+ does not return it. The host checks the exact action-to-port mapping before
260
+ publishing output or storing media. A generated adapter's declaration alone
261
+ does not prove either export works.
262
+
80
263
  Map existing app behavior to SDK input, shared-document and output interfaces.
81
264
  Do not recreate the application's logic in the shared host or add a special
82
265
  Block-ID branch. Persist editable state through declared host services and keep