A single timeline. Every version Respira has shipped, with the stories behind the ones that mattered. Click into any release tagged story for the full write-up.
No more Cannot declare class WP_Ability_Category site-down on Bedrock/Kinsta (WP 6.9+/7.0)
fixNo more Cannot declare class WP_Ability_Category site-down on Bedrock/Kinsta (WP 6.9+/7.0). On Bedrock layouts ABSPATH has no trailing slash, so the 7.4.2 collision guard's ABSPATH . WPINC join produced a malformed path,
fixOne-click "Connect to respira.press" no longer dead-ends on "you are not allowed to access this page." The OAuth round-trip returned the browser to a hidden admin alias that WordPress de-registers, so the final redirect
fixIn-place Divi 5 edits no longer collapse settings-shaped multi-element content. validate_render_critical_attrs is now settings-aware, so the validated inject path (used when an agent rebuilds an existing page) accepts th
June 14, 2026
Patch. Divi 5 page generation now produces native, editable, rendering modules from the looser content shapes agents actually send. Before, a homepage request often came back as
fixFIX: Divi 5 builds collapsed to plain text / a raw code block instead of native editable sections and modules. A new normalization pass lifts loose content synonyms (heading text, button text + url, paragraph content, ne
fixFIX: native Divi 5 modules could render as empty containers. The normalized content is now written to the settings bucket (which the complexifier expands into the title.innerContent.desktop.value / content.innerContent.d
fixFIX: a build whose attributes.content was a scalar string (e.g. divi/text) could fatal in the Divi 5 attribute-group deep-merge. The merge now runs only when the existing group is itself an array.
June 13, 2026
SmartCrawl Pro (WPMU DEV) SEO support
addSmartCrawl Pro (WPMU DEV) SEO support. Respira now detects SmartCrawl and writes and reads its native _wds_* post and term meta — title, meta description, focus keyword, canonical, and the split index/follow robots flags
fixElementor v4 atomic styles applied through an explicit styles:{} block were generated but never worn by the element. The flat-CSS write path already linked the minted style id into the element's class list; the styles-bl
fixElementor global colours: the kit's system colours (primary, secondary, text, accent) could not be changed. update_elementor_global_colors only ever wrote custom_colors, so passing a system _id appended a duplicate custo
fixDivi 5: a blurb's image was written to a group the renderer ignores, so it never appeared. Divi 5 reads the blurb image from imageIcon.innerContent.desktop.value.src and shows it only when useIcon is off; Respira wrote s
fixDivi 5: the bar counter targeted a module slug Divi 5 does not register. The number/percent → barProgress routing was keyed on divi/bar-counter / divi/bar-counters-item, which do not exist, so a counter rendered at 0%. I
fixDivi 5: an image's click-through link did not apply. image_url on divi/image wrote to …value.url, but Divi 5 reads the link from …value.linkUrl. It now writes linkUrl
June 12, 2026
Security validator false positive
fixSecurity validator false positive. The inline-event-handler pattern (/on\w+\s*=/i) matched onXXX= anywhere in content — including inside shortcode attribute values like button_text="Start minikursus for 222 kr.". The pat
fixPlaybooks not appearing in the ChatGPT tool list. get_ability_ids_for_adapter() called Respira_Playbooks::get_registered_ability_ids(), which reads from a static array populated during wp_abilities_api_init. That action
fixDivi 5.7 Visual Builder opens blank after Respira writes. Divi 5.7 changed its VB initialisation to read content from the WordPress autosave revision ({post_id}-autosave-v1) rather than the _et_pb_page_content meta. Page
fixDuplicated Divi 5.7 page appears empty in Visual Builder. Same root cause: newly duplicated pages have no autosave revision. Respira now seeds the revision at duplication time so the VB opens with the correct content
fixDivi code module becomes inaccessible after a CSS or HTML update. The same autosave-revision gap applied to targeted element updates: updating a code module's content wrote the new post_content but left the autosave revi
fixDivi 5 column widths collapse to 0px on a 3-column row. When an asymmetric flex column structure (e.g. 60/20/20) was distributed across 3 or more columns, the fractional percentages were computed correctly but the third
What the agent writes is what actually lands on the page
A deep pass through every supported builder, closing the gaps where a write reported success but the page stayed stale or blank. Styling now lands on Oxygen, Beaver Builder, Elementor v4 Atomic, Bricks, Divi 4 and Divi 5. Brizy and Visual Composer move from read to write, with their caveats stated. Recovery gets deeper: custom CSS and page settings are captured, and globals are versioned, so deleting a Bricks global class, a Divi preset, or an Elementor kit color leaves a recovery point. And when something cannot be persisted in a way the builder reads, Respira says exactly what did not land instead of reporting success. Every fix verified on a real site by loading the actual rendered page.
addBrizy moved from read to write. Respira can now write Brizy pages that Brizy's own editor opens and the front end renders. Writes are labeled with their caveats in the docs (front-end compile depends on Brizy's compiler
addVisual Composer moved from read to write. Respira now writes in VC's canonical storage format, so the editor loads the page and the front end renders. Labeled with its caveats (VC recompiles on the next editor save)
addGlobals are now versioned. Deleting a Bricks global class, a Divi preset, or an Elementor kit color now leaves a recovery point. "The agent deleted my global class" used to be unrecoverable; now you can roll it back. Res
addYour own custom CSS and page settings are now captured in snapshots, so the edits Respira makes to things like custom CSS are recoverable, not just the main content
addLoud-drop behaviour across builders. When a value cannot be persisted in a way the builder reads, Respira names exactly what did not land and tells the agent not to retry blindly. This is the systemic version of the per-
addAn internal check now runs across the test fleet to confirm that every builder function Respira calls actually exists in that builder. It would have caught several of the silent failures below the day they were written,
fixOxygen: generated CSS was being written without the selectors it needed, so styles never reached the page. Element styling now renders, and dynamic content resolves correctly. Code blocks that contained quotes could corr
June 10, 2026
Divi 5 builds with rich native modules by default
addDivi 5 builds with rich native modules by default. The agent now advertises divi/heading, divi/text, divi/image, divi/button, and divi/blurb alongside the structural blocks. Before this, the only content block offered by
addDropped Divi 5 styling now fails loudly. When a style attribute is not supported on a Divi 5 module, the write still saves the content but now returns a clear dropped_settings summary naming exactly which styles did not
changeConnecting an AI assistant moved to the respira.press dashboard. The plugin's connect screen is now a status band plus one button that opens the dashboard MCP page with this site preselected (you land signed in). Pick yo
June 10, 2026
inject_builder_content now accepts target_path to add modules to an existing column
addinject_builder_content now accepts target_path to add modules to an existing column. Pass the path of the target container (e.g. target_path: "sections[0].rows[0].columns[0]") along with content containing the new module
fixPlaybooks now appear in the streamable MCP tools/list. get_ability_ids_for_adapter() never read from the WP Abilities registry, so respira-playbooks/* IDs (registered dynamically at boot) were invisible to ChatGPT and Cl
fixinject_builder_content now accepts target_path to add modules to an existing column. Pass the path of the target container (e.g. target_path: "sections[0].rows[0].columns[0]") along with content containing the new module
fixDivi 5 column nodes now appear as columns[n] in path strings instead of modules[n]. build_path_string() previously used modules[n] for every node at depth 2 or deeper, making columns and leaf modules indistinguishable. A
fixWebMCP input size limit raised from 100 KB to 10 MB. The wmcp_max_input_size default was set in 2023 before Divi 5 adoption. Pages with > ~50 KB of builder content failed silently with Tool execution failed. Raised to 10
fixElementor Pro Global Widgets no longer cause a PHP 500 after any page edit. simplify_structure() only preserved id/elType/settings/elements/widgetType/isInner, so the top-level templateID property on Global Widget elemen
June 10, 2026
Divi 5 build guidance points the agent at the rich native modules
changeDivi 5 build guidance points the agent at the rich native modules. The server's Divi 5 blurb now says heading, text, image, button, and blurb are advertised by default and safe to build with, and to prefer them over divi
changeNo more per-inject Divi 4 vs Divi 5 round-trip. The editing contract now tells the agent to auto-detect the version from the page (respira_get_builder_info / respira_read_page, with the plugin already flipping into Divi
addDropped-styling warnings are hoisted to the top of build results. When a Divi 5 (or any builder) write drops style settings the builder does not recognise, wordpress_inject_builder_content, wordpress_build_page, and word
June 8, 2026
Playbook steps accept the hyphenated tool names MCP clients emit
fixPlaybook steps accept the hyphenated tool names MCP clients emit. A step naming a tool in the client form (e.g. respira_wordpress-create-page-duplicate, as ChatGPT exposes it) was rejected as "not in the playbook executi
fixElement-level tools reach their v2 routes from a playbook. The executor dispatched every step to the v1 REST namespace, but find_element, update_element, and the snapshot tools register only on v2, so those steps failed
fixupdate_element routes to the element-update endpoint, not update_module. The allowlist mapped respira_update_element to the update_module path (a whole-tree round trip that is lossy on Divi 4) and required a spurious bui
June 7, 2026
report_issue over the site-URL MCP endpoint
addreport_issue over the site-URL MCP endpoint. OAuth and dashboard-token clients (ChatGPT, Claude Desktop, claude.ai) can now file a structured bug report from inside the chat. It validates title/brief/steps, attaches the
addlist_playbooks and create_playbook over the site-URL MCP endpoint. The playbook management verbs were registered only as REST routes, never as MCP abilities, so the native endpoint never surfaced them (the npm server cal
fixA full-page Divi write could fail security_validation_failed on its own legitimate markup. The trusted-builder-shortcode check stripped opening tags and leaf modules but left orphan closing tags ([/et_pb_column] ...) on
fixThe documented id module identifier silently returned module_not_found on Divi. update_module accepts module_identifier.id (the Divi module_id, e.g. "ole") and the API mapped it, but the Divi resolver had no case for it,
fixDivi section paths accept a bare or slash-prefixed index. path: "6" and path: "/6" now target the seventh top-level section (equivalent to sections[6]), alongside the existing sections[6] and dotted-index forms
June 6, 2026
Divi 4 modules with a bracketed attribute value could be truncated on edit
fixDivi 4 modules with a bracketed attribute value could be truncated on edit. When a module carried an attribute whose value contains a ] inside quotes (the common case is a global color, which Divi serializes as global_co
fixbatch_update on Elementor wrote to the wrong attribute bucket. batch_update hardcoded 'attrs' as the key it patched, but Elementor stores element attributes under 'settings'. Batched edits on Elementor therefore wrote in
fixSix element and builder primitives were unreachable from playbooks. respira_create_page_duplicate, respira_create_post_duplicate, respira_extract_builder_content, respira_get_page_outline, respira_get_builder_inline_sche
fixClaude Desktop / claude.ai rejected the whole tool list when an inhaled ability had a union-typed input schema. The native /mcp endpoint passed each ability's inputSchema through unchanged. Some inhaled third-party abili
May 28, 2026
delete_media schema exposes approval_token + force
adddelete_media schema exposes approval_token + force. The destructive gate landed on the WP side in v7.1.0-beta.1 but the MCP schema didn't expose the params, so agents couldn't complete the two-step approval round-trip. N
fixB3 / N20: inject_builder_content Divi detector misclassified wrapped extracts. detectDiviContentFormat now unwraps the {content: [...]} round-trip shape via the shared helper before walking. Pre-fix, wrapped extracts ret
May 27, 2026
Divi 4 extract+inject round trip preserves per-column children order
fixDivi 4 extract+inject round trip preserves per-column children order. parse_divi_shortcodes flattened columns via array_merge and lost per-column boundaries; build_divi_shortcodes then round-robin'd children back across
fixElementor v3 Nested Element widgets — page-level saves no longer strip widget-level elements[]. complexify_structure only re-emitted $element['elements'] when the elType was a known container (v3 section/container/column
fixGutenberg update_element with {content: "..."} now persists to post_content. The universal interface wrapped any flat patch missing a "structural" key into the adapter's attrs bucket. For Gutenberg that meant {content: "
fixDivi 5 layout validator no longer over-rejects on append writes. B.W. reported every add_section / add_html / append-mode inject_builder_content failing with 16 verbatim "row should be inside section or column" errors —
fixDivi 5 approve/merge no longer corrupts < and > to literal "u003c". approve_duplicate_by_merging_into_original passed the duplicate's unslashed post_content straight to wp_update_post, which wp_unslash()s internally befo
fixmove_element no longer silently deletes; reorder_elements no longer 500s. The MCP schemas shipped param names the plugin handlers never read. move_element sent element_id + target_container_id while the plugin expected i
May 27, 2026
Per-client HTTP agents + destroy-on-watchdog-trip
fixPer-client HTTP agents + destroy-on-watchdog-trip. Pre-v6.19.3 the WordPressClient axios instances used Node's shared http.globalAgent / https.globalAgent. When a write tool hung past RESPIRA_MAX_TOOL_TIMEOUT_MS the watc
fixrestore_snapshot polls for completion when the request times out. Heavy Divi / Oxygen pages can take 1-3 min to restore; pre-v6.19.3 the synchronous POST exceeded axios's 30s timeout even though the server-side restore c
rmwordpress_search_abilities MCP tool. Hit /wp-json/respira/v1/abilities/search, a route the plugin never registered. Every call 404'd. wordpress_get_builder_info + wordpress_search_docs cover the discoverable surface; wor
schemawordpress_move_element + wordpress_reorder_elements aligned with the plugin contract. The MCP schemas shipped param names the plugin handlers never read; the plugin handlers had to be patched in 7.0.59 to accept the lega
May 24, 2026
rest_no_route errors now carry the attempted path
fixrest_no_route errors now carry the attempted path. Previously, when WordPress returned rest_no_route (54 hits across two sites the week of 2026-05-24), the MCP recorded the generic WP string "No route was found matching
changeinject_builder_content description now lists Divi render-critical attrs. When any of the 10 Divi module types in the validator is missing its required attr (e.g. divi/heading without title, divi/button without button_tex
changeread_theme_file description hardened against non-stylesheet attempts. The schema already enforced .css / .scss / .less / .json, but agents kept trying .php / .html (5 hits the week of 2026-05-24, returning respira_theme_
May 23, 2026
Divi is_builder_used() vetoes itself when _et_pb_use_builder='off'
fixDivi is_builder_used() vetoes itself when _et_pb_use_builder='off'. The explicit 'off' value is the user's signal that Divi is NOT active on this post (even though stale _et_pb_page_* meta from a previous Divi-active per
addupdate_element response now carries builder.name and builder.version. Surfaces the picked adapter directly in the response envelope so silent-write reports can name the adapter that claimed the post without a separate re
noteThe Lite plugin's is_divi_page() already vetoed on 'off' === $et_pb_use (only returns true on 'on'), so Lite was never affected and no sync port is needed.
noteOnce the customer confirms v7.0.56 lands the write correctly, the broader detect_builder() audit (theme-tiebreaker rule should also respect explicit per-post disables across all builders, not just Divi) is queued separat
May 23, 2026
expected_type opt-in pre-write validation on update_module for Divi 4
addexpected_type opt-in pre-write validation on update_module for Divi 4. Callers (MCP clients, apply_builder_patch, batch_update) can pass expected_type: 'et_pb_text' in the updates payload. If the resolver lands on a modu
addexpected_type and _skip_truncation_check are now also stripped from the attribute patch automatically so they cannot accidentally land in module attributes if a caller forgets to extract them.
noteThe root-cause fix (rewriting the path resolver to follow the nested children[] tree rather than the flat row-column merge) is queued for v7.0.56. Until then, agent clients calling Divi 4 update_module on multi-column ro
noteThe MCP server's update_module tool description will get a matching update in the next mcp-server release to advertise expected_type and recommend its use on Divi 4. Plugin-side ship goes out first so the surface is ther
May 23, 2026
Gutenberg is_builder_used() disqualifier checks values, not just key presence
fixGutenberg is_builder_used() disqualifier checks values, not just key presence. Each "other-builder" meta key now carries a predicate matching the source builder's own activity convention:
noteVerified the failure mode against M.P.'s exact scenario: a post duplicated from an original that has _et_pb_use_builder=off will, pre-v7.0.54, fall through Gutenberg's claim check despite Gutenberg being the only sensibl
noteThe pre-v7.0.54 disqualifier list pattern (presence-only) is a common code-smell across builder adapters. Future cleanup is queued to audit the cross-builder claim logic for the same stale-key class of bug, but for v7.0.
fixBricks option-group write endpoints recursively strip _respira_* keys from request bodies. handle_create_item was already stripping _respira_key_data at the top level only; expanded to recursive scrub_respira_internals()
fixupdate_element / element-ops envelope is_duplicate now matches the actually-resolved write target. Pre-v7.0.53, Respira_Element_Ops::target_metadata() read is_duplicate from resolve_mutation_target()'s output, which eval
fixGutenberg inject_content now guards the write against third-party save_post reverts AND verifies persistence. The customer report: 9 successive duplicates (340148, 340151, 340153, 340155, 340157, 340159, 340161, 340163,
noteThe Gutenberg silent-revert family also lives in the Divi adapter's update path for posts (Divi was enabled-then-disabled mid-session on the customer site, so duplicate detection may still route through Divi while Gutenb
noteThe Bricks scrub does not delete leaked data from already-corrupted rows — it strips at READ + WRITE. A separate one-shot migration to scrub stored values is queued but not blocking: the READ scrub keeps the leak out of
fixB-7: inject_builder_content rejects simplified types. Pre-fix the detector returned unknown for payloads using simplified types (section, row, column, heading, etc. without divi/ or et_pb_ prefix) and hard-failed with "D
fix{content: [...]} wrapper unwrap. Round-tripped extracts come back as {content: [...]}. The new unwrapBuilderContent helper normalises before forwarding so every downstream caller sees the same shape
fixCamrin@cspmarketingsolutions friendly→canonical param translation. Three structural tools (move_element, duplicate_element, reorder_elements) advertised friendly param names but the REST endpoints required typed pairs. D
May 22, 2026
Truncation guard in Respira_API::update_element only fires on REAL truncation now
fixTruncation guard in Respira_API::update_element only fires on REAL truncation now. Pre-v7.0.52 the guard at class-respira-api.php line 6159 compared the byte length of $updates['content'] (input) to the byte length of th
fixcontent + text identifier_types skip the verify step entirely. For those identifier shapes the post-write find_module is unreliable BY DESIGN (the identifier string was the thing we just changed). No verify, no false pos
fixNew updates._skip_truncation_check: true opt-out for callers that know the verify-find would land on the wrong node. Safety hatch — the guard stays opt-in-default for paths where it does catch real truncation
noteBug #1 from Morgan's report (update_element with match_content targets the FIRST match instead of the DEEPEST match) is actually addressed correctly by the v6.11.1+ find_divi4_shortcode deepest-match logic at class-build
noteBug #3 (4-minute timeout on update_page / inject_builder_content for ~113KB Divi shortcode pages) is the same large-page complexify-tree-walk overhead that bit M.P. on Fischers Fritze. Belongs to v7.1.
noteThe customer-facing impact of the false positive was severe: Morgan saw "tool failed" on a write that had actually persisted his changes correctly, retried via a workaround that bypassed type validation, and corrupted hi
May 21, 2026
Respira_Builder_Tree_Utility::matches() content identifier_type now deep-searches options / attrs / settings
fixRespira_Builder_Tree_Utility::matches() content identifier_type now deep-searches options / attrs / settings. Pre-7.0.51 the content matcher only checked $element['content'] (Elementor / Divi 4 top-level string) and $ele
fixupdate_element adds a normalize_element_updates($existing_element, $updates, $wrap_target) hook on Respira_Builder_Interface; Oxygen overrides it to route ct_image / ct_image_overlay flat patches into options.original. P
noteVerified end-to-end on Studio :8882 with Oxygen Classic 4.9.7. Test fixture: synthetic page with a ct_text_block whose options.ct_content is "Hello world<br>this is a paragraph ending in br" plus a ct_image with options.
noteThe normalize_element_updates hook lands on the interface as an optional method — adapters that don't override it pay no cost. Future adapter-specific patch normalisations (Beaver's nested font field family, Breakdance's
noteWider M.P. Härtetest findings: items #1, #2, #3, #5 are addressed by v7.0.47 → v7.0.50 (already shipped); the 4-minute timeout he flagged separately should also clear once v7.0.49's auto-heal removes the upstream 500 tri
May 21, 2026
divi_render_critical_attrs() no longer flags divi/column nodes missing attrs.type
fixdivi_render_critical_attrs() no longer flags divi/column nodes missing attrs.type. The render-critical-attrs map was introduced in v7.0.0 Bloom Phase B to catch LLM hand-writes that would render empty (heading without ti
noteVerified on Studio :8882 with synthetic 5-section Divi 5 tree containing 9 divi/column nodes with attrs => [] (the round-trip shape): validator returns 0 entries. Counter-test with deliberately bad leaf modules (heading
noteThis release narrows the validator surface but does NOT fix the broader inconsistency between build_page (skip validator) and inject_builder_content (apply validator). That's a deliberate scope decision: the column rule
noteThe Nettl reporter posted a very precise repro (5 sections, 4 rows, exact node counts) plus a working hypothesis pointing at content.innerContent. The actual root was different but the report's structured shape made the
May 21, 2026
Tree_Utility::matches() type+match_content branch deep-searches attributes / attrs / settings for the needle
fixTree_Utility::matches() type+match_content branch deep-searches attributes / attrs / settings for the needle. Pre-7.0.46 the branch only ran stripos($element['content'], $match_content). Self-closing Divi 4 modules (et_p
noteCloses the github #32 follow-up surface P.L. raised — third increment on this issue but the underlying bug was always one piece deeper than the previous fix suggested. v7.0.29 added attribute-text matching for update_mod
noteVerified by inspection: the new match path uses text_contains for the content body (HTML-tolerant via the existing v6.5.1 sanitiser) and any_string_contains for the attribute buckets (recursive deep-search). Both helpers
May 21, 2026
batch_update per-operation resolver now forwards match_content to Tree_Utility::find()
fixbatch_update per-operation resolver now forwards match_content to Tree_Utility::find(). Pre-7.0.45 the call site only passed 4 args (the optional 5th match_content was dropped), so any batch operation targeting a specifi
fixbatch_update remove action gets the same fix. Both actions in the same method use the same shared $op_match_content variable
noteOperator-trapping severity: pre-fix the API returned success: true with the write landing on the wrong element. Mid-batch silent data loss with a green-status response.
noteCloses github #32. The Divi 4 customer surface arc (P.L. / Catholic Mass Times) over the v7.0.29 -> v7.0.45 chain: kses corruption (closed v7.0.29), column corruption (closed v7.0.29), silent no-op (closed v7.0.29), per-
May 9, 2026
README accuracy pass: 30 skills
change8 slash commands for the most common workflows
change30 auto activating skills, broken down as:
change1 visual reviewer sub agent that shows what changed after every edit
changeFull access to all 180+ Respira MCP tools through the bundled @respira/wordpress-mcp-server
Flatsome UX Builder joins as builder #12. 15 new WooCommerce Commerce tools with storefront design intelligence. Context-aware MCP tool filtering reduces tools in context by ~40. Three coordinated releases.
addFlatsome UX Builder as Builder #12: Full support for the most popular WooCommerce theme on ThemeForest (200K+ sales). Extract, inject, element ops, build_page, and snapshots all work. Detection by active theme. Shortcode
addShortcodeParser utility: Shared shortcode parsing and reconstruction for Divi 4 and Flatsome. Parameterized by tag prefix, column format, and detection patterns. Strict tag allowlists prevent cross-builder content confus
addBundled WooCommerce entitlement: Studio and Founder plans now include the WooCommerce add-on at no extra cost. Maker and Builder customers continue to purchase it separately
addContext-aware tool filtering (MCP server v6.0.0): The MCP server now filters the tool list based on detected builder and active plugins. Bricks tools hidden when Bricks is not active, WooCommerce tools hidden when WooCom
addWooCommerce snapshot safety: All existing WooCommerce write tools (create_product, update_product, update_stock) now create before/after snapshots and log to the audit trail. Previously these operations were invisible an
addFlatsome Intelligence package: 55 element definitions with attributes, types, defaults, nesting rules, and responsive patterns. 6 pre-built page patterns for AI agents
65 new tools. Element-level editing across every supported builder, build_page declarative page creation, HTML-to-builder conversion, stock-image search, tool governance, and dynamic schemas for 12 builders.
addElement-level operations: find_element, update_element, move_element, duplicate_element, remove_element, batch_update (atomic), reorder_elements — works across all 11 builders via tree utility or native overrides
addbuild_page: Create complete pages from a declarative structure in a single API call. Returns preview URL
addStock images via Openverse: search_stock_images and sideload_image with CC attribution, domain allowlist, SSRF protection, and deduplication
addTool governance: Per-tool enable/disable with fail-open safety. Single chokepoint for REST + Abilities API. Audit logging
addElementor dynamic schemas: Reads control registry at runtime, maps to JSON Schema types. Settings validator with "did you mean?" suggestions
cookies. the legal kind. one click and i'll get out of your way.
what you'd actually be saying yes to
tune your cookie preferences
essentials stay on regardless. the rest is opt-in. nothing fires until you tap save.
essentials
the cookies that make logging in work and remember which partner sent you. switching these off would just break the site, so the law does not let me make you opt out.
first-touch source on a /respira_acq cookie, plus a flag if an ai chatbot referred you. helps me figure out what is working without turning you into a tracking pixel statue.
messaging
customer.io for in-app notes, chatwoot when you click the support bubble. off by default. on means i can actually answer you in the app.