Skip to content

AI agent: bound every persisted transcript field and make clampToLimit total #75

Description

@kipavy

Surfaced by the 3e (plan checklist) whole-branch review as pre-existing and deliberately left out of scope. Same shape as the eviction bug 3e fixed for plan entries — it has now bitten three times, so it deserves its own pass.

1. Unbounded transcript fields

src/plugins/ai-agent/state/persistence.ts clamps some strings but not all. Measured on the current code:

Field Kind Measured size
tool.tool tool 300,055 bytes
attachment.connectionName user 300,117 bytes

plan entries got a structural byte cap in 3e; tool and user did not. A single oversized entry inflates the persisted conversation and can push out real history.

2. clampToLimit throws on a non-string

text and detail have the identical exposure. Blast radius is bounded by agentStore.ts's try/catch — the failure mode is losing the conversation, not corrupting it — but a validator that throws on hostile input is the wrong default.

Scope

  • Bound every persisted string by construction, not per-field opt-in — an explicit field set, so a new field is bounded by default rather than by remembering.
  • Make clampToLimit total (non-string → rejected entry, not a throw).
  • Pin each bound with a mutation-proven test; assert the measured byte size rather than asserting it by construction (a 3d lesson).

Reference

.superpowers/sdd/3e/whole-branch-review.md §5 row 27, and the explanatory comment 3e left at the site in persistence.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-agentBYOK AI agent featurebugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions