scua, next
The SCUA Package Manager
Why SCUA needs one, what we're building, and where you come
in.
Ed Morley — CTO, 25 years in games.
Unabated Gamesunabated-games.com
·
LinkedIn
Press → or swipe to begin.
where we are
The language works. Sharing code doesn't.
SCUA runs real programs today: the partition runtime, the
compiler, gradual types, actors, capability I/O, a debugger,
a baseline JIT. What it doesn't have is any way for your
project to use code from mine.
- Every project is an island. If you want a behaviour-tree module someone else wrote, you copy the file and hope you remember where it came from.
- No versions, no upgrades. A fix in the original never reaches your copy.
- No discovery. You can't even find out that someone already solved your problem.
Languages live or die on this. A good language with no way
to share libraries stays a curiosity.
why bother
Ecosystems are the whole game.
Nobody picks a language for the syntax alone. They pick it
because the pathfinding library already exists, the
tweening library already exists, and getting either into a
project is one command.
- For people: the distance between "I need X" and "X is running in my project" should be about ninety seconds.
- For teams: studios need to share internal libraries across projects without inventing their own infrastructure every time.
- For AI agents: SCUA is built to be a language agents write. An agent needs to find a library, judge whether to trust it, and use it correctly, all without a human babysitting each step.
lua's lesson
Embedded packages are hard to retrofit.
Lua has a package manager, LuaRocks, and for standalone Lua
it does its job. But when Lua lives inside a C++ engine,
getting a package visible to your scripts can be fiddly:
search paths, install trees, per-platform differences. Most
studios end up vendoring libraries by hand instead.
- No blame here. The embedded case just wasn't the one package tooling grew up around, and bolting it on afterwards is genuinely hard.
- The infrastructure has also run for two decades on volunteer time and donated hosting. Admirable, and fragile.
The takeaway for SCUA: design for the embedded user from
the start, and keep the infrastructure simple enough that
it can't fall over.
the other cautionary tale
npm shows what bolted-on safety costs.
npm won its ecosystem, and then spent a decade paying for
early design choices. We get to read that bill before
writing our own.
- Install scripts. Installing a package runs its code. That one choice became the main malware channel; a 2025 worm rode it through more than five hundred packages. npm turned scripts off by default in 2026, years after the pattern was obvious.
- Auto-floating versions. One phished maintainer and the bad release ships to everyone by morning.
- left-pad. A package vanished and builds broke across the ecosystem, because names could be unpublished.
- node_modules. The same files copied into every project on your disk, forever.
the homework
We did the research before picking a design.
This wasn't a whiteboard sketch. We studied how a dozen
ecosystems store, serve, version, and trust packages, the
ones that got it right and the post-mortems of the ones
that didn't, then wrote three complete competing designs
and stress-tested them against each other before choosing.
A dozen ecosystems studiedstorage and dedup, registries, supply-chain
security, versioning, embedded builds, and docs
for AI agents
3 competing designsfrom "no infrastructure at all" to "rebuild
distribution around content hashes"
Every trade-off written downincluding the arguments against the design we
chose
The long version is in the repo, under
docs/proposals/package-manager/.
the plan
A registry is just a directory of files.
The winning design (we call it Harbor) has one trick at its
centre: the package repository is a static file layout.
The same layout works at every distance from your code.
deps/ in your project · vendored, offline
~/.scua/store on your machine · shared by all projects
buildbox.lan in your studio · a bucket or an nginx dir
the public index on the internet · static files on a CDN
- No server software required at any tier. If you can host files, you can host packages.
- Every package is addressed by a hash of its content, so a copy from any mirror is provably the real thing.
the money question
Built to cost almost nothing to run.
A package ecosystem shouldn't need a company attached to
keep it alive. So rather than plan to fund the expensive
parts, we designed them out.
- Publishing runs on your machine. The registry never executes anything; it stores what you signed.
- Package bytes stay on the publisher's hosting (a releases page, a bucket, wherever). The public index holds names and hashes: kilobytes, on a CDN.
- Anyone can mirror anything, because hashes make mirrors trustworthy by construction.
The public index is cheap enough that we can host it
ourselves from day one.
teams and companies
Your packages, inside your firewall.
Private repositories aren't a paid add-on. They're the same
file layout, hosted wherever you already host things.
- A company registry is a bucket or a directory behind nginx. No instance, no licence, nothing to patch.
- Your internal names are sealed to your registry in the project manifest, so a public package can never shadow an internal one. That attack class (it hit Apple and Microsoft via npm) is a config error here, not an exploit.
- Fully offline and air-gapped workflows are the same mechanism, not a special mode. Console build farms included.
embedded, properly
The engine case comes first this time.
The whole point. When SCUA lives inside your C++ app,
packages should feel like part of the build, not a path
hack.
- scua vendor / scua bundle turn your dependency set into a plain directory or a single relocatable blob that your engine build owns.
- The runtime resolves packages with a tiny read-only lookup. No filesystem probing, no environment variables, and no network code in scua at all. You can ship a build where networking simply doesn't exist.
- The package tool is a separate binary (scua-pkg), with its own releases. Updating the language never forces package-infrastructure churn on you, and vice versa.
security, part one
The safety you get on day one.
Most of the protection costs no infrastructure, because
it's structural. No moderator enforces these; the design
just doesn't contain the hole.
- Installing never runs code. Not a script, not a build step, nothing. The npm malware channel doesn't exist here.
- Updates happen when you ask. Publication is not distribution: a compromised maintainer's new release reaches nobody until they explicitly update.
- Packages can't lie about what they touch. A package's capabilities (files, network, clock) are computed from its code. One that never imports net cannot phone home, and the resolver checks that. No reviewer required.
- Names can't vanish. Yank marks a version bad; nothing ever un-exists. No left-pad.
security, part two
Trust as a traffic light. An honest one.
Every package gets a light, computed on your machine
against your policy. You always see the reasons, not just
a colour, and no registry gets to sell anyone a badge.
- Green: verified, history logged, capabilities within budget, vouched for by audits you chose to trust.
- Amber: nothing known to be wrong, but the evidence isn't there yet. The tool tells you exactly what's missing.
- Red: a security advisory, a failed check, or a capability it shouldn't have. Blocked.
Honesty matters here: at launch, most public packages will
sit at amber, because the audit and witnessing layer that
feeds green needs an ecosystem (and funding) we don't have
yet. The light will brighten as that arrives. It will not
pretend.
and the robots
Packages that teach your AI to use them.
A package can carry a compact pack for agents: a one-page
API summary, schemas, and examples that are tested in CI so
they actually compile. Pinned to the exact version you
resolved, because the docs are hashed with the code.
- An agent can search structurally: "a noise generator that imports nothing" is a real query, not a vibe.
- The trust light comes as machine-readable JSON, so a harness can auto-accept green, ask you about amber, and refuse red.
- Pack text is treated as data, not instructions, so a malicious package can't prompt-inject its way into your agent's plans through its own docs.
the road
First the verbs, then the evidence.
One design, shipped in stages. Same commands and file
formats throughout, so nothing you adopt early gets
migrated out from under you.
- Now → M1: add, vendor, bundle, publish, self-hosted registries, the public index. Everything on static files.
- From the very first publish: a signed public log of every name-to-hash binding. Nobody independently witnesses it yet, but history can't be backfilled, so it begins on day one.
- Later → M2: independent witnesses, signed publisher identity, an audit ecosystem, search. Those need an operator and money, so they wait until both exist. Nothing else waits for them.
The full plan is ADR-0076 in the repo, with every trade-off
argued in the open.
the ask
Help us make packages the thing people praise SCUA for.
This is early, which means small contributions steer big
outcomes. Concretely:
- Publish something small. The first twenty packages shape every convention. A screen-shake helper counts.
- Embed SCUA and tell us where it hurts. Especially vendoring into engine builds, consoles, and offline setups. That's the case we refuse to fumble.
- Try self-hosting the registry layout at your company and tell us what breaks.
- Read the proposals and argue with them. They're in docs/proposals/package-manager/. Arguing with them helps more than agreeing.
- Later, if your org can witness a log or sponsor a CDN bill, that is what turns the amber lights green. Talk to us.
Unabated Gamesunabated-games.com
·
LinkedIn