Skip to content

performance:goal: require a scaling arm when the subject reads growing state #4438

Description

@kyle-sexton

Problem

The claude-ops Stop hook cost 137 ms against a 50 KB transcript and 6,977 ms against a 10 MB one, because its warm path re-read the whole file (#4389). A single-size measurement would have passed it.

Proposal

When the subject reads state that grows with use (transcripts, logs, caches, histories), goal requires the metric to be measured at two or more sizes spanning realistic use, and adds a done criterion that cost does not grow with size (or grows within a stated bound). The target skill should flag such subjects when ranking candidates.

Found during the Windows hook-latency work under #4373 (#4389/#4408, #4415/#4421, #4416/#4422).

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Sep 24, 2026
  2. kyle-sexton commented on Sep 27, 2026

    @kyle-sexton
    ContributorAuthor

    This was generated by AI during triage.

    Triage: briefed, delegable (enhancement, priority: medium)

    Verified. The motivating evidence holds: #4389 records the hook-failure-audit Stop hook at 137 ms (50 KB), 1,374 ms (2 MB) and 6,977 ms (10 MB) transcripts, with a constant process count of 3, so a single-size run or a spawn-count counter alone would have passed it. Redundancy check: the performance:goal skill body (metric, floor, realistic/ideal targets, percentiles, done criteria) and the performance:target ranking (evidence tiers, layer attribution, counters) contain no requirement to measure at more than one input size and no flag for subjects that read growing state. Not implemented.

    Related, not a cluster: #4439 and #4440 are separate proposals against the same skills (independent decisions). #4270 (agent-ready) edits the same goal skill body; whoever picks either should rebase on the other.

    Brief

    Goal. A performance goal on a subject whose cost can depend on accumulated state cannot be declared done from a measurement at one size.

    Behavior, performance:goal:

    1. When the subject reads state that grows with use (transcripts, logs, caches, histories, databases, queues), the goal must name the growing input and require the metric at two or more sizes spanning realistic use (smallest to largest realistically seen, not two nearby points).
    2. The goal's "done" criteria gain a scaling criterion: cost does not grow with the input size, or grows within a stated bound (for example, per new unit of content rather than per total content).
    3. The goal output template gains a line recording the growing input, the sizes, and the scaling criterion (or an explicit "not applicable: subject reads no growing state").
    4. A gotcha states the failure this prevents, with the perf(claude-ops): hook-failure-audit Stop hook reads the whole transcript on every Stop (7 s at 10 MB) #4389 numbers as the worked example, and notes that a constant counter (spawns) does not rule out size-proportional cost.

    Behavior, performance:target: when ranking candidates, flag any candidate that reads growing state so the scaling requirement travels into /performance:goal.

    Acceptance criteria:

    • Both skill bodies state the rules above; any volatile specific they restate carries the repo's required verification record (skill-body rules).
    • An eval case in each skill's evals: a goal request for a subject reading a transcript must require a multi-size measurement and a scaling done criterion; a target ranking for such a subject must flag it.
    • Skill lint/validation passes.

    Out of scope: changing snapshot or verify mechanics beyond what the goal template requires them to carry forward; any harness code.

  3. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Sep 27, 2026
  4. kyle-sexton commented on Sep 29, 2026

    @kyle-sexton
    ContributorAuthor

    Issue stays closed for now; no follow-up issue is needed. This comes from the 2026-09-29 audit of the unattended Cursor run (report: .work/audit/REPORT.md).

    What the audit found. #4823 shipped a scaling-arm requirement but missed scope from this issue: a target eval, the #4389 worked example, the constant-counter caveat, and a stated growth bound in place of the word "unproven". Evidence: .work/audit/units/4438/pr-4823.diff.

    What happens next. Draft PR #5283 delivers each of these: goal requires a stated growth bound, techniques.md gains the constant-counter worked example, and evals cover the growing-state candidate for goal and target. Because that covers the missing scope, a separate follow-up would duplicate it. Note: goal/SKILL.md ends at 207 lines against 205 on main, so the planned shrink was not reached; the procedures did move to techniques.md. The PR is a draft and is not merged. If delivery is blocked, this issue gets reopened.

  5. kyle-sexton commented on Sep 29, 2026

    @kyle-sexton
    ContributorAuthor

    Correction to the earlier comment on this issue: the constant-counter worked example (the #4389 timings and their Claim/Basis/As-of/Recheck record) is in plugins/performance/skills/goal/SKILL.md, in the Gotchas ("One size is not enough" bullet), not in techniques.md. The 0.3.0 CHANGELOG entry and the PR #5283 body now say the same. techniques.md gains the moved parallel-units and growing-state procedures only.

    Two scope notes for the owner on PR #5283:

    • goal/SKILL.md ends at 207 lines against 205 on main. The comment above said the planned shrink was "not reached" before the final line count was known; 207 is the final figure.
    • snapshot step 3 (run every recorded size) and verify (Scaling:/Event:/Unit: handling, and NOT MET for an unmeasured event target) were wired to consume goal's new lines. That goes past this issue's out-of-scope clause and adds a verdict rule. The owner can drop that wiring without affecting the goal changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions