Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Agent/developer operating rules for the **start-technologies monorepo root**. Th

See [ARCHITECTURE.md](ARCHITECTURE.md) for the layout and [CONTRIBUTING.md](CONTRIBUTING.md) for the build/test/format workflow.

**Keep these docs current.** Every scope carries `AGENTS.md` / `ARCHITECTURE.md` / `README.md`, most still with a `CONTRIBUTING.md` beside them (and `CLAUDE.md`, a one-line `@AGENTS.md` import). When a change alters structure, conventions, the build/test/release flow, or product context, update the matching doc(s) in the **same change** — never defer. These docs are **hierarchical**: each scope's docs cover only what is specific to it and must not repeat anything already stated at a higher scope (e.g. commit/PR conventions live only in this root `CONTRIBUTING.md`).
**Keep these docs current.** Every scope carries `AGENTS.md` / `ARCHITECTURE.md` / `README.md` (and `CLAUDE.md`, a one-line `@AGENTS.md` import). When a change alters structure, conventions, the build/test/release flow, or product context, update the matching doc(s) in the **same change** — never defer. These docs are **hierarchical**: each scope's docs cover only what is specific to it and must not repeat anything already stated at a higher scope (e.g. commit/PR conventions live only in this root `CONTRIBUTING.md`).

**Anything an agent must follow belongs _in_ `AGENTS.md`, not behind a link from it.** The `AGENTS.md` standard is plain Markdown with **no import syntax** — unlike `CLAUDE.md`, whose `@file` imports expand into context at launch. So a pointer in `AGENTS.md` ("see X for the release process") is just a suggestion that the agent spend a tool call, and agents routinely don't: that is exactly how start-sdk 2.0.4 and 2.0.5 shipped untagged. Inline the rule; link only to _reference_ material an agent can safely skip (`ARCHITECTURE.md`, a product book). `CLAUDE.md` stays a one-line `@AGENTS.md` import — Claude Code does not read `AGENTS.md` natively.

**So `CONTRIBUTING.md` is being folded into `AGENTS.md` — in every scope _but_ the root.** A sub-scope `CONTRIBUTING.md` earns nothing (GitHub gives it no special treatment) and costs an agent a hop, so its contents belong in that scope's `AGENTS.md`. `projects/start-sdk/` is migrated and has none; every other scope still has the split. When you next do substantial work in a scope that hasn't migrated, fold its `CONTRIBUTING.md` into its `AGENTS.md`, delete it, and repoint every inbound link in the same change — don't leave dangling cross-references, and don't migrate scopes you aren't otherwise touching. **The root [`CONTRIBUTING.md`](CONTRIBUTING.md) stays**: GitHub surfaces it (the contributing prompt on new issues/PRs, the community profile), so it remains the human-facing front door — the social layer, and a pointer _to_ `AGENTS.md` for the mechanics. That pointer runs one way; a human will follow a link, an agent won't.
**So `CONTRIBUTING.md` is being folded into `AGENTS.md` — in every scope _but_ the root.** A sub-scope `CONTRIBUTING.md` earns nothing (GitHub gives it no special treatment) and costs an agent a hop, so its contents belong in that scope's `AGENTS.md`. When you next do substantial work in a scope that hasn't migrated, fold its `CONTRIBUTING.md` into its `AGENTS.md`, delete it, and repoint every inbound link in the same change — don't leave dangling cross-references, and don't migrate scopes you aren't otherwise touching. **The root [`CONTRIBUTING.md`](CONTRIBUTING.md) stays**: GitHub surfaces it (the contributing prompt on new issues/PRs, the community profile), so it remains the human-facing front door — the social layer, and a pointer _to_ `AGENTS.md` for the mechanics. That pointer runs one way; a human will follow a link, an agent won't.

**A product's user docs and changelog ship with the code.** Any change that alters user-visible behavior **must** update that product's user-facing documentation book (its `docs/` directory — e.g. `projects/start-os/docs/`, `projects/start-tunnel/docs/`, `projects/start-sdk/docs/`) in the **same change**, and **must** add a `CHANGELOG.md` entry for that product (a version bump always pairs with its changelog). Don't land code and defer its docs or changelog to a follow-up. The conventions for authoring **any** of those books — mdBook versions, admonitions, tabs, `SUMMARY.md`, the shared `theme/` — live in [`projects/start-docs/AGENTS.md`](projects/start-docs/AGENTS.md) and its `CONTRIBUTING.md`. That project is a sibling, not an ancestor, so nothing loads it for you: read it before editing book pages anywhere in the repo.

