Skip to content

fix(admin): the dialog gate's ui getter now reads through, as its comment already claimed (#404) - #414

Merged
edgehero merged 1 commit into
mainfrom
fix/dialog-gate-lazy-ui
Sep 24, 2026
Merged

edgehero merged 1 commit into
mainfrom
fix/dialog-gate-lazy-ui

Conversation

@edgehero

Copy link
Copy Markdown
Owner

A review pass of the change that added it found the claim and the code disagreeing, after it had merged.

gateDialogs defines ui as a getter rather than a frozen value, and says why: pi's own ui getter THROWS
once its context is stale, and pi can rebind the ui context mid-session, so the one property this wrapper
replaces has to preserve on that property what the descriptor copy preserves on every other.

The getter did not do that. It closed over the wrapper built at construction and never consulted ctx.ui
again -- measured at zero reads of the original across three reads of the gated one -- which is exactly the
behaviour of the frozen value the comment says it fixes. And the test pinned the DEFECT: it asserted the
reads did not happen.

It reads through now, rebuilding the wrapper only when the underlying ui is a different object, so a hot
path that touches ctx.ui repeatedly pays an identity comparison rather than a rebuild.

The test says what the rule is instead of what the bug was: each read reaches pi's own getter, a rebind is
FOLLOWED rather than remembered, and a stale context still throws through the gate. Mutating the read back
to a one-shot turns two tests red.

Latent rather than live: nothing in this extension triggers a session replacement today, which is why a
wrong comment survived a merge. It is the class of defect this round kept finding in its own prose, and the
fix is to make the code true rather than to soften the sentence.

No version moves.

Refs #404

…omment already claimed (#404)

A review pass of the change that added it found the claim and the code disagreeing, after it had merged.

`gateDialogs` defines `ui` as a getter rather than a frozen value, and says why: pi's own `ui` getter THROWS
once its context is stale, and pi can rebind the ui context mid-session, so the one property this wrapper
replaces has to preserve on that property what the descriptor copy preserves on every other.

The getter did not do that. It closed over the wrapper built at construction and never consulted `ctx.ui`
again -- measured at zero reads of the original across three reads of the gated one -- which is exactly the
behaviour of the frozen value the comment says it fixes. And the test pinned the DEFECT: it asserted the
reads did not happen.

It reads through now, rebuilding the wrapper only when the underlying `ui` is a different object, so a hot
path that touches `ctx.ui` repeatedly pays an identity comparison rather than a rebuild.

The test says what the rule is instead of what the bug was: each read reaches pi's own getter, a rebind is
FOLLOWED rather than remembered, and a stale context still throws through the gate. Mutating the read back
to a one-shot turns two tests red.

Latent rather than live: nothing in this extension triggers a session replacement today, which is why a
wrong comment survived a merge. It is the class of defect this round kept finding in its own prose, and the
fix is to make the code true rather than to soften the sentence.

No version moves.

Refs #404

Signed-off-by: Rob Boerman <robboerman@live.nl>
@edgehero
edgehero merged commit c1c54ed into main Sep 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant