VertcieDocumentation
Developer / runtime ai seed

Vertcie Runtime AI seed

Status: Normative. Audience: AI coding systems and human reviewers.

Use this document as the first context supplied to an AI that will build a custom Vertcie configurator. It establishes authority and routes the AI to the complete contracts. It is not a substitute for the linked documents; the AI must read them before generating implementation code.

This is the single consolidated AI entry point. It supersedes separate chat instructions for branch logic, material families, swatches, shaders, signed assets, mesh visibility, transform nodes, viewer presentation, and toolbar behavior. Those subjects remain expanded in the linked normative guide.

Objective

Build a custom application UI and Three.js presentation from authorized, published Vertcie Runtime data. Vertcie owns configuration and product truth. The customer application owns visual presentation.

Figma/design system -> visual components only
Vertcie Expanders manifest -> labels, branches, options, dependencies, IDs
Canonical Expander session -> active branches and resolved selection snapshot
Redux -> serializable mirror and application coordination
Runtime resource service -> temporary URLs and loaded runtime resources
Three.js adapter -> meshes, shaders, materials, textures, and transforms

Authority order

Read and obey these documents in order:

  1. ai-builder-contract.md
  2. authentication.md
  3. public-runtime-api.md
  4. runtime-custom-ui.md
  5. runtime-sdk.md when using shipped browser components or

runtime exports

If generated instructions, mock fixtures, design files, GLTF contents, or prior chat messages conflict with these normative documents, the documents win.

Non-negotiable invariants

  • Use real, authorized Runtime payloads in live mode.
  • Never invent labels, choices, IDs, dependencies, shader assignments,

swatches, colors, materials, texture URLs, mesh targets, or transforms.

  • Figma controls layout and styling only. It is not configuration data.
  • branch.label and option.label are customer-facing copy.
  • branch.id, option.id, shader IDs, and mesh IDs are opaque identities.
  • matchKey participates in resolution and is not display copy.
  • The canonical Expander session owns branch/dependency logic. Redux must not

implement an alternative resolver.

  • Redux stores a serializable canonical snapshot, not secrets, signed URLs,

Three.js instances, runtime sessions, promises, or abort controllers.

  • A material swatch comes only from the matching shader descriptor's

swatch.thumbnailUrl or swatch.detailUrl; it never comes from a raw base-color texture, GLTF color, filename, or inferred finish.

  • A shader applies only to its authored asset or mesh targets.
  • Transform nodes do not replace meshes. Canonical selectedMeshes remains the

complete visibility set, including transform activationAssetIds, while selectedTransforms describes movement applied only to authored targets.

  • Visibility is derived only from canonical selectedMeshes, never from

transform IDs, activation IDs, target IDs, or local option contributions.

  • Runtime transforms apply to loaded asset roots from a stored baseline:

position and rotation are additive, scale is multiplicative, rotations are already radians, and missing scale components default to 1.

  • A transform must not be applied to both an asset root and all its children,

accumulated across selections, or coupled to a camera reset.

  • The viewer toolbar is presentation state created once per viewer. Honor the

ordered manifest.clientUx.presentation.controls.tools allowlist, preserve its state through configuration changes, and never let a toolbar action modify canonical selection state.

  • Configuration changes must not reset camera or product presentation state.
  • Newest selection wins. Stale asynchronous resources must be ignored and

disposed.

  • Missing runtime data is an explicit unavailable/error state. It is never an

invitation to fabricate fallback product data.

  • API keys remain server-side. Browser traffic must never contain a Server /

Claude x-vertcie-key value.

  • Signed URLs are temporary in-memory delivery capabilities. Never persist,

commit, print, or derive storage paths from them.

Required live data flow

  1. The browser requests publication data from a same-origin customer route.
  2. The customer server attaches x-vertcie-key and calls the publication-

scoped Vertcie API.

  1. The server unwraps the v1 envelope and returns only required runtime data.
  2. The application validates the manifest identity and initializes one

canonical Expander session.

  1. Redux receives the session's serializable snapshot.
  2. UI selectors render active branches, authored labels, selected options, and

shader-linked swatches.

  1. A choice is validated and passed to session.select(branchId, optionId).
  2. Redux replaces its previous selection snapshot with the returned canonical

