Uh oh!
There was an error while loading. Please reload this page.
perf(core): batch resolveUserAuthzGrants' independent reads — 8 sequential legs become 4 waves (#10825) - #11197
Conversation
…ntial legs become 4 waves (#10825) cloud#1539 measured (R²=0.9994, causal latency injection) that an authenticated request is ~23.4 sequential DB legs and that LEGS, not query count, are the latency multiplier. resolveUserAuthzGrants contributed 8 of them (legs 6-13), all live reads with no caching. Wave 1 now issues the five reads that depend only on (userId, tenantId) concurrently: sys_user (memoized; condition mirrors the sequential implementation exactly — a fully-seeded API-key principal still never touches the table), sys_member{user_id}, sys_user_position, sys_member{organization_id} (fellow-org), and sys_user_permission_set. The dependent chain stays sequential because it IS dependent: sys_position needs wave 1's position names, sys_position_permission_set needs those rows' ids, sys_permission_set needs the union of direct- and position-granted set ids. 8 legs -> 4 on the fullest path, 2 on the lightest. Per the prod model (server_ms ~= 33 + L x 36.6) that removes ~150-220ms from every authenticated request. Equivalence is PROVEN, not asserted (the card's red line): resolve-authz-context.batch-equivalence.test.ts is a differential control — an 11-fixture matrix (multi-org, lapsed memberships, deactivated positions/sets, validity windows, limit truncation at 200/1000, seeded API-key principals, ai_seat both ways) whose goldens were captured from the SEQUENTIAL implementation at main 795ea05 (post-#10982, per the #10982 handoff on the card: the lapsed-own-membership fixture's text now cites the 2026-08-22 ruling, and its job here is pinning why the two sys_member reads are NOT merged into one $or — that merge is a measured privilege escalation). Three assertions per fixture: the grants envelope deep-equals (including array order), the query multiset is identical (same objects/filters/limits/isSystem — a widened $in or dropped tenancy filter fails even when the envelope agrees), and the leg count matches a per-fixture table while beating the sequential count. The two sys_member reads and the memoized sys_user read remain exactly as they were; nothing is cached, nothing survives the request. Takeover of the stale Round-A delegation per the maintainer's 2026-08-23 prompt; os-elon's serial ruling stands (#10826 follows on this file). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 9 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 6 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 74670f924eeab48ede7e2c54ef01beb74cb37e6d && git checkout 74670f924eeab48ede7e2c54ef01beb74cb37e6d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 52a41b72ee01bc24bdd6ac8eb1a37485eb2b4946 a1d2b184dd7e1613269bea075d4d974681b05274 && git checkout -B drift-repro 52a41b72ee01bc24bdd6ac8eb1a37485eb2b4946 && git merge --no-ff a1d2b184dd7e1613269bea075d4d974681b05274
node scripts/docs-audit/affected-docs.mjs --json 52a41b72ee01bc24bdd6ac8eb1a37485eb2b4946
|
Uh oh!
There was an error while loading. Please reload this page.
…ettings.getMany (objectstack-ai#10826) (objectstack-ai#11208) The caller half of objectstack-ai#10826 (service half: objectstack-ai#11200). One grouped namespace read replaces three per-key get()s — queries 16-18 of 24 on the measured rig collapse to one, with per-key answers unchanged by the service's equivalence contract. Feature-detected: an older service without getMany keeps the three parallel gets (still one leg — this is a query-count fix per the card's own calibration, not a latency fix). A thrown getMany lands exactly where a thrown get did: failed=true and the direct $in fallback, which reads the same three keys. Serial constraint honored: landed after objectstack-ai#11197 (objectstack-ai#10825) on this file. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
What
Wave 1 issues the five reads that depend only on
(userId, tenantId)concurrently —sys_user(memoized, condition byte-mirrors the sequential path),sys_member{user_id},sys_user_position,sys_member{organization_id},sys_user_permission_set. The dependent chain (sys_position→sys_position_permission_set→sys_permission_set) stays sequential because it is data-dependent. 8 legs → 4 on the fullest path (2 lightest); per cloud#1539's prod model that is ~150–220ms off every authenticated request. No caching — nothing survives a request.Equivalence proven, not asserted (the card's red line)
resolve-authz-context.batch-equivalence.test.ts: 11-fixture differential matrix, goldens captured from the sequential implementation at main795ea05a7(post-#10982). Per fixture: (1) grants envelope deep-equal incl. array order, (2) query multiset identical — same objects/filters/limits/tenancy/isSystem(a widened$inor merged read fails even when the envelope agrees), (3) leg count matches a per-fixture table and beats sequential, with a wave-1-completeness check so a member-by-member await can't silently restore the cost.#10982 handoff honored (all three items)
Goldens re-captured from current
main; thelapsed-own-membership-among-active-peersfixture kept — its job is pinning why the twosys_memberreads are not merged into one$or(measured privilege escalation) — with its explanatory text rewritten to cite the 2026-08-22 ruling; the changed value is documented as #10982's, not this batch's.Numbers
security/suite 432 passed (17 files) incl. the 34 new differential assertions; tsc error count identical to main (99 — the +1 over the ledger's 98 pre-exists on main). Changeset included.Closes#10825. #10826 follows serially on this file per os-elon's ruling.
🤖 Generated with Claude Code