Skip to content

Failsafe write guards for AI-driven abilities#18

Merged
oxyc merged 4 commits into
masterfrom
failsafe-write-guards
May 26, 2026
Merged

Failsafe write guards for AI-driven abilities#18
oxyc merged 4 commits into
masterfrom
failsafe-write-guards

Conversation

@oxyc

@oxyc oxyc commented May 26, 2026

Copy link
Copy Markdown
Member

Summary

Failsafes that make AI-assistant-driven writes safe to run in production, focused on operations that have no undo (Gravity Forms fields, taxonomy terms, Polylang translation links). Companion to generoi/gds-assistant#25.

Least-privilege capability for Gravity Forms

Most write abilities already enforce capabilities (internally, returning forbidden, or via their REST controller), and reads are intentionally public. The exception is the Gravity Forms abilities (forms-*, feeds-*): they call GFAPI directly with permission_callback => '__return_true' and no internal check, so any chat user (edit_posts) could edit/delete forms and feeds — breaking ActiveCampaign/webhook integrations — or read submissions (PII). CapabilityPolicy requires manage_options for them at registration via wp_register_ability_args, only replacing the permissive default (never loosening a real check). Deliberately narrow; filterable via gds-mcp/ability_capability.

Destructive-write guards (data layer)

  • forms-update — refuses to remove a field or change its type when the form has entries (orphans submissions, no revisions) unless confirm_destructive is set.
  • translations-link — refuses relinks that change a post's language or orphan existing translation siblings unless confirm_destructive.
  • content deleteforce=true permanent delete removed. Always trashes (recoverable); types without trash support fall back to permanent delete.

confirm_destructive is injected by gds-assistant only after a human approves in chat, so the guards also protect non-chat callers.

Tests

CapabilityPolicyTest (new), extended GravityFormsAbilityTest and LinkTranslationsAbilityTest, updated ContentAbilityTest/WorkflowTest for trash-only delete.

🤖 Generated with Claude Code

@oxyc

oxyc commented May 26, 2026

Copy link
Copy Markdown
Member Author

Companion (assistant side, consumes the confirm_destructive guards added here): generoi/gds-assistant#25

oxyc and others added 4 commits May 26, 2026 12:16
…abilities

The Gravity Forms abilities (forms-*, feeds-*) call GFAPI directly with permission_callback => __return_true and no internal check, so any chat user (edit_posts) could edit/delete forms and feeds — breaking integrations — or read submissions (PII). CapabilityPolicy requires manage_options for them via wp_register_ability_args. Deliberately narrow: other write abilities already enforce caps internally or via their REST controller, and reads are intentionally public, so they're left untouched. Filterable via gds-mcp/ability_capability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…onfirmation

forms-update fully replaces the fields array; dropping a field or changing its type orphans that field's submitted entries, with no revisions to recover. updateForm() now diffs old vs new fields and, when the form has entries, refuses removals/type-changes unless confirm_destructive is set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
content-delete no longer exposes force=true. Content is always trashed (recoverable); types without trash support fall back to a permanent delete since they have no recoverable option.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
translations-link overwrites Polylang's translation group and can strip a post from its current group, silently orphaning previously-linked posts with no revisions. It now refuses relinks that change a post's language or drop existing siblings unless confirm_destructive is set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@oxyc oxyc force-pushed the failsafe-write-guards branch from 938a7a9 to e7ebb1e Compare May 26, 2026 15:16
@oxyc oxyc merged commit b5e1d67 into master May 26, 2026
2 checks passed
@oxyc oxyc deleted the failsafe-write-guards branch May 26, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant