ADR 0001: Project & Contract model
Status: Accepted (P0)
Context
Section titled “Context”Studio is a visual editor that must produce deterministic, compilable code for multiple targets (Core, Angular, React, later Java) from a single canvas model. We need one authoritative representation the canvas edits, and a separate, strictly derived representation that targets consume — otherwise editor state and generated output drift, or the canvas ends up understanding target-specific code shapes.
Decision
Section titled “Decision”MdyStudioProject(plan section 5) is the single canonical source of truth. The canvas, undo/redo, and all editor commands (ADR 0003) operate exclusively on this structure. The canvas never edits generated source (R1).Contract v2is a one-way, deterministic derived export:Project -> Contract. It strips all editor-only metadata (presentation, IDs not needed downstream, Studio bookkeeping) and is validated by strict-parsing it with the existing Contract parser before it is trusted by any target.- Round-tripping is defined only as
StudioProject JSON -> StudioProject JSON(save/load/import/export). Studio never imports arbitrary source and reverse-engineers a project from it (R13) — that direction is explicitly out of MVP scope (plan section 3). targets: Record<string, unknown>on the project holds only target-specific options (e.g. chosen output style), never target-specific model data — target logic lives in target plugins (ADR 0004), not in the project shape.
Consequences
Section titled “Consequences”- Every feature ships as a project-model change first; Contract mapping (or an explicit “unsupported” diagnostic) is part of the definition of done for any new node/validator kind (plan section 15).
- Editor bugs and codegen bugs are separable: if Contract strict-parses and a target fixture still produces wrong output, the bug is in that target’s pipeline (ADR 0004), not in the model.
- Adding a wholly new output shape (e.g. a future “form JSON schema” export)
only requires a new
Project -> Xmapping function, no canvas change.
Verification
Section titled “Verification”packages/studio-contract/test/compile.test.mjs— the checkout project compiles to a contract that strict-parses with the real core parser, which is the actual guarantee: the compiler is not trusted about its own output.npm run test:studio— round-trip is exercised as project JSON to project JSON only.scripts/audit-package-independence.mjs— the editor never reaches a target implementation.
Unguarded: nothing checks that targets holds only options and never model data. It is a shape
convention, and a target could smuggle model data through it without failing anything.
Security and privacy
Section titled “Security and privacy”A project file is untrusted input — it is saved, shared and imported. It is parsed as data and never executed, and Studio never reverse-engineers a project from arbitrary source, which keeps a whole class of “import this file” attack out of scope. Compiled contracts inherit the guarantees of ADR 0007.
Rejection-test answers (plan section 2)
Section titled “Rejection-test answers (plan section 2)”- Java addable without canvas model change? Yes — Java consumes
Contract/ProjectJSON exactly like Core/Angular/React; nothing in this ADR is JS/TS-specific. - Target loads lazily, no hardcoded UI import? N/A to this ADR directly — see ADR 0004.
- Rename/move preserves all references? N/A to this ADR directly — see ADR 0002.
- Same normalized project → byte-identical output? Yes by construction:
Contract v2and every target artifact are pure functions ofMdyStudioProject; see../checkout-example.mdfor a concrete instance with no non-deterministic fields (no timestamps, no insertion-order-dependent data).
Satisfies
Section titled “Satisfies”R1, R10, R13.