{
  "version": "watercolor-capabilities-1",
  "updated": "2026-09-08",
  "purpose": "Choose a current execution backend before reading historical technique records",
  "guide": "/sketch/knowledge/capabilities.md",
  "currentPainting": "/sketch/experiments/reference-finale-v20/selected.json",
  "permittedPaintingOperations": ["brush", "wait"],
  "notPermitted": ["shape fill", "arbitrary mask", "reference bitmap as paint", "post-render blur or noise"],
  "removedAndRejected": ["constant-v1", "constantRate"],
  "physicalCalibration": "not_validated",
  "noviceAgentTransfer": "not_tested",
  "deployment": "no_cloudflare_deployment_in_current_work",
  "backends": [
    {
      "id": "legacy-paper-v3",
      "selection": {"sceneVersion": "astra-sketch-1", "materialModel": "paper-brush-v3"},
      "role": "Current adopted v20 painting and existing material techniques",
      "entry": {
        "page": "/sketch/",
        "browserGlobal": "astraSketch",
        "module": "/sketch/render.js",
        "export": "createScenePainter"
      },
      "execution": "CPU material calculation; detached painter or current-document API",
      "defaults": {"drying": "normal", "reservoirSupply": "requires_explicit_supply", "tuftDynamics": "requires_explicit_dynamics"},
      "capabilities": {
        "waterBrushAndPrewet": "supported_empirical",
        "finiteReservoirAndPickup": "opt_in_empirical",
        "gesturePoseAndTime": "opt_in_procedural",
        "singleTuftDynamics": "opt_in_empirical",
        "paperAffinityTransport": "supported_empirical",
        "internalWaterLateralDiffusion": "supported_empirical",
        "thinFilmAndTilt": "absent",
        "rewetting": "partial_empirical",
        "dryingHold": "opt_in_whole_paper_during_layer"
      },
      "checkpoint": "astraSketch.checkpoint returns a scene document copy; branch and replay, not a Film material-state checkpoint",
      "examples": ["/sketch/experiments/reference-finale-v20/selected.json"],
      "knowledge": ["/sketch/knowledge/drying-v20.json", "/sketch/knowledge/rewetting-v17.json", "/sketch/knowledge/coupled-contact-v15.json"],
      "paintingAdoption": "used_by_current_v20",
      "limits": ["Not calibrated to physical paper or watercolor", "Per-cell granulation is a proxy, not transported pigment-species identity", "Existing v20 still has repeated canopy forms and simplified reflection boundaries"]
    },
    {
      "id": "film-v21-compatibility",
      "selection": {
        "sceneVersion": "astra-sketch-1",
        "materialModel": "paper-brush-v3",
        "filmSerializationVersion": "thin-film-v21",
        "options": {"passOrdering": "legacy-v21", "reactionStep": null, "paperAffinity": 0, "pigmentGranulation": null}
      },
      "role": "Inspect historical v21 experiments; not the adopted painting backend",
      "entry": {
        "page": "/sketch/experiments/thin-film-v21/",
        "browserGlobal": "astraFilm",
        "module": "/sketch/film/jobs.js",
        "export": "createFilmJobs"
      },
      "execution": "Dedicated browser Worker; explicit webgl2 or cpu backend",
      "defaults": {"backend": "webgl2", "resolution": 512, "contactStep": 0.05, "drying": "normal"},
      "capabilities": {
        "waterBrushAndPrewet": "supported_empirical",
        "finiteReservoirAndPickup": "opt_in_empirical",
        "gesturePoseAndTime": "uses_existing_brush_preparation",
        "singleTuftDynamics": "uses_existing_brush_preparation",
        "paperAffinityTransport": "absent",
        "internalWaterLateralDiffusion": "absent",
        "thinFilmAndTilt": "experimental_dimensionless",
        "rewetting": "partial_empirical",
        "dryingHold": "opt_in_whole_paper_during_layer"
      },
      "checkpoint": "Material state at command boundaries; wait for paused or complete before requesting; not interchangeable with astraSketch checkpoint",
      "examples": ["/sketch/experiments/thin-film-v21/contact-fine.json"],
      "knowledge": ["/sketch/knowledge/thin-film-v21.json"],
      "paintingAdoption": "none; v21 mountain candidates rejected, retain v20",
      "limits": ["Legacy pass ordering is biased", "Very small transport steps can lose drying and settling changes to numerical precision", "Pigment granulation attribute remains a stationary per-cell proxy", "Does not preserve all prior v3 paper behavior"]
    },
    {
      "id": "film-v22-paper-experiment",
      "selection": {
        "sceneVersion": "astra-sketch-1",
        "materialModel": "paper-brush-v3",
        "filmSerializationVersion": "thin-film-v21",
        "options": {"passOrdering": "balanced-v22", "reactionStep": 0.02, "mixing": "wet-mass", "pigmentGranulation": 0.7},
        "everyColoredBrush": {"granulation": 0.7},
        "explicitOptionRequired": true
      },
      "role": "Controlled paper-height by affinity experiment with one uniform pigment property",
      "entry": {"page": "/sketch/experiments/paper-audit-v22/", "module": "/sketch/film/jobs.js", "export": "createFilmJobs"},
      "execution": "Dedicated browser Worker; explicit webgl2 or cpu backend",
      "capabilities": {
        "waterBrushAndPrewet": "supported_empirical",
        "finiteReservoirAndPickup": "opt_in_empirical",
        "gesturePoseAndTime": "uses_existing_brush_preparation",
        "singleTuftDynamics": "uses_existing_brush_preparation",
        "paperAffinityTransport": "opt_in_uniform_pigment_property_only",
        "internalWaterLateralDiffusion": "absent",
        "thinFilmAndTilt": "experimental_dimensionless",
        "rewetting": "partial_empirical",
        "dryingHold": "opt_in_whole_paper_during_layer",
        "passOrdering": "balanced-v22",
        "reactionIntegration": "explicit_reactionStep_separate_from_fine_transport"
      },
      "experiment": {
        "status": "started; consult result artifacts before claiming success",
        "factors": {"reliefHeight": [0.0025, 0.025], "paperAffinity": [0, 4]},
        "manifest": "/sketch/experiments/paper-audit-v22/manifest.json",
        "examples": ["/sketch/experiments/paper-audit-v22/low-plain.json", "/sketch/experiments/paper-audit-v22/low-affinity.json", "/sketch/experiments/paper-audit-v22/high-plain.json", "/sketch/experiments/paper-audit-v22/high-affinity.json"],
        "judgeSeparately": ["bare paper", "fine pigment variation", "pigment relation to paper valleys", "broad color variation", "stroke seams", "edge preservation", "mass budget"]
      },
      "checkpoint": "Film material-state checkpoint, only after paused or complete; scene document copies are not accepted substitutes",
      "paintingAdoption": "unconfirmed; retain v20",
      "noviceAgentTransfer": "not_tested",
      "limits": ["One shared granulation property, not multi-pigment attribute transport", "Colored brush granulation must match pigmentGranulation or input is rejected", "No calibrated physical paper scale, sizing, or pigment species", "Affinity is an empirical model, not a full Curtis paper reproduction", "Do not apply historical v21 timing or success claims to changed v22 numerical options"]
    }
  ],
  "sharedWorkflow": [
    "Choose backend and load its validated example",
    "Keep original input; use detached rendering for experiments",
    "Change only declared experimental factors",
    "Inspect actual intermediate images and material state",
    "Judge numerical behavior, physical plausibility, picture quality and skill transfer separately",
    "Keep failed inputs and images; adopt only observed improvements"
  ],
  "filmPersistence": {
    "pause": "Request pause, then wait for observe().status === paused; complete also permits checkpoint",
    "storage": "Caller must save the checkpoint or scene; no automatic durable storage",
    "tabLifetime": "Browser Worker is lost when the tab is closed; no background cloud execution",
    "timing": "Material, compute and viewer clocks are separate; 4x affects viewing only"
  }
}
