# Pulp support matrix
# Vocabulary: stable, usable, experimental, partial, planned, unsupported
schema_version: 2

platforms:
  macos:
    status: usable
    notes: Primary development platform. ARM64 (Apple Silicon) only.
  windows:
    status: experimental
    notes: WASAPI audio, Win32 MIDI, NSIS installer, Authenticode signing. CI enabled.
  linux:
    status: experimental
    notes: ALSA audio, ALSA MIDI, .deb packaging. CI enabled.
  ios:
    status: experimental
    notes: Foundation in place. AVAudioSession, AUv3, UIKit views, Metal surface.
  web:
    status: experimental
    notes: WAMv2, WebCLAP adapters, Emscripten build pipeline, browser test host. Not yet runtime-validated in browser.

formats:
  vst3:
    macos: usable
    windows: partial
    linux: partial
  au_v2:
    macos: usable
    windows: unsupported
    linux: unsupported
  clap:
    macos: usable
    windows: partial
    linux: partial
  standalone:
    macos: usable
    windows: partial
    linux: partial
  auv3:
    macos: experimental
    ios: experimental
  lv2:
    linux: experimental
  wam_v2:
    web: experimental
  webclap:
    web: experimental
  aax:
    macos: experimental
    windows: experimental
    linux: unsupported

# Plugin extensions / host-query interfaces that ride on top of a format
# (separate from the format itself). Status reflects the Pulp side of the
# integration; SDKs are developer-supplied where required.
plugin_extensions:
  ara:
    status: experimental
    notes: >
      Interface stubs in core/format/include/pulp/format/ara.{hpp,cpp}; impl
      returns false. No format adapter wires the host-query path yet.
      Tracked under production-readiness workstream 06.
    limitations:
      - "AraDocumentController is a stub — playback renderer not implemented."
      - "VST3, CLAP, AU adapters do not declare ARA extension support."
      - "Celemony ARA SDK is developer-supplied; not bundled."
# Known limitations per format. Keyed the same as `formats:`. The renderer
# in capabilities.md surfaces these as a "Known limitations" link on each
# row. Production-readiness workstream 08 sub-deliverable 8.5.
#
# Adding an entry here is non-blocking — the entry's status in `formats:`
# is the load-bearing label. `format_limitations:` exists so readers don't
# confuse "the adapter compiles" with "the adapter is feature-complete."
format_limitations:
  vst3:
    - "Dynamic bus arrangements limited; setBusArrangements only renegotiates the primary stereo bus today (workstream 01)."
  au_v2:
    - "Outbound parameter changes are not emitted to the host — automation read on AU v2 effects only flows host → plugin (workstream 01)."
  clap:
    - "Only the first input bus and first output bus are routed; declared sidechain or additional buses are ignored (workstream 01)."
    - "Processor::set_sidechain is never called from the CLAP adapter — sidechain inputs land on the primary bus (workstream 01)."
  lv2:
    - "Atom sysex is ignored — the run() loop only promotes 1–3-byte short MIDI messages out of the input atom sequence; sysex sidecar wiring is tracked under issue #239 (workstream 01)."
  aax:
    - "Custom editor surface not wired — Pro Tools shows the auto-generated parameter strip rather than a Pulp ViewBridge editor (followups plan, row 7)."
    - "AudioSuite role is declared but not exercised end-to-end (followups plan, row 13)."
  auv3:
    - "iOS jetsam pressure not modeled — heavy V8 / WebView workloads in the AUv3 process risk termination at ~50 MB (workstream 05)."
  wam_v2:
    - "Browser origin sandbox only; no Pulp-side capability manifest yet (security plan v4 §4.5)."
  webclap:
    - "Same browser-sandbox-only constraint as wam_v2."

scripted_ui:
  ui_script_target_wiring:
    status: usable
    notes: UI_SCRIPT is threaded through VST3, AU, CLAP, and Standalone targets via PULP_UI_SCRIPT_PATH.
  scripted_editor_loading:
    macos: usable
    windows: partial
    linux: partial
    notes: Scripted editor sessions load in the supported desktop targets. Non-macOS desktop hosts are not yet runtime-validated to the same level.
  live_js_reload:
    macos: usable
    windows: unsupported
    linux: unsupported
    notes: Available in desktop standalone hosts that poll ScriptedUiSession::poll(). Runtime-validated only in the standalone macOS lane; plugin hosts still need a host-neutral polling contract.
  live_theme_reload:
    macos: usable
    windows: unsupported
    linux: unsupported
    notes: Sibling theme.json overrides reload in ScriptedUiSession. Runtime-validated only in the standalone macOS scripted UI lane.
  state_preservation:
    status: usable
    ci_test: pulp-test-state
    notes: Knob, fader, toggle, checkbox, toggle-button, and XY pad values are restored across scripted UI reloads. JavaScript heap state is rebuilt.

