weigh: read the grants before walking to the root #168

Merged
PerishFire merged 1 commit from land/cap/lazy into main 2026-08-19 08:30:34 +00:00
Owner

Placing a row for authority built its whole anchor chain first and consulted
the grants afterwards. The chain costs one point query per hop per row, and the
widest grant there is — all over a unit — never looks at it. Every read paid
for a walk whose answer was already decided.

The grants that need no chain are read first now, and the walk happens only if
none of them answered. Order is free to change here because grants combine by
union: any match admits, so which one matches first cannot alter the outcome.

Measured with the bench that found it, two hundred rows and ten reads each:

depth 0   1.83ms -> 1.18ms
depth 1  18.10ms -> 1.89ms
depth 2  33.24ms -> 2.56ms

Thirteen times at depth two, and the cost stops climbing with depth, because
the depth was never the thing being paid for.

This is the read path only. spans still walks first, and it has to: it asks
about every verb at once and cannot know which of them a row-scoped grant will
answer. It runs when a caller enumerates what it may do, not on the way to a
row.

Nothing about who may see what changes. The seeded estate that pays this cost
in practice is the one whose grants are widest, which is why it went unnoticed:
the more permissive the estate, the more it was paying for a decision it had
already made.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

Placing a row for authority built its whole anchor chain first and consulted the grants afterwards. The chain costs one point query per hop per row, and the widest grant there is — `all` over a unit — never looks at it. Every read paid for a walk whose answer was already decided. The grants that need no chain are read first now, and the walk happens only if none of them answered. Order is free to change here because grants combine by union: any match admits, so which one matches first cannot alter the outcome. Measured with the bench that found it, two hundred rows and ten reads each: depth 0 1.83ms -> 1.18ms depth 1 18.10ms -> 1.89ms depth 2 33.24ms -> 2.56ms Thirteen times at depth two, and the cost stops climbing with depth, because the depth was never the thing being paid for. This is the read path only. `spans` still walks first, and it has to: it asks about every verb at once and cannot know which of them a row-scoped grant will answer. It runs when a caller enumerates what it may do, not on the way to a row. Nothing about who may see what changes. The seeded estate that pays this cost in practice is the one whose grants are widest, which is why it went unnoticed: the more permissive the estate, the more it was paying for a decision it had already made. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
weigh: read the grants before walking to the root
Some checks failed
guard / guard (pull_request) Failing after 2m20s
d081d9b9c3
Placing a row for authority built its whole anchor chain first and consulted
the grants afterwards. The chain costs one point query per hop per row, and the
widest grant there is — `all` over a unit — never looks at it. Every read paid
for a walk whose answer was already decided.

The grants that need no chain are read first now, and the walk happens only if
none of them answered. Order is free to change here because grants combine by
union: any match admits, so which one matches first cannot alter the outcome.

Measured with the bench that found it, two hundred rows and ten reads each:

    depth 0   1.83ms -> 1.18ms
    depth 1  18.10ms -> 1.89ms
    depth 2  33.24ms -> 2.56ms

Thirteen times at depth two, and the cost stops climbing with depth, because
the depth was never the thing being paid for.

This is the read path only. `spans` still walks first, and it has to: it asks
about every verb at once and cannot know which of them a row-scoped grant will
answer. It runs when a caller enumerates what it may do, not on the way to a
row.

Nothing about who may see what changes. The seeded estate that pays this cost
in practice is the one whose grants are widest, which is why it went unnoticed:
the more permissive the estate, the more it was paying for a decision it had
already made.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Land-Source: cap/lazy@857a8cf9e2
PerishFire force-pushed land/cap/lazy from d081d9b9c3
Some checks failed
guard / guard (pull_request) Failing after 2m20s
to 4b0554c68d
All checks were successful
guard / guard (pull_request) Successful in 2m13s
guard / guard (push) Successful in 1m54s
2026-08-19 08:28:13 +00:00
Compare
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
PerishLab/keel!168
No description provided.