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
37 changes: 32 additions & 5 deletions docs/adr/0039-a-grid-can-be-keyed-on-an-os.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,32 @@ Written down because the gate looks like an access control and is not one: it st

## D-c — The taxonomy is closed, and `other` never becomes a grid

Exactly four tokens: `macos`, `windows`, `linux`, `omarchy`. An unrecognised Linux resolves to
`linux`; anything else resolves to **nothing**, and no grid is provisioned.
Exactly three tokens: `macos`, `linux`, `omarchy`. An unrecognised Linux resolves to `linux`;
anything else — **Windows included** — resolves to **nothing**, and no grid is provisioned.

**AMENDED 2026-09-03: `windows` is REMOVED. Windows is not an OS grid this product serves.** It was
in the original taxonomy and shipped in `v0.3.29`; the decision is to drop it, not to defer it.

⚠️ **This is the one token the set has ever LOST rather than never had, and that asymmetry is the
whole risk.** Every other absence in this ADR is an absence nobody has to remember — `other`,
FreeBSD, a frozen build naming no system. `windows` is different: `platform.system()` obviously knows
about it, `host.platform_kind()` still carries it (a build target is not a community), and every map
in this feature looks incomplete without it. So the removal is written down in three places that a
person editing the map will actually read — `os_grid._BY_SYSTEM`, `os_networks
.DEFAULT_SERVED_OS_TOKENS` and `_OS_LABELS` — and pinned by a test that asserts the ABSENCE, because
no matrix can fail for a row that is simply no longer there.

⚠️ **Removing the token does NOT stop an existing Windows grid serving.** The served list governs
CREATION only; admission is `store.os_gate_for`, which compares a request's claim against the row's
own `access_os` and never consults it. So a CLI old enough to still claim `windows` — `v0.3.29` and
anything before this change — keeps being admitted to a `windows` grid that is still `active`.
Retiring the OS therefore has an operational half that the code cannot do: **take the existing
Windows grids out of service**, which is exactly what D-c's neighbour `os_grids_enabled` already says
("to stop serving one OS in particular, drop its token … *and stop the grid*").

A Windows machine now takes the branch a BSD takes: no token, no `os=` on the wire, and D-k's
`unsupported_system` sentence naming the set it is outside of — which is more actionable than
`not_served`, since the latter invites waiting for a deployment that is never coming.

The closed set is forced by D-d: auto-provisioning on an open value space means every unrecognised
string becomes a permanent empty grid. `shared/system/host.platform_kind()` already carries an `other`
Expand Down Expand Up @@ -615,7 +639,9 @@ asked for their own `GET /grid/overview`: 11 nodes answered, and one is named
`MacBooks-MacBook-Pro-7.local` verbatim. ⚠️ **Not a prevalence estimate** — no `os-community` grid
exists in prod yet, so none of those 11 is the population at issue, and 10 of them are hand-named.

**The other three tokens of D-c's taxonomy, read the same day.** ⚠️ These are **source reads of the
**The other tokens of D-c's taxonomy, read the same day.** (Taken while `windows` was still one of
them; it has since been removed from the taxonomy, and its bullet is kept as the record of what was
and was not measured.) ⚠️ These are **source reads of the
installers**, not measurements on installed machines, and are held to that lower standard — they
bound this decision's reach, they are not what it rests on.

Expand All @@ -627,11 +653,12 @@ bound this decision's reach, they are not what it rests on.
grid for. `basecamp/omarchy` contains **zero** hostname references — `boot.sh` layers onto an
existing Arch install — so the name comes from `archinstall`, whose default is the constant
`hostname: str = 'archlinux'`.
- **`windows` is unmeasured**, and was never in issue 15's scope.
- **`windows` was unmeasured**, and was never in issue 15's scope. It is no longer a token at all
(D-c, amended 2026-09-03), so the gap it left is now moot.
- **The fleet as deployed carries no person's name**: the dev VM is `grid-dev` from cloud-init, and
every Linux node in the prod sweep is provisioner-named.

So the residue is a **desktop-consumer** phenomenon and, among the four tokens, confirmed on `macos`
So the residue is a **desktop-consumer** phenomenon and, among the tokens then in the set, confirmed on `macos`
and indicated on `linux`. None of that changes the decision — a residue observed on a live row is not
overturned by the count of platforms sharing it — but it does say who D-n protects.

Expand Down
22 changes: 15 additions & 7 deletions shared/system/os_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
⚠️ **This is not `host.platform_kind()`, and the two must not be merged.** That one answers *"which
binaries run here"* and splits macOS by CPU generation (``macos-arm64`` / ``macos-x86_64``); reusing it
would put Apple Silicon and Intel Mac users in two different communities. Two questions, two
vocabularies, even where today's values overlap (ADR 0039 D-c).
vocabularies, even where today's values overlap (ADR 0039 D-c). ``platform_kind()`` still carries
``windows``; **this module deliberately does not**, and that divergence is the clearest illustration of
why they are two vocabularies rather than one — *which binaries run here* and *which community does
this person join* are different questions, and dropping a community does not drop a build target.

⚠️ **The taxonomy is CLOSED, and that is what makes auto-provisioning safe.** An unrecognised system
resolves to ``None`` and no grid is provisioned for it; on an open value space every unrecognised
Expand Down Expand Up @@ -51,18 +54,23 @@
from pathlib import Path

OS_MACOS = "macos"
OS_WINDOWS = "windows"
OS_LINUX = "linux"
OS_OMARCHY = "omarchy"

#: Every token this CLI can emit. Closed by decision (ADR 0039 D-c) — see the module docstring.
OS_TOKENS: tuple[str, ...] = (OS_MACOS, OS_WINDOWS, OS_LINUX, OS_OMARCHY)

# `platform.system()` → OS token. Only the systems that HAVE a grid appear; everything else — a BSD, a
# Java runtime, the empty string a frozen build can report — is absent and resolves to None.
OS_TOKENS: tuple[str, ...] = (OS_MACOS, OS_LINUX, OS_OMARCHY)

# `platform.system()` → OS token. Only the systems that HAVE a grid appear; everything else — Windows,
# a BSD, a Java runtime, the empty string a frozen build can report — is absent and resolves to None.
#
# ⚠️ **Windows is absent BY DECISION, not by oversight** (ADR 0039 D-c, amended). It is the one system
# in this map's history that was removed rather than never added, so it is the one an editor is most
# likely to "restore" on the grounds that `platform.system()` obviously knows about it. A Windows
# machine takes exactly the branch a BSD takes: no token, no `os=` on the wire, and the sentence that
# names the set it is outside of — which is a different and more actionable answer than being told a
# control plane is not serving its grid today.
_BY_SYSTEM = {
"Darwin": OS_MACOS,
"Windows": OS_WINDOWS,
"Linux": OS_LINUX,
}

Expand Down
84 changes: 67 additions & 17 deletions tests/test_local_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11745,7 +11745,7 @@ def handler(request):

