complete-append-only-insert-guards

Validates D1 BEFORE INSERT guard triggers against every unique conflict key on append-only tables.

Updated Jul 9, 2026
One-click install
npx skills add https://github.com/shuddl/shuddl-os --skill complete-append-only-insert-guards-shuddl
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: complete-append-only-insert-guards
Source: https://github.com/shuddl/shuddl-os/tree/main/.claude/skills/complete-append-only-insert-guards
Command: npx skills add https://github.com/shuddl/shuddl-os --skill complete-append-only-insert-guards-shuddl

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? On Cloudflare D1, INSERT OR REPLACE silently deletes conflicting rows through every UNIQUE key, and because recursive_triggers is off, the BEFORE DELETE guard never fires — so a BEFORE INSERT guard whose WHEN clause omits even one unique key leaves a silent hole that can erase Merkle-chained ledger rows. ## Core Features & Use Cases - Guard completeness rule: Enumerates the mechanical requirement that a guard's WHEN EXISTS clause OR together the PRIMARY KEY, every UNIQUE column, and every UNIQUE INDEX (mirroring partial-index WHERE predicates). - Real defect walkthrough: Dissects the live events_guard_ins gap where hash and the device unique index were unguarded, and provides the corrected forward-only migration pattern. - Lint parity guidance: Covers rebuilding the FORBIDDEN_REPLACE source regex from the shared SCHEMA/Q/DELIM fragments so it matches the migration scanner, plus a six-step checklist for any new guarded table or unique key. - Use Case: When adding a UNIQUE index to the events table, use this Skill to extend the guard trigger, add the table to GUARDED_TABLES, and write per-key RAISE(ABORT) tests shipped as a new forward-only migration. ## Quick Start Ask the AI to review the WHEN clause of events_guard_ins against every unique constraint declared in 0001_ledger_core.sql and draft the corrective forward-only migration.

Frequently Asked Questions about complete-append-only-insert-guards

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I write an append-only BEFORE INSERT guard trigger in SQLite D1?▼

Write a BEFORE INSERT trigger whose WHEN EXISTS clause ORs together the PRIMARY KEY, every UNIQUE column, and every UNIQUE INDEX on the table, ending with SELECT RAISE(ABORT). Mirror any partial index's WHERE predicate so uncovered rows are not aborted.

Why does INSERT OR REPLACE bypass my BEFORE DELETE trigger on Cloudflare D1?▼

D1 runs with PRAGMA recursive_triggers = 0 and it cannot be changed, so the implicit DELETE that REPLACE performs never fires the BEFORE DELETE guard. The BEFORE INSERT guard is the only backstop, and only for the conflict keys its WHEN clause names.

Does INSERT OR REPLACE delete rows on every unique key or just the primary key?▼

REPLACE deletes pre-existing rows through every UNIQUE and PRIMARY KEY constraint it conflicts with, per the SQLite documentation. A guard testing only the PK leaves other unique keys as silent holes.

Can I edit an existing migration file to fix an incomplete guard trigger?▼

No, migrations are forward-only and locked via db/migrations.lock.json anchored to git HEAD. Ship a new sequentially-numbered migration that adds a complete second BEFORE INSERT guard alongside the existing one.

When should a guard allow identical-hash re-ingest instead of aborting?▼

Only when the table has no secondary UNIQUE key beyond its PRIMARY KEY, as with positions, where idempotent INSERT OR IGNORE re-ingest is sanctioned. Copying that hash <> NEW.hash shape to a table like events re-opens every secondary unique key.