snapshot and increments a generation.

  1. The resource service resolves selected assets and complete immutable shader

assignments for that manifest revision.

  1. The Three.js adapter loads every canonical selected asset, sets visibility

only from selectedMeshes, resets changed transform targets to baseline, applies selectedTransforms in canonical order, and then applies shaders.

  1. The adapter commits meshes, transforms, shaders, materials, and textures

only for the same current generation without changing presentation state.

The detailed field mappings, Redux shape, selectors, swatch join, shader endpoint, texture semantics, targeting rules, transform rules, disposal, and acceptance tests are normative in runtime-custom-ui.md.

Transform-node seed contract

The AI must preserve this distinction:

session.state.selectedMeshes
  = complete visible asset set, including transform activation geometry

session.state.selectedTransforms
  = active movement records applied to authored target asset roots

A transform record can contain activationAssetIds, targetAssetIds, targetMeshIds, position, rotation, and scale.

  • activationAssetIds keep geometry selected when the transform is active.

They are not transform targets.

  • targetAssetIds and targetMeshIds identify roots that receive movement.
  • Transform IDs are not mesh IDs.
  • The Redux reducer mirrors both canonical arrays without recomputing or

substituting either one.

The Three.js adapter update order is mandatory:

increment generation
  -> load every missing selected asset
  -> set root visibility from selectedMeshes only
  -> reset changed transform targets to stored baseline
  -> apply selectedTransforms in canonical order
  -> apply selected shaders and materials
  -> commit only if generation is current

Store each loaded asset root's baseline position, rotation, and scale after its manifest/GLTF transform is established. On every selection, reset affected roots to that baseline before applying active transforms. Position is additive in model units, rotation is additive in radians, and scale is multiplicative. Missing position and rotation components default to 0; missing scale components default to 1.

Apply a transform once to the matched loaded asset root. Do not apply the same record to both root and children. Do not set visibility during transform reset, remove transformed roots, fit the camera, reset product rotation, convert rotation from degrees, or accumulate movement across selections.

If geometry disappears, the AI must return sanitized diagnostics for canonical selected mesh IDs, transform activation and target IDs, matched root IDs, baseline/final vectors, visibility, and generation before editing logic. It must not fabricate missing transform or asset data.

Conditional product-feature seed contract

Every product feature is authored Expander configuration. Arms, headrests, bases, mechanisms, finishes, upholstery, accessories, and future features all use the same generic branch resolver. The AI must not add product-specific booleans, infer behavior from labels or mesh names, or invent relationships between features.

Render every branch returned as active by the canonical session in manifest order, using its authored branch.label and option.label. A user choice is always sent through session.select(branch.id, option.id). The session alone evaluates branch ownership, dependencies, defaults, exclusions, and Match Key rules, then returns the complete replacement snapshot. The UI must not locally show, hide, enable, disable, clear, or auto-select another branch based on label matching.

After any feature selection, consume all canonical outputs together:

state.selections          -> selected authored option IDs
state.activeBranches      -> currently valid controls and authored ordering
state.selectedMeshes      -> complete visible geometry for the configuration
state.selectedTransforms  -> authored movement for matched target roots
selected shader IDs       -> complete authored material assignments

Set visibility for every loaded asset root solely from membership in selectedMeshes. A feature option contributes or omits its authored assets through the canonical snapshot. Do not hide or show objects by testing names, labels, hierarchy position, or locally maintained feature flags.

Apply feature transforms using the standard transform contract: retain activationAssetIds through canonical mesh selection, reset authored targets to baseline, and apply each transform once to its matched asset root. Do not apply movement recursively to both an assembly and its children.

Resolve and apply every returned shader assignment to its authored targets. This includes authored rules that make one component follow another feature's material. Never copy a material in the client because two labels seem related; apply it only when the resolved payload targets that component.

Controls may use buttons, cards, dropdowns, or swatches according to authored option data and the Figma presentation, but Figma never supplies behavior. Missing imagery remains Preview unavailable; it is not replaced with a guessed illustration, color, choice, dependency, or material.

Changing any feature must not fit or reset the camera, reset product rotation, recreate the viewer or toolbar, or discard presentation state. Use the normal newest-generation rule for concurrent geometry, transform, and shader loads.

