The two orgScopingRule calls show the same rule configured two ways and do not run on their own. The complete example is under Usage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.9 KiB
PolicyEnforced
Check that a stated policy is enforced in the code, not only written down.
PolicyEnforced is a small policy gate engine. A rule is data: which paths it covers, what content makes a file subject to it, what content satisfies it, and how an author documents an exemption. The engine is pure. You pass in the files (usually the ones a change touched) and it returns what was checked, what passed, what was exempted and what failed.
What it checks and why
Policy gates written as shell scripts tend to get copied from app to app and
edited in place. Some copies drift for no reason. Others have to differ: an
org-scoping check for an app that filters by an org_id column would flag
every handler in an app that has no tenant columns and authorises through
RBAC capability checks. One shared script cannot serve both, and a separate
copy per app is the wrong fix. So the engine is shared and the patterns are
parameters. Two configurations of the same rule (a complete, runnable example
is under Usage):
// An app that scopes rows by tenant column
orgScopingRule({
guards: /requireOrg|resolveOrg/,
inlineTenantFilter: /\.eq\((['"])(organization_id|org_id|owner_id)\1/,
})
// An app with no tenant columns that uses RBAC checks
orgScopingRule({
serviceClients: /createServiceClient|createClient\(/,
guards: /requireAuth|requireProjectCap|requireAdminCap/,
})
The engine is built against three failure modes.
- A vacuous run is not a pass.
passedandvacuousare separate fields, and a rule that no file was subject to is reported as NOT ASSESSED. "No changed file was covered by this rule" is not evidence that the policy holds. A gate that prints a check mark for both is indistinguishable from one that does nothing, which is the same defect as a test that cannot fail. - Regex state can skip files. A rule built with a
/gpattern carrieslastIndexfrom one file to the next, so later files can pass unexamined and the gate goes green while covering nothing. Every pattern is tested through a fresh non-global copy. - A gate with no escape hatch gets switched off. The first legitimate cross-tenant cron job would force someone to disable it. Exemptions are a documented comment marker, and they are counted and cited in the report so they stay visible.
A pass names the files it checked, and a violation cites the file and line where the rule's trigger matched. A result of "3 files checked" that does not say which files is an asserted result, which is the kind of claim this library exists to catch.
One limit to keep in mind: the org-scoping rule confirms that a guard is present. It does not prove the guard filters to the caller's own rows. That still needs tests and review.
Rules included
orgScopingRuleflags a handler that uses a service-role client (row-level security bypassed) with no authorization guard, tenant filter or exemption.inOverflowRuleflags a dynamic.in('col', ids)filter with no chunking helper. With supabase-js, a long id list goes into the query string, the request fails, anddata || []turns that into an empty result with no error. A literal array is bounded and is not flagged.claimRuleflags a public claim (for example "99.9% uptime SLA" on a pricing page) when nothing in the code enforces it.
You can also write a PolicyRule object directly.
Usage
import { evaluatePolicy, formatReport, orgScopingRule, inOverflowRule } from '@extant2000/policy-enforced'
const rules = [
orgScopingRule({ guards: /requireOrg|resolveOrg/, inlineTenantFilter: /\.eq\((['"])(org_id|owner_id)\1/ }),
inOverflowRule({ chunkHelpers: /selectInChunks/ }),
]
const files = [
{ path: 'server/api/invoices.get.ts', content: "const db = createServiceClient()\nreturn db.from('invoices').select()" },
{ path: 'server/api/contacts.get.ts', content: "await requireOrg(event)\nconst db = createServiceClient()" },
]
const report = evaluatePolicy(rules, files)
console.log({ passed: report.passed, vacuous: report.vacuous })
for (const v of report.violations) console.log(`${v.ruleId} ${v.path}:${v.line} ${v.excerpt}`)
// The full report for a CI log, with remedies under each violation
console.log(formatReport(report))
toReport(report) returns the same result as a CapabilityReport from
@extant2000/evidence-record. evaluateRule(rule, files) runs a single rule.
Sample output
Produced by running the example above (first two lines):
{ passed: false, vacuous: false }
org-scoping server/api/invoices.get.ts:1 const db = createServiceClient()
In the full report, in-overflow shows as NOT ASSESSED, since neither file
used a dynamic .in() filter.
Install
The package is published to the GitLab package registry, so point the
@extant2000 scope there first:
npm config set @extant2000:registry https://gitlab.com/api/v4/packages/npm/
npm install @extant2000/policy-enforced
License
MIT. Copyright (c) 2026 Extant 2000 LLC. See LICENSE.