YC Opened the Harness It Runs Itself With: Here’s How You Spin Up qm on Fly in an Afternoon
Y Combinator just published the agent harness it uses to run its own company. It’s not a demo or a reference implementation: it’s what’s actually behind the work of accounting, legal, events, and engineering at YC, including the work of building qm.
The repo is github.com/yc-software/qm, MIT license, 19 commits in, and today it hit the front page of Hacker News with 640 points and 151 comments. The tagline is deliberately scoped:
“A multiplayer agent harness for work. In Slack and on the web.”
That word — multiplayer — is the whole thesis, and it’s what separates qm from the stack of agent runners we’ve been covering this year. Let’s install it and see what’s underneath.
What “Multiplayer” Actually Buys You
Most agent tooling assumes one developer, one terminal, one context. qm assumes a company.
Each person and each Slack channel has its own scope. A scope isn’t a config profile: it’s an isolated unit with its own memory, its own files, its own keychain, its own set of permissions, its own crons, and its own durable sandbox. Your scope’s memory doesn’t leak into mine. The #finance room’s keychain isn’t reachable from the #eng room’s agent.
That’s the part where it’s worth stopping. The hard problem in agent deployments for teams was never “can the model call a tool.” It was “how do I give the agent enough credentials to be useful without giving every agent in the company all the credentials.” Scopes are qm’s answer, and they’re why this is architecturally more interesting than a shared bot token in a Slack workspace.
On top of that: crons and watches run work when nobody’s looking, and scopes can build and publish internal web apps. Same identity and configuration, whether you’re in Slack or the web UI.
Underneath it’s Node/TypeScript on Fastify, PostgreSQL for sessions, memory and queue, and a sandbox per scope for tool execution. Optional plugins cover Slack, the web UI, and an admin panel.
The Part That Should Matter Most to You: It’s Not a Vendor Play
Here’s the design decision that makes qm worth your time even if you never adopt it:
“Pick your own harness and model and switch between them — Pi, OpenCode, Codex, and Claude Code.”
The core is harness-agnostic. YC built the scopes model, the permissions system, the sandbox, and the Slack integration as the durable layer, and left the coding agent itself as a swappable component.
That inverts the usual dependency. If you standardize your team on Claude Code today and in six months Codex is better, you migrate the agent, not the deployment. Everything expensive to build — the identity model, the credential boundaries, the audit surface, the Slack wiring — survives the switch.
Anyone who’s watched a team rebuild all their internal tooling because a vendor changed course knows exactly how much that’s worth.
Getting It Running
The CLI is a deployment CLI, not the runtime. It delegates to Docker with Buildx, flyctl, the AWS CLI, and git, so have those on your machine first. You run Terraform against the modules init generates for you.
There are three targets: docker, fly, and aws. Start with docker. You get the full scopes model on your own machine before spending a dime on infrastructure, and you find out if qm fits your team’s mental model before you’re debugging a Fargate task definition.
npm exec --yes --package=@yc-software/qm@latest -- \
qm init . --org acme --target docker
npm install
qm init materializes a deployment repository. You get qm.config.jsonc (commits, no secrets inside), a package.json that pins the CLI to the exact version the directory was built with, a deployment.md generated and written for your target, .env.example alongside a .env that’s ignored, Slack manifest files, and sandbox/, plugins/, and infra/ directories.
That version pin is a small detail with big consequences: contract: 1 is just the compatibility floor, and the pin means every checkout of your repo resolves the same interpreter. You upgrade deliberately, not because someone ran npm update on a Friday.
From there on, the loop is the same regardless of target:
npm exec qm -- check # config, secrets, tools, skills, plugins — no network
npm exec qm -- infra render
npm exec qm -- doctor # verify external prerequisites, read-only
npm exec qm -- infra build-image
npm exec qm -- plan
npm exec qm -- up --yes
npm exec qm -- check --live
It’s worth internalizing the order: check before doctor before plan before up. Three of those four are read-only, which means you can get pretty far toward a correct deployment without mutating anything.
When you move to Fly, change the target in init — --target fly — and qm runs the services as Fly apps with Fly Machines as agent computers. On AWS you get ARM64 tasks pinned by digest on ECS Fargate, with Lambda MicroVMs as agent computers, and mutations in AWS require explicit --yes.
The AWS path has an operational convenience worth mentioning: it takes an RDS snapshot before deploy, under a deploy lease and before mutations, named after your deployment manifest and recorded in it. qm rollback --to <revision-or-sha> restores code and configuration and prints the data restoration point, so code rollback and data rollback remain separate decisions. You can disable snapshots with aws.predeployDbSnapshot: false — having to opt out is the correct default.
For day-to-day work you have status, logs [service] -f --tail n, outputs --json, secrets push --from <file> and slack render. down --purge when you’re done experimenting.
Three Security Postures, and Their Honest Reading
qm brings an org-level security posture with three values, described in the repo like this:
- Strict — “every harness tool call pauses for human approval”
- Auto (the default) — “a classifier screens provenance-labelled external data”
- Dangerous — “no content screening, no pauses between tool calls”
The provenance labelling of the default Auto is what’s interesting: external data carries a label, and the classifier filters on that label instead of trying to reason about content cold.
Now the part that deserves more attention than launch coverage gave it. YC’s own SECURITY.md is unusually frank, and doesn’t read like marketing:
- qm is described as experimental software. Isolating data by scope is framed as a design goal, and explicitly “not a promise that data cannot leak, a certification, or a substitute for a deployment-specific security review”.
- The command policy is evadable via obfuscation or having the agent write a script. YC’s framing: it catches mistakes, not sophisticated attacks.
- Sandbox credentials stay in plaintext while in use. If the agent process is compromised, they’re exposed.
- A credential’s purpose travels as guidance, not as applied authorization.
- Org admins can read transcripts, memory, and sensitive metadata. It gets audited, but doesn’t require separate approval.
- Published app links are bearer tokens. Anyone with the link gets in, and revocation is incomplete.
There’s also a dependency cooldown of 7 days (min-release-age=7) that crawls npm installs, and that’s a genuinely good supply-chain default that more projects should copy.
Read that list for what it is: a team documenting their threat model with honesty instead of claiming a boundary they haven’t built yet. That’s more useful than a vendor security page. But it also means the right move for most teams is --target docker on a laptop, or a deployment on Fly with non-production credentials — don’t route your company’s actual keychain through there this quarter.
The HN Thread Objection
There’s a criticism from the thread worth dragging over here. Despite the pitch of deploying in your own cloud account, a commenter argued that the architecture “feels like it’s written to run on one mac/vm”, with the same practical constraints as the platforms qm positions itself against. YC’s own announcement frames qm as “easy to customize, like Hermes or OpenClaw, but useful for a whole company” — and if you’ve already deployed Hermes, that’s exactly the comparison you should test yourself instead of taking for granted.
Nineteen commits are nineteen commits. The scopes model is the real contribution here, and it’s worth studying whether you deploy it or not.
Who Should Actually Run This
If you’re a solo developer, Mux or a plain harness will serve you better; qm’s entire value proposition is the boundary between people, and there’s no boundary to draw there.
If you manage a team of five to fifty and you’ve been improvising agent access with shared tokens and good intentions, spend an afternoon on --target docker. The scopes model will align with how your team already thinks about permissions, or it won’t, and you’ll know in a couple of hours. It’s a cheap answer to an expensive question.
And you? How are you solving today the problem of giving an agent credentials without opening up the whole house — scopes, shared tokens, or hasn’t anyone touched the topic on your team yet?