A restore point on every content edit
Every content change Respira makes, to pages, posts, builder layouts, options and the site structure below, creates a restore point first. Snapshots are full fidelity: they capture the page builder's own data, not just rendered HTML, so a rollback brings back the real layout, not a flattened copy.
- One-click rollback. Roll any change back to the state before it ran.
- Cascade rollback. One call restores every object changed in a single edit session to its pre-session state, so a multi-step edit undoes cleanly.
- Structure too. ACF field groups, custom post types, and taxonomies are snapshotted and restorable, not just pages and posts.
- Deletes go to the trash, with a snapshot. A page, post, custom post or media item an agent deletes is moved to the trash after a snapshot is taken, and the answer carries the snapshot id. A restore brings it back with its old status and slug; media files come back byte for byte. A permanent delete happens only after a snapshot that can recreate the item under the same ID, and if that snapshot cannot be taken, nothing is deleted.
- Theme files too. A theme file write stores the file's current bytes in a snapshot first. A restore puts the previous content back, or removes a file the write created.
- What has no undo. WordPress core updates, creating, changing or deleting users, deleting menus or terms, and installing or removing plugins are not snapshotted, and neither is a plugin update outside the guarded update below. Your host's backup is the way back for those, and the destructive ones wait for your approval first.
Copy first, then swap
By default the AI works on a duplicate and you approve the swap. Editing the live original directly is off unless you turn it on.
- Plan mode. Start a session with
mode: plan and every write comes back as a step with its predicted effect, nothing written. You read the plan, and apply_plan runs the accepted steps in order through the same checks as a direct call, with one receipt at the end. It is only tool results, so it works in every MCP client (class-respira-plan-session.php). - Content-loss check. Before a swap goes live, Respira checks for unexpected content loss and blocks a risky replace unless you explicitly force it.
- Stale-base detection. If the original changed since the copy was made, the swap is blocked, so the AI cannot clobber a newer edit you made by hand.
- Render-checked, on every builder. After a write, Respira reads the saved content the way WordPress does and renders it in process, the block editor included. A broken block, an attribute that does not parse or a heading that renders as nothing is named in the result, next to the snapshot that undoes the write (
class-respira-render-validator.php).
Destructive actions need approval
Deleting a page, post, media item, or user, installing or activating a plugin, and bulk operations all require an explicit approval step. Approval tokens expire after 10 minutes, and an approval is for a person: an agent that receives one shows it to you and asks.
Per-tool governance lets you turn any individual tool on or off for a site, so you decide exactly what an AI is allowed to do. Access profiles bundle those switches into one setting: Everything, Content or Observe. Both hold on every door into the site, the npm server, the REST API and the site's own MCP endpoint that Claude Desktop, ChatGPT and Respira AER use, with your per-tool choices stacking on top (class-respira-tool-governance.php).
Abilities from other plugins are off until you enable them by name. One setting, off by default, lets an agent run the ones their plugin declares read-only and not destructive; every such call still passes Respira's safety wrap, the activity log and the plugin's own permission check (class-respira-ability-reach.php).
A plugin update with its own way back
The guarded update brings one wordpress.org plugin to the exact version an advisory names, with a restore point before and a health check after. It runs from the Security page of your dashboard and from the /security card in Respira AER, on one site or a fleet, and every run ends in a receipt (class-respira-guarded-update.php).
- Preflight. Before anything is written it checks the offer, that the previous version is archived on wordpress.org (a premium plugin is refused: no archive, no rollback), the new version's PHP and WordPress requirements, permission and governance, the backup plugin the site runs, and that the site answers from the server.
- Restore point, by tier. Duplicator and BackWPup take a fresh backup through their own abilities and the run waits for it. UpdraftPlus is started the way its own command line does and the run reads the record it writes. Any other backup plugin, or none, is a finding, no backup detected, and the one-press path stays closed unless you say in so many words that no restore point is accepted.
- Four health checks. After the update: the site answers, the front page and the most recently edited page answer, no new fatal in debug.log, and the builder still renders.
- Rollback. When a check fails, the previous version comes back from wordpress.org.
- Receipt. The versions, the advisory, every preflight answer, the four checks, the rollback if any and the duration go to the activity log and back to whoever pressed the button.
What an agent cannot change
The options that lock people out of a site are refused to every agent: siteurl, home, admin_email, who may register and with which role, the active plugins and theme, every WordPress key and salt, and Respira's own safety, governance, connection and licence settings. The refusal comes before the snapshot, so nothing is left behind. A filter can add names to the list; it cannot take any away.
- Secrets stay redacted. Values that look like keys, salts, tokens or passwords read back as
[redacted], inside settings arrays too, and WordPress's salts and Respira's own licence key are never returned. - Every SVG is cleaned first. An SVG an agent uploads is sanitised before it is stored: scripts, event handlers, foreign objects and every reference to outside content are removed, and one that cannot be parsed, or still carries anything dangerous, is refused. Respira never changes which file types a site accepts (
class-respira-svg-sanitizer.php). - Site rules are final. A refusal from a site rule ends the attempt. The agent is told to say so, never to work around it, in the rules every channel loads before the first tool call.
Scoped keys, standard WordPress auth
Connect with a WordPress Application Password or a scoped Respira token. Keys are not all-or-nothing.
- Scopes. Keys carry scopes such as read-only, full-fidelity read, write, and force-approve, so a key only does what you grant it.
- Encrypted at rest. API keys are encrypted with AES-256-GCM.
- Rate limited. 1000 calls per key per hour by default, configurable.
- License-gated. If a license lapses, its keys stop working.
A connection you can see into
Respira's clients send the credential a second time, in a header of Respira's own, and the plugin reads that copy when a request arrives with none, so a host that strips the Authorization header does not end the connection. The copy never overwrites a real Authorization header, is accepted only as a Respira key or access token, and can be switched off with one constant in wp-config.php (class-respira-auth-fallback.php).
- Troubleshoot. Respira › Troubleshoot in wp-admin runs the connection checks from the site's own server and shows each as pass or fail, with the cause and one next step: the REST API, the Authorization header and Respira's backup header, the MCP address, sign-in discovery, a bot filter that refuses the user agents claude.ai's and ChatGPT's connectors send, the security plugins and CDNs in front of the site, and whether the site can reach respira.press.
- A report for your host. One button produces a plain-text report: what failed, what to allow, and the id of every test request, with no passwords, cookies, keys or page contents.
- Errors that say what to do. An error on the connection, sign-in or approval path names its cause (credential, capability, licence, security gate, approval, host environment, and the rest) and says whether sending the same call again can work.
Your content never leaves your server
Respira records operation outcomes only: which action ran, on which resource, how many lines changed, and which builders and plugins were detected. It does not collect, store, or transmit your page or post content, and it cannot see your site content from its dashboard or internal tools.
When you connect an AI tool such as Claude, ChatGPT, or Cursor, the prompts and content you send to that tool are handled under that tool's own terms, not Respira's.
Every action is logged
Each key action is recorded: who, when, what resource, the result, and which AI client and version made the call. The audit log lives on your site, under your control.
- Write receipts. Every write response states whether stored content actually changed, with a fingerprint of storage before and after the write. A write that changed nothing says so instead of claiming an edit (
class-respira-write-receipt.php). - Sealed entries. Each audit entry carries a sequence number and a keyed hash chained to the entry before it, so an altered or missing entry is detectable, not silent (
class-respira-audit-seal.php). - Kept 180 days, by your choice. Entries older than the window are removed once a day, oldest first as one unbroken run, so the seal keeps verifying. The window is set in Respira, Settings, under Audit & approvals: 0 keeps everything, otherwise 7 to 3650 days. An agent cannot change it (
class-respira-audit-retention.php).
Infrastructure and compliance, EU data residency, encryption in transit and at rest, Postgres row-level security, GDPR, and sub-processors, live on the Trust Center.