rtistree 0.5.0
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.
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/art-direction.d.ts +77 -0
- package/dist/art-direction.js +186 -0
- package/dist/art-direction.js.map +1 -0
- package/dist/artifacts.d.ts +24 -0
- package/dist/artifacts.js +49 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/assets.d.ts +16 -0
- package/dist/assets.js +96 -0
- package/dist/assets.js.map +1 -0
- package/dist/benchmark.d.ts +76 -0
- package/dist/benchmark.js +118 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +300 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +5315 -0
- package/dist/commands.js +591 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +20 -0
- package/dist/components.js +98 -0
- package/dist/components.js.map +1 -0
- package/dist/construction.d.ts +53 -0
- package/dist/construction.js +80 -0
- package/dist/construction.js.map +1 -0
- package/dist/critique.d.ts +44 -0
- package/dist/critique.js +45 -0
- package/dist/critique.js.map +1 -0
- package/dist/detail.d.ts +5 -0
- package/dist/detail.js +52 -0
- package/dist/detail.js.map +1 -0
- package/dist/document.d.ts +64 -0
- package/dist/document.js +56 -0
- package/dist/document.js.map +1 -0
- package/dist/export.d.ts +405 -0
- package/dist/export.js +344 -0
- package/dist/export.js.map +1 -0
- package/dist/font-inspection.d.ts +8 -0
- package/dist/font-inspection.js +34 -0
- package/dist/font-inspection.js.map +1 -0
- package/dist/graphics.d.ts +9 -0
- package/dist/graphics.js +72 -0
- package/dist/graphics.js.map +1 -0
- package/dist/history-storage.d.ts +10 -0
- package/dist/history-storage.js +59 -0
- package/dist/history-storage.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +18 -0
- package/dist/layout.js +155 -0
- package/dist/layout.js.map +1 -0
- package/dist/loader.d.ts +9 -0
- package/dist/loader.js +108 -0
- package/dist/loader.js.map +1 -0
- package/dist/mcp.d.ts +4 -0
- package/dist/mcp.js +223 -0
- package/dist/mcp.js.map +1 -0
- package/dist/merge.d.ts +6 -0
- package/dist/merge.js +49 -0
- package/dist/merge.js.map +1 -0
- package/dist/native.d.ts +3 -0
- package/dist/native.js +6 -0
- package/dist/native.js.map +1 -0
- package/dist/paint.d.ts +9 -0
- package/dist/paint.js +331 -0
- package/dist/paint.js.map +1 -0
- package/dist/path-edit.d.ts +20 -0
- package/dist/path-edit.js +30 -0
- package/dist/path-edit.js.map +1 -0
- package/dist/pdf-output.d.ts +21 -0
- package/dist/pdf-output.js +297 -0
- package/dist/pdf-output.js.map +1 -0
- package/dist/pipeline.d.ts +39 -0
- package/dist/pipeline.js +227 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/print-scene.d.ts +490 -0
- package/dist/print-scene.js +55 -0
- package/dist/print-scene.js.map +1 -0
- package/dist/production-workflow.d.ts +251 -0
- package/dist/production-workflow.js +335 -0
- package/dist/production-workflow.js.map +1 -0
- package/dist/program-worker.d.ts +1 -0
- package/dist/program-worker.js +31 -0
- package/dist/program-worker.js.map +1 -0
- package/dist/program.d.ts +85 -0
- package/dist/program.js +246 -0
- package/dist/program.js.map +1 -0
- package/dist/project-config.d.ts +91 -0
- package/dist/project-config.js +187 -0
- package/dist/project-config.js.map +1 -0
- package/dist/project.d.ts +897 -0
- package/dist/project.js +347 -0
- package/dist/project.js.map +1 -0
- package/dist/raster-edit.d.ts +61 -0
- package/dist/raster-edit.js +91 -0
- package/dist/raster-edit.js.map +1 -0
- package/dist/raster-studio.d.ts +84 -0
- package/dist/raster-studio.js +236 -0
- package/dist/raster-studio.js.map +1 -0
- package/dist/render.d.ts +79 -0
- package/dist/render.js +437 -0
- package/dist/render.js.map +1 -0
- package/dist/rich-text.d.ts +10 -0
- package/dist/rich-text.js +56 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/schema.d.ts +1912 -0
- package/dist/schema.js +571 -0
- package/dist/schema.js.map +1 -0
- package/dist/spatial.d.ts +10 -0
- package/dist/spatial.js +29 -0
- package/dist/spatial.js.map +1 -0
- package/dist/studio-reference.d.ts +153 -0
- package/dist/studio-reference.js +39 -0
- package/dist/studio-reference.js.map +1 -0
- package/dist/svg.d.ts +5 -0
- package/dist/svg.js +315 -0
- package/dist/svg.js.map +1 -0
- package/dist/techniques.d.ts +74 -0
- package/dist/techniques.js +164 -0
- package/dist/techniques.js.map +1 -0
- package/dist/verify.d.ts +36 -0
- package/dist/verify.js +277 -0
- package/dist/verify.js.map +1 -0
- package/dist/viewport.d.ts +3 -0
- package/dist/viewport.js +71 -0
- package/dist/viewport.js.map +1 -0
- package/dist/workflow.d.ts +53 -0
- package/dist/workflow.js +66 -0
- package/dist/workflow.js.map +1 -0
- package/docs/agent-art-workflow.md +201 -0
- package/docs/agent-setup.md +83 -0
- package/docs/atelier.md +117 -0
- package/docs/cli-reference.md +61 -0
- package/docs/decisions/001-runtime-and-renderer.md +35 -0
- package/docs/decisions/002-composable-scenes-and-history.md +28 -0
- package/docs/decisions/003-editing-refinement-and-agent-validation.md +45 -0
- package/docs/decisions/004-print-production-and-projects.md +19 -0
- package/docs/decisions/005-programmable-digital-art.md +15 -0
- package/docs/decisions/006-staged-2d-art-production.md +13 -0
- package/docs/decisions/007-foundation-first-art-direction.md +13 -0
- package/docs/decisions/008-agent-onboarding-and-trial-lessons.md +48 -0
- package/docs/engine-overview.md +174 -0
- package/docs/evolution.md +179 -0
- package/docs/getting-started.md +107 -0
- package/docs/next-milestone.md +61 -0
- package/docs/previews/a3-production.json +36 -0
- package/docs/previews/benchmark.json +42 -0
- package/docs/previews/landscape.png +0 -0
- package/docs/previews/performance.json +24 -0
- package/docs/previews/poster.png +0 -0
- package/docs/production.md +107 -0
- package/docs/releasing.md +60 -0
- package/docs/scene-format.md +126 -0
- package/docs/studio.md +108 -0
- package/examples/hello/README.md +14 -0
- package/examples/hello/refine.json +10 -0
- package/examples/hello/render.mjs +9 -0
- package/examples/hello/scene.json +19 -0
- package/licenses/DM-Serif-Display-OFL.txt +93 -0
- package/licenses/Inter-OFL.txt +93 -0
- package/package.json +84 -0
- package/schemas/authoring.schema.json +2177 -0
- package/schemas/brief.schema.json +57 -0
- package/schemas/command.schema.json +3154 -0
- package/schemas/construction.schema.json +159 -0
- package/schemas/critique.schema.json +101 -0
- package/schemas/document.schema.json +41 -0
- package/schemas/export.schema.json +89 -0
- package/schemas/fragment.schema.json +1861 -0
- package/schemas/patch.schema.json +3177 -0
- package/schemas/pipeline.schema.json +205 -0
- package/schemas/production.schema.json +452 -0
- package/schemas/program.schema.json +152 -0
- package/schemas/project.schema.json +115 -0
- package/schemas/raster-read.schema.json +42 -0
- package/schemas/raster-write.schema.json +75 -0
- package/schemas/scene.schema.json +2014 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ADR 002: Composable scene sources with a transactional resolved state
|
|
2
|
+
|
|
3
|
+
Status: accepted for the MVP. Later extensions and superseded limitations are documented in [ADR 003](003-editing-refinement-and-agent-validation.md).
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
An agent-friendly scene should not require one enormous file. Background, copy, products, textures, and assets need independent authoring and inspection. At the same time, a render must consume one unambiguous state, and an edit batch must either commit completely or leave that state unchanged.
|
|
8
|
+
|
|
9
|
+
## Decision
|
|
10
|
+
|
|
11
|
+
A root YAML/JSON scene can include fragments containing assets, layers, and more includes. Include paths and asset paths are relative to the declaring file. Includes are expanded depth-first in declaration order; local layers follow included layers. IDs share one namespace, and duplicate IDs, missing references, cycles and path escapes are errors. Fragments cannot replace the canvas or verification rules. Those belong to the root manifest.
|
|
12
|
+
|
|
13
|
+
The loader normalizes this graph into the canonical scene schema. A single scene file remains supported. Modularity is an authoring concern; the renderer sees a complete, validated scene tree and never performs file inclusion itself.
|
|
14
|
+
|
|
15
|
+
Persist agent edits in a hash-chained append-only journal alongside the authoring sources. The sources remain the baseline; replaying the journal yields the working state. Each transaction contains a resolved snapshot, command list, reason, source and state hashes, asset hashes, and locality measurements. Undo and redo are also journal entries. Writers take an exclusive project lock, validate the candidate scene, render it, check locality for scoped edits, append the record and synchronize it to disk.
|
|
16
|
+
|
|
17
|
+
Exporting produces a new flat baseline scene with content-addressed raster assets. This is also the supported way to start a new authoring/history cycle. Export does not rewrite the original fragments. A caller may split an exported baseline into fragments before making new agent edits.
|
|
18
|
+
|
|
19
|
+
## Consequences
|
|
20
|
+
|
|
21
|
+
- Projects can be organized by semantic responsibility without coupling the renderer to file layout.
|
|
22
|
+
- An edit never partly rewrites several fragments. Rejected patches have no persisted effect.
|
|
23
|
+
- History uses complete state snapshots for transparent recovery and deterministic undo; storage is linear in scene size times edit count. Delta compression and content-addressed state snapshots are future optimizations.
|
|
24
|
+
- Scene-source changes during an active history are rejected, rather than silently rebased. Restore original sources and export before restructuring an edited project.
|
|
25
|
+
- Assets stay external. Export pins hashes, and history records and checks exact asset bytes.
|
|
26
|
+
- Include instances are not templates: including the same IDs twice is an error. Parameterized components and namespaced instances are future capabilities.
|
|
27
|
+
- Operation/mask/tile bounds use global canvas coordinates. Geometric layer bounds use parent coordinates. This makes raster scope contracts easy to measure, but a later semantic move does not automatically move previous world-space paint operations.
|
|
28
|
+
- The final-composite locality guard may reject a child edit beneath a blurred ancestor or a mask dependency. Editing the enclosing composited group is the appropriate alternative. The engine does not silently broaden scope.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ADR 003: Attached edits, adaptive patches, measured verification, and source rebasing
|
|
2
|
+
|
|
3
|
+
Status: accepted. Extends ADR 001 and supersedes the MVP limitations in ADR 002.
|
|
4
|
+
|
|
5
|
+
## Delivery order
|
|
6
|
+
|
|
7
|
+
The user requested: complete the editing API; attach paint to objects; add adaptive refinement and faster rendering; improve verification; improve authoring; then run unscripted agent trials. Implementation and validation followed that order.
|
|
8
|
+
|
|
9
|
+
## Editing and coordinates
|
|
10
|
+
|
|
11
|
+
Commands now cover registering/removing assets and fonts; shape, generator, geometry, transform, mask, layout, source, visibility, role and stacking changes; verification rules; and update/removal of individual effects, operations and tiles. Partial style changes preserve unspecified fields. The first interactive trial uncovered a Zod-default regression here; a focused regression test now covers it.
|
|
12
|
+
|
|
13
|
+
Raster operations, geometric masks, palette tiles and promoted regions accept `space: canvas|layer`. Omission preserves v1 canvas behavior. Commands capture a `reference_size` for layer-relative data. The renderer combines the object's current world transform with its size relative to that reference. Movement, rotation and resizing therefore move its paint. Authors writing files directly should supply `reference_size` when paint must scale with later source edits.
|
|
14
|
+
|
|
15
|
+
The locality contract is the integer enclosing rectangle of the transformed scope. The painter additionally clips to the transformed footprint. Replacing/removing operations measures the union of the old and new scopes. Parent effects and mask dependencies can still cause scope rejection; edits never silently broaden the permitted area.
|
|
16
|
+
|
|
17
|
+
## Adaptive detail and rendering
|
|
18
|
+
|
|
19
|
+
A layer can contain independently addressable promoted regions. Each has an ID, bounds, scale from 1–4, optional external raster source, and a list of patch-local operations. Promotion without a source or edits changes no pixels. Detailed patches are derived from the current semantic surface, supersampled locally, edited, and composited back. Demotion restores the underlying semantic result. Upsampling an imported raster does not invent missing source detail; new paint can use the finer sampling grid.
|
|
20
|
+
|
|
21
|
+
A bounded LRU cache stores immutable layer surfaces and text diagnostics. Keys cover resolved geometry, descendant/mask dependencies, source content, assets, fonts, and omitted-layer options. Edits invalidate affected surfaces while unchanged layers are reused. This is incremental layer rasterization; a general dirty-tile compositor is still future work.
|
|
22
|
+
|
|
23
|
+
A viewport fast path allocates region-sized surfaces for simple pointwise scenes. Curves, transforms, raster assets, context filters, promoted patches and other antialias-sensitive cases use full-canvas rendering and an exact crop. Testing demonstrated that clipping a rotated rectangle or ellipse on a smaller Skia device can change boundary pixels, so those cases deliberately retain the original device. `regionMode: full` and `cache: false` expose reference paths for equivalence tests. Draft remains a downsampled render.
|
|
24
|
+
|
|
25
|
+
## Verification and critique
|
|
26
|
+
|
|
27
|
+
`pixel-contrast` compares the actual composite to a counterfactual render with the target omitted, sampling solid glyph/shape interiors. `visible-area` measures how much of the target contributes to the final image. These account for opacity and overlying content; the existing declared-colour rule remains separately available. They are engineering measurements with documented sampling limits, not an accessibility certification or an aesthetic score.
|
|
28
|
+
|
|
29
|
+
Visual critique is an explicit external input from a vision-capable agent or human, bound to both scene and PNG hashes. It contains a reviewer, summary, severity-tagged findings and score. A typed callback integrates a critic into the bounded edit loop; MCP/CLI tools allow an interactive agent to inspect and record its own critique. Unresolved medium/high findings prevent a visual pass. The renderer has no model-provider dependency or credentials. A particular model service is not silently installed or called.
|
|
30
|
+
|
|
31
|
+
## Authoring and history
|
|
32
|
+
|
|
33
|
+
Components are file-level parameterized templates. Expansion namespaces instance child IDs and internal mask references, validates parameters, and rejects recursion. The canonical document remains a resolved layer tree. Rebase can propagate nonconflicting template/source edits into working state; instance editing does not write a template back automatically.
|
|
34
|
+
|
|
35
|
+
Custom font files are project-local, hashed, registered under content-based aliases and copied during export. Layout adds aspect ratios, proportional growth and main-axis justification.
|
|
36
|
+
|
|
37
|
+
New history records retain the authoring baseline. `rebase` performs a three-way merge of that baseline, the agent's working scene and current authored sources. ID-bearing layer arrays merge by identity. Conflicting paths are errors, not guesses; successful rebases are audited and undoable. Older v0.1 histories without a retained baseline require restoring/exporting their original source before using this workflow.
|
|
38
|
+
|
|
39
|
+
`compact` compresses the full journal into an immutable gzip archive and starts an appendable active log. A content-hashed pointer and duplicate-record checks make the pointer/log transition recoverable after a crash. Full undo/redo is retained. Compression reduces disk use but does not yet eliminate full replay in memory.
|
|
40
|
+
|
|
41
|
+
## Agent trials and limits of evidence
|
|
42
|
+
|
|
43
|
+
Three interactive trials were completed after the engineering work: a reading-club poster using an asset, a marsh illustration from primitives, and local refinement of a supplied rough pear raster. The assistant inspected initial PNGs, recorded findings, chose corrections after inspection, and inspected final PNGs. The benchmark driver contains no corrective patches. Saved audits capture the actual edits, including the caption bug and subsequent repair.
|
|
44
|
+
|
|
45
|
+
These are same-agent authoring and critique, not blinded or independent human evaluations. The briefs were authored in this task; they are not a held-out test set. Token usage is recorded as unavailable because the host did not expose it. Mechanical results include pixel locality, cold/cache equality and self-contained export equality. This is evidence that the workflow can be exercised end to end, not evidence of general artistic superiority.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ADR 004: Physical documents, colour-managed exports and sequential print rendering
|
|
2
|
+
|
|
3
|
+
Status: accepted for v0.3. Extends the existing TS/CPU-Skia architecture.
|
|
4
|
+
|
|
5
|
+
The user requested JPEG, TIFF and physically accurate CMYK PDF output, coherent project creation, practical editing features and a harder generated-asset trial. These are implemented as an export/document layer over the existing deterministic scene engine.
|
|
6
|
+
|
|
7
|
+
Sharp 0.35.4 / its pinned libvips build handles raster encoding and ICC conversion. PDFKit 0.20.2 produces vector paths, font subsets, gradients and PDF page boxes; pdf-lib 1.17.1 independently reads back exported structures. Fontkit checks actual glyph coverage. Fast XML Parser supports a closed static SVG importer; native Skia PathOps handles path booleans. Versions are pinned in the lockfile.
|
|
8
|
+
|
|
9
|
+
Physical dimensions remain separate from design/raster pixels. An outer transform scales scene geometry for print while preserving attached coordinates and source pixel grids. Print output is bounded by edge, megapixel and surface budgets. Sequential uncached composition releases surfaces as soon as compositing no longer needs them, retaining semantic mask dependencies. This was selected over introducing a general tile compositor whose clipping/filter equivalence would need a separate validation effort.
|
|
10
|
+
|
|
11
|
+
Colour conversion occurs at input normalisation and export; the working engine remains 8-bit sRGB. The pinned Sharp source explicitly uses perceptual rendering intent, so other intents are rejected instead of accepted as ineffective settings. CMYK requires an explicit project profile. Assigning an output intent is distinguished from converting raster/vector values. Profiles are hashed, embedded and read back; the demo profile is not a printer recommendation.
|
|
12
|
+
|
|
13
|
+
Hybrid PDF preserves supported text, vectors, gradients and isolation-free groups. Context-sensitive layers fall back to rasters. Gradient interpolation occurs in the output colour space. Ordinary PDF 1.7 is the delivered format; PDF/X certification, spot colours, overprint and higher-precision working pixels are deliberately not claimed. CMYK soft proofs are ICC round trips and do not simulate a specific paper white or monitor calibration.
|
|
14
|
+
|
|
15
|
+
`rtistree.yaml` owns the scene entry point, output directory and presets. Source scenes remain independently usable. New projects include local schemas and fragments; portable project exports also copy pinned output profiles. Existing JSON scene export remains available explicitly as `--format project`. Mismatched output extensions are errors.
|
|
16
|
+
|
|
17
|
+
The print trial revealed two defects that were fixed during implementation: metadata configuration could overwrite the requested CMYK conversion, and mask inversion after erosion expanded the selected foreground instead of shrinking it. Actual-file tests and visual proof inspection cover these cases. The original engine regression suite remains in place, alongside production and editing tests.
|
|
18
|
+
|
|
19
|
+
See [the production guide](../production.md) for capabilities and operational limits, [the A3 evidence](../previews/a3-production.json), and [the generated-asset print trial](../../examples/print-trial/README.md).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# ADR 005: Programmable raster authoring with baked, replayable recipes
|
|
2
|
+
|
|
3
|
+
Status: accepted for v0.4.
|
|
4
|
+
|
|
5
|
+
The user wants an agent to work like a traditional digital artist, including creating detailed scenes without image-generation models. Additional declarative shapes alone do not provide a practical route to arbitrary textures and painted detail. We therefore add a programmable authoring boundary while retaining the deterministic scene engine.
|
|
6
|
+
|
|
7
|
+
JavaScript is the authoring language because it can share the existing native Canvas ecosystem and typed SDK. No additional runtime dependency is needed. A synchronous program receives seeded field, brush, sampling, displacement and height-lighting helpers plus a native Canvas context. The agent can implement another algorithm directly when the provided vocabulary is insufficient. The API is available through CLI, SDK and MCP, including inline source and a machine-readable help tool for agents without filesystem access.
|
|
8
|
+
|
|
9
|
+
Program execution is explicit and produces a baked asset. A recipe pins source text, parameters, seed, input snapshots and output hash. Playback never evaluates project code. This preserves portable scene rendering and the existing history model, and avoids making ordinary scene loading an implicit code-execution boundary. Recipes can be exported and explicitly replayed. A live procedural dependency graph is not introduced in this milestone.
|
|
10
|
+
|
|
11
|
+
Workers provide cancellation and V8 heap limits; helper allocations and output dimensions are checked separately. The VM is not represented as a security sandbox, because native Canvas objects expose host methods and native allocation is outside V8 accounting. Only trusted code should be executed. A hardened plugin runtime or OS isolation would be a separate design.
|
|
12
|
+
|
|
13
|
+
Dense region editing uses existing promoted raster regions, extended with explicit `replace` and `over` semantics. Exact-size PNGs carry dense data instead of JSON pixel arrays. Transactions check stale scene hashes and edit locality. Attached patches follow object transforms. The trial found a near-zero pressure gradient failure; a minimum subpixel dab radius fixes it. Region testing also corrected final print-region copy bounds to use the transformed frame.
|
|
14
|
+
|
|
15
|
+
The artistic evaluation is kept separate from mechanical verification. The wheel trial reproduces its pixels without external image inputs, but still reads as a synthetic illustration. Successful software tests and deterministic replay are not evidence of human-level artistic skill or photographic realism. See [the studio guide](../studio.md) and [trial](../../examples/manual-wheel-trial/README.md).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 006 — Staged 2D art production
|
|
2
|
+
|
|
3
|
+
Accepted: 2026-09-09.
|
|
4
|
+
|
|
5
|
+
Keep the CPU Skia/TypeScript engine and its native Canvas and pixel escape hatches. Do not introduce a 3D renderer or image-generation dependency. Build an agent-operated production workflow around the existing painter.
|
|
6
|
+
|
|
7
|
+
A production plan defines a brief and ordered stages, each with visible acceptance criteria. Candidates freeze the scene, its build graph, the composite, thumbnail, optional detail crops and technical report. An observer supplies hash-bound brief-fidelity and artistic-quality ratings plus evidence for every stage criterion. Technical verification remains separate: an empty rule set is reported as such, and a successful render does not prove good art. Selection restores a candidate through an undoable scene transaction. Advancement requires the selected candidate to remain the current scene. Scores are stage-relative, subjective observations, not calibrated universal art metrics.
|
|
8
|
+
|
|
9
|
+
Editable raster programs form an explicit DAG. Each node subscribes to named shared parameters and image dependencies. Build keys include exact source, parameters, dimensions, seed, frozen input hashes, runtime and technique version. Unchanged nodes reuse verified outputs; dependants rebuild when their input content changes. A failed node cannot partially update the scene. Rendering never executes code. Builds pin the actual executed source in scene metadata, so candidate selection and portable export retain editable recipes as well as baked pixels.
|
|
10
|
+
|
|
11
|
+
Keep reusable methods at the technique level: bristle strokes, pressure, dry paint, glazing, scumbling, palette interpolation, atmospheric colour and weave. Subject anatomy and composition belong to authored artwork, not dragon-specific engine commands. Existing raw Canvas paths, arbitrary pixel fields, masks and warps remain available.
|
|
12
|
+
|
|
13
|
+
Tradeoffs: this is an agent-operated atelier, not a prompt-to-art generator. The caller must plan, draw, inspect and judge. Local worker execution remains trusted-code execution, not a security sandbox. Bristle strokes approximate digital paint; they do not simulate pigment chemistry or wet paint. Cached outputs and candidate journals have no automatic garbage collector yet. Session review state stays local; portable scene export preserves the selected art and inline build graph, not all rejected candidates and reviews.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 007 — Foundation-first art direction and honest failure
|
|
2
|
+
|
|
3
|
+
Accepted: 2026-09-09.
|
|
4
|
+
|
|
5
|
+
The previous dragon trial demonstrated prompt compliance and reproducibility but failed the user's artistic standard. Its self-assigned passing quality scores were not credible evidence of good art. More texture did not correct anatomy, gesture or value construction.
|
|
6
|
+
|
|
7
|
+
Codify the production process in a discoverable machine-readable guide (`artDirectionGuide`, CLI/MCP `studioHelp`) and in `docs/agent-art-workflow.md`. Add enforceable reference-log, alternative-count and reviewer requirements to existing stage plans. Preserve review history. Blocking defects cannot be averaged away by high scores. Revisions must name a parent, a correction hypothesis and a visual comparison.
|
|
8
|
+
|
|
9
|
+
Add a general named 2D construction graph for points, anchored offsets and curve handles. This supports structural edits across connected contours without hard-coding dragon anatomy into the engine. Retain Canvas and pixel escape hatches. No 3D renderer or image-generation dependency is introduced.
|
|
10
|
+
|
|
11
|
+
The tool enforces declared workflow facts, not artistic truth. It cannot authenticate reviewer identity, verify that references were studied, distinguish meaningful alternatives from trivial pixel changes, or guarantee artistic excellence. Agent instructions must explicitly acknowledge these limits and prohibit self-declaring human approval.
|
|
12
|
+
|
|
13
|
+
The follow-up dragon remains a grayscale work in progress, with failed construction/quality criteria and a human checkpoint still pending. The useful result is a stronger, inspectable correction loop; weak artwork must remain reported as weak artwork.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Agent onboarding and procedural asset lessons
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
The foundation-first guide was available through `studioHelp` and the SDK, but
|
|
6
|
+
new agents had to discover and request it. The Verdigris Watch trial also exposed
|
|
7
|
+
gaps in the guide: technically valid assets could have reversed walking motion,
|
|
8
|
+
contradictory prop perspective, excessive joint bend and crossed limb chains.
|
|
9
|
+
These failures needed subject-specific observation, not additional surface detail.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
Keep compact instructions, structured guidance, calibration cases and a starter
|
|
14
|
+
production plan in `src/art-direction.ts`. Ship these through the existing npm
|
|
15
|
+
`dist` and `docs` entries without requiring source examples or a provider-specific
|
|
16
|
+
skill installation.
|
|
17
|
+
|
|
18
|
+
- MCP includes the compact rules in initialization instructions, a discoverable
|
|
19
|
+
JSON resource and pointers in authoring tool descriptions. `studioHelp` returns
|
|
20
|
+
the same complete guide.
|
|
21
|
+
- CLI exposes `art-guide` without requiring a project, and advertises it in help.
|
|
22
|
+
- SDK exports the guide and compact instructions. The host supplies them to its
|
|
23
|
+
agent; importing a graphics library does not itself change an LLM's context.
|
|
24
|
+
- A starter plan uses existing alternative, reference, criterion and review gates.
|
|
25
|
+
It does not implicitly require human approval for every task.
|
|
26
|
+
|
|
27
|
+
The guide distinguishes technical correctness, functional behaviour and visual
|
|
28
|
+
acceptance. It requires representative samples, actual image/loop inspection,
|
|
29
|
+
shared construction, parent-linked revisions and faithful retention of feedback.
|
|
30
|
+
General lessons are embedded; a particular knight pose or colour palette is not
|
|
31
|
+
prescribed for unrelated tasks.
|
|
32
|
+
|
|
33
|
+
## Limits
|
|
34
|
+
|
|
35
|
+
Instructions are context, not model training or enforcement. Clients can omit
|
|
36
|
+
them and agents can ignore them. The existing production API enforces declared
|
|
37
|
+
review gates, hashes and blocking issues only for callers using that workflow.
|
|
38
|
+
Low-level rendering remains available. Neither transport nor workflow can prove
|
|
39
|
+
that a reviewer looked at an image or judged it well. Motion formulas are examples
|
|
40
|
+
for ordinary forward walking, not universal criteria for all animation.
|
|
41
|
+
|
|
42
|
+
## Verification
|
|
43
|
+
|
|
44
|
+
Interface tests connect a fresh MCP client, read initialization instructions,
|
|
45
|
+
discover and read the resource, and compare it with `studioHelp`, CLI output and
|
|
46
|
+
the SDK guide. The starter plan is exercised through the production API and cannot
|
|
47
|
+
select an unreviewed candidate. A package check verifies that compiled guidance
|
|
48
|
+
and documentation are present in the distributable.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Rtistree
|
|
2
|
+
|
|
3
|
+
A deterministic raster graphics engine that agents can inspect, edit, verify, and replay. A persistent scene is the source of truth; PNG, JPEG, TIFF, PDF and SVG are outputs.
|
|
4
|
+
|
|
5
|
+
Version 0.4 adds a programmable digital-art studio: seeded raster programs, pressure brushes, texture fields, warps, displacement, height-field lighting and dense regional edits. Programs bake to pinned assets with portable, replayable recipes; normal rendering never executes code. See the [studio guide](studio.md), [decision](decisions/005-programmable-digital-art.md) and [wheel trial made without image generation](../examples/manual-wheel-trial/README.md).
|
|
6
|
+
|
|
7
|
+
TypeScript provides the scene schema, transactions, CLI, and MCP tool server. The next-stage implementation includes attached painting, adaptive patches, incremental layer rendering, visual critique and source rebasing. **Native CPU Skia** performs rendering through `@napi-rs/canvas`. No browser, WebGL, GPU, model API key, or external service is required.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Print production and new projects
|
|
12
|
+
|
|
13
|
+
Version 0.3 adds physical documents, ICC-managed CMYK exports, embedded PDF fonts/vector geometry, project creation, source crops/perspective, mask algebra, tonal adjustments, clone/heal, path booleans and richer typography. See the [production guide](production.md), [recorded decisions](decisions/004-print-production-and-projects.md) and [masked generated-asset print trial](../examples/print-trial/README.md).
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
graphics project new artwork --size A3 --orientation landscape --ppi 300 --bleed 3mm
|
|
17
|
+
graphics render artwork --preset screen
|
|
18
|
+
# Configure the printer/paper ICC profile in rtistree.yaml before CMYK export.
|
|
19
|
+
graphics preflight artwork --preset print
|
|
20
|
+
graphics export artwork --preset print --format pdf
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Print PDFs encode exact trim/bleed dimensions and are reopened for validation. PDF/X certification, spot colours and overprint are not claimed. The engine remains an 8-bit sRGB working renderer with explicit colour-managed output.
|
|
24
|
+
|
|
25
|
+
## Run it
|
|
26
|
+
|
|
27
|
+
Requires Node.js 22 or newer. Dependencies and bundled fonts are pinned in `package-lock.json`.
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npm ci
|
|
31
|
+
npm run build
|
|
32
|
+
npm test
|
|
33
|
+
npm run demo
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The demo renders a poster, measures an underlit region, applies a local correction, and checks replay, undo, redo, and a self-contained export. It writes before/after images and evidence into `examples/poster/renders/`, plus a landscape into `examples/landscape/renders/`. Every demo run uses a fresh working project and leaves the example's authoring files untouched.
|
|
37
|
+
|
|
38
|
+
The recorded poster benchmark changes **4,704 pixels inside a 56 × 84 region, zero pixels outside**, improves rule verification from fail to pass, and reproduces identical PNG bytes after reopen, undo/redo, and export. This establishes mechanical correctness, not a general measure of artistic quality. See [recorded evidence](previews/benchmark.json).
|
|
39
|
+
|
|
40
|
+
Use the executable after building:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
node dist/cli.js render examples/poster/scene.yaml -o /tmp/poster.png
|
|
44
|
+
node dist/cli.js inspect examples/poster/scene.yaml
|
|
45
|
+
node dist/cli.js inspect-region examples/poster/scene.yaml 755 610 56 84
|
|
46
|
+
node dist/cli.js apply examples/poster/scene.yaml examples/poster/refine.json
|
|
47
|
+
node dist/cli.js verify examples/poster/scene.yaml
|
|
48
|
+
node dist/cli.js render examples/poster/scene.yaml -o /tmp/refined.png
|
|
49
|
+
node dist/cli.js undo examples/poster/scene.yaml
|
|
50
|
+
node dist/cli.js redo examples/poster/scene.yaml
|
|
51
|
+
node dist/cli.js export examples/poster/scene.yaml -o /tmp/rtistree-export/scene.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`npm run graphics -- …` runs the same CLI from source. Installing the package exposes the `graphics` executable. `graphics --help` lists commands. JSON goes to stdout; errors go to stderr. Verification failures exit with code 2, other failures with code 1.
|
|
55
|
+
|
|
56
|
+
## Compose a project from files
|
|
57
|
+
|
|
58
|
+
A manifest can reference as many independently authored fragments as needed:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
version: 1
|
|
62
|
+
canvas:
|
|
63
|
+
width: 1024
|
|
64
|
+
height: 1024
|
|
65
|
+
background: '#102c31'
|
|
66
|
+
include:
|
|
67
|
+
- layers/background.yaml
|
|
68
|
+
- layers/product.yaml
|
|
69
|
+
- layers/typography.yaml
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Each fragment contains `layers`, optional `assets`, and optional nested `include` paths. Paths resolve relative to the declaring file and must stay inside the project. Layer and asset IDs share a project namespace. Included layers compose in declaration order, followed by local layers; sibling `z` values determine paint order. Groups preserve hierarchy.
|
|
73
|
+
|
|
74
|
+
The [poster example](../examples/poster/scene.yaml) uses this format. [Scene format documentation](scene-format.md) describes coordinates, layout, operations, and validation.
|
|
75
|
+
|
|
76
|
+
## Agent interface
|
|
77
|
+
|
|
78
|
+
Art-direction guidance ships with the engine. MCP clients receive concise rules
|
|
79
|
+
at connection time and can read the full versioned guide through `studioHelp` or
|
|
80
|
+
the `rtistree://guides/art-direction` resource. CLI agents use `graphics art-guide`
|
|
81
|
+
without opening a project. SDK hosts can include `rtistreeAgentInstructions` in
|
|
82
|
+
their agent context and expose `artDirectionGuide`.
|
|
83
|
+
|
|
84
|
+
The guide includes representative-sample workflows, connected figure construction,
|
|
85
|
+
shared prop perspective, ground-contact animation checks, lessons from failed
|
|
86
|
+
asset trials and a starter production plan using existing review gates. Technical,
|
|
87
|
+
functional and visual acceptance are separate. This makes the knowledge available
|
|
88
|
+
to new agents; it does not guarantee that every client presents it or every model
|
|
89
|
+
follows it. See [the agent workflow](agent-art-workflow.md).
|
|
90
|
+
|
|
91
|
+
Start the MCP server with a scene:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
node dist/cli.js serve /absolute/path/to/scene.yaml
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Configure an MCP client to launch `node`, with the absolute path to `dist/cli.js`, `serve`, and the absolute scene path as arguments. Transport is stdio; the server writes only protocol messages to stdout.
|
|
98
|
+
|
|
99
|
+
Tools: `inspectScene`, `inspectLayer`, `inspectRegion`, `render`, `renderRegion`, `apply`, `undo`, `redo`, `verify`, `history`, `recordCritique`, `readCritique`, `rebase`, `compactHistory`, `exportArtwork`, `preflight`, `softProof`, `studioHelp`, `runProgram`, `replayProgram`, `readRasterRegion`, `writeRasterRegion`. Image tools return PNG image content so a vision-capable agent can inspect the result. `apply` advertises a typed command schema and requires an explanation. Supply the scene hash returned by inspection to reject stale edits.
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"reason": "Brighten the underlit detail without changing the surrounding composition",
|
|
104
|
+
"expected_hash": "sha256:…",
|
|
105
|
+
"commands": [
|
|
106
|
+
{
|
|
107
|
+
"type": "applyRasterOperation",
|
|
108
|
+
"target": "cover",
|
|
109
|
+
"operation": {
|
|
110
|
+
"type": "brightness",
|
|
111
|
+
"bounds": [755, 610, 56, 84],
|
|
112
|
+
"amount": 0.06
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The SDK also exposes `Project`, `SkiaRenderer`, `parseScene`, layout and verification functions, and `runIterations(project, editingAgent, options)`. The injected agent receives the scene, PNG, and verifier report and returns a patch or `null`. Iteration budgets, stale-state checks, stall thresholds, and cancellation bound the loop. An optional typed `critic` callback adds visual feedback; `requireCritique: true` requires a current critique before passing, and unresolved medium/high findings prevent success. Model choice and vision critique stay outside the renderer; there is no built-in LLM or diffusion service.
|
|
120
|
+
|
|
121
|
+
## Persistence and reproducibility
|
|
122
|
+
|
|
123
|
+
Authoring fragments remain intact. Successful mutations append a transaction to `history/<scene-filename>.operations.jsonl`. Each record stores its commands, reason, full resolved state, previous-record hash, input/output scene hashes, asset hashes, and measured locality. Reads replay this journal over the original scene. Undo/redo append records rather than deleting history. Full state snapshots favor correctness and recovery over storage efficiency in this MVP.
|
|
124
|
+
|
|
125
|
+
A failed batch leaves the scene unchanged. A project lock prevents concurrent writers; an expected scene hash handles stale agents. Incomplete or altered journal records are rejected. If a writer crashes, inspect the PID in the `.lock` file before removing the stale lock. After manual source edits, run `graphics rebase scene.yaml` to merge nonconflicting changes into the working state. Conflicts report exact paths without committing. `graphics compact scene.yaml` compresses history while retaining every undo/redo state. New histories retain their source baseline; legacy histories require restoring/exporting the original source before rebasing. Changed raster asset bytes are also rejected after history exists.
|
|
126
|
+
|
|
127
|
+
Exports copy raster assets and custom fonts into content-addressed files and pin their hashes. Every PNG has a `.evidence.json` sidecar recording renderer/backend/runtime versions, scene hash, asset hashes, bundled font hashes, dimensions, quality, and PNG hash. Byte identity is tested on the same pinned runtime and platform. Cross-platform Skia byte identity is **not** promised.
|
|
128
|
+
|
|
129
|
+
## Implemented scope
|
|
130
|
+
|
|
131
|
+
- JSON/YAML scenes and recursive multi-file composition; strict validation and JSON Schema generation.
|
|
132
|
+
- Groups, semantic roles, shapes and SVG-style paths, text wrapping, local PNG/JPEG/WebP assets, gradients, seeded noise, transforms, row/column layouts, anchors, percentages, opacity, and nine blend modes.
|
|
133
|
+
- Rectangle, ellipse, polygon and semantic-alpha masks; feathering, layer blur, and adjustment layers.
|
|
134
|
+
- Scoped fill, paint/erase strokes, blur, brightness, contrast, saturation, hue shifts, noise, colour replacement, direct pixels, and palette tiles. Binary rasters remain external assets.
|
|
135
|
+
- Exact region crops, structural/color inspection, append-only transactions, undo/redo, self-contained export, CLI, and MCP.
|
|
136
|
+
- Text overflow, declared contrast, safe-area, overlap, copy/role and region-luma rules, issue heatmaps, measured edit locality, and bounded agent iterations.
|
|
137
|
+
|
|
138
|
+
The remaining extensions are automatic quadtree subdivision, a general dirty-tile compositor, advanced SVG import, mesh warp/smudge, general segmentation, provider-specific model integrations, learned asset generation, and animation. Draft still downsamples after rendering. Safe pointwise region scenes use smaller viewport surfaces; antialias-sensitive scenes fall back to a full composite and exact crop.
|
|
139
|
+
|
|
140
|
+
## Next-stage examples and agent trials
|
|
141
|
+
|
|
142
|
+
See [the new API and workflows](evolution.md) and [ADR 003](decisions/003-editing-refinement-and-agent-validation.md). New features include mutable effects/operations, object-relative paint, promoted patches at 1–4× resolution, layer caching, rendered contrast/visibility rules, hash-bound visual critiques, component instances, custom fonts, source rebasing and compressed history.
|
|
143
|
+
|
|
144
|
+
Three interactive trials are recorded in [agent-trials/results.json](../examples/agent-trials/results.json), with before/after images, briefs, complete audit snapshots and portable final scenes. Corrections were selected after inspecting the images. The visual scores are same-agent judgments; these are not independent quality evaluations, and token usage was unavailable. All three final scenes passed their configured checks and reproduced after export. The pear trial preserved every checked nonfruit pixel.
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
node dist/cli.js render examples/agent-trials/reading-club/final/scene.json -o /tmp/reading-club.png
|
|
148
|
+
node dist/cli.js render examples/agent-trials/pear/final/scene.json -o /tmp/pear.png
|
|
149
|
+
npm run performance
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The performance probe records cache counters and local timings in `docs/previews/performance.json`. Its 16-layer edit reuses 15 surfaces and rasterizes one, while matching an uncached render exactly.
|
|
153
|
+
|
|
154
|
+
See [architecture decisions](decisions/001-runtime-and-renderer.md), [multi-file persistence decision](decisions/002-composable-scenes-and-history.md), and the original [architecture proposal](../agentic-raster-graphics-architecture.md).
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
npm run check
|
|
160
|
+
npm run format:check
|
|
161
|
+
npm run schema
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Subsystems are separate modules in `src/`: schema, loader, layout, assets, paint, renderer, commands, project transactions, verification, workflow, CLI and MCP. The `Renderer` interface makes backend replacement independent of scene authoring or agent logic. The original proposal's package boundaries are module boundaries until independent packaging has a concrete benefit.
|
|
165
|
+
|
|
166
|
+
Bundled fonts are Inter and DM Serif Display from Fontsource, under their bundled SIL Open Font Licenses. They cover Latin text; custom project fonts can supply broader script coverage. Arbitrary system-font fallback remains disabled. Example artwork and book-cover raster are built from this engine's own primitives; regenerate the cover with `node --import tsx scripts/create-fixtures.ts`.
|
|
167
|
+
|
|
168
|
+
## Staged 2D art production
|
|
169
|
+
|
|
170
|
+
Dependency-aware painting pipelines, immutable candidate comparisons, hash-bound visual reviews and gated production stages are available through the CLI, SDK and MCP. Seeded oil/filbert/scumble/ink brushes complement native Canvas paths and raw pixels. See [the atelier workflow](atelier.md) and the hand-authored dragon trial in `examples/dragon-oil-trial`. No image-generation or 3D dependency is used.
|
|
171
|
+
|
|
172
|
+
Read [Art direction for agents](agent-art-workflow.md) before making art. The foundation-first protocol, named 2D construction guides, explicit blocking issues and parent-linked revisions are also discoverable through `graphics studio-help`. The [grayscale dragon study](../examples/dragon-foundation/README.md) demonstrates the process and records its unresolved artistic failures.
|
|
173
|
+
|
|
174
|
+
The [dragon head lighting experiment](../examples/dragon-head-study/README.md) uses the existing 2D tools for an original head, reflected green fire and two local revisions. It remains below the supplied artistic quality reference; code-only reproduction is verified separately from that verdict.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Editing and agent workflows
|
|
2
|
+
|
|
3
|
+
## Complete edits
|
|
4
|
+
|
|
5
|
+
`apply` is still a transaction containing `reason`, optional `expected_hash` and `commands`. The generated [command schema](../schemas/command.schema.json) is authoritative.
|
|
6
|
+
|
|
7
|
+
| Area | Commands |
|
|
8
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| Inputs | registerAsset, removeAsset, registerFont, removeFont |
|
|
10
|
+
| Composition | addLayer, removeLayer, moveLayer, resizeLayer, setGeometry, setTransform, setZ, groupLayers, align, distribute |
|
|
11
|
+
| Appearance | setShape, setGenerator, setSource, setMask, setLayout, setVisibility, setRole, setOpacity, setBlendMode, setText, setStyle |
|
|
12
|
+
| Effects | applyEffect, updateEffect, removeEffect |
|
|
13
|
+
| Raster edits | applyRasterOperation, updateRasterOperation, removeRasterOperation, replaceTile, removeTile |
|
|
14
|
+
| Adaptive patches | promoteRegion, updateRegion, demoteRegion |
|
|
15
|
+
| Verification | setVerification |
|
|
16
|
+
|
|
17
|
+
Update/removal commands address zero-based indices reported by `inspectLayer`. Promoted regions use stable IDs. Asset/font registration uses project-relative file paths and is validated before commit. Null clears a mask, layout, transform or role. Partial style updates preserve all omitted properties.
|
|
18
|
+
|
|
19
|
+
## Object-relative painting
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"reason": "Add a highlight that follows the product",
|
|
24
|
+
"commands": [
|
|
25
|
+
{
|
|
26
|
+
"type": "applyRasterOperation",
|
|
27
|
+
"target": "product",
|
|
28
|
+
"operation": {
|
|
29
|
+
"type": "paintStroke",
|
|
30
|
+
"space": "layer",
|
|
31
|
+
"bounds": [8, 8, 80, 100],
|
|
32
|
+
"path": [
|
|
33
|
+
[20, 24],
|
|
34
|
+
[35, 72]
|
|
35
|
+
],
|
|
36
|
+
"radius": 8,
|
|
37
|
+
"hardness": 0.4,
|
|
38
|
+
"colour": "#ffe0ad",
|
|
39
|
+
"opacity": 0.5
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The command captures the layer's current size in `reference_size`. Moving, scaling or rotating the object carries the paint with it. Direct scene authors can explicitly supply the reference dimensions. The default remains `space: canvas` for backward compatibility. Geometric masks can choose their own space. Semantic masks always sample the target's rendered alpha. Feather radii remain raster-pixel radii.
|
|
47
|
+
|
|
48
|
+
## Adaptive regions
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"type": "promoteRegion",
|
|
53
|
+
"target": "product",
|
|
54
|
+
"region": {
|
|
55
|
+
"id": "surface-detail",
|
|
56
|
+
"space": "layer",
|
|
57
|
+
"bounds": [20, 30, 64, 64],
|
|
58
|
+
"scale": 4,
|
|
59
|
+
"operations": [
|
|
60
|
+
{
|
|
61
|
+
"type": "paintStroke",
|
|
62
|
+
"bounds": [0, 0, 64, 64],
|
|
63
|
+
"path": [
|
|
64
|
+
[4, 12],
|
|
65
|
+
[54, 42]
|
|
66
|
+
],
|
|
67
|
+
"radius": 0.6,
|
|
68
|
+
"colour": "#f0d7a2"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The patch is 256 × 256 samples, but occupies 64 × 64 logical units. Its operations use patch-local coordinates. An optional `source` refers to a registered raster asset for explicit high-resolution content. Maximum patch size is 16 megapixels. Promotion with no source or operations changes nothing; demotion removes the patch and reveals the semantic result. Patches execute after ordinary operations and before the layer mask/opacity.
|
|
76
|
+
|
|
77
|
+
`SkiaRenderer` caches immutable layer surfaces with a configurable byte budget. `clearCache()` discards them; `render(..., {cache:false})` gives a fresh reference. `statistics` records reuse, rasterization and memory. Region rendering uses a conservative viewport fast path and falls back for curves, transforms, assets and context filters; `regionMode: full` requests the reference path explicitly.
|
|
78
|
+
|
|
79
|
+
## Pixel measurements and visual review
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
verification:
|
|
83
|
+
rules:
|
|
84
|
+
- { type: pixel-contrast, target: headline, minimum: 4.5, percentile: 0.1 }
|
|
85
|
+
- { type: visible-area, target: product, minimum: 0.7 }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `Project.verify()` or `verifyRendered(scene, root, renderer)` for these rules. They render the final image with and without a target and sample the target's solid interiors. Occlusion, opacity and background effects therefore influence the measurements. `visible-area` measures detectable contribution, so a shape matching its background can have zero visible contribution even if it is geometrically present.
|
|
89
|
+
|
|
90
|
+
For visual critique, render and inspect the PNG, then submit:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"scene_hash": "sha256:...",
|
|
95
|
+
"png_hash": "sha256:...",
|
|
96
|
+
"reviewer": "Your vision agent",
|
|
97
|
+
"method": "vision-agent",
|
|
98
|
+
"summary": "The title is readable, but the product competes with the background.",
|
|
99
|
+
"score": 0.65,
|
|
100
|
+
"issues": [
|
|
101
|
+
{
|
|
102
|
+
"id": "separation",
|
|
103
|
+
"category": "composition",
|
|
104
|
+
"severity": "medium",
|
|
105
|
+
"target": "product",
|
|
106
|
+
"message": "The product silhouette is difficult to read.",
|
|
107
|
+
"suggestion": "Reduce background contrast behind it."
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`graphics critique scene.yaml critique.json` or the MCP `recordCritique` tool stores it. Stale scene/PNG hashes are rejected. `readCritique` returns only the current critique. A callback of type `VisualCritic` can perform this review in `runIterations`; use `requireCritique: true` to require it for success. Visual and rule scores inform stall detection; unresolved medium/high visual findings prevent a pass. The adapter is provider-neutral and requires the caller to supply the actual vision-capable reviewer. No synthetic review is substituted when one is absent.
|
|
114
|
+
|
|
115
|
+
## Components and fonts
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
components:
|
|
119
|
+
badge:
|
|
120
|
+
parameters: { label: NEW, colour: '#d9aa72' }
|
|
121
|
+
layers:
|
|
122
|
+
- id: plate
|
|
123
|
+
type: vector
|
|
124
|
+
bounds: [0, 0, 120, 40]
|
|
125
|
+
shape: { type: rectangle, fill: '{{colour}}', radius: 4 }
|
|
126
|
+
- id: label
|
|
127
|
+
type: text
|
|
128
|
+
bounds: [8, 12, 104, 24]
|
|
129
|
+
content: '{{label}}'
|
|
130
|
+
style: { size: 12, align: center }
|
|
131
|
+
layers:
|
|
132
|
+
- { use: badge, id: new-badge, bounds: [40, 40, 120, 40] }
|
|
133
|
+
- use: badge
|
|
134
|
+
id: sale-badge
|
|
135
|
+
bounds: [190, 40, 120, 40]
|
|
136
|
+
params: { label: SALE, colour: '#8db1a1' }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Components can live in included fragments. Instance children become `new-badge-plate`, `new-badge-label`, etc. Internal semantic mask targets are namespaced as well. Exact `{{parameter}}` substitutions retain value types; embedded substitutions allow scalars. Unknown parameters/components, duplicate IDs and recursive definitions fail validation. Instance placement accepts bounds, transform, role and z. The canonical scene is fully expanded and remains editable.
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
fonts:
|
|
143
|
+
brand-display:
|
|
144
|
+
source: fonts/BrandDisplay.otf
|
|
145
|
+
hash: sha256:...
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Choose `style.font: brand-display`. Fonts are registered under content-based aliases; changing a font file without updating its expected hash fails. History checks custom-font provenance, and exports copy font files. A custom file supplies one face; register a separate ID for another weight. Bundled names are reserved.
|
|
149
|
+
|
|
150
|
+
Layout supports `aspect_ratio`, positive `grow` weights and `layout.justify: start|center|end|space-between`. Aspect ratio derives height when height is unspecified. Main-axis growth divides space remaining after fixed children and gaps. Existing absolute and percentage layouts continue to work.
|
|
151
|
+
|
|
152
|
+
## Source changes and compressed history
|
|
153
|
+
|
|
154
|
+
After changing a source fragment or a component definition:
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
graphics rebase scene.yaml
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This merges disjoint source and agent changes using the retained authoring baseline. Conflicts report paths such as `/layers/headline/style/colour` and leave history untouched. Resolve the conflicting source fields and retry, or export the working scene into a new project. Rebase is audited and undoable. Histories created before baseline retention require their original source to be restored and exported first.
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
graphics compact scene.yaml
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Compaction compresses full records into an immutable gzip archive with a content-hashed pointer, then starts an empty active log. Every undo/redo state remains accessible. It reduces storage; replay still reads all records. Missing/tampered archives fail closed. Do not delete archives referenced by the pointer.
|
|
167
|
+
|
|
168
|
+
## Interactive benchmarks
|
|
169
|
+
|
|
170
|
+
`BenchmarkSession` requires visual review before each checkpoint. Briefs describe the objective and optional allowed region; the driver does not contain a solution or choose an edit.
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
graphics benchmark scene.yaml brief.json before
|
|
174
|
+
# Inspect, critique, apply edits, then inspect and critique again.
|
|
175
|
+
graphics benchmark scene.yaml brief.json after
|
|
176
|
+
graphics benchmark scene.yaml brief.json finish
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The report records actual edit/command counts, rule results, visual scores, locality, uncached equality and self-contained export equality. Token counts are nullable rather than guessed. The [recorded trials](../examples/agent-trials/results.json) were performed interactively by the assistant in this task, with self-authored briefs and same-agent visual critique. They establish a usable end-to-end workflow; broader held-out evaluation and independent human review remain future evidence to collect.
|