Diffusion roadmap
Status: 2026-10-14 (oxygenhub#199). This replaces the earlier draft in
oxygen/docs/diffusion_roadmap.md. The design for each step is in
diffusion.md; this page says what is built, what is
designed, what is planned, and what comes later, and in what
order. A claim here is only as strong as its label.
1. What Diffusion is for
Diffusion keeps the repositories that depend on each other up to date: when an upstream moves, each consumer gets a signed proposal that brings the move, tested by the consumer's own pipeline, with the exact list of changes it brings.
Today it does this for Oxygen subrepos: code you own or follow across repositories, such as R* API inside the games. That is where Oxygen can do what nothing else can (§5). It is not yet a replacement for Renovate or Dependabot on package registries; §3 B is how it becomes one.
2. Built
| What | Issue |
|---|---|
| The reverse pin index: who pins what, at which state, on which bookmark | #148 |
Following an upstream (follow = any, green or off, in .oxymodules, the repository or the site) | #148 |
The bump: one hub-signed change on diffusion/<path>, moved in place, proposed once, labelled dependencies | #148 |
The changelog in the proposal, with watch paths flagged | #148 |
| The Diffusion tab, the two-half pills, Admin › Diffusion, the overview card | #150, #160 |
GET /repos/{o}/{n}/consumers and /diffusion | #153 |
Auto-land, opt-in per consumer (land = auto), only when the upstream is checked and the consumer's run passed | #174 |
| Catching up: a consumer that turns following on gets its bump at once | #148 |
| A landing moves the pin index and starts the target's pipeline, as a push does | #150, #197 |
3. Roadmap
A. Trust the basics (next)
Diffusion only earns trust if nothing is held silently. #197 (a landed
state that never ran held every green consumer back) is the kind of
fault this phase removes for good.
- A1. The guarantees, written down and tested. Every move of a followed bookmark gets a run; a consumer only moves forward; one bump per consumer and path; every bump is signed; a held bump always says why. Each guarantee gets an end-to-end test.
- A2. Why is it held? The hub already knows the reasons when it declines to auto-land (no bump, manual, upstream unverified, upstream state unchecked, consumer run not passed, landing refused). Show them on the Diffusion tab, the proposal and the API, with the action that clears each.
- A3. Confidence across consumers. The hub sees every consumer's result, so a bump can say "this upstream state passes in 7 of 8 consumers", and an upstream can see which consumers it is about to break. No package-registry tool can know this.
- A4. Rollback. Undo a landed bump in one action: a proposal that pins the previous state, with the failing run linked.
- A5. Landing rules for agents. Today a token with
repo:writemay land, whatever key it signs with. Add per-bookmark landing rules (required reviews and checks) and make tokens marked as an agent's unable to land. D4 depends on this. - A6. Numbers. Publish, per hub and per repository: time from an upstream landing to its consumers' bumps proposed and landed, the share of bumps that land green, and bumps held and why.
B. Ecosystems
Diffusion's model (index, follow, bump on diffusion/..., test, propose,
land) does not depend on what a dependency is. An ecosystem adapter
tells it how to read and move one kind.
- B1. The adapter contract. An adapter answers four questions, and
runs as a Flow job in the sandbox, so the hub never executes ecosystem
code itself:
- find: which manifests in a state it owns;
- list: the dependencies they declare, with their current versions;
- resolve: the newest version allowed by the consumer's rules (exact, semver range, pinned digest);
- apply: rewrite the manifest and its lockfile to a version, as a change. Network access is through a registry mirror the site configures, never open. The bump, changelog, checks, pills and auto-land are Diffusion's own, the same for every ecosystem.
- B2. Cargo (we use it): git dependencies on repositories of this
hub and crates from a registry;
Cargo.lockupdated withcargo update -p; changelogs from the hub for hub repositories, from release notes otherwise. - B3. Docker (we use it):
FROMlines and Compose images, by tag and by digest, from registries the site lists and from the hub's own images; a bump pins a digest. - B4. Adapters from others. A declarative adapter (a KDL file: manifest patterns, a command for each of the four steps, the image to run them in) that a repository, an organisation or the site adds, so npm, pip, Go, Maven and the rest can be added by the people who use them. We ship npm and pip as worked examples, not as the only ones.
C. Security: OSV alerts
- C1. Advisories in, offline. The hub mirrors the OSV database (osv.dev's daily dumps for the ecosystems in use) on a schedule, so matching never sends a repository's dependencies to a third party. This matters for sovereign sites, which may also point the mirror at their own copy.
- C2. Matching. Each consumer's dependencies (from the pin index and the adapters' list) are matched against the advisories, at every push and when the mirror updates.
- C3. Alerts. A Security tab per repository and an organisation
view: advisory, severity, the affected dependency and path, the fixed
version. Owners are notified (
security.alert, "🚨 Security Alert"). - C4. Security bumps. A bump to the lowest fixed version, labelled
security, ignoring quiet hours and grouping, and offered for auto-land when the consumer allows it. - C5. Advisories out. An upstream on the hub can publish its own advisories (OSV JSON in the repository or from its Security tab); the hub serves them in OSV format, and every consumer on the hub is alerted at once through the pin index, including for Oxygen subrepos, which no public database covers.
D. Designed, not built
- D2. Partial pins and the culprit (diffusion.md §6): pin an upstream state minus one change and what is built on it, with no rewriting; find the change that broke a consumer by testing subsets. A job's path scope may order the search (changes inside the failing job's scope first) but never prunes it: a test can depend on code outside its scope.
- D3. Consumers test upstream proposals (§7): a check per consumer on the upstream proposal, run with the consumer's pin swapped for the proposal's projected state, committing nothing.
- D4. Repair (§8): migrations shipped with an upstream change, and an agent's fix as a separate change on the bump, under the landing rules of A5.
E. Reach
- E1. Follow releases and tags, with semver rules, not only bookmarks.
- E2. Grouping and quiet hours.
- E3. Chains: a landed bump moves a bookmark that others follow.
- E4. Across hubs (diffusion.md §5): polling first, signed notes to make it prompt, evidence of "green" checked by the consumer's hub.
- E5. Reusing a receipt instead of re-running a job, for jobs marked hermetic, when a signed receipt exists for the same pipeline, scope tree and environment. To be measured before it is promised.
Later
These need Cylinder (an artifact repository, an idea not yet started) or are research; none is promised:
- signed channels (
rstar-api:stable) whose moves are gated by consumer checks; - deployment leases that keep pinned states from being collected;
- requiring N independent runners to reproduce a result before a bump auto-lands.
4. Order
A1–A6, then B1–B3 with C1–C4 alongside (the adapters' list is what OSV matching needs), then D3, D2, B4, C5, D4, then E. A and C are what make Diffusion safe to rely on; B is what makes it useful beyond Oxygen subrepos; D is what makes it unique.
5. Compared honestly
| Renovate / Dependabot | Monorepo at head | Diffusion today | Diffusion with this roadmap | |
|---|---|---|---|---|
| Ecosystems | Very many | Not applicable | Oxygen subrepos only | Cargo, Docker, adapters for the rest |
| Security alerts | Yes (advisory databases) | Tooling of your own | No | OSV, mirrored offline, and advisories for hub repositories |
| Breakage found | After upstream ships | Before landing | After upstream lands, in the bump | Before upstream lands (D3), for consumers on the hub with tests |
| Partial updates | Revert in a fork, by hand | Not applicable | No | Yes, without rewriting (D2) |
| Rebasing bumps | Often | Not applicable | Never: one bump per path, moved in place | Same |
| Confidence | Adoption statistics from public data | Everything tested together | Pills per consumer | Results across every consumer (A3) |
| Provenance | Commit signatures where used | Usually unsigned | Signed bump, signed changes, signed receipts | Same, checked across hubs (E4) |
| Sovereignty | Hosted service or self-hosted bot | One central repository | Your hub, your runners | Plus an offline advisory mirror (C1) |
6. The earlier draft, corrected
The draft in oxygen/docs/diffusion_roadmap.md described several things
as if they existed. For the record:
- An agent key without
refsscope cannot sign references, but on the hub landing is decided by the token, so an agent token withrepo:writecould land. A5 fixes this. - Path scope cannot exclude upstream changes from a culprit search (D2).
- Receipt reuse,
reproduced(N), channels, leases andartifact(...)revsets do not exist (E5 and Later). flow-casfsis a FUSE mount; sub-second job starts are not measured.- Serial numbers are enforced for trust policies; cross-hub bookmark moves are not built (E4).
- Bumps can conflict: two moves of the same pin edit the same
.oxymodulesentry. They never need rebasing because each path has one bump, moved in place.