@pytest.mark.parametrize(
"system,expected",
[("Darwin", "macos"), ("Linux", "linux"), ("Windows", "windows")])
[("Darwin", "macos"), ("Linux", "linux")])
def test_fetch_tokens_sends_the_os_token_of_the_machine_it_runs_on(
monkeypatch, tmp_path, system, expected
):
Expand All @@ -11755,7 +11755,7 @@ def test_fetch_tokens_sends_the_os_token_of_the_machine_it_runs_on(
assert params["device_id"] == "dev-1" # the OS rides ALONGSIDE the device id, never instead of it


@pytest.mark.parametrize("system", ["FreeBSD", "Java", ""])
@pytest.mark.parametrize("system", ["Windows", "FreeBSD", "Java", ""])
def test_fetch_tokens_sends_no_os_parameter_when_the_system_resolves_to_nothing(
monkeypatch, tmp_path, system
):
Expand Down Expand Up @@ -11865,20 +11865,23 @@ def test_the_id_is_read_the_way_os_release_is_actually_written(monkeypatch, tmp_
assert params["os"] == "omarchy", label


@pytest.mark.parametrize("system,expected", [("Darwin", "macos"), ("Windows", "windows")])
@pytest.mark.parametrize("system,expected", [("Darwin", "macos"), ("Windows", None)])
def test_a_machine_that_is_not_linux_never_consults_os_release(
monkeypatch, tmp_path, system, expected
):
"""A Mac with a stray `/etc/os-release` is still a Mac.
"""A Mac with a stray `/etc/os-release` is still a Mac — and a Windows box is still outside the set.

The distro read hangs off the `linux` answer and nothing else. Written down because the file is
not Linux's alone — a container image, a Homebrew package or a hand-rolled script can leave one
on macOS — and a lookup done before the system is known would move that machine's grid.
not Linux's alone — a container image, a Homebrew package, WSL or a hand-rolled script can leave
one on either system — and a lookup done before the system is known would move that machine's
grid, or invent one for a machine this CLI serves no grid to at all.

``expected`` is ``None`` for the system with no token: the parameter is ABSENT, not empty.
"""
monkeypatch.setenv("GRID_HOME", str(tmp_path))
params = _fetch_tokens_query(
monkeypatch, tmp_path, system, os_release=_OMARCHY_OS_RELEASE)
assert params["os"] == expected
assert params.get("os") == expected


@pytest.mark.parametrize(
Expand Down Expand Up @@ -11929,6 +11932,36 @@ def test_a_gigantic_os_release_is_not_read_into_memory(monkeypatch, tmp_path):
assert os_grid.os_token() == "linux"


def test_windows_is_not_a_system_this_cli_has_a_grid_for(monkeypatch, tmp_path):
"""Windows is deliberately OUTSIDE the closed set — the OS grids are macOS, Linux and Omarchy.

⚠️ **A Windows machine is not a machine with a broken claim; it is a machine with no OS grid**,
and it takes the same branch a BSD does. The distinction matters because it decides which sentence
the person reads: `UNSUPPORTED_SYSTEM` names the set they are outside of, which is actionable,
while `NOT_SERVED` would tell them to wait for a deployment that is never coming.

⚠️ It is also the one entry in this file that removes a system rather than adding one, so the pin
is on the ABSENCE. Re-adding `windows` to `_BY_SYSTEM` would leave every other test in this file
green — the matrices simply would not exercise it — which is why this asserts on the token and on
the wire rather than trusting a parametrize to notice.
"""
from cli import os_grid_notice
from shared.system import os_grid

assert "windows" not in os_grid.OS_TOKENS
assert not hasattr(os_grid, "OS_WINDOWS")

params = _fetch_tokens_query(monkeypatch, tmp_path, "Windows")
assert "os" not in params, "a Windows machine must claim nothing at all, not an unserved token"

absent = _absence(monkeypatch, "Windows", None, tmp_path)
assert absent is not None
assert absent.reason == os_grid_notice.UNSUPPORTED_SYSTEM
assert absent.os_token is None
# The sentence names the machine's own system and the set it is outside of.
assert "Windows" in absent.line() and "windows" not in absent.line().split(":", 1)[1]


def test_omarchy_is_one_of_the_tokens_this_cli_can_emit():
"""The closed set grew, and three things read it rather than writing the members out again.

Expand Down Expand Up @@ -21204,13 +21237,19 @@ def test_sync_json_survives_empty_list_warning(monkeypatch, tmp_path, capsys):
# sign-in is a line people learn to scroll past.


def _absence(monkeypatch, system, os_served):
"""The notice a machine running ``system`` produces for that ``os_served`` answer."""
def _absence(monkeypatch, system, os_served, tmp_path=None):
"""The notice a machine running ``system`` produces for that ``os_served`` answer.

``/etc/os-release`` is pointed at a path that does not exist unless a caller supplies one, so a
``Linux`` case here means *an ordinary Linux machine* rather than *whatever this developer runs*.
"""
import platform

from cli import os_grid_notice
from shared.system import os_grid

monkeypatch.setattr(platform, "system", lambda: system)
monkeypatch.setattr(os_grid, "_OS_RELEASE", (tmp_path or Path("/nonexistent")) / "none")
return os_grid_notice.absence(os_served)


Expand Down Expand Up @@ -21242,7 +21281,7 @@ def test_a_control_plane_that_serves_no_grid_for_this_os_is_a_different_answer(m
assert (absent.system, absent.os_token) == ("Darwin", "macos")


@pytest.mark.parametrize("system", ["Darwin", "Linux", "Windows"])
@pytest.mark.parametrize("system", ["Darwin", "Linux"])
def test_a_deployment_serving_no_os_grid_at_all_still_says_so(monkeypatch, system):
"""The state a reviewer will read as a bug, pinned as the decision it is (ADR 0039 D-k).

Expand Down Expand Up @@ -21321,7 +21360,7 @@ def test_nothing_is_said_when_the_machine_has_a_token_and_no_refusal(monkeypatch
assert _absence(monkeypatch, "Darwin", os_served) is None


@pytest.mark.parametrize("system", ["Linux", "Windows", "Darwin"])
@pytest.mark.parametrize("system", ["Linux", "Darwin"])
def test_every_system_the_cli_has_a_token_for_stays_quiet_when_served(monkeypatch, system):
assert _absence(monkeypatch, system, True) is None

Expand Down Expand Up @@ -39980,14 +40019,25 @@ def test_a_root_the_operator_NAMED_is_not_judged_by_the_defaults_rules(
assert not (tmp_path / "never-made").exists(), "the default root was made despite a named one"


def _refresh_body(monkeypatch, system):
"""The JSON body `refresh_network_token` builds on a machine whose ``platform.system()`` is that."""
def _refresh_body(monkeypatch, tmp_path, system, os_release=None):
"""The JSON body `refresh_network_token` builds on a machine whose ``platform.system()`` is that.

``/etc/os-release`` is stubbed here for the same reason `_fetch_tokens_query` stubs it: since
`omarchy` landed, a Linux machine's token is read off that file, and leaving the real one in place
would make a `("Linux", "linux")` case a statement about the host running the suite rather than
about the code.
"""
import json as _json
import platform

from remote import control_plane
from shared.system import os_grid

monkeypatch.setattr(platform, "system", lambda: system)
os_release_path = tmp_path / "os-release"
if os_release is not None:
os_release_path.write_text(os_release, encoding="utf-8")
monkeypatch.setattr(os_grid, "_OS_RELEASE", os_release_path)
seen = {}

def handler(request):
Expand All @@ -40001,7 +40051,7 @@ def handler(request):

@pytest.mark.parametrize(
"system,expected",
[("Darwin", "macos"), ("Linux", "linux"), ("Windows", "windows")])
[("Darwin", "macos"), ("Linux", "linux")])
def test_the_refresh_exchange_carries_the_os_token_too(monkeypatch, tmp_path, system, expected):
"""ADR 0039 D-e, issue 10 — the claim rides the RENEWAL, not only the first fetch.

Expand All @@ -40015,12 +40065,12 @@ def test_the_refresh_exchange_carries_the_os_token_too(monkeypatch, tmp_path, sy
refresh credential already travels in the body, so the claim goes with it.
"""
monkeypatch.setenv("GRID_HOME", str(tmp_path))
body = _refresh_body(monkeypatch, system)
body = _refresh_body(monkeypatch, tmp_path, system)
assert body["os"] == expected
assert body["refresh_token"] == "rt-1" # the claim rides ALONGSIDE the credential, never instead


@pytest.mark.parametrize("system", ["FreeBSD", "Java", ""])
@pytest.mark.parametrize("system", ["Windows", "FreeBSD", "Java", ""])
def test_the_refresh_exchange_omits_the_os_key_when_there_is_no_token(monkeypatch, tmp_path, system):
"""Omitted entirely, never an empty string — the same discipline as the fetch, for the same reason.

Expand All @@ -40029,7 +40079,7 @@ def test_the_refresh_exchange_omits_the_os_key_when_there_is_no_token(monkeypatc
every OTHER grid it belongs to: this call is not about OS grids, it merely also serves them.
"""
monkeypatch.setenv("GRID_HOME", str(tmp_path))
body = _refresh_body(monkeypatch, system)
body = _refresh_body(monkeypatch, tmp_path, system)
assert "os" not in body
assert body["refresh_token"] == "rt-1"

Expand Down
Loading