Skip to content

docs: whether a driver belongs in the URL, and where each layer gets its name - #243

Merged
retr0h merged 1 commit into
mainfrom
docs/driver-naming-rule
Oct 1, 2026
Merged

retr0h merged 1 commit into
mainfrom
docs/driver-naming-rule

Conversation

@retr0h

@retr0h retr0h commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Two sections in domains.md. No code changes.

Four domains run a tool underneath. Two name it in the URL and two do not, and nothing said which was right, so the provider tree, the API directories and the agent processors each answered it differently.

The question is who chooses the tool

The caller chooses a container runtime. Running Docker rather than Podman is a decision somebody made and wants to address directly, so it is a path segment: /container/docker. Podman becomes /container/podman beside it, and both can exist on one host.

The caller does not choose a package manager. The host already decided. Asking a fleet to install a package cannot mean knowing which of them run apt, so the tool is absent: /package. /ntp and /schedule are the same shape, with chrony and cron behind the entrypoint and room to swap them.

Backwards in either direction costs something real: a tool in the URL the caller did not choose makes a fleet-wide call impossible, and a tool missing from the URL the caller did choose makes two runtimes on one host unaddressable.

Each layer takes its name from the URL

Layer From /container/docker /network/dns
API handler directory first segment api/node/container/ api/node/network/
API handler files second segment docker_create.go dns_get.go
agent processor first segment processor_container.go processor_network.go
SDK service last segment client/docker.go client/dns.go
CLI command the path node container docker node network dns

The API layer is flat. network already follows this exactly. The container handlers do not: the directory is node/docker and the files are container_*.go, which has it inverted on both counts.

The provider tree is the deliberate exception. It nests by implementation so a second driver is a new directory rather than a scattering of files, which is why it may be deeper than the URL: provider/network/netplan/dns serves /network/dns.

What this says is currently wrong

api/node/docker/        ->  api/node/container/
  container_*.go        ->    docker_*.go           (prefix inverted)
processor_docker.go     ->  processor_container.go
/schedule/cron          ->  /schedule               (cron is not a caller's choice)
client/cron.go          ->  client/schedule.go
provider/scheduled/     ->  provider/schedule/      (a tense, not a name)

container/docker, node/apt, node/ntp and network/netplan/* are all correct as they stand.

Rule first, code second. just test passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

…its name

Four domains run some tool underneath. Two name it in the URL and two do
not, and nothing said which was right, so the provider tree, the API
directories and the agent processors each answered it differently.

The question is whether the caller chooses the tool or the host does. A
caller chooses a container runtime, so /container/docker names it and
Podman can sit beside it. A caller does not choose a package manager, so
/package hides apt, because a fleet-wide install cannot require knowing
which hosts run Debian. /ntp and /schedule follow the second shape: chrony
and cron are behind the entrypoint, swappable without the caller caring.

The second section records where each layer takes its name from, which is
always the URL. The API layer is flat, one directory per first segment with
the second segment as a filename prefix, which is what network already does
and what the container handlers do not.

The provider tree is the deliberate exception. It nests by implementation so
a second driver is a new directory rather than scattered files, and it is
therefore allowed to be deeper than the URL.

Refs osapi-io/osapi#566

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Thank you for contributing to this project! 😊🕹️

@retr0h
retr0h merged commit dd6e89a into main Oct 1, 2026
5 checks passed
@retr0h
retr0h deleted the docs/driver-naming-rule branch October 1, 2026 19:48
retr0h added a commit to osapi-io/osapi that referenced this pull request Oct 1, 2026
* refactor: names follow the URL they serve

Applies the rule in osapi-io/specs#243. Five moves, no change to the
provider tree's nesting.

cron is not a caller's choice the way a container runtime is, so it leaves
the URL. /schedule/cron becomes /schedule, the permission scopes become
schedule:read and schedule:write, and the SDK service is Schedule. The
provider keeps its driver directory at provider/schedule/cron, because that
is where a second driver would go.

The container handlers had the convention inverted: the directory was named
for the second URL segment and the files for the first. The directory is now
container and the files are docker_*.go, which is what network already does
with dns_get.go and route_get.go. The agent processor follows.

mem becomes memory. An abbreviation is not a name, and the URL, the SDK and
the generated types all said memory already.

What deliberately did not change: /container/docker keeps its driver in the
URL, provider/container/docker and provider/network/netplan/* keep their
nesting, and node/apt and node/ntp keep hiding their drivers.

Refs #566

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

* refactor(ui): regenerate the client and follow the schedule name

The spec change renamed the schedule operations and schemas, so the
generated UI client had to be regenerated. orval writes new files but does
not delete the ones it no longer produces, which left the old
schedule-management-api-cron-operations module and twenty cron*.ts schemas
beside the new ones. Both sets exported the same shapes and the build broke
on the stale half.

The three hand-written components follow: cron-picker, cron-block and
cron-delete-block are named for the resource rather than the driver, like
every other component in that directory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

* style: wrap a line golines flags after the memory rename

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

* fix: finish the memory and schedule renames in test files

Three classes of reference the sweeps missed, all caught by go vet rather
than by go test.

The memory package's own _test.go files are package memory_test and refer
to the package under test by its import name. The import path was rewritten
and the references were not, because the sweep skipped files inside the
package's own directory to avoid touching gopsutil's mem.

The SDK's Client field is Schedule now, and two tests plus one example still
read c.Cron.

go test had been reporting these packages as cached passes from before the
rename, which is why they looked green locally while CI failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant