This tool's agent runs skills that are written as markdown files. Each skill is a recipe for what to do when the user asks for a specific kind of work — "give me a morning brief," "find a contact named X," "prep hearing for case Y." The skills contain prose explanations interleaved with bash blocks the agent executes. The bash blocks often contain JavaScript snippets in node -e "..." heredocs.

From the language model's perspective these are instructions. From the runtime's perspective they're code. When the agent invokes a skill, the bash blocks run as bash, the JavaScript inside runs as JavaScript, and any bug in the JavaScript is a real bug — same as a bug in the binaries.

Two earlier releases this month fixed pattern bugs in the binaries:

Both fixes patched the binaries. Neither fix patched the skill files.

Three skill files (status, brief, prep-hearing) still had the bare ^VERIFY regex copy-pasted into their JavaScript heredocs. When the agent ran "morning brief," it loaded the skill, executed the bash blocks, and the JavaScript inside hid every verify-task. The bug from 4.5.96 had been fixed in the task-walker but was still live in three of the four code paths that filter tasks.

One skill file (find-contact) still had the punctuation-sensitive search. When the agent ran "find Dr. O'Doe," it loaded the skill, executed the bash block, and the lowercase-only search returned no matches. The agent then suggested creating a new contact — producing duplicate records in the upstream system for doctors whose names happened to contain apostrophes.

How this got missed

The fix for each binary was a 1-line regex change. When I made the change, I tested the binary, verified the fix, shipped the release. The test confirmed the binary's behavior was correct. The test didn't sweep for other copies of the pattern.

The skills are .md files, not .mjs. Grep for ^VERIFY in the codebase: grep -rn '^VERIFY' bin/ lib/ src/ finds the binaries. Adding skills/ finds the rest. I just didn't add it.

The same shape was visible in the lock-helper bug (4.5.99 through 4.5.110): same code copy-pasted into five modules, fix shipped to one, found independently in two more, finally extracted to a shared helper. That extraction prevents this exact failure mode for locks going forward — every caller delegates to one helper, fixes apply everywhere automatically.

Skills can't be refactored that way because they're standalone files the agent reads as instructions. The fix has to be applied to every copy. The rule is: when you fix a copy-pasted bug, grep the entire codebase including markdown.

What I'm changing in my workflow

Every bug-fix patch now ends with a sweep step:

  1. Fix the bug in the file where the probe found it.
  2. Grep the entire codebase for the same shape — including .md, .json, .yaml, anything that might contain executable patterns or pattern strings.
  3. Apply the same fix to every match.
  4. Include the sweep step in the release notes so the reader can verify it ran.

For this release: fixed three more copies of the VERIFY-noise regex and one copy of the search normalizer. Total bug-fix lines: roughly 20. Total time: 15 minutes. The bugs had been live in the skill files for weeks because the sweep step wasn't part of the original fix workflow.

The other consequence

Because the skill files run as instructions to the language model, the model has been seeing buggy code patterns and treating them as how-to examples. When the model writes new code for similar problems, it copies the patterns it has seen. A buggy regex in a skill file isn't just executed — it's also taught.

For a tool that uses LLM-extracted classifications as part of its decision making, the skills are training data for the model's session. Fixing them affects both the runtime behavior and the patterns the model picks up from context.

This is a small release in line count but it closes a propagation gap that had been silently widening for weeks. The general principle — fix every copy at once — should be baked into the patch workflow for every codebase that has copy-paste code in non-.mjs locations.

The version on the install URL is 4.5.113.