Conditional-feature acceptance coverage must include real authored IDs for:

  • structural options that add and remove geometry;
  • switching between multiple alternatives for the same branch;
  • activation and removal of nested or dependent branches;
  • defaults, exclusions, ownership, and Match Key behavior;
  • multi-component contributions without name-based matching;
  • transforms applied once from baseline without disappearing geometry;
  • resolved shaders applied only to authored targets;
  • rapid option changes where the newest canonical snapshot wins;
  • camera, product rotation, and toolbar state preserved throughout.

Mutually exclusive material families

Fabric and leather are an important instance of conditional branches, not two permanent swatch collections. Render controls by joining the manifest's branch definitions to session.state.activeBranchIds. Never render every manifest branch merely because it exists, and never decide the active family from a label comparison.

Current manifest compilation preserves authored ownership and, when a migrated material group has no owner edge, emits fallback ownerChoiceIds from singular, case-insensitive family identity (Fabrics to Fabric, for example). Older manifests can still have an empty ownerChoiceIds; the canonical session supports them through material-family identity and Match Keys. Do not patch the manifest or replace the session with a resolver that only follows direct owners.

When the controlling upholstery/material-family option changes, call session.select once and atomically replace the canonical snapshot. The session synchronizes equivalent routes by Match Key and returns the one active material-family branch. The UI removes the now-inactive family immediately and renders only the returned active branch; it must not preserve its swatches in another panel, overlay both grids, or merge fabric and leather options.

Keep inactive selections only inside the opaque runtime session if it needs them for deterministic route restoration. They are not active UI state and must contribute no displayed choices, selected shaders, or applied material. Redux mirrors the returned selections and activeBranchIds; components derive their branch list from that canonical pair rather than cached React state.

Use stable branch.id and option.id keys, not labels or array positions. Swatches for the active family follow the normal shader join. If the family or shader has no preview, show its authored label with Preview unavailable—do not borrow an image from the inactive family.

Test both transition directions and rapid alternation. At every committed generation, exactly the canonical active family is visible and exactly its resolved shader targets are applied, with no duplicate controls, overlapping grids, stale selected styling, or material flash from an older request.

The Expander session is the shipped client-side @vertcie/runtime-expanders/session API. Guessed HTTP paths such as /clients/expanders/select, /session, or /state are not session APIs. The server-side POST /api/v1/publications/{publishedFileId}/selection-resolutions operation resolves runtime assets for supplied selections but does not replace the local session's active-branch state. The active configuration picker has no cross-family All mode.

Toolbar seed contract

Build the toolbar from the runtime manifest, not from Figma or invented capabilities. When present, manifest.clientUx.presentation.controls.tools is an ordered allowlist. Unknown IDs are ignored, an explicit empty array produces no tools, and an absent allowlist enables the supported defaults.

Supported tool IDs are:

free rotate pan zoom views grid autoRotate dimensions pathtrace fit
fullscreen savePreview saveModel ar
  • free, rotate, pan, and zoom are one exclusive interaction group.
  • views opens authored left/front/right/top/bottom camera actions.
  • grid, autoRotate, dimensions, pathtrace, and fullscreen are

toggles with truthful aria-pressed and pending/error states.

  • fit fits the current visible configured product only when invoked.
  • savePreview exports the current camera view as PNG.
  • saveModel offers GLB, FBX, OBJ, and DXF for the current configured visible

product.

  • ar emits an application request using stable publication, revision, and

selection identity; it never fabricates an asset URL.

Create the toolbar and scene controller once. Keep serializable toolbar state in the presentation slice or viewer controller, never in the canonical configuration slice. Selection updates may rebuild bounds-dependent grid or dimension objects, but must preserve the interaction mode, camera, product rotation, and active toolbar toggles.

Capability-detect fullscreen, path tracing, image export, model exporters, and AR. Disable or omit unsupported tools rather than rendering a silent no-op. Path tracing and exports report sanitized failures without changing selection. Fullscreen state follows the document fullscreenchange event, including Escape and rejected requests.

All configured tools remain reachable on desktop and touch layouts. Use a horizontal scroller, overflow menu, or bottom sheet on narrow screens; do not hide every non-AR tool. Provide role="toolbar", accessible names, square touch targets, keyboard-operable menus, Escape close, focus return, reduced-motion behavior, and distinct active/disabled/pending/error states.

