Verbs
Understanding the action grammar - consistent naming for events, relations, and operations
Verbs
A Verb is a complete action grammar with all its forms. The Verb grammar provides consistent naming across events, relations, actions, and results throughout the system.
The Verb Grammar
Every Verb has 9 properties that define its complete action semantics:
| Property | Description | Example (create) | Example (approve) |
|---|---|---|---|
actor | Who performs | creator | approver |
act | The verb | creates | approves |
action | Noun form | create | approve |
activity | Gerund (-ing) | creating | approving |
object | Input | (the thing being created) | (the thing being approved) |
result | Output | creation | approval |
event | Past tense | created | approved |
reverse | Reverse relation | createdBy | approvedBy |
inverse | Opposite action | delete | reject |
Why Verb Grammar?
The Verb grammar solves a common problem in software: inconsistent naming.
Without Verb Grammar
// Inconsistent naming
interface Task {
creator: User // actor form
created: Date // event form
createdDate: Date // redundant
createTime: Date // more redundancy
}
// Events have different patterns
type Events =
| { type: 'TaskCreated' } // past tense
| { type: 'ApprovalReceived' } // noun form
| { type: 'Completing' } // gerund form
| { type: 'Delete' } // verb formWith Verb Grammar
// Consistent naming
interface Task {
creator: User // actor
createdAt: Date // event + At
createdBy: User // reverse relation
}
// Events follow pattern: {Noun}{Event}
type Events =
| { type: 'TaskCreated' }
| { type: 'TaskApproved' }
| { type: 'TaskCompleted' }
| { type: 'TaskDeleted' }The 9 Forms Explained
1. Actor (Who)
The person or system that performs the action.
| Verb | Actor | Usage |
|---|---|---|
| create | creator | task.creator |
| approve | approver | invoice.approver |
| complete | completer | task.completer |
| assign | assigner | task.assigner |
| review | reviewer | pr.reviewer |
| delete | deleter | record.deleter |
2. Act (Present Tense Verb)
The action in present tense, third person singular.
| Actor | Act | Usage |
|---|---|---|
| creator | creates | "Creator creates Task" |
| approver | approves | "Approver approves Invoice" |
| completer | completes | "Completer completes Task" |
| assigner | assigns | "Assigner assigns Task" |
3. Action (Verb Noun)
The command or imperative form.
| Action | Usage |
|---|---|
| create | await create(task) |
| approve | await approve(invoice) |
| complete | await complete(task) |
| assign | await assign(task, user) |
| delete | await delete(record) |
4. Activity (Gerund -ing)
The ongoing process form.
| Activity | Usage |
|---|---|
| creating | "Creating Task..." |
| approving | "Approving Invoice..." |
| completing | "Completing Task..." |
| assigning | "Assigning Task..." |
Used in:
- UI loading states: "Creating your account..."
- Progress indicators: "Approving invoice..."
- Log messages: "Creating product..."
5. Object (Input)
The thing being acted upon.
| Action | Object |
|---|---|
| create | Task data |
| approve | Invoice |
| complete | Task |
| assign | Task + User |
6. Result (Outcome Noun)
The outcome or artifact of the action.
| Action | Result | Usage |
|---|---|---|
| create | creation | const creation = await create(task) |
| approve | approval | const approval = await approve(invoice) |
| complete | completion | const completion = await complete(task) |
| assign | assignment | const assignment = await assign(task, user) |
| delete | deletion | const deletion = await delete(record) |
7. Event (Past Tense)
The event name when the action occurred.
| Event | Usage |
|---|---|
| created | TaskCreated, ProductCreated |
| approved | InvoiceApproved, ProposalApproved |
| completed | TaskCompleted, WorkflowCompleted |
| assigned | TaskAssigned, RoleAssigned |
| deleted | TaskDeleted, UserDeleted |
Event pattern: {Noun}{Event}
8. Reverse (Inverse Relation)
The reverse relationship for lookups.
| Event | Reverse | Usage |
|---|---|---|
| created | createdBy | task.createdBy (who created it) |
| approved | approvedBy | invoice.approvedBy |
| completed | completedBy | task.completedBy |
| assigned | assignedBy | task.assignedBy |
| deleted | deletedBy | record.deletedBy |
9. Inverse (Opposite Action)
The action that undoes or opposes the original.
| Action | Inverse | Relationship |
|---|---|---|
| create | delete | Create ↔ Delete |
| approve | reject | Approve ↔ Reject |
| assign | unassign | Assign ↔ Unassign |
| archive | restore | Archive ↔ Restore |
| enable | disable | Enable ↔ Disable |
| start | stop | Start ↔ Stop |
| open | close | Open ↔ Close |
Common Verbs
Lifecycle Verbs
| Action | Actor | Event | Inverse |
|---|---|---|---|
| create | creator | created | delete |
| update | updater | updated | restore |
| delete | deleter | deleted | restore |
| archive | archiver | archived | restore |
| restore | restorer | restored | archive |
Workflow Verbs
| Action | Actor | Event | Inverse |
|---|---|---|---|
| start | starter | started | stop |
| pause | pauser | paused | resume |
| resume | resumer | resumed | pause |
| complete | completer | completed | reopen |
| cancel | canceler | canceled | restart |
Approval Verbs
| Action | Actor | Event | Inverse |
|---|---|---|---|
| submit | submitter | submitted | withdraw |
| approve | approver | approved | reject |
| reject | rejecter | rejected | approve |
| review | reviewer | reviewed | - |
Assignment Verbs
| Action | Actor | Event | Inverse |
|---|---|---|---|
| assign | assigner | assigned | unassign |
| claim | claimer | claimed | unclaim |
| delegate | delegator | delegated | reclaim |
State Verbs
| Action | Actor | Event | Inverse |
|---|---|---|---|
| enable | enabler | enabled | disable |
| disable | disabler | disabled | enable |
| activate | activator | activated | deactivate |
| publish | publisher | published | unpublish |
| lock | locker | locked | unlock |
Usage in Code
Events
// Event pattern: {Noun}{Event}
type TaskEvent =
| { type: 'TaskCreated', task: Task }
| { type: 'TaskAssigned', task: Task, assignee: User }
| { type: 'TaskCompleted', task: Task }
| { type: 'TaskApproved', task: Task, approver: User }
| { type: 'TaskRejected', task: Task, reason: string }
| { type: 'TaskDeleted', taskId: string }Relations
interface Task {
id: string
title: string
// Actor relations
creator: User // actor
assignee?: User // actor
// Reverse relations
createdBy: User // reverse
assignedBy?: User // reverse
approvedBy?: User // reverse
// Timestamps (event + At)
createdAt: Date // event
assignedAt?: Date // event
completedAt?: Date // event
approvedAt?: Date // event
}Actions
// Action pattern: {action}({object}): Promise<{result}>
async function create(data: CreateTaskInput): Promise<Task> {
const task = await db.tasks.create(data)
await emit({ type: 'TaskCreated', task })
return task
}
async function assign(taskId: string, userId: string): Promise<Task> {
const task = await db.tasks.update(taskId, { assignee: userId, assignedAt: new Date() })
await emit({ type: 'TaskAssigned', task, assignee: userId })
return task
}
async function complete(taskId: string): Promise<Task> {
const task = await db.tasks.update(taskId, { status: 'completed', completedAt: new Date() })
await emit({ type: 'TaskCompleted', task })
return task
}UI States
// Activity form for loading states
const [state, setState] = useState<
| { status: 'idle' }
| { status: 'creating' } // activity
| { status: 'created', task: Task } // event
| { status: 'error', error: Error }
>({ status: 'idle' })
function handleSubmit() {
setState({ status: 'creating' })
create(data)
.then(task => setState({ status: 'created', task }))
.catch(error => setState({ status: 'error', error }))
}Verb Collections
The system has a verbs collection to define standard verbs:
interface Verb {
id: string
actor: string // "creator"
act: string // "creates"
action: string // "create"
activity: string // "creating"
result: string // "creation"
event: string // "created"
reverse: string // "createdBy"
inverse?: string // "delete"
}Standard verbs are pre-defined:
const verbs: Verb[] = [
{
actor: 'creator',
act: 'creates',
action: 'create',
activity: 'creating',
result: 'creation',
event: 'created',
reverse: 'createdBy',
inverse: 'delete',
},
{
actor: 'approver',
act: 'approves',
action: 'approve',
activity: 'approving',
result: 'approval',
event: 'approved',
reverse: 'approvedBy',
inverse: 'reject',
},
// ... more standard verbs
]Naming Patterns
Database Fields
| Pattern | Example | Usage |
|---|---|---|
{actor} | creator, approver | Who performed action |
{event}At | createdAt, approvedAt | When action occurred |
{event}By | createdBy, approvedBy | Who performed (reverse relation) |
Event Types
| Pattern | Example |
|---|---|
{Noun}{Event} | TaskCreated, InvoiceApproved |
{Noun}{Event} | UserRegistered, PaymentCompleted |
Function Names
| Pattern | Example | Returns |
|---|---|---|
{action} | create(), approve() | The result entity |
{action}{Noun} | createTask(), approveInvoice() | The result entity |
UI Copy
| Pattern | Example |
|---|---|
{Activity}... | "Creating task...", "Approving invoice..." |
{Event}! | "Created!", "Approved!" |
{Action} {Noun} | "Create Task", "Approve Invoice" |
Workflow State Machines
Verbs define state transitions in workflows:
const taskWorkflow = {
states: {
draft: {
on: {
submit: { target: 'submitted', actions: ['notifyReviewer'] }
}
},
submitted: {
on: {
approve: { target: 'approved', actions: ['notifyCreator'] },
reject: { target: 'rejected', actions: ['notifyCreator'] },
withdraw: { target: 'draft' }
}
},
approved: {
on: {
start: { target: 'in_progress', actions: ['assignWorker'] }
}
},
in_progress: {
on: {
complete: { target: 'completed', actions: ['notifyStakeholders'] },
pause: { target: 'paused' }
}
},
paused: {
on: {
resume: { target: 'in_progress' }
}
},
completed: {
on: {
reopen: { target: 'in_progress' }
}
},
rejected: {
on: {
resubmit: { target: 'submitted' }
}
}
}
}Each transition uses a Verb:
submit,approve,reject,start,complete,pause,resume,reopen
Benefits
1. Consistency
All events, relations, and actions follow the same pattern.
2. Predictability
If you know the verb "create", you can predict:
- Event:
TaskCreated - Relation:
task.createdBy - Timestamp:
task.createdAt - Action:
await create(task)
3. Type Safety
TypeScript can enforce the grammar:
type VerbGrammar<T extends string> = {
actor: `${T}er`
act: `${T}s`
action: T
activity: `${T}ing`
event: `${T}ed`
reverse: `${T}edBy`
}
type CreateVerb = VerbGrammar<'create'>
// {
// actor: "createer" // ❌ TypeScript would catch this
// ...
// }4. Internationalization
The grammar provides clear translation keys:
{
"verb.create.actor": "creator",
"verb.create.activity": "creating",
"verb.create.event": "created"
}5. Auto-generated UI
Components can render automatically from Verb grammar:
function ActionButton({ verb, noun }: { verb: Verb, noun: string }) {
return <Button>{verb.action} {noun}</Button>
}
// Renders: "Create Task", "Approve Invoice", "Complete Order"Advanced Patterns
Composite Verbs
Some actions are compositions:
// reassign = unassign + assign
async function reassign(taskId: string, fromUserId: string, toUserId: string) {
await unassign(taskId, fromUserId)
await assign(taskId, toUserId)
}Contextual Verbs
Same verb, different contexts:
// Task approval
await approve(task) // TaskApproved
// Invoice approval
await approve(invoice) // InvoiceApproved
// Pull request approval
await approve(pullRequest) // PullRequestApprovedChained Verbs
Workflows chain verbs:
// create → submit → approve → start → complete
const task = await create({ title: "Write docs" })
await submit(task.id)
await approve(task.id)
await start(task.id)
await complete(task.id)