Expand All @@ -30,7 +30,7 @@ Each product lives under `projects/` as a thin wrapper; the bulk of the code liv
- `projects/start-sdk/` — `@start9labs/start-sdk` (source in `lib/`; imports the shared `@start9labs/start-core` lib and bundles it into its published `dist/`) + `Makefile`/`s9pk.mk` + `docs/` (packaging mdbook).
- `projects/brochure-marketplace/` — public marketplace/landing Angular app (deploys to marketplace.start9.com).
- `projects/start-docs/` — the documentation website (build infra + landing + Bitcoin guides; each product's own book lives in its `docs/`).
- `shared-libs/crates/start-core/` — the **entire** Rust backend lib (package `start-core`, lib name `start_core`). All six bins depend on it. Internally unchanged from the old `core/` crate.
- `shared-libs/crates/start-core/` — the **entire** Rust backend lib (package `start-core`, lib name `start_core`). All six bins depend on it.
- `shared-libs/ts-modules/` — shared **TypeScript** modules (the common thread is just that they are TS — not Angular-specific). These are the Angular libs `shared/` (`@start9labs/shared`) and `marketplace/` (`@start9labs/marketplace`), plus the non-Angular `start-core/` (`@start9labs/start-core`: SDK core types/ABI/effects/OS bindings, the TS projection of the `start-core` crate, consumed by web and bundled into the SDK; versionless, not published separately). The Angular workspace is rooted at the repo root (`angular.json`/`package.json`). Product apps reference the libs by package name.
- Top level also holds the shared build infra (`build/`, `Makefile`), `apt/`, the shared `debian/build.sh`, `scripts/` (maintainer release tooling — `manage-release.sh <subcommand> <project>` drives a product through pre-check/tag/release/sign/publish; `deploy-migration-payload.sh` publishes a 0.3.5.1 → 0.4.0 migration OTA payload to a legacy registry), `rfcs/` (protocol drafts), and `shared-libs/crates/patch-db/` (first-party crate, consumed by `start-core` and web).

Expand All @@ -44,7 +44,7 @@ Each product lives under `projects/` as a thin wrapper; the bulk of the code liv
## Branches and channels

- **`master` is always shippable, and every push to it publishes.** Only merge work that is finished and tested: a master push indexes StartOS images into the alpha registry, publishes `.deb`s into the `alpha` apt suite, and — once the `STARTWRT_ALPHA_REGISTRY` repo variable is set — StartWRT images into its alpha registry. There is no staging step between merging and publishing. The SDK is the deliberate exception: an npm version can never be republished, so it publishes only on release.
- **Work that can't land piecemeal goes on `integration/<topic>`.** Land the pieces there as ordinary PRs, soak the branch as a unit, and delete it on merge. The PR merging it into master is the last gate before it ships, so CI builds the full flashable image matrix on that PR specifically — the bypass lives in `startos-iso.yaml`'s `changes` job and start-wrt's `image` job, both keyed on `head_ref` starting with `integration/` and `base_ref` being `master`. The old `next/patch` | `next/minor` | `next/major` branches are **retired**; don't add a workflow trigger for them.
- **Work that can't land piecemeal goes on `integration/<topic>`.** Land the pieces there as ordinary PRs, soak the branch as a unit, and delete it on merge. The PR merging it into master is the last gate before it ships, so CI builds the full flashable image matrix on that PR specifically — the bypass lives in `startos-iso.yaml`'s `changes` job and start-wrt's `image` job, both keyed on `head_ref` starting with `integration/` and `base_ref` being `master`.
- **Re-indexing a version into a registry requires removing it first.** `registry os asset add` upserts the platform slot but **rejects** a write whose blake3 differs from the commitment already there (`registry/os/asset/add.rs`, `registry.os.asset.commitment-mismatch`) — so publishing a second build under a version number that already holds one fails, even though `registry os version add` itself is a harmless upsert. Alpha rolls the same version on every master push, so both deploy jobs run `registry os version remove` first. Anything that re-publishes a version in place must do the same.
- **Alpha is the source a release is promoted from, so a master push must build release-equivalent artifacts.** `os promote` copies each asset's URL and signed commitment through verbatim (`registry/os/promote.rs`), so the bytes a master push uploads are the bytes production eventually serves — from the same S3 key. Two consequences: `ENVIRONMENT` is empty on master (only PRs and `integration/*` default to `dev`), and alpha images must **not** be given a separate S3 prefix, or promoted production assets would point inside it. It also means an S3 key, once published, is immutable: both deploy jobs refuse to overwrite an object that already exists and fail listing every conflict, since replacing those bytes would leave an already-promoted signature validating against content that no longer matches. Re-running a deploy for a commit that was published before therefore needs a dispatch with `force-overwrite`.

Expand Down Expand Up @@ -156,4 +156,4 @@ Already enforced or checked elsewhere (listed here for completeness; documented
- [`projects/brochure-marketplace/AGENTS.md`](projects/brochure-marketplace/AGENTS.md) — public marketplace site
- [`projects/start-docs/AGENTS.md`](projects/start-docs/AGENTS.md) — documentation website; also the authoring conventions for every product book
- [`shared-libs/AGENTS.md`](shared-libs/AGENTS.md) — shared libs container: [`crates/start-core`](shared-libs/crates/start-core/AGENTS.md) (Rust backend), [`web`](shared-libs/ts-modules/AGENTS.md) (Angular workspace + UI/setup-wizard/shared libs)
- `shared-libs/crates/patch-db/` — first-party crate (maintained in-tree; the standalone `Start9Labs/patch-db` repo is being retired)
- `shared-libs/crates/patch-db/` — first-party crate (maintained in-tree)
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ start-technologies/ # repo root (monorepo)
│ ├── src/bin/{startbox,start-container}.rs
│ ├── web/ # Angular UI + setup-wizard
│ ├── container-runtime/ # Node LXC service runtime
│ ├── debian/ apt/ assets/ build/
│ ├── debian/ assets/ build/
│ ├── *.service services.slice
│ └── Cargo.toml # → depends on start-core
├── projects/start-cli/ # start-cli bin (src/main.rs)
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This guide is for contributing to the Start9 monorepo (StartOS and the other products that live here). If you are interested in packaging a service for StartOS, visit the [packaging guide](https://docs.start9.com/packaging). If you are interested in promoting, providing technical support, creating tutorials, or helping in other ways, please visit the [Start9 website](https://start9.com/contribute).

This file covers what is **common to the whole monorepo** — the shared toolchain, branch policy, the cross-cutting test/format entry points, and code/commit conventions. **Per-product system dependencies, build targets, deploy steps, and release procedure live in that product's own scope** — its `AGENTS.md` (e.g. [`projects/start-sdk/AGENTS.md`](projects/start-sdk/AGENTS.md)), or its `CONTRIBUTING.md` in scopes not yet migrated (e.g. [`projects/start-os/CONTRIBUTING.md`](projects/start-os/CONTRIBUTING.md) for building the StartOS OS image). See [`AGENTS.md`](AGENTS.md) for that migration and the reasoning behind it.
This file covers what is **common to the whole monorepo** — the shared toolchain, branch policy, the cross-cutting test/format entry points, and code/commit conventions. **Per-product system dependencies, build targets, deploy steps, and release procedure live in that product's own scope** — its `AGENTS.md` (e.g. [`projects/start-sdk/AGENTS.md`](projects/start-sdk/AGENTS.md)), or its `CONTRIBUTING.md` in scopes not yet migrated (e.g. [`projects/start-os/CONTRIBUTING.md`](projects/start-os/CONTRIBUTING.md) for building the StartOS OS image).

## Documentation

Expand All @@ -13,7 +13,7 @@ The repo root's docs split across four files:
- `CONTRIBUTING.md` — this file; how to contribute
- `AGENTS.md` — AI-developer/agent operating rules (`CLAUDE.md` is a one-line `@AGENTS.md` import)

**These docs must be kept up to date.** When you change project structure, conventions, build process, or product context, update the relevant file(s) in the same change — do not defer. Each product and shared library keeps its own `README.md`/`ARCHITECTURE.md`/`AGENTS.md` for what is specific to it (most still carry a `CONTRIBUTING.md` too, which is being folded into that scope's `AGENTS.md` — see [`AGENTS.md`](AGENTS.md)) — see `projects/*/`, `shared-libs/crates/start-core/`, `shared-libs/ts-modules/`, and `projects/start-os/container-runtime/`.
**These docs must be kept up to date.** When you change project structure, conventions, build process, or product context, update the relevant file(s) in the same change — do not defer. Each product and shared library keeps its own `README.md`/`ARCHITECTURE.md`/`AGENTS.md` for what is specific to it — see `projects/*/`, `shared-libs/crates/start-core/`, `shared-libs/ts-modules/`, and `projects/start-os/container-runtime/`.

### The user-facing books, and `live-docs`

Expand Down
6 changes: 1 addition & 5 deletions projects/start-cli/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,8 @@ generator is `cargo test -p start-core export_manpage_start_cli`.
falsey → `PREFER_DOCKER` is set (Docker). Truthy (`1/true/y/yes`) → Podman.
- **In a StartOS image `start-cli` is a symlink to `startbox`** (see OS `Makefile`), the same
`MultiExecutable` multiplexer. The standalone bin here enables only the `start-cli` sub-bin.
- **Stale paths:** older docs referenced `core/`, `web/`, `sdk/`, `patch-db/` at the repo root.
They now live at `shared-libs/crates/start-core`, `shared-libs/ts-modules` + product `web/`, `projects/start-sdk/`,
`shared-libs/crates/patch-db`. Use the new paths.

## Verifying a command

Build the bin, then run it against a StartOS test VM (see root docs for `helix-vm` /
`start-cli` host flow). Remote commands need `-H https://<ip>` and an `auth login`; local
Build the bin, then run it against a StartOS test VM. Remote commands need `-H https://<ip>` and an `auth login`; local
commands (`s9pk`, `init-key`, `pubkey`, `util`) need no server.
4 changes: 2 additions & 2 deletions projects/start-docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This is the `projects/start-docs/` project in the `start-os` monorepo. It owns t

The site is composed of independent mdBook instances — one per product. Each book has its own `book.toml`, `src/SUMMARY.md`, and content tree. Books build into subdirectories of `docs/` (the build output, gitignored) and are deployed together under a shared domain.

Since this is now part of the `start-os` monorepo, the per-product books live **next to the code they document**, not inside this directory. This `docs/` project owns only the build infra, the shared theme, the landing page, and the Bitcoin Guides book.
The per-product books live **next to the code they document**, not inside this directory. This `docs/` project owns only the build infra, the shared theme, the landing page, and the Bitcoin Guides book.

```
start-os/ (monorepo root)
Expand Down Expand Up @@ -51,7 +51,7 @@ book_dir() {
}
```

So `packaging` is served from `projects/start-sdk/docs`, and any book not explicitly mapped (currently just `bitcoin-guides`) is expected to live directly under this project (`projects/start-docs/`). To move or add a book, edit `book_dir()` and `versions.conf`.
So `packaging` is served from `projects/start-sdk/docs`, and any book not explicitly mapped is expected to live directly under this project (`projects/start-docs/`). To move or add a book, edit `book_dir()` and `versions.conf`.

## Shared Theme

Expand Down
2 changes: 1 addition & 1 deletion projects/start-docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Linux instructions here.
- Anything that isn't a general OS picker (backup targets, cloud providers, …) gets its own `global` — don't overload `platform`.
- Omit `global` for a one-off, page-local group.

Keep the outer picker flat: the only sanctioned nesting is a single distro/version sub-group (with its own `global`) inside one platform tab. Don't nest `platform` inside `platform`, or nest more than one level deep.
Keep the outer picker flat: the only sanctioned nesting is a single distro/version sub-group (with its own `global`) inside one platform tab.

### Cross-Book Links

Expand Down
8 changes: 3 additions & 5 deletions projects/start-os/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ Two Angular 22 apps live under `web/`:
They are part of the single Angular workspace rooted at `../../` (the repository root)
(the root `angular.json` points each project's `root` at `projects/start-os/web/...`).
They consume the shared `@start9labs/shared` and `@start9labs/marketplace` libs
from the shared TypeScript modules at `../../shared-libs/ts-modules` and the SDK
base from `../start-sdk`. The frontend talks to
from the shared TypeScript modules at `../../shared-libs/ts-modules`. The frontend talks to
the backend exclusively over JSON-RPC, with reactive state via Patch-DB.

`web/patchdb-ui-seed.json` / `patchdb-ui-seed.beta.json` seed initial UI state
Expand All @@ -70,8 +69,7 @@ and [AGENTS](container-runtime/AGENTS.md) — read those before editing it.
`backup-fs/` is the `startos-backup-fs` crate (a workspace member): an encrypted,
erasure-coded FUSE filesystem used for StartOS backups. It builds to the
`startos-backup-fs` binary (installed as `/usr/bin/startos-backup-fs` and
`mount.backup-fs`). It was migrated into the monorepo from the former
`Start9Labs/start-fs` repo and is no longer an external git dependency.
`mount.backup-fs`).

## Systemd units and cgroups

Expand Down Expand Up @@ -137,5 +135,5 @@ resolving, so the UI is always eventually consistent with the backend.
## Further reading

- [../../shared-libs/crates/start-core](../../shared-libs/crates/start-core) — Rust backend
- [../../shared-libs/ts-modules](../../shared-libs/ts-modules) — shared TypeScript modules + workspace (currently the Angular libs `shared` and `marketplace`)
- [../../shared-libs/ts-modules](../../shared-libs/ts-modules) — shared TypeScript modules + workspace
- [container-runtime/ARCHITECTURE.md](container-runtime/ARCHITECTURE.md) — runtime
Loading