diff --git a/extensions/workboard/src/gateway.test.ts b/extensions/workboard/src/gateway.test.ts index 958e9da3c9f2..5e35c6acae76 100644 --- a/extensions/workboard/src/gateway.test.ts +++ b/extensions/workboard/src/gateway.test.ts @@ -339,7 +339,7 @@ describe("workboard gateway methods", () => { expect(respond.mock.calls[0]?.[0]).toBe(false); expect(respond.mock.calls[0]?.[2]).toMatchObject({ - message: expect.stringMatching(/^labels must be 40 characters or fewer(?: \(got 41\))?\.$/), + message: "labels must be 40 characters or fewer.", }); }); diff --git a/extensions/workboard/src/store-normalizers.test.ts b/extensions/workboard/src/store-normalizers.test.ts index 2454363cb269..603ec0806e3b 100644 --- a/extensions/workboard/src/store-normalizers.test.ts +++ b/extensions/workboard/src/store-normalizers.test.ts @@ -1,7 +1,10 @@ // Regression coverage for the bounded-string normalizer used across Workboard -// input validators. The helper is shared by comment, label, title, url, and -// other bounded fields; an opaque error message blocks agents that overshoot -// the limit because they cannot tell how far over they are. +// input validators. The helper is shared by comment body, card id, link +// target, link URL, and link title; an opaque error message blocks agents +// that overshoot the limit because they cannot tell how far over they are. +// Title / notes / labels use their own independent validators and emit +// generic error messages that are intentionally out of scope for this +// helper. import { describe, expect, it } from "vitest"; import { normalizeBoundedString } from "./store-normalizers.js"; @@ -26,19 +29,24 @@ describe("normalizeBoundedString", () => { }); it("keeps the error message length-aware for every bounded field", () => { - // title/notes/labels/targetCardId/url/title are bounded through the same - // helper. A regression that drops the (got N) suffix will fail here. + // The `normalizeBoundedString` helper is the shared diagnostic owner for + // comment body, card id, link target, link URL, and link title. A + // regression that drops the (got N) suffix will fail here. + // + // Note: `normalizeTitle`, `normalizeNotes`, and `normalizeLabels` are + // independent validators with their own generic error messages, not + // consumers of this helper, so they are intentionally excluded from + // this matrix. Closes the false-confidence gap that ClawSweeper + // flagged on the prior matrix. const cases: ReadonlyArray<{ readonly field: string; readonly limit: number; readonly actual: number; }> = [ - { field: "labels", limit: 40, actual: 41 }, { field: "link title", limit: 180, actual: 181 }, - { field: "title", limit: 180, actual: 9999 }, - { field: "notes", limit: 4000, actual: 4001 }, { field: "link target", limit: 120, actual: 121 }, { field: "link URL", limit: 2000, actual: 2001 }, + { field: "card id", limit: 120, actual: 121 }, ]; for (const c of cases) { const overlong = "x".repeat(c.actual);