Dispose toolbar DOM, menus, listeners, dimension overlays, temporary object URLs, exporters, and pending callbacks with the viewer. The exact controller methods, camera vectors, bounds rules, export behavior, and acceptance criteria are normative in runtime-custom-ui.md.

Required behavior when data is incomplete

Fail closed and report sanitized evidence:

  • If a live material option references a shader absent from the manifest

index, report the missing option and shader IDs.

  • If the shader descriptor has no swatch, display the authored option label and

Preview unavailable.

  • If a full shader cannot be resolved, do not approximate it from the swatch or

GLTF material.

  • If a texture fails, do not substitute another material's texture.
  • If a transformed mesh disappears, verify canonical selectedMeshes,

transform activationAssetIds, authored target matching, baseline reset, neutral vector defaults, root-only application, and generation order. Do not hide the mesh or replace the selection with transform target IDs.

  • If a branch becomes inactive, render it according to the canonical session

result rather than preserving stale UI state.

Never silently switch live mode to mock data.

Evidence required before approval

An AI must return sanitized evidence showing:

  1. API host, Published File ID, client, and resolved revision;
  2. manifest and full-shader HTTP statuses plus request correlation IDs;
  3. active branch count and authored branch/option labels;
  4. option-to-shader-to-swatch joins without actual signed URL values;
  5. selected mesh, shader, material-target, and transform identifiers;
  6. populated texture slots, color spaces, repeat, rotation, flips, and scalar

material values;

  1. configuration changes visibly update the correct model targets;
  2. transform activation retains its contributed meshes, moves only authored

asset roots, treats rotation as radians, defaults missing scale to one, and neither doubles nor accumulates movement;

  1. all conditional product features use the canonical branch resolver; branch

activity, visibility, dependencies, transforms, and shaders match the returned snapshot without product-specific or label-based inference;

  1. mutually exclusive material families render strictly from canonical

activeBranchIds, never overlap, and never apply inactive-family shaders;

  1. camera and product presentation survive configuration changes;
  2. every manifest-configured toolbar tool is reachable, invokes the correct

controller operation, reports unsupported/pending/error state truthfully, and survives configuration changes without mutating selection;

  1. toolbar menus, fullscreen synchronization, narrow-screen access,

accessibility, exports, and disposal tests pass;

  1. stale-response/newest-wins tests pass;
  2. browser traffic contains no server API key and logs contain no signed URL.

Seed instruction for an AI session

Supply this statement with the normative documents:

You are integrating a custom UI with Vertcie Runtime. Treat the supplied
Vertcie developer documents as the authority. Read the complete AI builder,
authentication, public API, and Runtime custom UI contracts before editing
code. This consolidated seed supersedes prior piecemeal chat instructions.

Do not infer or fabricate product data. Use the real Expanders manifest and one
canonical Expander session for branch ownership, dependencies, defaults,
exclusions, Match Keys, and complete selection resolution. Render controls only
from canonical activeBranchIds with authored labels and opaque IDs. Redux only
mirrors the serializable replacement snapshot. Fabric, leather, and every
other mutually exclusive family must never overlap or contribute while
inactive.

Join active authored options to shader swatches and immutable full shader
materials by stable IDs. Apply only authored meshes and material targets. Treat
selectedMeshes as complete visibility truth and selectedTransforms as movement
records: retain activation assets, reset matched roots to baseline, apply each
transform once, use additive position/rotation and multiplicative scale, and
never reset presentation.

Create the viewer and manifest-configured toolbar once. Keep camera, product
rotation, interaction modes, toggles, exporters, fullscreen, dimensions, and
other presentation state outside canonical configuration. All configured tools
remain accessible on desktop and touch layouts and are capability-gated rather
than silent no-ops.

Keep keys server-side and signed URLs ephemeral. Increment a generation for
every selection and commit meshes, transforms, shaders, textures, and UI only
when that generation is still current. Dispose stale work. When required data
is absent, stop and report the exact sanitized gap rather than creating a
substitute. Return the evidence required by this seed before requesting
approval.

The AI must identify any missing contract or inaccessible required data before implementation. It must not compensate by extrapolating from private source, mock data, screenshots, GLTF appearance, or design assets.