```json
{"files":{"main.ts":"import {run} from './core.ts';\nimport {POLICY} from './policy.ts';\nexport function evaluate(payload: any): any { return run(payload, POLICY); }\n","policy.ts":"export const POLICY: any = {\n  deny_wins: false,\n  expiry_inclusive: false,\n  inherit_roles: false,\n  owner_bypass: false,\n  action_casefold: false,\n  group_union: false,\n  resource_scope: 'prefix',\n  suspended_denies: false,\n  token_ttl: 200,\n  wildcard_action: false,\n  default_allow: false,\n  audit_denials: false\n};\n","helpers.ts":"export function lower(s: string): string {\n  return String(s).replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));\n}\n\nexport function isAllow(g: any): boolean {\n  if (g == null) return false;\n  if (typeof g.allow === 'boolean') return g.allow;\n  if (typeof g.effect === 'string') return lower(g.effect) === 'allow';\n  if (typeof g.allowed === 'boolean') return g.allowed;\n  return false;\n}\n\nexport function isDeny(g: any): boolean {\n  if (g == null) return false;\n  if (typeof g.allow === 'boolean') return !g.allow;\n  if (typeof g.effect === 'string') return lower(g.effect) === 'deny';\n  if (typeof g.allowed === 'boolean') return !g.allowed;\n  return false;\n}\n","core.ts":"import {lower, isAllow, isDeny} from './helpers.ts';\n\nexport function run(payload: any, policy: any): any {\n  const subject = (payload && payload.subject) || {};\n  const resource = (payload && payload.resource) || {};\n  const now = payload.now;\n  const out = (allowed: boolean, reason: string, matched: number[]) => ({\n    allowed,\n    reason,\n    matched,\n    audit: !allowed && policy.audit_denials ? [reason] : []\n  });\n\n  if (subject.tenant !== resource.tenant) return out(false, 'tenant', []);\n  if (now - payload.issued_at > policy.token_ttl) return out(false, 'token', []);\n  if (policy.suspended_denies && subject.suspended) return out(false, 'suspended', []);\n  if (policy.owner_bypass && subject.owner) return out(true, 'owner', []);\n\n  const roles = new Set<string>(Array.isArray(subject.roles) ? subject.roles : []);\n  if (policy.group_union && Array.isArray(subject.groups)) {\n    for (const g of subject.groups) roles.add(g);\n  }\n  if (policy.inherit_roles) {\n    const parents = payload.role_parents || {};\n    const stack = Array.from(roles);\n    while (stack.length) {\n      const r = stack.pop() as string;\n      const ps = parents[r];\n      if (Array.isArray(ps)) {\n        for (const p of ps) {\n          if (!roles.has(p)) { roles.add(p); stack.push(p); }\n        }\n      }\n    }\n  }\n\n  const grants: any[] = Array.isArray(payload.grants) ? payload.grants : [];\n  const act = policy.action_casefold ? lower(payload.action) : payload.action;\n  const rid = String(resource.id);\n  const matched: number[] = [];\n  const matchedGrants: any[] = [];\n  grants.forEach((g: any, i: number) => {\n    if (!g || !roles.has(g.role)) return;\n    const ga = policy.action_casefold ? lower(g.action) : g.action;\n    const actionOk = ga === act || (policy.wildcard_action && g.action === '*');\n    if (!actionOk) return;\n    const scope = String(g.scope);\n    const scopeOk = policy.resource_scope === 'exact' ? scope === rid : rid.startsWith(scope);\n    if (!scopeOk) return;\n    const e = g.expires;\n    const expOk = e === null || e === undefined || (policy.expiry_inclusive ? now <= e : now < e);\n    if (!expOk) return;\n    matched.push(i);\n    matchedGrants.push(g);\n  });\n\n  if (matched.length === 0) return out(!!policy.default_allow, 'default', []);\n  const anyAllow = matchedGrants.some(isAllow);\n  const anyDeny = matchedGrants.some(isDeny);\n  const allowed = policy.deny_wins ? anyAllow && !anyDeny : anyAllow;\n  return out(allowed, 'grants', matched);\n}\n"}}
```