Move the lifecycle predicate into lib/acl/lifecycle.ts (re-exported from
the ACL module) so it can be unit-tested without a database. Adds Node
built-in test-runner coverage for the boundary conditions that define
the fix: past expiry -> dead, expiry == now -> dead (exclusive), revoke
beats a future expiry, and liveWhere kept in lockstep with grantIsLive.
Runner is node:test via ts-node (no new dependency; pnpm add is blocked
by the nix-built node_modules hoist pattern). 'npm test' -> 7 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>