{"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 = {\"action_casefold\": false, \"audit_denials\": false, \"default_allow\": false, \"deny_wins\": false, \"expiry_inclusive\": false, \"group_union\": false, \"inherit_roles\": false, \"owner_bypass\": false, \"resource_scope\": \"prefix\", \"suspended_denies\": false, \"token_ttl\": 200, \"wildcard_action\": false};\n", "helpers.ts": "export function lower(s: any): string { return String(s).replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32)); }\n", "core.ts": "import {lower} from './helpers.ts';\n\nfunction result(allowed: boolean, reason: string, matched: number[], policy: any): any {\n  return {allowed, reason, matched, audit: (!allowed && policy.audit_denials) ? [reason] : []};\n}\n\nexport function run(payload: any, policy: any): any {\n  const subject = payload.subject || {};\n  const resource = payload.resource || {};\n  const now = payload.now;\n  if (subject.tenant !== resource.tenant) return result(false, 'tenant', [], policy);\n  if (now - payload.issued_at > policy.token_ttl) return result(false, 'token', [], policy);\n  if (policy.suspended_denies && subject.suspended) return result(false, 'suspended', [], policy);\n  if (policy.owner_bypass && subject.owner) return result(true, 'owner', [], policy);\n  const roles = new Set<string>(subject.roles || []);\n  if (policy.group_union) for (const g of (subject.groups || [])) roles.add(g);\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      for (const p of ps) {\n        if (!roles.has(p)) { roles.add(p); stack.push(p); }\n      }\n    }\n  }\n  const grants = payload.grants || [];\n  const matched: number[] = [];\n  const effects: boolean[] = [];\n  const rid = String(resource.id);\n  grants.forEach((g: any, i: number) => {\n    if (!roles.has(g.role)) return;\n    let actOk: boolean;\n    if (policy.wildcard_action && g.action === '*') actOk = true;\n    else if (policy.action_casefold) actOk = lower(g.action) === lower(payload.action);\n    else actOk = g.action === payload.action;\n    if (!actOk) 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 exp = g.expires;\n    if (!(exp === null || exp === undefined || (policy.expiry_inclusive ? now <= exp : now < exp))) return;\n    matched.push(i);\n    effects.push(g.effect === 'allow');\n  });\n  if (matched.length === 0) return result(!!policy.default_allow, 'default', [], policy);\n  const anyAllow = effects.some((e) => e);\n  const anyDeny = effects.some((e) => !e);\n  const allowed = policy.deny_wins ? (anyAllow && !anyDeny) : anyAllow;\n  return result(allowed, 'grants', matched, policy);\n}\n"}}