audio_io:
  coreaudio:
    status: usable
    platform: macos
  avaudiosession:
    status: experimental
    platform: ios
    notes: >-
      AVAudioSession category / interruption / route-change / media-services-reset
      all observed in Swift and forwarded to native listeners via
      pulp_ios_audio_session_emit (#329 / PR #374). Runtime validation
      still waits on iOS on-device smoke (#249).
  wasapi:
    status: experimental
    platform: windows
    notes: >-
      Shared-mode playback with IMMNotificationClient hotplug (landed
      PR #281). Input capture + exclusive-mode paths tracked in #243.
  alsa:
    status: experimental
    platform: linux
    notes: >-
      Output path works. Input capture and real device-metadata
      enumeration tracked under #215 child issue.
  jack:
    status: planned
    platform: linux
    notes: Source exists at core/audio/platform/linux/jack_device.cpp but the factory unconditionally returns AlsaSystem; JACK is never selected at runtime. See production-readiness workstream 02.2.

midi_io:
  coremidi:
    status: usable
    platform: macos
  win32_midi:
    status: experimental
    platform: windows
  alsa_midi:
    status: experimental
    platform: linux

rendering:
  dawn_metal:
    status: experimental
    platform: macos
    notes: Presentable surface via CAMetalLayer-backed NSView. GPU path opt-in via use_gpu in WindowHost and PluginViewHost. CoreGraphics remains default.
  skia_graphite:
    status: experimental
    platform: macos
    notes: Skia Graphite wired through Dawn device. Offscreen and on-screen rendering work. CoreGraphics is still the default path.
  dawn_metal_ios:
    status: experimental
    platform: ios
    notes: IOSGpuWindowHost and IOSGpuPluginViewHost implemented. Not yet runtime-validated on device.
  dawn_d3d12:
    status: experimental
    platform: windows
    notes: Surface creation via SurfaceSourceWindowsHWND implemented. SDL3 extraction for HWND. Not runtime-validated on hardware.
  dawn_vulkan:
    status: experimental
    platform: linux
    notes: Surface creation via SDL3 X11/Wayland extraction implemented. Not runtime-validated on hardware.
  coregraphics_fallback:
    status: usable
    platform: macos
    notes: Current default render path for all macOS view hosts. Production-ready.

css_parity:
  grid_layout:
    status: usable
    notes: >
      CSS Grid Layout Level 1: LayoutMode::grid, template columns/rows with fr/px/auto
      units, column/row gaps, auto-placement, grid item spanning (grid-column/grid-row).
      JS bridge: createGrid, setGrid.
  flexbox:
    status: usable
    notes: >
      Full flexbox: direction, wrap, grow/shrink/basis, gap, row-gap/column-gap,
      justify-content (start/center/end/space-between/space-around/space-evenly),
      align-items, align-self, order, margin, padding shorthand expansion.
  transforms:
    status: usable
    notes: >
      CSS Transforms Level 1: translate(x,y), rotate(deg), scale(s), skew(x,y).
      Transform origin (normalized 0–1). Composited in paint_all. JS bridge:
      setTranslate, setRotation, setScale, setTransformOrigin.
  animations:
    status: usable
    notes: >
      FrameClock-driven animation system. ValueAnimation with easing curves
      (ease-in/out/in-out, cubic, spring). Motion tokens for consistent timing.
      Widget-level animations: knob hover glow, toggle slide, fader thumb scale,
      scroll bar fade, tooltip opacity. JS bridge: animate, defineKeyframes,
      setAnimation, setMotionToken.
  backgrounds_borders:
    status: usable
    notes: >
      CSS Backgrounds Level 3: background-color, linear-gradient (4 directions +
      multi-stop). Border: width, color, radius (per-corner planned). Box shadow:
      offset, blur, spread, color. JS bridge: setBackground, setBorder,
      setBackgroundGradient, setBoxShadow.
  filters:
    status: usable
    notes: >
      CSS Filter Effects Level 1: blur(px). Applied per-element in paint_all.
      JS bridge: setFilter("blur(4px)").
  colors:
    status: usable
    notes: >
      CSS Color Level 4: #RGB, #RRGGBB, #RRGGBBAA, rgb(), rgba(), hsl(), hsla(),
      100+ named CSS colors. Full parseColor() in C++ bridge and JS prelude.
  text:
    status: usable
    notes: >
      CSS Text Level 3: text-transform (uppercase/lowercase/capitalize),
      text-decoration (underline/line-through/overline), text-align (left/center/right),
      text-overflow (ellipsis/clip), font-size, font-weight, font-style, letter-spacing,
      line-height, multi-line labels. JS bridge: setTextTransform, setTextDecoration,
      setTextAlign, setTextOverflow, setFontSize, setFontWeight, setFontStyle.
  positioning:
    status: usable
    notes: >
      CSS Positioned Layout Level 3: position (static/relative/absolute/fixed/sticky),
      top/right/bottom/left offsets, z-index. Applied during layout_children.
      JS bridge: setPosition, setTop/Right/Bottom/Left, setZIndex.
  canvas_2d:
    status: usable
    ci_test:
      - pulp-test-canvas
      - pulp-test-canvas-widget
    notes: >
      25 draw command types on CanvasWidget: fillRect, strokeRect, fillRoundedRect,
      strokeRoundedRect, fillCircle, strokeCircle, strokeLine, fillText, setFont,
      setFillColor, setStrokeColor, setLineWidth, beginPath, moveTo, lineTo,
      quadTo, cubicTo, closePath, fillPath, strokePath, save, restore, translate,
      scale, rotate, clipRect. Full JS canvas bridge API.
  opacity:
    status: usable
    notes: Per-element opacity (0.0–1.0) applied as layer alpha in paint_all.
  overflow:
    status: usable
    notes: Overflow hidden/visible clipping on container views.
  cursor:
    status: usable
    notes: CSS cursor property with 7 styles (default, pointer, crosshair, text, grab, grabbing, not-allowed).
  transitions:
    status: partial
    notes: Transition duration stored as theme dimension token. Full CSS transition shorthand parsed in JS prelude.
  calc_expressions:
    status: usable
    notes: >
      calc(), min(), max(), clamp() expression evaluator with nested function support,
      arithmetic operators (+, -, *, /), and mixed-unit operands. Proper operator
      precedence (multiply/divide before add/subtract).
  unit_resolution:
    status: usable
    notes: >
      resolveLength() converts em (parent font-size), rem (root font-size),
      % (parent dimension), vw/vh/vmin/vmax (viewport), ch (approximate) to px.
      resolveCSSLength() provides unified calc-aware API.
  selectors:
    status: usable
    notes: >
      Full selector engine: tag, .class, #id, descendant (space), child (>),
      :first-child, :last-child, :nth-child(An+B), :nth-last-child, :only-child,
      :empty, :checked, :disabled, :not(selector), :hover, :focus, :active,
      :first-of-type, :last-of-type, :nth-of-type(An+B),
      attribute selectors [attr], [attr="val"], [attr~=], [attr^=], [attr$=], [attr*=].
  dom_api:
    status: usable
    notes: >
      closest(selector), matches(selector), contains(node), innerHTML get/set with
      HTML parser, outerHTML, querySelector/querySelectorAll on elements,
      append/prepend/before/after/replaceWith (DOM4), classList.replace(),
      focus()/blur(), cloneNode, createDocumentFragment(), <option> sync for <select>.
  events:
    status: usable
    ci_test: pulp-test-events
    notes: >
      click, dblclick, mousedown/up, mouseenter/leave, wheel, scroll, contextmenu,
      keydown/keyup, input/change, focus/blur, pointer events (L2), gesture events.
      stopPropagation, stopImmediatePropagation, preventDefault. CustomEvent constructor.
      window.addEventListener for global events. Capture + bubble event flow.
  per_side_borders:
    status: usable
    notes: >
      Per-side borders (border-top/right/bottom/left with individual width + color).
      Per-corner border-radius (border-top-left-radius etc., 4 independent corners).
  animation_properties:
    status: usable
    ci_test:
      - pulp-test-animation
      - pulp-test-widget-animation
    notes: >
      CSS animation-* properties parsed: name, duration, timing-function, delay,
      iteration-count (including infinite), direction, fill-mode. animation shorthand.
      Execution via FrameClock animate() bridge.
  css_shorthands:
    status: usable
    notes: >
      flex-flow, place-items, place-content, inset, box-sizing (parsed),
      margin-inline/block, padding-inline/block (CSS logical properties),
      -webkit-line-clamp, background-repeat (parsed).
  media_queries:
    status: usable
    notes: >
      matchMedia() with min-width, max-width, min-height, max-height, orientation
      (landscape/portrait). window.innerWidth/innerHeight dynamic via getRootSize().
  aspect_ratio:
    status: usable
    notes: CSS aspect-ratio property (16/9 shorthand or single number).
  visibility:
    status: usable
    notes: CSS visibility hidden (preserves layout space, sets opacity to 0).
  pointer_events_css:
    status: usable
    notes: CSS pointer-events none/auto. View.hit_testable_ flag skips in hit_test.
  outline:
    status: usable
    notes: CSS outline property (width, color). Parsed from shorthand "2px solid blue".
  white_space:
    status: usable
    notes: CSS white-space (normal/nowrap/pre). Maps to Label multi_line flag.
  text_shadow:
    status: partial
    notes: CSS text-shadow parsed (offset, blur, color). Bridge stub — rendering planned.
  font_family:
    status: partial
    notes: CSS font-family property parsed. Bridge stub — font selection planned.

widgets:
  image_view:
    status: usable
    notes: ImageWidget with placeholder rendering, JS bridge createImage/setImageSource.
  list_box:
    status: usable
    notes: >
      Virtualized ListBox with scroll wheel support, auto-scroll on keyboard navigation.
      JS bridge: createListBox, setListItems, setListSelected, setListRowHeight.
  combo_box:
    status: usable
    ci_test: pulp-test-combo-dropdown
    notes: Dropdown with global click-outside dismiss, keyboard navigation, hover tracking.
  scroll_view:
    status: usable
    ci_test: pulp-test-scroll-view
    notes: ScrollView with smooth scroll animation, bar fade-in/out, content size management.
  text_editor:
    status: usable
    ci_test: pulp-test-text-editor
    notes: >
      Full text editor: selection (click/double/triple), clipboard (Cmd+C/X/V/A),
      undo/redo (Cmd+Z/Shift+Z), numeric-only, password mode, multi-line,
      placeholder, IME composition with marked text.
  tree_view:
    status: usable
    ci_test: pulp-test-tree-view
    notes: Hierarchical tree with expand/collapse, indent levels.
  progress_bar:
    status: usable
    notes: Progress indicator with animated fill.
  tooltip:
    status: usable
    notes: Fade-in/out tooltip attached to any view.
  # Audio / music-domain widgets.
  meter:
    status: usable
    notes: Meter, MultiMeter, CorrelationMeter — peak/RMS level bars with ballistics. See core/view/include/pulp/view/widgets.hpp.
  spectrum_view:
    status: usable
    notes: Real-time FFT spectrum display with log/linear frequency axis. See core/view/include/pulp/view/widgets.hpp.
  spectrogram_view:
    status: usable
    notes: Scrolling STFT spectrogram. See core/view/include/pulp/view/widgets.hpp.
  waveform_view:
    status: usable
    notes: WaveformView for rendering audio buffers. See core/view/include/pulp/view/widgets.hpp.
  waveform_editor:
    status: usable
    notes: Selection, zoom, region-based editor built on WaveformView. See core/view/include/pulp/view/widgets/waveform_editor.hpp.
  midi_keyboard:
    status: usable
    notes: Display + interaction keyboard; note-on/off events routed through Binding. See core/view/include/pulp/view/widgets/midi_keyboard.hpp.
  preset_browser:
    status: usable
    notes: Searchable, category-grouped preset browser with keyboard navigation. See core/view/include/pulp/view/widgets/preset_browser.hpp.
  eq_curve_view:
    status: usable
    notes: Draggable EQ band handles with live curve render. See core/view/include/pulp/view/widgets/eq_curve_view.hpp.
  graph_editor_view:
    status: usable
    ci_test: pulp-test-graph-serializer
    notes: Canvas-based node editor on top of pulp::canvas; renders a SignalGraph as a draggable, connectable graph. See core/view/include/pulp/view/widgets/graph_editor_view.hpp.
  # General-purpose UI widgets surfaced by the audit as missing rows.
  file_browser:
    status: usable
    notes: FileBrowser + FileDropZone. See core/view/include/pulp/view/widgets/file_browser.hpp.
  color_picker:
    status: usable
    notes: HSV + hex color picker with live swatch. See core/view/include/pulp/view/widgets/color_picker.hpp.
  concertina_panel:
    status: usable
    notes: Stacked accordion-style panel with expand/collapse per section. See core/view/include/pulp/view/widgets/concertina_panel.hpp.
  split_view:
    status: usable
    notes: Draggable splitter between two views; horizontal and vertical. See core/view/include/pulp/view/widgets/split_view.hpp.
  breadcrumb:
    status: usable
    notes: Breadcrumb trail navigation. See core/view/include/pulp/view/widgets/breadcrumb.hpp.
  lasso:
    status: usable
    notes: Marquee / drag-to-select overlay. See core/view/include/pulp/view/widgets/lasso.hpp.
  code_editor:
    status: usable
    ci_test: pulp-test-code-editor
    notes: Syntax-highlighted text editor with gutter and line numbers. See core/view/include/pulp/view/widgets/code_editor.hpp.

js_authoring:
  web_compat_layer:
    status: usable
    notes: >
      JS prelude providing document.createElement, element.style, addEventListener,
      StyleSheet, querySelector/querySelectorAll, getBoundingClientRect, getComputedStyle.
      148 named CSS colors, shorthand expansion, transform/transition parsing.
      No DOM/CSSOM — pure JS shim over native widget bridge.

documentation:
  getting_started:
    status: usable
    notes: Setup, first plugin, UI scripting, hot-reload, themes.
  migration_guide:
    status: usable
    notes: React/CSS side-by-side mapping tables for developers coming from web.
  api_reference:
    status: usable
    notes: All 111+ JS bridge functions documented with signatures and examples.
  cookbook:
    status: usable
    notes: 10 practical recipes for common UI patterns.
  starter_template:
    status: usable
    notes: Gain plugin template with UI script, --template CLI flag.
  component_showcase:
    status: usable
    notes: Every widget type demonstrated in one JS file.
  design_token_guide:
    status: usable
    notes: Theme system, inheritance, custom tokens, export formats.
  custom_rendering_guide:
    status: usable
    notes: Three layers — JS canvas to GPU shaders.

testing:
  web_compat_validation:
    status: usable
    notes: >
      424 browser-style validation tests: CSS value/color/shorthand/calc parsing (157),
      computed style + layout tests for flex/grid/position/nested (135),
      event tests for click/hover/keyboard/focus/bubbling/selectors (81),
      visual reftests and screenshot regression (46).
  unit_tests:
    status: usable
    notes: 1622+ Catch2 tests across all subsystems. CI on every PR.
  format_validation:
    status: usable
    notes: CLAP dlopen tests, VST3 load tests, auval for AU.
  audio_golden_files:
    status: usable
    notes: DSP output compared against reference files with tolerance.

platform_maturity:
  cursor_management:
    status: usable
    platform: macos
    notes: CursorStyle enum mapped to NSCursor in mouseMoved. All 7 styles supported.
  tab_focus:
    status: usable
    notes: Tab/Shift+Tab cycles focus through focusable views. Wraps at ends.
  accessibility:
    macos:
      status: usable
      notes: VoiceOver via NSAccessibilityElement. AccessRole maps to NSAccessibilityRole.
    ios:
      status: usable
      notes: VoiceOver via UIAccessibilityElement with accessibilityIncrement/Decrement for sliders. See core/view/platform/ios/accessibility_ios.mm.
    android:
      status: usable
      notes: TalkBack via JNI bridge exposing role, label, value, table metadata, and click/increment/decrement actions. See core/view/platform/android/accessibility_android.cpp.
    windows:
      status: partial
      notes: UIA stub — role mapping defined, IRawElementProviderSimple/WM_GETOBJECT/event firing pending. See production-readiness workstream 04.
    linux:
      status: partial
      notes: AT-SPI stub — role mapping defined, D-Bus registration pending. See production-readiness workstream 04.
  ime_composition:
    status: usable
    platform: macos
    notes: Full NSTextInputClient — setMarkedText, unmarkText, firstRectForCharacterRange for candidate window positioning.
  context_menu:
    status: usable
    notes: on_context_menu callback on View, rightMouseDown dispatch, showContextMenu/registerContextMenu bridge.
  keyboard_shortcuts:
    status: usable
    notes: registerShortcut bridge function, shortcuts checked before global key dispatch.
  file_dialogs:
    status: partial
    notes: >-
      macOS native (NSOpenPanel/NSSavePanel) — `usable`. Non-Apple
      platforms route through a host-registered backend with honest
      has_backend() — PRs #312/#316. No native provider ships yet
      for Windows/Linux/Android; callers register their own backend
      or receive explicit no-selection. #338/#339.

input:
  pointer_events:
    status: usable
    notes: >
      W3C PointerEvent API: pointerdown/pointermove/pointerup/pointercancel with
      pointerId, pointerType (mouse/touch/pen), isPrimary, pressure, clientX/clientY.
      Unified model — same JS code works for mouse (macOS), touch (iOS), and stylus (Apple Pencil).
  pointer_capture:
    status: usable
    notes: >
      setPointerCapture/releasePointerCapture for drag interactions.
      gotpointercapture/lostpointercapture events. Implicit release on pointerup.
  stylus:
    status: usable
    platform: ios
    notes: >
      Apple Pencil properties: pressure (0.0–1.0), altitudeAngle, azimuthAngle.
      pointerType="pen" discrimination. Exposed via PointerEvent JS API.
  gesture_events:
    status: usable
    notes: >
      gesturestart/gesturechange/gestureend with scale and rotation.
      macOS: magnifyWithEvent/rotateWithEvent trackpad gestures.
      iOS: multi-touch gesture analysis (planned).
  ipados_hover:
    status: usable
    platform: ios
    notes: UIHoverGestureRecognizer for trackpad/mouse hover on iPadOS 13+.
  touch_action_css:
    status: usable
    notes: CSS touch-action property to control default gesture handling (auto, none, pan-x, pan-y, manipulation).
  coalesced_predicted:
    status: partial
    notes: >
      getCoalescedEvents()/getPredictedEvents() API on PointerEvent objects.
      JS API structure in place. iOS coalescedTouches/predictedTouches data piping planned.

runtime_apis:
  canvas_2d:
    status: usable
    ci_test:
      - pulp-test-canvas
      - pulp-test-canvas-widget
    notes: >
      25+ draw commands including gradient fills (linear/radial), arc/ellipse,
      textAlign/textBaseline, clearRect, clipRect, globalAlpha, lineCap/lineJoin,
      globalCompositeOperation (blend modes), fillRoundedRect, strokeCircle.
  clipboard:
    status: usable
    ci_test: pulp-test-clipboard
    notes: >-
      navigator.clipboard.readText/writeText via platform::Clipboard C++ API.
      macOS/iOS/Windows use native pasteboard APIs. Linux uses
      xclip/wl-copy (#309 / PR #320) — set_text returns false honestly
      when neither is on PATH. Android routes through a host-registered
      bridge (Clipboard::set_android_bridge / clear_android_bridge);
      generated app wiring tracked in #345.
  local_storage:
    status: usable
    notes: localStorage.getItem/setItem/removeItem — file-backed in temp directory.
  performance:
    status: usable
    notes: performance.now() via std::chrono::steady_clock (sub-millisecond precision).
  fetch:
    status: usable
    notes: Minimal fetch(url, opts) via curl exec. GET/POST, returns {text(), json()}.
  encoding:
    status: usable
    notes: TextEncoder/TextDecoder (UTF-8), atob/btoa (base64).
  crypto:
    status: partial
    notes: crypto.getRandomValues() (Math.random-based, not cryptographic).
  image_constructor:
    status: usable
    notes: new Image() with src setter and onload callback for preloading.
  console_extended:
    status: usable
    notes: console.log/warn/error/info/debug + console.time/timeEnd.
  structured_clone:
    status: usable
    notes: structuredClone() via JSON round-trip.
  custom_event:
    status: usable
    notes: CustomEvent constructor with detail property, dispatchEvent support.
  timers:
    status: usable
    notes: setTimeout/setInterval/requestAnimationFrame via __requestFrame__ bridge.
  canvas_draw_image:
    status: partial
    notes: canvasDrawImage renders placeholder; full Skia image decode pipeline planned.
  drag_and_drop:
    status: usable
    notes: registerDrop(id, callback) + View::on_drop. Receives type/data/x/y on file or text drop.
  font_loading:
    status: partial
    notes: loadFont(path) bridge validates existence. Full Skia font registration planned.
  webgpu_shaders:
    status: usable
    notes: >
      Dawn/WebGPU backend available. applyShader(canvasId, skslCode) for custom
      SkSL fragment shaders. getGPUInfo() queries backend. compileShader() validates.

ai_shader_design:
  yoga_layout:
    status: usable
    notes: >
      Meta Yoga v3.2.1 (MIT) replaces hand-rolled flexbox. Correct CSS Flexbox L1:
      margin:auto centering, flex-wrap, absolute positioning, min-content/max-content.
  shader_engine:
    status: usable
    notes: >
      RuntimeEffectCache (process-lifetime SkRuntimeEffect compiler). draw_with_sksl()
      on Canvas with GPU rendering via SkiaCanvas. compileShader() validates SkSL.
      setWidgetShader/clearWidgetShader for Knob/Fader/Toggle body-layer shaders.
      Shader `time` is now driven from FrameClock. Recommended workflow is
      preset/material-first restyling with audio-plugin style-family routing;
      raw SkSL remains a developer escape hatch.
  declarative_schema:
    status: usable
    notes: >
      Rive-inspired JSON widget schema: elements (arc/circle/line/rect/text),
      value binding, color token resolution, percentage dimensions. Interpreted
      by render_schema() at paint time. setWidgetSchema/clearWidgetSchema on
      Knob/Fader/Toggle. Recommended for structured non-color widget look changes
      alongside preset/material overrides.
  lottie_animations:
    status: partial
    notes: >
      setWidgetLottie/seekWidgetLottie bridge. Lottie JSON storage and scrub state
      on Knob/Fader/Toggle. Native Skottie rendering still pending.
      Skottie headers+libs available for future native GPU rendering.
  web_animations_api:
    status: usable
    notes: >
      element.animate(keyframes, options) with Animation object (play/pause/cancel).
      Easing: linear, ease-in, ease-out, ease-in-out. fill mode, animationend event.
  design_tokens_interop:
    status: usable
    notes: >
      importDesignTokens/exportDesignTokens in W3C Design Tokens format.
      Enables round-trip with Figma token plugins, Stitch, v0.
  model_agnostic_ai:
    status: usable
    notes: >
      setAICli/getAICli configures AI CLI command at runtime.
      Default: Claude. Swappable to Gemini/Codex CLI. execAsync enables
      non-blocking shell-backed chat flows in local tools. Design workflows now
      carry provider/model/reasoning-effort metadata and expand command templates
      with {prompt_file}, {model}, {provider}, {reasoning_effort}, and {output_file}.
      Full navigator.gpu pipeline API not exposed — Canvas 2D + shaders is the design.
  design_debug_harness:
    status: experimental
    notes: >
      `pulp design-debug` runs the design chat pipeline headlessly and emits
      before/after/diff screenshots plus a JSON report containing provider/model/
      reasoning-effort metadata, target bounds, prompt/response files, and
      screenshot diff statistics. Supports replaying saved responses. The default
      Skia backend renders widget SkSL offscreen (`render_backend: skia-headless`,
      `widget_sksl_render_supported: true`). `--capture-backend live-gpu` now
      drives the real `pulp-design-tool` app in automation mode and records
      `render_backend: skia-live-gpu` with true live GPU widget screenshots.

design_import:
  figma_adapter:
    status: usable
    notes: JSON IR parsing, audio widget detection, token extraction. MCP live fetch via Claude skill.
  stitch_adapter:
    status: usable
    notes: JSON IR + HTML fallback parsing. Stitch MCP integration via Claude skill.
  v0_adapter:
    status: usable
    notes: JSON IR + Tailwind className extraction. URL fetch via --url flag.
  pencil_adapter:
    status: usable
    notes: JSON IR parsing with Yoga layout near-1:1 translation. Pencil MCP integration via Claude skill.
  code_generator:
    status: usable
    notes: >
      Native mode (createCol/createKnob/setFlex) and web-compat mode
      (document.createElement/style). Audio widget sizing constraints,
      Yoga layout requirements encoded.
  w3c_tokens:
    status: usable
    notes: >
      Full W3C/DTCG Design Tokens: group $type inheritance, alias resolution
      with cycle detection, math expressions, composite types (typography,
      shadow, border). Round-trip safe.
  figma_variables_sync:
    status: experimental
    notes: Parse Figma Variables JSON, export Theme as Figma Variables format. Slash-to-dot path conversion.
  stitch_design_system_sync:
    status: experimental
    notes: Parse Stitch Design System JSON (colors, fonts, roundness, spacing), export Theme as Stitch format.
  validation:
    status: usable
    notes: Headless render + screenshot comparison. Similarity threshold, diff image generation.
  cli_import_design:
    status: experimental
    notes: >
      pulp import-design with --from, --file, --url, --frame, --screen,
      --output, --tokens, --validate, --reference, --diff, --debug flags.
  cli_export_tokens:
    status: experimental
    notes: pulp export-tokens with theme JSON input or built-in dark theme default.
  claude_skill:
    status: usable
    notes: /import-design skill with MCP-aware flow for Figma, Stitch, Pencil, v0.

subsystems:
  runtime: stable
  events: usable
  audio: usable
  midi: usable
  signal: usable
  state: stable
  format: usable
  platform: usable
  canvas: usable
  render: experimental
  view: usable
  osc: experimental

# ── Known limitations (workstream 08 slice 8.5) ───────────────────────────────
#
# Each entry keys a capability path already declared above and carries a list
# of known limitations that should be visible to plugin authors. Every
# limitation MUST cite a tracking location — typically a planning doc or
# a GitHub issue — so readers can follow the work.
#
# tools/list_limitations.py renders this block as a markdown table for
# injection into docs/reference/capabilities.md (manual for v1; auto-inject
# follows in slice 8.3).
#
# Consistency rule enforced by check-docs-consistency.py (warn-mode):
# every key under limitations: must resolve to a real entry in the matrix.
limitations:
  formats.clap:
    - text: "Only bus index 0 is routed to process(); multi-bus + sidechain not wired to set_sidechain()."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.1"
    - text: "MIDI vocabulary limited to note on/off; CC, pitchbend, aftertouch, sysex, MIDI 2.0/UMP not routed."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.1"
  formats.vst3:
    - text: "Only bus index 0 routed to process(); multi-bus + sidechain not wired."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.2"
    - text: "setBusArrangements forwards without validating channel counts or reading negotiated layout."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.2"
    - text: "MIDI vocabulary limited to note on/off; controller, poly pressure, note expression not routed."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.2"
  formats.au_v2:
    - text: "Plugin-side parameter changes do not propagate back to the host (no AUParameterListenerNotify)."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.3"
    - text: "MIDI input dead: AUEffectBase has no MIDI routing."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.3"
  formats.auv3:
    - text: "Single input bus; no sidechain support."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.4"
    - text: "MIDI arrives as raw bytes; no type dispatch to note/CC/pitchbend/aftertouch."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.4"
    - text: "iOS validation is stale — no on-device example or AVAudioSession ↔ C++ bridge."
      tracked_in: "planning/production-readiness/05-auv3-mobile.md"
  formats.lv2:
    - text: "Atom sysex events are not routed — only 1–3-byte short MIDI messages in the atom input sequence reach Processor::process()."
      tracked_in: "planning/production-readiness/01-format-adapters.md#1.5"
  audio_io.wasapi:
    - text: "Shared mode only; no exclusive mode."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.1"
    - text: "Input capture not wired — input_view is always empty."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.1"
    # Hotplug: IMMNotificationClient device-change callbacks landed in
    # PR #281; stale stub entry removed on 2026-04-18 during parity-audit
    # docs refresh (#348).
  audio_io.alsa:
    - text: "No input capture path."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.2"
    - text: "Hardcoded sample-rate list; no real enumeration."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.2"
  audio_io.jack:
    - text: "Dead code — factory always returns AlsaSystem; JACK is never selected at runtime."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.2"
  midi_io.coremidi:
    - text: "UMP type-4 (MIDI 2.0 channel voice) packets are silently dropped in the input handler."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.6"
  midi_io.win32_midi:
    - text: "Legacy mmeapi; no windows.devices.midi2, no hotplug. SysEx input routed via MIM_LONGDATA; WinRT MIDI runtime still pending."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.4"
  midi_io.alsa_midi:
    - text: "Running status not handled; timestamps always 0; no hotplug. SysEx input accumulator landed."
      tracked_in: "planning/production-readiness/02-audio-midi-io.md#2.5"
  platform_maturity.accessibility.windows:
    # UIA bootstrap landed in PR #283 (UIAutomationCore linked, session
    # init wired). Remaining: IRawElementProviderSimple provider tree +
    # WM_GETOBJECT integration + value/focus/selection event emission
    # — tracked in #247.
    - text: "UIA provider tree and event emission pending (bootstrap in place via #283)."
      tracked_in: "planning/production-readiness/04-accessibility.md#4.1"
  platform_maturity.accessibility.linux:
    # AT-SPI D-Bus bridge bootstrap landed in PR #280. Remaining:
    # per-view AtkObject model + value/text/focus event emission.
    - text: "AT-SPI per-view accessible objects and events pending (bridge bootstrap in place via #280)."
      tracked_in: "planning/production-readiness/04-accessibility.md#4.2"

# ── Schema-v2 additions (workstream 08 slice 8.1) ─────────────────────────────
#
# Widgets: inventory every widget in core/view/include/pulp/view/ so the
# consistency checker can cross-reference capabilities.md and catch stale
# widget tables. Status reflects the widget class itself, not the theme/
# platform surface it renders on.
widgets:
  label:            { status: usable, header: widgets.hpp }
  knob:             { status: usable, header: widgets.hpp }
  fader:            { status: usable, header: widgets.hpp }
  toggle:           { status: usable, header: widgets.hpp }
  checkbox:         { status: usable, header: widgets.hpp }
  toggle_button:    { status: usable, header: widgets.hpp }
  icon:             { status: usable, header: widgets.hpp }
  image_view:       { status: partial, header: widgets.hpp,
                      notes: "Placeholder rendering; Skia decode lands in workstream 07 slice 7.4." }
  meter:            { status: usable, header: widgets.hpp }
  multi_meter:      { status: usable, header: widgets.hpp }
  correlation_meter: { status: usable, header: widgets.hpp }
  xy_pad:           { status: usable, header: widgets.hpp }
  waveform_view:    { status: usable, header: widgets.hpp }
  spectrum_view:    { status: usable, header: widgets.hpp }
  spectrogram_view: { status: usable, header: widgets.hpp }
  panel:            { status: usable, header: widgets.hpp }
  combo_box:        { status: usable, header: ui_components.hpp }
  tooltip:          { status: usable, header: ui_components.hpp }
  progress_bar:     { status: usable, header: ui_components.hpp }
  list_box:         { status: usable, header: ui_components.hpp }
  scroll_view:      { status: usable, header: ui_components.hpp }
  text_editor:      { status: usable, header: text_editor.hpp }
  tree_view:        { status: usable, header: tree_view.hpp }
  preset_browser:   { status: usable, header: preset_browser.hpp }
  midi_keyboard:    { status: usable, header: midi_keyboard.hpp }
  waveform_editor:  { status: usable, header: waveform_editor.hpp }
  eq_curve_view:    { status: usable, header: eq_curve_view.hpp }
  file_browser:     { status: usable, header: file_browser.hpp }
  file_drop_zone:   { status: usable, header: file_drop_zone.hpp }
  code_editor:      { status: usable, header: code_editor.hpp }
  breadcrumb:       { status: usable, header: breadcrumb.hpp }
  split_view:       { status: usable, header: split_view.hpp }
  concertina_panel: { status: usable, header: concertina_panel.hpp }
  toolbar:          { status: usable, header: toolbar.hpp }
  color_picker:     { status: usable, header: color_picker.hpp }
  property_list:    { status: usable, header: property_list.hpp }
  graph_editor_view: { status: usable, header: graph_editor_view.hpp,
                       notes: "Canvas-based node editor driving SignalGraph." }
  canvas_widget:    { status: usable, header: canvas_widget.hpp }
  table:            { status: partial, header: table.hpp,
                      notes: "Basic rows; sortable columns + virtualization land in workstream 07 slice 7.3." }
  modulation_matrix:   { status: planned, notes: "Workstream 07 slice 7.1." }
  ab_compare:          { status: planned, notes: "Workstream 07 slice 7.2." }
  resizable_shell:     { status: planned, notes: "Workstream 07 slice 7.5 (documented pattern)." }

# Plugin formats beyond audio host integration.
ara:
  status: planned
  notes: >
    Interface stub exists in core/format/{include,src}/pulp/format/ara.{hpp,cpp};
    host_supports_ara() returns false. No format adapter integration yet.
    Production-readiness workstream 06 tracks the ARA 2.x implementation
    across VST3 + AU + CLAP.
  tracked_in: "planning/production-readiness/06-ara.md"

# Accessibility feature coverage (beyond platform bridge existence). This is
# separate from platform_maturity.accessibility.* which records per-platform
# bridge status. The entries below describe which cross-platform a11y
# primitives are uniformly exposed.
accessibility_features:
  roles_labels_values:
    status: usable
    notes: AccessRole enum + access_label + access_value on View; exposed on all four functional bridges (macos/ios/android and matrix skeleton on windows/linux).
  slider_increment_decrement:
    status: usable
    notes: on_accessibility_adjust(float) routed through VoiceOver/TalkBack increment/decrement actions.
  actions:
    status: planned
    notes: Per-widget std::vector<Action> exposure lands in workstream 04 slice 4.3.
  live_region_announce:
    status: planned
    notes: announce(text, politeness) cross-platform API lands in workstream 04 slice 4.3.
  tree_invalidation_events:
    status: planned
    notes: View-tree change notifications (NSAccessibilityPostNotification / UiaRaiseAutomationEvent / object:text-changed) land in workstream 04 slice 4.3.
  a11y_test_harness:
    status: planned
    notes: Headless AX introspection tests per platform land in workstream 04 slice 4.4.
