Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RFD 0013 — Toolchain distribution + oxup toolchain manager

  • State: accepted — partially implemented (Stage 0 deployed, Stage 4 merged)
  • Opened: 2026-06-01
  • Last revised: 2026-06-02
  • Decides: how Argon ships to engineer laptops (Mac arm64) + ODE sandbox AMIs (Linux arm64 + x86_64); whether to adopt a rustup-style toolchain manager; the AWS-hosted distribution architecture; the ~/.argon/ legacy-install cleanup story.
  • Status: Implemented — the v0.2 toolchain shipped; this RFD is the design record.

Question

v0.1.0 ships a single ox binary from a homemade install.sh against git clone. For Sharpe-internal v0.2, what’s the install + distribution + toolchain-management story?

Decision

Adopt the rustup-style architecture with an oxup manager binary + argv[0] dispatch, splitting the compiler into four logical tools (oxc / ox / ox-lsp / oxfmt), distributed via AWS S3 + CloudFront at argon.sharpe-dev.com (managed via Pulumi in the shared infra account 285688017134). The user-facing reference is the book Toolchain chapter; the dist mechanics live in infra/ + the release pipeline.

Sharpe-internal scope means: no LICENSE / no Marketplace publish / no public installer; private bucket via Cloudflare-proxied CloudFront; CI’s ArgonReleaseRole is narrow-scoped (S3 PutObject + CloudFront invalidate only). Okta-gated downloads deferred to v0.3 (separate RFD).

Account note: the distribution lives in AWS account 285688017134, which is the default SSO profile (~/.aws/config) — the shared infra account where the ODE/orca-mvp Pulumi stacks, the s3://sharpe-pulumi-state backend, and the *.sharpe-dev.com wildcard ACM cert already live. It is not the shared-admin profile (account 548277374575, which is empty). Maintainers authenticate with assume default / AWS_PROFILE=default.

Implementation status (2026-06-02)

  • Stage 0 deployed to account 285688017134: S3 argon-dist-sharpe + CloudFront E16VOSAVQFX5Y8 (argon.sharpe-dev.com, proxied) + ArgonReleaseRole (OIDC). Edge verified (HTTP 403 = healthy empty bucket).
  • Stage 4 merged (PR #6): release.yml publish-dist (OIDC → S3 → CloudFront) + nightly cron, wired via repo secret AWS_ROLE_ARGON_RELEASE + var ARGON_CLOUDFRONT_DIST_ID. Graduated to the §5 toolchain (Stages 1–3 having landed): builds all four binaries, assembles argon-<v>-<plat>.tar.gz via scripts/assemble-toolchain.sh, and publishes the [artifacts.*] channel-<channel>.toml via scripts/make-channel-manifest.sh — the schema oxup install consumes (round-trip tested in oxup/src/fetch.rs; the format is pinned by scripts/make-channel-manifest.sh). Fixed two latent contract bugs (bare-ox tarball; [platforms.*] vs [artifacts.*] manifest).
  • Stays in the mgmt account (285). A move to a workload account (prod/623) was investigated and rejected: the workload-account org SCP p-pif76ezm denies s3:PutBucketPolicy / PutBucketPublicAccessBlock to interactive SSO admins, so the CloudFront-OAC bucket policy can only be set by an SCP-exempt CI role. For an internal static CDN that’s not worth a full CI-driven deploy apparatus; 285 (where SSO admins can set bucket policies) is the right home for maintainer-operated tooling. Maintainer-local pulumi up runs from nix develop .#infra.
  • Adjacent: Argon-aware PR review bots (claude-review.yml + claude.yml, PR #7) landed alongside this work.
  • Remaining: Stages 1–3, 5–7 (binary split → share/std/oxupoxfmt → hosted install.sh → smoke) → tag v0.2.0.

Scope of infra/

This RFD authorizes the new top-level infra/ directory holding the Pulumi project (TypeScript + Bun, matches the ODE pattern at ontology-tooling/infra/) that creates the distribution stack:

  • argon-dist-sharpe S3 bucket (us-east-2, private, OAC-only read)
  • CloudFront distribution (PriceClass_100, TLS 1.2+, two cache policies)
  • Reuse of the existing *.sharpe-dev.com wildcard ACM cert (us-east-1)
  • Cloudflare CNAME argon.sharpe-dev.com → CloudFront (proxied / orange cloud)
  • ArgonReleaseRole IAM role with GitHub OIDC trust for sharpe-dev/argon tag pushes

Maintainers run pulumi up locally with the default profile (assume default). CI never touches the infra stack — only the ArgonReleaseRole it outputs.

Scope of oxup/

This RFD also authorizes the new top-level oxup/ directory (Stage 3) — a standalone Rust crate (its own Cargo.toml/Cargo.lock, not a member of compiler/’s workspace) so it stays cheap to build for bootstrap. It is a single binary with argv[0] dispatch:

  • Invoked as ox/oxc/ox-lsp/oxfmt (via symlinks), it resolves the active toolchain (§4) and execs the real tool from ~/.argon/toolchains/<spec>/bin/<tool>.
  • Invoked as oxup, it’s the manager CLI (init/install/update/default/list/which/uninstall/self-update).

Decomposition (decided during Stage 2/3): Stage 3 lands in two PRs.

  • 3a — network-free foundation: the crate, argv[0] dispatch, toolchain resolution (§4 precedence), the ~/.argon layout, and the local manager commands (which/list/default/uninstall). Its own CI job in check.yml.
  • 3b — the network layer: install/update/self-update + auto-fetch-on-miss from argon.sharpe-dev.com, plus the release.yml §5 tarball (bin/ + share/std + manifest.toml) the fetch consumes. 3b also drops the Stage 2 stdlib embed once the tarball ships share/std. Gated on the release pipeline producing real toolchains.

Three-platform build matrix (v0.2)

  • macos-arm64 — all Sharpe dev machines (Apple Silicon)
  • linux-aarch64 — ODE sandbox AMIs + arm Linux CI runners
  • linux-x86_64 — generic Linux + non-arm CI runners

Intel Mac (macos-x86_64) deferred; Windows deferred.

Build order (eight stages, ~8 focused days)

StageOutput
0infra/ Pulumi project + apply via assume default (account 285688017134)
1Compiler binary split (oxc/ox/ox-lsp/oxfmt bin targets in compiler/)
2Stdlib migration (include_str!share/std/)
3oxup crate (argv[0] dispatch + channel resolver + auto-fetch)
4Release pipeline (GitHub Actions → S3 → CloudFront invalidate)
5oxfmt opinionated formatter (parse → CST walk → normalized emit)
6Hosted install.sh at argon.sharpe-dev.com/install.sh
7Smoke + docs + clean-VM verification

Out of scope for this RFD

  • Okta-gated downloads (Google Workspace SSO) — v0.3 RFD
  • Package registry + lockfile — v0.3+ when external deps land
  • Apple Developer signing / notarization — internal binaries
  • Telemetry payloads — opt-out reserved in settings.toml; no payload sent

See

  • The book Toolchain chapter (spec/reference/src/toolchain.md) — the user-facing install/channel/version reference
  • /infra/README.md — operator’s guide for running pulumi up
  • /infra/index.ts — top-level Pulumi wiring
  • ontology-tooling/infra/ — the ODE pattern this design adapts