First public release

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 14:49:02 -04:00
co-authored by Claude Opus 5.5
commit 8dfe18703b
17 changed files with 2385 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
/**
* A policy that must hold in the running codebase, not merely in a document.
*
* Policy gates written as shell scripts tend to share one engine and differ
* only in their patterns. An org-scoping gate copied across several apps can
* legitimately end up with a distinct copy per app, and that divergence is
* CORRECT, not drift: one app scopes by an `org_id` tenant column, another has
* no tenant columns at all and authorises via RBAC capability checks. Forcing
* one script would break one of them.
*
* So the engine is shared and the policy is data.
*/
export interface PolicyRule {
/** Stable id, used in output and to reference a rule. */
id: string
/** One line: what must be true. */
description: string
/**
* Only files whose path matches one of these substrings/patterns are
* considered. Kept deliberately simple — a rule that needs a real glob
* engine is usually a rule that wants narrowing instead.
*/
pathIncludes: string[]
/**
* The file is SUBJECT to this rule only if its content matches. This is the
* risky construct — a service-role client, an unbounded `.in()`, and so on.
*/
trigger: RegExp
/**
* Any match here makes the file compliant. Multiple entries are OR-ed,
* because there is usually more than one legitimate way to satisfy a policy.
*/
allow: RegExp[]
/**
* A comment marker that documents a deliberate exemption, e.g.
* `org-scoping-exempt:`. Exemptions are part of a workable gate: without one,
* the legitimate cross-tenant cron job forces someone to disable the check
* entirely.
*/
exemptMarker: string
/** Lines printed under a violation telling the author how to fix it. */
remedy: string[]
}
export interface SourceFile {
path: string
content: string
}
export interface Violation {
ruleId: string
path: string
/** Why it failed, in one line. */
reason: string
/**
* 1-indexed line where the trigger matched — the construct that made this
* file subject to the rule. A violation that names only the file sends the
* reader hunting; this points at the line that did it.
*/
line?: number
/** The matched line, trimmed. */
excerpt?: string
}
export interface RuleResult {
rule: PolicyRule
/** Files the rule actually examined (matched pathIncludes). */
considered: number
/** Files that were subject to it (matched the trigger). */
subject: number
/** Files excused by an exemption marker. */
exempted: number
violations: Violation[]
/**
* Paths that were subject to the rule and satisfied it.
*
* Retained so a PASS can cite what it checked. A gate that reports "✓ 3
* files checked" without naming them is an asserted result, and this
* library's whole premise is that written policy and enforced policy are
* different things.
*/
compliantPaths: string[]
/** Paths excused by the exemption marker — counted, never hidden. */
exemptedPaths: string[]
}
export interface PolicyReport {
results: RuleResult[]
violations: Violation[]
passed: boolean
/**
* True when there was nothing to check. Distinguished from `passed` on
* purpose: "no changed files matched" is not evidence the policy holds, and
* a report that conflates them is the same lie as a test that cannot fail.
*/
vacuous: boolean
}