Skip to content

rate-limit-guard: reader-contract overstates the tee's forward-pass upgrade path #1685

Description

@kyle-sexton

What

plugins/rate-limit-guard/reference/reader-contract.md draws a conclusion from
the writer's forward-pass filter that is broader than the filter supports.

The description of the filter is accurate. The inference from it is not.

Evidence

reference/reader-contract.md (in the loop-lane single-account gap bullet):

Locally relevant today: the writer already forward-passes any top-level key
matching account, so an identity field costs no plugin change the release
one appears.

scripts/statusline-tee.sh — the filter itself:

+ (to_entries
   | map(select(.key == "rate_limits" or .key == "session_id"
                or .key == "session_name" or (.key | test("account"; "i"))))
   | from_entries)

to_entries is applied to the root object only, and the pattern matches the
literal substring account, case-insensitively. So the first clause is exactly
right.

The second clause is the problem: "an identity field costs no plugin change"
holds only if the field upstream eventually ships is both top-level and
account-named. A field called user, identity, org, subscription, or
seat, or one nested under an object (user.account_uuid), is silently
dropped — and silently, because the filter has no else branch.

The doc therefore promises a no-change upgrade path the code cannot guarantee,
in a contract that fail-closes on every other unresolvable input.

Why it matters

This sentence is load-bearing for the account-identity design in #1218. Anyone
planning that work reads it as "the writer is already ready" and skips checking
the filter. It is also the kind of claim that ages badly: it will read as true
right up until the release where it silently is not.

Resolution shapes

  1. Narrow the claim to what the filter does. Say the field costs no plugin
    change if it is top-level and account-named, and that any other shape
    needs a filter change. Documentation-only, mechanical, trivially reversible.
  2. Widen the filter to match the claim. Recurse, or match a wider set of
    identity-ish key names. Behavioral change to a shipped script, needs its own
    test coverage, and risks forward-passing fields nobody intended.

Shape 1 is the smaller and safer correction, and it is the one that makes the
document honest immediately. Shape 2 is a design question that belongs with
#1218 rather than with this correction, since #1218's recommended field is
deliberately named to satisfy the existing filter.

Related

No linked issue.

Metadata

Metadata

Assignees

Labels

agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: lowNice-to-have, cosmetic, or speculative; opportunistic.work-class: mechanicalDeterministic, trivially reversible maintenance: dependency bumps, lint/format, sync.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions