#339

vercel-optimize: sanitizer behavior doesn't match its docs, and citation checks are skipped when stack detection fails

Opennotreallyaccurate-creatoropened 1mo ago

vercel-optimize: sanitizer behavior doesn't match its docs, and citation checks are skipped when stack detection fails

Found by reading skills/vercel-optimize (installed copy, skills-lock hash fb87d3a1…). Paths below are relative to the skill directory. I traced the code but did not reproduce items 1–4 in a live run.

1. The caveat sanitizers hold recommendations back instead of shipping them with a caveat

Several sanitizers say in their header comments that they add a caveat instead of dropping. For example:

  • lib/sanitizers/rate-limit.mjs:1: "Prepend a caveat (don't drop — customer may be on a higher tier)"
  • lib/sanitizers/pre-release.mjs:1: "Append a caveat (don't drop — customer may opt in to canary)"

But they all return needsReview: true, and so do middleware-conflict, undeclared-dep, rendering-mode-mislabel, bot-protection-certainty and cache-tag-invalidation-certainty. scripts/verify-and-regen.mjs:255-264 then leaves every needsReview recommendation out of verifiedRecommendations/renderableRecommendations, and scripts/render-report.mjs:54-68 lists it as "needs a manual safety review". So the caveat text gets written to rec.fix and never reaches the report.

Either the comments are out of date, or the hold-back rule is stricter than intended. The deciding question is whether a recommendation with a caveat like "verify your OpenAI tier" should ship.

2. The "12 sanitizers" table in references/recommendations.md is out of date

references/recommendations.md:123-136 doesn't match lib/sanitizers/index.mjs:

  • Missing from the table: window-units, function-duration-invocations, bot-protection-certainty and cache-tag-invalidation-certainty, which are all in the SANITIZERS array.
  • Wrong actions: rows 4–6 (pre-release, middleware-conflict, undeclared-dep) say they only append or prepend text. All three also set needsReview, which holds the recommendation back (see item 1).

3. One needsReview line can never take effect

lib/sanitizers/index.mjs:56-58 sets rec.needsReview = true when the citation strippers remove every citation. But an empty citations[] always triggers missing-citation at :62-65, which drops the recommendation, so that needsReview flag can never matter.

Related: the if (result.dropped) branch in the sanitizer loop (:46-48) is currently unreachable, because none of the 11 sanitizers in SANITIZERS returns dropped: true. That may be intentional, so new sanitizers can drop, but it's worth confirming.

4. Citation checks are skipped when signals.json has no detected stack

scripts/verify-and-regen.mjs:42-44 reads framework and version from signals.stack. If either is missing:

  • lib/sanitizers/index.mjs:51 skips sanitizeCitations entirely, so neither unknown-citation nor version-mismatch runs.
  • verifyCitationAppliesToVersion returns unsupported (lib/verify-claim.mjs:180-182), which doesn't count against the pass rate.
  • A citation that isn't in docs-library.json only fails citation_in_library. That counts toward the pass rate, but it isn't a hard rewrite trigger.

Example: a recommendation with one made-up URL and four verified file_exists claims has a pass rate of 4/5 = 0.8. The rewrite only triggers below 0.8 (verify-and-regen.mjs:175), so the recommendation ships with the made-up citation.

Also, verifyCitationInLibrary accepts any string matching /^[\w-]+:[\w-]+$/ as a valid skill-rule reference without looking it up (lib/verify-claim.mjs:170-172). When the stack is known, sanitizeCitations catches this through lookupSkillRule. When it isn't, nothing does.

The documented invocation passes --signals (SKILL.md:233-236), so this only happens when stack detection fails or the framework isn't supported.

Possible fixes: any of these would close it.

  • Run the unknown-citation part of sanitizeCitations even without framework/version. Only the version check needs the stack.
  • Make a failed citation_in_library a hard rewrite trigger.
  • Look up skill-rule references in verifyCitationInLibrary instead of accepting them by format.

Activity

1
shuaiyafei29d ago

I would like to work on the deterministic parts of this issue. I will make unknown URL and skill-rule validation run even when framework/version detection is unavailable, keep version filtering conditional on a known stack, remove the unreachable needsReview assignment before missing-citation drops the recommendation, and update the sanitizer reference table. I will leave the caveat/withholding policy unchanged because that requires a maintainer product decision. I will include focused regression tests and run the full vercel-optimize test loop.