Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add rules/openstory-so/openstory/drizzle-patternsgit clone --depth 1 https://github.com/openstory-so/openstoryWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/rules/openstory-so/openstory/drizzle-patterns)<a href="https://agentmods.dev/rules/openstory-so/openstory/drizzle-patterns"><img src="https://agentmods.dev/badge/rules/openstory-so/openstory/drizzle-patterns.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.02688 |
| Opus 5 | $0.00000 | $0.01344 |
| Sonnet 5 | $0.00000 | $0.00538 |
| Haiku 4.5 | $0.00000 | $0.00269 |
Grade A, and why
drizzle-patterns scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 445 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Drizzle ORM Patterns
Schema Definition
import {
pgTable,
uuid,
text,
timestamp,
boolean,
jsonb,
integer,
} from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
export const teams = pgTable('teams', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email'),
isAnonymous: boolean('is_anonymous').default(true).notNull(),
teamId: uuid('team_id').references(() => teams.id),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
export const sequences = pgTable('sequences', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
script: text('script'),
teamId: uuid('team_id')
.references(() => teams.id)
.notNull(),
createdBy: uuid('created_by')
.references(() => users.id)
.notNull(),
styleId: uuid('style_id').references(() => styles.id),
metadata: jsonb('metadata'),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
export const frames = pgTable('frames', {
id: uuid('id').primaryKey().defaultRandom(),
sequenceId: uuid('sequence_id')
.references(() => sequences.id, { onDelete: 'cascade' })
.notNull(),
order: integer('order').notNull(),
description: text('description').notNull(),
thumbnailUrl: text('thumbnail_url'),
status: text('status').notNull().default('pending'), // pending, processing, completed, failed
error: text('error'),
createdBy: uuid('created_by')
.references(() => users.id)
.notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
export const styles = pgTable('styles', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
description: text('description'),
teamId: uuid('team_id')
.references(() => teams.id)
.notNull(),
styleData: jsonb('style_data').notNull(), // Style Stack JSON
createdBy: uuid('created_by')
.references(() => users.id)
.notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
// Relations
export const teamsRelations = relations(teams, ({ many }) => ({
users: many(users),
sequences: many(sequences),
styles: many(styles),
}));
export const usersRelations = relations(users, ({ one, many }) => ({
team: one(teams, {
fields: [users.teamId],
references: [teams.id],
}),
sequences: many(sequences),
frames: many(frames),
styles: many(styles),
}));
export const sequencesRelations = relations(sequences, ({ one, many }) => ({
team: one(teams, {
fields: [sequences.teamId],
references: [teams.id],
}),
frames: many(frames),
style: one(styles, {
fields: [sequences.styleId],
references: [styles.id],
}),
creator: one(users, {
fields: [sequences.createdBy],
references: [users.id],
}),
}));
export const framesRelations = relations(frames, ({ one }) => ({
sequence: one(sequences, {
fields: [frames.sequenceId],
references: [sequences.id],
}),
creator: one(users, {
fields: [frames.createdBy],
references: [users.id],
}),
}));
export const stylesRelations = relations(styles, ({ one, many }) => ({
team: one(teams, {
fields: [styles.teamId],
references: [teams.id],
}),
creator: one(users, {
fields: [styles.createdBy],
references: [users.id],
}),
sequences: many(sequences),
}));
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 5d ago First seen · 445 lines · 0 tokens per session scan A 87a904a4a959
drizzle-patterns is a cursor rule published in the GitHub repository openstory-so/openstory (568 stars, last pushed yesterday), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 2,688 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other cursor rules, from other repositories
sql-types-imports
Canonical import paths for SQL types.
type-extraction-from-contract
Extract TypeScript types from contract.d.ts and helpers.
prisma
Enforce best practices for Prisma ORM, ensuring type-safe, performant, and maintainable database interactions in modern TypeScript applications.
manage-hierarchical-resources
Cursor rule "manage-hierarchical-resources" from PaulJPhilp/EffectPatterns, covering manage hierarchical resources and example.
cursorrules
You are an expert in Solidity, TypeScript, Node.js, postgres, Sqlite3, and Prisma.
prisma
Prisma database patterns and conventions for Next.js and TypeScript projects.