How AI Lock prevents AI agents from overwriting human edits — field-level protection enforced at the engine level.
The problem
You carefully edit a blog post title. An AI agent runs overnight and overwrites it with a generated version. Your work is gone.
This happens in every CMS that bolts AI onto existing content workflows. AI and humans fight over the same fields with no rules about who wins.
How AI Lock works
@webhouse/cms tracks who last edited each field — human or AI. When a human edits a field, it becomes locked. AI agents can never overwrite a locked field. Only a human can unlock it.
This isn't a setting you toggle. It's enforced at the engine level, in every write operation, through the WriteContext actor system.
The _fieldMeta system
Every document has a _fieldMeta object that tracks the lock state per field:
{
"slug": "my-post",
"data": {
"title": "My Carefully Written Title",
"content": "AI-generated content here..."
},
"_fieldMeta": {
"title": {
"lockedBy": "user",
"lockedAt": "2026-03-30T10:00:00Z",
"lastEditedBy": "cb@webhouse.dk"
},
"content": {
"lockedBy": null,
"lastEditedBy": "ai:content-writer"
}
}
}In this example:
- title is locked — a human edited it. No AI agent can touch it.
- content is unlocked — AI generated it. AI agents can update it freely.
Write context actors
Every write operation carries a WriteContext that identifies who's making the change:
interface WriteContext {
actor: "user" | "ai" | "system" | "import";
userId?: string;
agentId?: string;
source?: string;
}When actor: "user", the CMS auto-locks edited fields. When actor: "ai", the CMS checks locks and skips locked fields.
What happens when AI tries to write a locked field
- AI agent calls
update_documentwith new data for all fields - CMS engine reads
_fieldMetafor each field - Locked fields are silently skipped — AI data is ignored for those fields
- Unlocked fields are updated normally
- No error thrown — the agent doesn't need to know about locks
This means AI agents can run bulk operations across the entire site without any risk of overwriting human work.
Configuration
Per-field AI lock behavior
{
name: 'title',
type: 'text',
aiLock: {
autoLockOnEdit: true, // Lock when human edits (default: true)
lockable: true, // Whether field can be locked at all (default: true)
requireApproval: false, // Require human approval before AI writes
}
}Unlocking a field
In the editor, each field shows a lock icon when locked:
- 🔒 Locked — human-edited, AI cannot change
- 🔓 Unlocked — AI can update freely
Click the lock icon to toggle. Only humans can unlock fields.
Use cases
Content Writer agent
- AI generates blog posts → all fields unlocked
- Human edits the title → title locks
- AI runs SEO optimization → updates description, keywords, but skips title
Translator agent
- AI translates all fields to Danish
- Human corrects a specific phrase → that field locks
- AI re-translates the page → skips the corrected field
Bulk SEO optimization
- AI runs
bulk_updateon 100 documents - Documents with human-edited meta titles → titles preserved
- Documents with AI-generated titles → titles updated
For AI builders
When building sites or scripts that write content:
// Creating content as AI (fields stay unlocked)
await cms.content.create('posts', {
slug: 'new-post',
data: { title: 'AI Title', content: '...' },
}, { actor: 'ai', agentId: 'content-writer' });
// Creating content as user (fields auto-lock)
await cms.content.create('posts', {
slug: 'new-post',
data: { title: 'My Title', content: '...' },
}, { actor: 'user', userId: 'cb@webhouse.dk' });Why this is different
Other CMS platforms with AI features either:
- Let AI overwrite everything (dangerous)
- Require manual "approve each change" workflows (slow)
- Have no concept of field-level ownership (crude)
@webhouse/cms AI Lock is:
- Automatic — locks on human edit, no manual step
- Granular — per-field, not per-document
- Non-blocking — AI agents run freely, locked fields are silently skipped
- Transparent — lock state visible in editor and
_fieldMeta - Engine-level — enforced in every write path, not just the UI