Framework-less by design — bindings are snippets, not packages
createStore implements the repo-wide Observable<T>, so every framework binds
it in a line of your code:
const store = P.createStore({ global: initialBits });
// React useSyncExternalStore(store.subscribe, () => store.getSnapshot())
// Vue shallowRef + store.subscribe + onScopeDispose
// Svelte store already satisfies the Svelte store contract
// Express (req,res,next) => P.has(req.perms, "x") ? next() : res.sendStatus(403)
// Next mw P.has(P.decode(cookie, "base64url"), "x")Reads are synchronous (a render can't await); loading is not the store's job —
fetch with query-core (or SSR) and push results in via set / setScope. An
unknown scope falls back to global, keeping every check total. Scoped
resolution memoizes via P.createResolver({ compute, ttl, version }), keyed by
actor · scope · version so an epoch bump invalidates an actor's whole scope set
at once.
Cross-project & polyglot
P.buildLock(); // permissions.lock.json — a name→bit manifest
P.diffLock(previous); // [] when safe; flags bit-reuse / bit-change / removal — fail CI
P.catalog(); // rows for a role-editor UI (hidden flags omitted)The lock file is the interop artifact: a Go or Python service needs only it plus three lines of bit math, and CI catches any consumer drifting from it.