Summary
Writing an ordinary GitHub Actions workflow in a repository with no Vercel surface at all injects the "MANDATORY: Your training data for these libraries is OUTDATED and UNRELIABLE" block plus Vercel deployment guidance.
The cause here is not the workflow skill's globs. It is deployments-cicd's own pathPatterns, which list the generic CI files that nearly every repository has:
# skills/deployments-cicd/SKILL.md
pathPatterns:
- '.github/workflows/*.yml'
- '.github/workflows/*.yaml'
- '.gitlab-ci.yml'
- 'bitbucket-pipelines.yml'
- 'vercel.json'
- 'apps/*/vercel.json'
.github/workflows/*.yml matching implies nothing about Vercel. A repository can have GitHub Actions and no relationship to Vercel whatsoever, which is the common case.
This is distinct from the two existing reports, and survives whatever is done about them:
Both concern the workflow skill. deployments-cicd names these paths explicitly in its own frontmatter, so fixing the workflow skill leaves this firing.
Repro
The repository under test is a private operations repo: launchd job definitions, six .plist files, a handful of Python scripts, two shell scripts. No package.json, no lockfile, no JavaScript, no vercel.json, no .vercel/. I added a CI workflow to it and got Vercel deployment docs.
Running the hook directly, with a fresh session_id per case, because the per-session dedupe will otherwise make a second run look like a fix:
echo '{"session_id":"fresh-1","cwd":"/tmp/probe","hook_event_name":"PreToolUse",
"tool_name":"Write","tool_input":{"file_path":".github/workflows/ci.yml",
"content":"name: CI\non: [pull_request]\njobs: {test: {runs-on: ubuntu-latest}}"}}' \
| CLAUDE_PLUGIN_ROOT=<plugin> node hooks/pretooluse-skill-inject.mjs
Actual: two skills injected.
- "workflow" matched suffix pattern `workflows/**` on Write: .github/workflows/ci.yml
- "deployments-cicd" matched full pattern `.github/workflows/*.yml` on Write: .github/workflows/ci.yml
Expected: nothing. There is no Vercel surface in the repository or in the file.
Why it matters
The injected text is imperative: "MANDATORY", "DO NOT guess, assume, or rely on memorized APIs". In a repo where Vercel is irrelevant, that instructs an agent to go read documentation for a platform the project does not use, spending context and inviting irrelevant suggestions. A maintainer's reasonable response is to disable the plugin.
Proposed fix
The plugin already has the right precedent: resolveVercelJsonSkills (hooks/src/vercel-config.mts) refines a vercel.json match by reading the file's keys rather than trusting the path. Generic CI files deserve the same treatment, since unlike vercel.json the path carries no signal at all.
The match is currently unconditional (hooks/src/pretooluse-skill-inject.mts, around line 448 on main):
const reason = matchPathWithReason(filePath, entry.compiledPaths);
Requiring a Vercel signal in the file being written, for generic CI paths only:
const GENERIC_CI_PATH =
/(^|\/)\.github\/workflows\/|(^|\/)\.gitlab-ci\.ya?ml$|(^|\/)bitbucket-pipelines\.ya?ml$/i;
const VERCEL_SIGNAL = /vercel|turborepo|\bnext(\.js| build|-app)/i;
function vercelSignalPresent(filePath: string, fileContent: string): boolean {
if (VERCEL_SIGNAL.test(filePath)) return true;
if (fileContent && VERCEL_SIGNAL.test(fileContent)) return true;
if (!fileContent) {
try {
return VERCEL_SIGNAL.test(readFileSync(filePath, "utf8"));
} catch {
return false;
}
}
return false;
}
let reason = matchPathWithReason(filePath, entry.compiledPaths);
if (reason && GENERIC_CI_PATH.test(filePath) && !vercelSignalPresent(filePath, fileContent)) {
reason = null;
}
fileContent is already assembled a few lines above from content / old_string / new_string, and readFileSync is already imported, so this needs no new plumbing. The disk read only happens on Read, where the tool input carries no content.
I applied exactly this locally and tested four cases, each with a fresh session:
| Case |
Before |
After |
.github/workflows/ci.yml, no Vercel anywhere |
2 skills injected |
nothing |
.github/workflows/deploy.yml running vercel deploy --prod |
injected |
still injected |
src/workflows/order.ts (Workflow DevKit) |
injected |
still injected |
vercel.json |
injected |
still injected |
The false positive disappears and I could not find a true positive it costs. A repo-level gate (a vercel.json, a .vercel/ directory, or a Vercel dependency anywhere in the tree) would be stronger still, and would also address the class #144 describes, but the file-level check is the smaller change.
Environment
|
|
| Plugin |
0.25.1 installed; patterns and the unguarded match verified unchanged on main at 0.50.0 |
| Node |
v22.22.2 |
| OS |
macOS 26.1, arm64 |
I reproduced on the installed 0.25.1. I have not run 0.50.0, so I checked the source instead: skills/deployments-cicd/SKILL.md still carries the four generic CI patterns, and pretooluse-skill-inject.mts still matches on path alone.
Summary
Writing an ordinary GitHub Actions workflow in a repository with no Vercel surface at all injects the "MANDATORY: Your training data for these libraries is OUTDATED and UNRELIABLE" block plus Vercel deployment guidance.
The cause here is not the
workflowskill's globs. It isdeployments-cicd's ownpathPatterns, which list the generic CI files that nearly every repository has:.github/workflows/*.ymlmatching implies nothing about Vercel. A repository can have GitHub Actions and no relationship to Vercel whatsoever, which is the common case.This is distinct from the two existing reports, and survives whatever is done about them:
workflowskill misfiring on.github/workflows/*through the suffix pass inpatterns.mjs.**/orchestrat*/workflows/**path patterns #144 (open) is theworkflowskill's*workflow*/**/orchestrat*globs, plus the unconditional session-start block.Both concern the
workflowskill.deployments-cicdnames these paths explicitly in its own frontmatter, so fixing theworkflowskill leaves this firing.Repro
The repository under test is a private operations repo: launchd job definitions, six
.plistfiles, a handful of Python scripts, two shell scripts. Nopackage.json, no lockfile, no JavaScript, novercel.json, no.vercel/. I added a CI workflow to it and got Vercel deployment docs.Running the hook directly, with a fresh
session_idper case, because the per-session dedupe will otherwise make a second run look like a fix:Actual: two skills injected.
Expected: nothing. There is no Vercel surface in the repository or in the file.
Why it matters
The injected text is imperative: "MANDATORY", "DO NOT guess, assume, or rely on memorized APIs". In a repo where Vercel is irrelevant, that instructs an agent to go read documentation for a platform the project does not use, spending context and inviting irrelevant suggestions. A maintainer's reasonable response is to disable the plugin.
Proposed fix
The plugin already has the right precedent:
resolveVercelJsonSkills(hooks/src/vercel-config.mts) refines avercel.jsonmatch by reading the file's keys rather than trusting the path. Generic CI files deserve the same treatment, since unlikevercel.jsonthe path carries no signal at all.The match is currently unconditional (
hooks/src/pretooluse-skill-inject.mts, around line 448 onmain):Requiring a Vercel signal in the file being written, for generic CI paths only:
fileContentis already assembled a few lines above fromcontent/old_string/new_string, andreadFileSyncis already imported, so this needs no new plumbing. The disk read only happens onRead, where the tool input carries no content.I applied exactly this locally and tested four cases, each with a fresh session:
.github/workflows/ci.yml, no Vercel anywhere.github/workflows/deploy.ymlrunningvercel deploy --prodsrc/workflows/order.ts(Workflow DevKit)vercel.jsonThe false positive disappears and I could not find a true positive it costs. A repo-level gate (a
vercel.json, a.vercel/directory, or a Vercel dependency anywhere in the tree) would be stronger still, and would also address the class #144 describes, but the file-level check is the smaller change.Environment
mainat 0.50.0I reproduced on the installed 0.25.1. I have not run 0.50.0, so I checked the source instead:
skills/deployments-cicd/SKILL.mdstill carries the four generic CI patterns, andpretooluse-skill-inject.mtsstill matches on path alone.