DEV Community

Zack Chew
Zack Chew

Posted on

Five things I disabled before installing a vendor's agent runtime

Two services I connected recently both call the thing they ship a "skill". One is a hosted endpoint. The other is a zip file. The review those two need has almost nothing in common, and I do not think the word is doing anyone any favours.

Luckin Coffee runs an MCP server at their own domain. My agent sends JSON-RPC over HTTPS, and their code stays on their machines. The questions there are the familiar ones. What can it see, what scopes did I grant, can it spend my money.

Quark Drive, Alibaba's consumer cloud storage, ships a package instead. You download a zip, unpack Node scripts, and those scripts run inside your agent's process with your filesystem and your egress. The question is no longer what you granted. It is what that code does while it sits there.

Credit where it is due

Quark distributes the runtime from its own manifest and CDN, and authorization goes through an official OAuth endpoint scoped for agents. The token lands in the user's own instance and nobody proxies it.

That matters because the alternative, which I have also written adapters for, is scraping a website's internal endpoints and praying they do not rotate. A vendor that publishes a real package and a real OAuth flow is doing the right thing.

Which is exactly why it is worth reading the package instead of assuming.

What is inside is a CLI's habits

I unpacked version 1.0.11 and read it. What I found is what a desktop command line tool would reasonably ship.

Telemetry sampling is hardcoded at 1, so every event goes up. One call hands the raw user query to the telemetry client. Another reports a session id. The startup chain includes a self updater.

For a tool you open, use, and close, all four are defensible. Full-rate telemetry on a young product is how you find bugs. A self updater means users get fixes without being told to upgrade.

Now move the same code into a process that runs for months, holds a user's cloud storage token, and shares an address space with other skills.

The raw query stops being a search string. In an agent it is frequently the user's actual sentence, which carries filenames and people and reasons. And the self updater means the code you reviewed on Tuesday is not necessarily the code running on Friday. On a desktop that is a feature. For something holding a user's files, I would like to know when it changes.

What the install actually does

Version pinned at 1.0.11. Archive URL and SHA-256 both hardcoded. Download, hash, and abort on mismatch before anything is unpacked.

After unpacking, copy exactly two files, scripts/quark-drive.cjs and scripts/hash-worker.cjs, after asserting both exist. The upstream install.sh never runs.

Then five targeted edits to the runtime:

  1. sampleRate:1 becomes sampleRate:0
  2. the telemetry client constructor becomes a Proxy whose every method is a no-op
  3. the setRawQuery call becomes a discard
  4. the setSessionId call becomes a discard
  5. the self updater is removed from the startup chain

A wrapper sits outside all of it and refuses update, --verbose, --session-input, --session-id and --raw-query with exit code 2. Execution goes through env -i so the child gets HOME, PATH, LANG, BROWSER=false, CI=1 and nothing else.

Upgrades stage into a temp directory, move the old tree aside, and roll it back if the swap fails. The user's existing config.json holds their OAuth token, so it is checked with lstat for being a regular file under 1 MiB before being copied forward, into a 700 directory at 600.

The part worth stealing

Every one of those five edits asserts an exact occurrence count before it applies. Three for the sampling pattern, one each for the rest. If the count is off, the install throws with the label and the number it actually found.

unexpected quark runtime: self updater (0)
Enter fullscreen mode Exit fullscreen mode

Here is why that matters more than the edits themselves. When upstream refactors, a naive string replace matches nothing and reports success. The install completes, the tree looks right, and the telemetry and self updater are running exactly as they always were. You are now shipping a build you believe is hardened and is not.

Counting turns that silent success into a loud failure. I would rather the install break and make me read the new version than have it quietly hand me a false sense of what I disabled.

That generalizes past this package. Any time you patch someone else's code as part of a build, assert the shape you expected to find. A patch that no-ops is worse than a patch that fails, because only one of them tells you.

The question I ask now

Services decoupling from platforms is real. Capability ships as a skill, every agent can read it, and the aggregator in the middle stops being mandatory.

What changed underneath is where the integration lives. Calling someone's API and hosting someone's code are different risks wearing the same word. The worst case for the first is that you do not get your data. The worst case for the second is behaviour you did not ask for, running next to everything your agent can reach.

So the first thing I want to know about a new skill is whose machine it runs on. For a hosted endpoint, read the scopes and find out whether it can spend money. For a package, find out whether the self updater can be turned off, what it reports, and whether you can pin a version and verify it.

The Quark package works well once it is pinned. Search, upload, download, share and save all behave. Its AI summarization sends the selected file's contents back to Quark, which is the sort of thing a user should get to decide for themselves rather than discover later.

I run a small hosted service for agent bots and this is one of about 135 connectors we maintain, so I read a lot of these packages. openclawlaunch.com

Top comments (1)

Collapse
 
daymondhyper profile image
DaymondHyper

Useful read. My main lesson with agents was that the prompt matters less than the guardrails around it. I moved most of my rules into code checks and the flip rate dropped a lot. Do you do the same or do you keep it all in the prompt?