carlos / platform Public

instances create should imply enable, and default -host: enable's admission-control purpose is recorded as gone Feature Request open

Migrated from github.com/carlosframework/platform issue #96, opened 2026-08-07. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".

Still outstanding: instances create should imply enable and default -host to the app's platform domain.

---

Summary

Getting one app serving takes three separate create-shaped verbs — carlos apps create, carlos instances enable, carlos instances create — and for a member in signed-in mode, the middle one no longer decides anything. Its stated purpose is recorded in the spec as having been removed.

Proposal: instances create should imply enable when no manifest exists and no operator-only flags are given, and create should default its -host to the app's platform domain. The verbs stay for the cases that need them; the common path stops requiring all three.

enable's original justification is documented as gone

§3.1 introduces the manifest as "the app's opt-in and policy", written by the operator in direct/store mode. Issue #66's addendum (§12a) then opened a member-facing door, and records the consequence in its own "Recorded, not built" list:

> no per-app/per-account cap on records beyond the rate limiter (the > operator opt-in used to be the admission control — a ceiling wants its > own ruling)

So the gate enable represented has already been dissolved for members. What remains in signed-in mode, per §12a and instances_cli.go:

| Field | Signed-in mode | |---|---| | domain | pinned server-side to <sqid>.<PLATFORM_APPS_DOMAIN> — "nothing the request carries can name another" | | pool | refused — "operator policy the door never writes" | | regions | refused — same | | channel | absent preserves, explicit replaces | | seed | absent preserves, [] clears |

Every field is pinned, refused, or defaulted. A member running instances enable supplies no information the console does not already have. It is a required round-trip that changes nothing.

Why the split still makes sense elsewhere

Worth keeping, and why this asks for an implication rather than a merge:

  • enable is 1 per app, create is 1..N. Policy versus instance.
  • They can carry different authority. In store mode enable writes -domain, -pool, -regions — an operator setting an envelope a member then creates inside. That separation is real and should stay.
  • apps create genuinely cannot imply an instance. A -kind static app is served from the bucket, and a -kind service route proxies an externally-managed process; neither has instances at all.

None of that applies to a member deploying a single-instance app on a deployment whose domain is already pinned — which is the first-run path.

The -host default

create requires -host <label>.<domain>. For a single-instance app the obvious value is the app's own platform domain, <app>.<sqid>.<apps-domain> — which is what the platform mints for the app anyway. Requiring it to be typed is asking the operator to restate a value the platform derived.

Worth noting for anyone reading this as "manual placement": -host is the public hostname, not a machine. Placement across a fleet is already automatic — records carry region/pool and each box's reconcile pass materializes what matches. The naming requirement is the only manual part, and it is the derivable one.

Suggested shape

carlos apps create -app echo          # claim (see #79 — must precede first ship)
carlos ship    -app echo ...
carlos promote -app echo <ver> canary/first
carlos instances create -app echo     # implies enable; -host defaults to the
                                      # app's platform domain

instances enable stays for: operator/store mode, custom domains, pools, region allow-lists, seeds, and changing policy later on an app that already has instances. Restricting afterwards is the natural order — you deploy, then you constrain.

Why this is worth more than an ergonomics complaint

The three-verb split serves fleets, static sites, and operator/member privilege separation. A first-time user has none of those, and pays the entire cost — including apps create being an unrecoverable one-way door if run in the wrong order (#79). The costs land exactly where the benefits do not.

Related

#79 (ship-before-claim is unrecoverable), #81, #83, #85, #86, #94, #95 — all found walking this same first-run path once.