fix: stop reading skills once the byte budget is reached, not only exceeded; review round 2 (#2294)

The byte side of the catalog budget compared with `<=`, so a run whose charged
bytes exactly equalled the limit still read one more skill. Use a strict `<`,
matching the skill count and the setting's description. The skill whose reads
cross the limit is still reported in full.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6i1HBSdSS9kL4npZ2dDSe
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-14 00:44:31 -04:00
commit 940c8479a1

View file

@ -335,8 +335,14 @@ export async function verifySkills(
// Static checks still run for every entry — they cost no I/O, so a skill
// past the budget is still reported on, just not read. What stops is the
// reading.
//
// ⚠️ STRICT on bytes, like the count. A run whose charged bytes exactly
// equal the limit has REACHED it, and `<=` read one more skill past a
// budget that was already spent (Copilot, #2294). The skill whose reads
// cross the limit is still reported in full — that is decided by charging
// after the entry, below, not by this comparison.
const withinBudget =
walkedSkills < budget.maxSkills && catalogBytes <= budget.maxBytes;
walkedSkills < budget.maxSkills && catalogBytes < budget.maxBytes;
// The entry's own SKILL.md, read once and used twice — for its digest and
// for the frontmatter cross-check. Reading it twice would double the load
// on the server and, worse, could compare a digest against one snapshot