KQ-2083 · ALLOW/RULES

Allow Rules

A permission prompt that can become a standing rule: Always allow opens a sentence of selects that widens one yes into a pattern (the action, the files, a cost ceiling), with a live rule chip, a reach strip that lights in a cascade the recent requests the rule would have covered, and a conflict that names the deny rule it collides with, rings that rule and holds Create. Create folds the request card on springs.glide into its rule chip while the list opens a slot on the same spring, the chip flies into that slot on glide, and the row's fire count rolls from 0 to 1 on springs.snap as the next waiting request rises in. The builder is a toolbar of select-only comboboxes (Left and Right move, Up and Down change, Enter opens), the rules are roving stops where Enter edits and R revokes after a confirm, and below 30rem the panes sit behind tabs and the chip flies to the Rules tab.

KQ-2083 · ALLOW/RULES

Permissions

5 rules · 3 waiting

Basinworks file agent wants to write a file

2 min ago · 2 more waiting

reports2026q3basin-levels.csv12 KB · $0.02

“Saving the merged gauge readings for the Q3 basin report.”

Standing rules

14 days · fires
  • 1,284×
  • 212×
  • 96×
  • 3×
  • 41×

Up and Down move between rules. Enter edits a rule, R revokes it after a confirm.

request · write basin-levels.csv · 5 rules

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/allow-rules

Props

request
AllowRequest | null
default defaultAllowRequest
The permission asked for now: { id, agent, verb, path, size?, cost, reason, at }; null when nothing waits.
waiting
AllowRequest[]
default defaultAllowWaiting
Requests waiting behind it, in order; each decision brings the next one in.
templates
AllowTemplates
default templatesFor(request)
The builder's options, narrowest first: { verbs, scopes, costs }, each { id, label, value }.
rules / defaultRules
AllowRule[]
default — / defaultAllowRules
Standing rules, controlled or initial: { id, effect, pattern, fires, daily?, lastFiredAt? }.
onRulesChange
(rules) => void
default —
Fires with the whole list after a rule is created or revoked.
history
AllowHistoryItem[]
default defaultAllowHistory (40)
Recent requests, newest first; the reach strip lights the ones a rule would have covered.
onAllowOnce
(request) => void
default —
Allow once was pressed.
onDeny
(request) => void
default —
Deny was pressed.
onCreateRule
(rule, request) => void
default —
A rule was created from the request; it fires once for it.
onEditRule
(rule) => void
default —
Enter on a rule, or Edit that rule on a conflict.
onRevokeRule
(rule) => void
default —
A rule was revoked after its confirm.
status
"ready" | "loading" | "empty" | "error"
default "ready"
Whether the permissions have loaded.
onRetry
() => void
default —
Try again was pressed after a failure to load.
now
number
default Oct 17 2026, 14:00 UTC
The moment ages are counted from, in ms.
chipStyle
"pill" | "tag" | "code"
default "pill"
How a rule is drawn: a pill with an effect dot, a notched tag, or a mono glob pattern.
listDensity
"compact" | "cozy" | "roomy"
default "cozy"
Row height of the rules list; compact drops the last-fired line.
accent
"cobalt" | "plum" | "mint" | "ink" | string
default "cobalt"
Allow rules, the builder and Create: a named pigment or any CSS colour.
formatMoney
(amount) => string
default Intl USD
How money is written.
height
number
default 560
Tallest the surface grows, in px, before its panes scroll.
disabled
boolean
default false
Read only.
className
string
default —
Classes for the surface.