Opening a Repo Is Now an Execution Event

Opening a Repo Is Now an Execution Event

If you work on Rails for a living, you clone repositories you didn’t write all week long: a gem you’re debugging, a client’s application you’re about to audit, a bug reproduction attached to an issue. For years, opening one of those in your editor was the safe part. You were reading someone else’s code, not running it, and the only real rule was to not run anything until you had looked.

That rule quietly stopped being enough. AI coding editors like Claude Code and Cursor read project-local configuration the moment you open a repository, and some of that configuration is executable. A repo you cloned five seconds ago can hand your editor a command to run before you have read a line of it, and this is not hypothetical: the npm worm that hit keyv this week (Socket opens a new window , Aikido opens a new window , and Microsoft opens a new window all covered it) weaponized exactly this, writing itself into .claude/settings.json so it runs again for anyone who opens the project.

In this post, we’ll look at why opening a repository in an AI editor is now an execution event, how the keyv worm turned that into a live attack, and what to check in a cloned repo’s .claude/ and .vscode/ directories before you point your editor at it.

Why opening a repo now executes code

For years the mental model was simple: untrusted code runs when you tell it to. You install a package and its install scripts run, you run the app and its code runs, but opening a repository to read it was passive. Looking wasn’t doing.

AI editors break that model by design. Claude Code reads .claude/settings.json on every session start, and one of the things that file can configure is a SessionStart hook, a shell command that runs when the session begins, with no separate step asking you to approve it first. A .claude/ directory you didn’t create can hand your session a command just as easily as one you built yourself.

Cursor and VS Code have the same shape with more friction: a task in .vscode/tasks.json can be set to run on folder open, though only in a workspace you have trusted and only once you have opted into automatic tasks. Either way, the config is meant to be read and acted on the moment the project opens, which is exactly what makes it useful to someone who has slipped it into a repo you are about to clone.

A configuration-injection bug in marimo opens a new window , a Python notebook tool (CVE-2026-67618 opens a new window ), surfaced the same week and leaked API keys the moment you opened a crafted notebook, a different mechanism with the same shape. Two unrelated tools hitting the same problem in the same week is a sign this is a shift in how tools treat project-local config, not an npm or a Rails quirk. The common thread is that the more a tool reads and acts on configuration shipped inside a project, the more of its behavior a repo you didn’t write controls the moment you open it.

Already weaponized: the keyv worm

The keyv worm shows this is not a theoretical risk. The npm package keyv, along with a few hundred others, was compromised on August 4th, 2026, in a self-propagating worm variously called ChainDrop or “Shai-Hulud: Here We Go Again”. The credential-stealing half of it is ordinary: an install script harvests tokens and keys from the filesystem and ships them out to the attacker. The half that matters here is how it sticks around. As Socket noted, listing it among techniques “not documented in earlier Shai-Hulud reporting,” the payload writes a SessionStart hook into .claude/settings.json and a folderOpen task into .vscode/tasks.json.

Those files are never touched by npm install. The next time you or a teammate opens the project, they are read by your editor, which means the infection outlives the dependency. You can pull the compromised package out of your lockfile and the hook waiting in .claude/ is still there, ready to run the next time someone opens the repo in Claude Code. That is the difference between “we shipped a bad dependency” and “everyone who opens this repo runs the payload,” and it is why cleaning up after this worm is not just a lockfile edit.

Why your usual instincts miss it

None of the usual reflexes catch this. “Don’t run code you haven’t read” and “only install signed, attested packages” are both good habits, and both miss the point here, because the dangerous part isn’t something you run or install at all. The hook rides in the repository’s own files. Provenance, a signed record tying a package back to the exact source commit and CI build that produced it, tells you which pipeline published a dependency; it says nothing about a .claude/settings.json committed straight into a repo you cloned. Ruby has its own take on verifying the packages you install, the gem signing and --trust-policy we looked at in The Forgotten Flag: How –trust-policy Works opens a new window , and it shares the same blind spot: signing covers the artifacts you install, not the config you open.

Why this lands on Rails teams

This started as an npm story, but the exposure isn’t really about your dependencies. If your Rails app has a Node asset pipeline it is worth keeping an eye on your lockfile, and keeping Gemfile.lock honest matters too (we have written before about supply-chain risk in your Gemfile opens a new window and about how patching a gem isn’t always the whole fix opens a new window ). But a gem or npm dependency audit looks at what you install. The .claude/ and .vscode/ vector is about what you open, and opening repositories you didn’t write is something Rails teams do constantly.

Consultancies live this at the extreme: at FastRuby.io we open other people’s Rails codebases for a living, cloning client applications to audit and upgrade them, more often than not with an AI editor already running. Every one of those repositories is, by definition, one we did not write, and any of them could ship a .claude/settings.json that runs the moment the session starts. A dependency audit answers “did I install something bad?” but it has nothing to say about the question that actually applies here: whose repo did I just open in Claude Code?

What to check before you open a repo

So before you open a freshly cloned repository in Claude Code, Cursor, or VS Code, especially one from outside your team, spend a minute on the config it ships with (the kind of check worth eventually baking into a Claude Code skill opens a new window so you are not relying on memory):

  • Open .claude/settings.json and look for a hooks key, particularly a SessionStart hook. A legitimate hook is one your own team added on purpose; anything you don’t recognize is worth reading in full, because it runs on session start whether or not you asked.
  • Open .vscode/tasks.json and look for a task set to run on folder open, and read exactly what its command does.
  • If the repo has a JavaScript pipeline, check whether your lockfile resolves keyv, flat-cache, file-entry-cache, or cacheable to one of the poisoned releases (keyv@6.0.0, flat-cache@6.1.24, file-entry-cache@11.1.6, cacheable@2.5.1) rather than to the older, clean lines. yarn why keyv or npm ls keyv shows what actually resolved.

If any of that turns up something you didn’t put there, deleting the file isn’t the end of it. Assume the command already ran, and rotate every credential the machine or CI run could have reached since you opened the repo, from a separate, uncompromised machine. A hook you remove after the fact doesn’t recall whatever it already sent out.

Conclusion

Opening a repository in your editor used to be the safe step, the thing you did precisely because you weren’t ready to run anything yet. AI editors changed that: Claude Code and Cursor read project-local config on open and can act on it, so cloning a repo you didn’t write and pointing an AI editor at it is an execution event in its own right. The keyv worm is the first widely seen case of someone weaponizing that, and it will not be the last.

For Rails teams, and especially for anyone who clones client code for a living, the habit worth building is a small one: before you open an unfamiliar repo in an AI editor, look at its .claude/ and .vscode/ directories the same way you would look at a shell script someone emailed you. A few minutes there is a lot cheaper than rotating every credential on the box afterward.

Wondering what is hiding in the .claude/ or .vscode/ config of the repos your team has been cloning, or want a second set of eyes on a codebase before you trust it? Send us a message! opens a new window

Get the book