sx delivered most of the foundation since the plan was written: alias re-exports instead of pub, the modules/std.sx facade barrel, and native std fs/process/json/cli/hash/log/test/socket/mem. Replace the 'sx Foundation Work' section with as-built status + remaining gaps, mark Phase 0 done / Phase 1 partial, note the superseded subplan-01 slices, and drop the retired flow-harness execution contract (subplan 08, roles, checkpoint files).
11 KiB
Distribution Platform in sx
Goal
Build an App Store-like distribution platform in sx, but not limited to iOS
apps. It should distribute mobile, desktop, and server/client artifacts through
a CI-friendly release workflow.
Supported targets for the first product direction:
- iOS: IPA metadata, TestFlight links, Enterprise/MDM manifests, artifact-only downloads
- Android: APK first, AAB later
- macOS: app archives, dmg/pkg metadata, signing and notarization status
- Linux: tarballs first, then deb/rpm/AppImage metadata
- Windows: zip/installer first, then MSIX/signing metadata
The main commands are:
distd: the HTTP API, install page, and artifact serverdist: the CI/admin CLI
The release workflow must be easy to integrate into CI. A CI job should be able to upload artifacts, create a release, attach platform variants, promote a channel, and receive machine-readable JSON output.
Product code should live in sx. C or system APIs are acceptable only as thin
platform backends for capabilities that sx cannot express yet.
Product Shape
This is an operational distribution tool first, not a public marketplace. The initial product should feel like a release console: quiet, dense, fast to scan, and optimized for repeated internal/private release work.
Core principles:
- CI is the primary writer.
- Humans inspect, promote, revoke, download, and audit.
- Releases are immutable.
- Channels are mutable pointers to releases.
- Artifacts are content-addressed and never silently replaced.
- Every upload, publish, promotion, token change, and deletion writes an audit event.
- The first version should be understandable from the filesystem and SQLite database during development.
Users And Actors
- CI runner: publishes releases with
dist ci publish. - Release manager: promotes channels, checks validation, and reads audit logs.
- Developer/tester: downloads the current artifact for a platform/channel.
- Admin: creates apps, manages tokens, and configures identity constraints.
distd: server/API/artifact store.dist: CLI for CI and local admin work.
Core Concepts
App:
- Product being distributed.
- Owns identity rules, allowed platforms, releases, channels, and tokens.
Release:
- Immutable version/build record for one app.
- Contains one or more platform artifacts.
Artifact:
- Uploaded file for a platform.
- Stored by digest and linked to release metadata.
Channel:
- Mutable pointer such as stable, beta, internal, nightly.
- Promotion changes the pointer, not the release.
Token:
- Scoped credential for CI and automation.
- Stored hashed, expires or can be revoked.
Audit event:
- Immutable record of important actions.
Main Workflows
CI publish:
- CI builds artifacts.
- CI writes or updates
dist.json. - CI runs
dist ci publish --server "$DIST_SERVER" --token "$DIST_TOKEN" --manifest dist.json --json. distvalidates the manifest and streams artifact uploads.distdvalidates metadata and stores artifacts by digest.- The release is published.
- A requested channel is promoted if policy allows it.
- CI receives JSON with release ids, artifact ids, digests, and URLs.
Human release management:
- Release manager opens the admin UI.
- They inspect release status, artifact validation, and audit history.
- They promote, rollback, revoke tokens, or download artifacts.
Install/download:
- User opens an app/channel install page.
- Platform detection chooses the most relevant artifact or install path.
- The page shows accurate platform-specific actions and metadata.
- Access policy determines whether the user can download or install.
iOS Install Policy
iOS needs special handling. The platform must not imply that a normal iPhone can install an arbitrary IPA from a web page.
Supported iOS modes:
- TestFlight: store a TestFlight link and open Apple's install flow.
- Enterprise/MDM: serve a valid HTTPS manifest plist for enrolled devices.
- Artifact only: allow authenticated IPA download, without presenting it as a normal mobile install action.
This distinction must be visible in both the API model and admin/install UI.
Architecture Overview
The intended stack is:
sx language and std primitives
-> infra libraries: http, json, hashing, storage, db, auth, archive
-> distribution domain: app, artifact, release, channel, token, audit
-> interfaces: CLI, HTTP API, install pages, admin UI
-> deployment: Docker image, NAS-friendly config, persistent data volume
Storage direction:
- SQLite first.
- Local filesystem artifact storage first.
- Object storage adapter later.
Deployment direction:
- Docker/OCI image.
- One persistent
/datavolume for database, artifacts, uploads, config, and logs. - One HTTP port.
/healthzendpoint.- Runs behind a reverse proxy for TLS.
- Runs as a non-root user.
- UGREEN NAS deployment through Docker/Container Manager is a first-version requirement.
sx Foundation Status
Re-evaluated 2026-06-11 against the current sx tree. The original foundation
asks have largely landed, with one design difference: sx has no pub keyword.
Visibility is import-scoped; aliases are the re-export mechanism
(print :: core.print), and a module's namespace tail carries one level into
flat importers. modules/std.sx is the curated barrel this plan asked for.
Delivered in sx and used by this repo:
- Module system: alias imports, alias re-exports, namespace barrels, one-level carry, dir-vs-file ambiguity rejection.
- Error handling: the
!error channel withraise/catch/onfail(bindings take parens),?Toptionals. stdmodules undermodules/std/: core, fmt, list, mem (typed allocator helpers overalloc_bytes/dealloc_bytes), fs, process, socket (raw TCP), json, xml, cli, hash (streaming SHA-256), log (leveled, no timestamps yet), test (bare assert).
Still missing from sx — the forward wishlist; each item either blocks a later subplan or has an explicit local workaround:
- Collections:
HashMap(linear scan overListpairs meanwhile). - Strings: validated UTF-8
String,StringBuilder, explicit Unicode model (byte length, scalar values, grapheme clusters, and display width are distinct; invalid UTF-8 must not silently become aString). - Bytes and a full path module (only
path_join/basename/dirnametoday). - Time/clock (publish shims
time(2)via FFI), random, encodings (base64url, percent). - HTTP server/client and TLS boundary — blocks subplan 04 and remote publish (subplan 03 Slice 3).
- SQLite — blocks subplan 02 Slice 2 (
db.jsonstands in). - Archive inspection — blocks deep IPA/APK validation (subplan 05).
- Config layering (env/file/CLI) and richer testing helpers.
Implementation Phases
Phase 0 - sx language/module prerequisites (done, as-built):
- Delivered in sx via alias re-exports and namespace barrels; there is no
pubkeyword.
Phase 1 - standard library foundation (partial):
- Delivered: fs, process, json, cli, hash, log, test, socket, mem.
- Outstanding: HashMap, StringBuilder/Unicode model, time, random, encodings, HTTP/TLS, SQLite, archive (see "sx Foundation Status").
Phase 2 - product domain:
- Define apps, releases, artifacts, channels, tokens, policies, and audit events.
Phase 3 - storage:
- Add SQLite persistence and filesystem artifact storage.
Phase 4 - CLI first:
- Make
dist ci publish --manifest dist.json --jsonwork before the admin UI.
Phase 5 - HTTP API:
- Expose app, release, upload, download, channel, token, and audit endpoints.
Phase 6 - artifact validation:
- Validate APK and IPA first, then desktop artifact metadata.
Phase 7 - channels and install pages:
- Add promotion, rollback, download URLs, and platform-specific install pages.
Phase 8 - admin UI:
- Build a dense operational UI for apps, releases, artifacts, tokens, settings, install pages, and audit logs.
Phase 9 - packaging:
- Package
distdand the admin UI into a Docker image suitable for UGREEN NAS.
CI Contract
The primary CI command should be:
dist ci publish \
--server "$DIST_SERVER" \
--token "$DIST_TOKEN" \
--manifest dist.json \
--json
The command should:
- Validate the manifest.
- Create or find the app.
- Create a draft release.
- Upload all artifacts with streaming SHA-256.
- Validate platform metadata.
- Publish the release.
- Promote the requested channel if specified.
- Print JSON containing release id, artifact ids, digests, and download URLs.
First Milestone
Milestone 1 is complete when:
- Required
sxlanguage/std primitives exist or have explicit temporary boundaries. distdcan run locally.dist ci publishcan publish a release with at least APK and IPA artifacts.- Artifacts are stored by digest.
- SQLite stores apps, releases, artifacts, channels, tokens, and audit events.
- A channel can be promoted and rolled back.
- Install/download pages accurately handle iOS, Android, and desktop artifacts.
- The admin UI can inspect apps, releases, validations, tokens, and audit logs.
- A Docker image can run on a UGREEN NAS with a persistent data volume.
Milestone 1 — Flow Step ↔ Subplan Slice Mapping
The flow decomposes subplan 02 (.agents/subplans/02-domain-and-storage.md)
Slice 1 into two steps. This records that decomposition so each step's scope is
verifiable from the repo:
- P2.1 — domain structs + boundary validation. Delivers subplan-02 Core
Structs (App, Platform, Release, Artifact, Channel, AuditEvent) and the
boundary validation portion of Slice 1 — slug, version, channel name,
platform id, and required-field presence, each with a distinct typed error.
Per the PO ruling this includes
Release.published_atandArtifact.metadata. Code lives undersrc/domain/; the acceptance test istests/domain_validate.sx. - P2.3 — in-memory repository + persistence. Delivers the rest of Slice 1:
the in-memory repository (create/list/get/update, find-by-slug,
find-artifact-by-digest) plus
db.jsonpersistence. - Token is in neither P2.1 nor P2.3. Subplan 02 lists Token under Core Structs, but its delivery slice is Slice 5 — Token Security (generation, hashing at rest, scopes, expiration/revocation). It is out of the Slice-1 steps above.
Non-goals For Version 1
- Public marketplace payments.
- Reviews and ratings.
- Organization billing.
- Sophisticated staged rollout targeting.
- CDN integration.
- Full signing/notarization automation.
- Object storage.
- Postgres.
Detailed Execution
PLAN.md is the overview. Slice breakdowns live in .agents/subplans/
(01–07). The active milestone slice plan and step progress live in current/
(PLAN.md, CHECKPOINT-DISTRIBUTION.md).
The multi-agent flow harness that originally executed this plan is retired;
work proceeds directly in-session, branch-based, with make test green at
each step boundary.