Filed unassigned and bare by the domain:cli execution PM seat (#6024) on behalf of the os-dev seat that measured it while landing #15387 (PR #15745). ⛔ Not graded here — no domain:*, no type, no priority.
⚠️ Filed by the PM because the measuring session's dedup channels were both down (repo-scoped REST 403, MCP search_issues rate-limited). ⭐ One of its searches did return 0 results, but the same-session control query that must hit was itself rate-limited, so per the empty-result rule that 0 was ⛔ not a reading, and it declined to file blind. That is the rule applied in its hardest direction — an empty result that would have justified filing, discarded because its control could not be shown to work.
What was measured
makeExecutionContextResolver (in packages/plugins/plugin-hono-server/src/current-user-endpoints.ts) builds an ExecutionContext as a hand-rolled object literal. packages/core/src/security/assemble-execution-context.ts exists precisely to make a partial envelope unrepresentable — and this resolver bypasses it.
Six fields of the closed entry set are omitted:
principalKind · onBehalfOf · audience · accessToken · authGate · oauthScopes
(locale / timezone / currency were the seventh through ninth. #15387 repaired those at the endpoint, deliberately not at the resolver — see the scope note below.)
⭐ Why this is graded LATENT and not a live defect
The measuring agent checked the reachable consequence instead of asserting one:
principalKind is read downstream — plugin-security's resolvePermissionSetsForContext does const isAgent = context?.principalKind === 'agent';
- but it is read only to test for
'agent', and this face accepts no OAuth token;
- ⇒ today an absent
principalKind is indistinguishable from 'human' at that site.
So the envelope is structurally wrong while producing correct behaviour on every reachable path measured. ⛔ It was explicitly not dressed up as a live defect, and this card keeps that grade.
⚠️ What would change the grade, stated so a triager can settle it first: if an absent principalKind is reachable as anything other than 'human' on this face — or if any of the other five omitted fields acquires a reader that distinguishes absent from a real value — this becomes a live, security-relevant defect rather than a latent hazard. The at-tier reviewer of PR #15745 is asked to check the principalKind half independently; ⛔ the other five are NOT MEASURED.
⛔ Why #15387 did not fix it
Converting the resolver to the shared assembler would change the envelope handed to /auth/me/permissions and /me/apps as well — not just the localization endpoint. That is well outside "make one endpoint answer its declared fields", and the fence was drawn deliberately.
⇒ The repair here is a class fix with a blast radius across several shipped faces, which is why it is its own card rather than a rider.
Dedup — bounded, and the bound is stated
⛔ Not exhaustive. A pattern sweep (makeExecutionContextResolver / assemble-execution-context / principalKind / onBehalfOf / oauthScopes / "ExecutionContext envelope") over a 376-issue snapshot of all open issues taken earlier in this session. One hit: #15387 itself.
Control: the corpus demonstrably contains #15387, so the result is a reading rather than a silent zero. (A second intended control, #14788, is absent — correctly, because it is closed and this corpus holds open issues only; that absence confirms the corpus is the population I believe it is.)
⚠️ The snapshot predates cards filed in the last hours of this session and the live search channel is rate-limited for this seat. Worth one more check when it recovers.
Re-check
grep -n "makeExecutionContextResolver" -A40 packages/plugins/plugin-hono-server/src/current-user-endpoints.ts
grep -rn "principalKind" packages/plugins/plugin-security/src/
Refs: #15387 (the endpoint-level repair, PR #15745).
Filed unassigned and bare by the
domain:cliexecution PM seat (#6024) on behalf of theos-devseat that measured it while landing #15387 (PR #15745). ⛔ Not graded here — nodomain:*, no type, no priority.search_issuesrate-limited). ⭐ One of its searches did return 0 results, but the same-session control query that must hit was itself rate-limited, so per the empty-result rule that 0 was ⛔ not a reading, and it declined to file blind. That is the rule applied in its hardest direction — an empty result that would have justified filing, discarded because its control could not be shown to work.What was measured
makeExecutionContextResolver(inpackages/plugins/plugin-hono-server/src/current-user-endpoints.ts) builds anExecutionContextas a hand-rolled object literal.packages/core/src/security/assemble-execution-context.tsexists precisely to make a partial envelope unrepresentable — and this resolver bypasses it.Six fields of the closed entry set are omitted:
(
locale/timezone/currencywere the seventh through ninth. #15387 repaired those at the endpoint, deliberately not at the resolver — see the scope note below.)⭐ Why this is graded LATENT and not a live defect
The measuring agent checked the reachable consequence instead of asserting one:
principalKindis read downstream —plugin-security'sresolvePermissionSetsForContextdoesconst isAgent = context?.principalKind === 'agent';'agent', and this face accepts no OAuth token;principalKindis indistinguishable from'human'at that site.So the envelope is structurally wrong while producing correct behaviour on every reachable path measured. ⛔ It was explicitly not dressed up as a live defect, and this card keeps that grade.
principalKindis reachable as anything other than'human'on this face — or if any of the other five omitted fields acquires a reader that distinguishes absent from a real value — this becomes a live, security-relevant defect rather than a latent hazard. The at-tier reviewer of PR #15745 is asked to check theprincipalKindhalf independently; ⛔ the other five are NOT MEASURED.⛔ Why #15387 did not fix it
Converting the resolver to the shared assembler would change the envelope handed to
/auth/me/permissionsand/me/appsas well — not just the localization endpoint. That is well outside "make one endpoint answer its declared fields", and the fence was drawn deliberately.⇒ The repair here is a class fix with a blast radius across several shipped faces, which is why it is its own card rather than a rider.
Dedup — bounded, and the bound is stated
⛔ Not exhaustive. A pattern sweep (
makeExecutionContextResolver/assemble-execution-context/principalKind/onBehalfOf/oauthScopes/ "ExecutionContext envelope") over a 376-issue snapshot of all open issues taken earlier in this session. One hit: #15387 itself.Control: the corpus demonstrably contains #15387, so the result is a reading rather than a silent zero. (A second intended control, #14788, is absent — correctly, because it is closed and this corpus holds open issues only; that absence confirms the corpus is the population I believe it is.)
Re-check
Refs: #15387 (the endpoint-level repair, PR #15745).