carlos / platform Public

cli: C13b is decided by the region source, not by comparing codes (nearest-region §9.6)

--region <home> against a switch-off console answers the home with source
default, so equal codes read as C11. Any non-chosen source after an explicit
--region now prints C13b. apps create's region line is asserted end to end.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev b830592985487d86573af51fabb48df64e9e5804 parent d1c41c1
4 files changed, +15 −4
  • apps.go +3 −2
  • apps_region.go +6 −1
  • apps_region_test.go +2 −0
  • fleets_cli_test.go +4 −1
diff --git a/apps.go b/apps.go
index c4c4e6540..10068422e 100644
--- a/apps.go
+++ b/apps.go
@@ -495,8 +495,9 @@ func runAppsCreate(args []string) {
}
printUsing(stdout, sess)
acct := resolvedAccount(sess, acctRaw, acctIDRaw)
+ region2 := strings.TrimSpace(*region)
res, err := sess.createApp(context.Background(), acct, strings.TrimSpace(*app), place2, *controlPlane, probe2,
- strings.TrimSpace(*region), detectTimezone())
+ region2, detectTimezone())
if err != nil {
log.Fatalf("apps create: %v", err)
}
@@ -504,7 +505,7 @@ func runAppsCreate(args []string) {
fmt.Fprintf(stdout, "%s %s in account %s — it's yours\n", c.ok("created app"), res.App, res.Account)
fmt.Fprintf(stdout, " open: %s\n", c.link(res.URL))
fmt.Fprintf(stdout, " ship: carlos ship --account %s --app %s ...\n", res.Account, res.App)
- printAppRegion(stdout, res, strings.TrimSpace(*region))
+ printAppRegion(stdout, res, region2)
// The app WAS created (everything above already printed and is true) —
// what's still unverified is whether --place actually stuck. The server
// echoes back what it really stored (handleAPICreateApp's "placement"
diff --git a/apps_region.go b/apps_region.go
index a7c1d77a0..126d85141 100644
--- a/apps_region.go
+++ b/apps_region.go
@@ -9,6 +9,11 @@ import (
// a single-region deployment, C13a when an older console ignored --region,
// C13b when a console with the switch off did, else C9 to C12 by source.
//
+// C13b is decided by the source, not by comparing codes: a console that
+// applied --region answers source "chosen", so any other source after an
+// explicit --region means it was ignored. Comparing codes misses --region
+// <the home> against a switch-off console, which answers the home itself.
+//
// An empty region_source with a region present means the console could not
// read the stored region back (it then answers the home with no source). That
// says nothing about whether --region was applied, so it prints nothing: not
@@ -21,7 +26,7 @@ func printAppRegion(w io.Writer, res apiCreateAppResult, asked string) {
}
case res.RegionSource == "":
// Region read-back failed on the console. Say nothing.
- case asked != "" && res.Region != asked:
+ case asked != "" && res.RegionSource != "chosen":
fmt.Fprintln(w, regionNotAppliedSwitchOff(res.RegionName))
case res.RegionsAvailable >= 2:
fmt.Fprintln(w, regionCreatedLine(res.RegionName, res.RegionSource))
diff --git a/apps_region_test.go b/apps_region_test.go
index f8e31ce62..c2a3390bf 100644
--- a/apps_region_test.go
+++ b/apps_region_test.go
@@ -82,6 +82,8 @@ func TestPrintAppRegion(t *testing.T) {
{"single region", apiCreateAppResult{Region: "ie", RegionName: "Ireland · Dublin", RegionSource: "default", RegionsAvailable: 1}, "", ""},
{"old console asked", apiCreateAppResult{}, "uk", regionNotRecordedOldConsole + "\n"},
{"switch off asked", apiCreateAppResult{Region: "ie", RegionName: "Ireland · Dublin", RegionSource: "default", RegionsAvailable: 2}, "uk", regionNotAppliedSwitchOff("Ireland · Dublin") + "\n"},
+ {"switch off, asked the home itself", apiCreateAppResult{Region: "ie", RegionName: "Ireland · Dublin", RegionSource: "default", RegionsAvailable: 1}, "ie", regionNotAppliedSwitchOff("Ireland · Dublin") + "\n"},
+ {"switch on, explicit region", apiCreateAppResult{Region: "uk", RegionName: "UK · London", RegionSource: "chosen", RegionsAvailable: 2}, "uk", regionCreatedLine("UK · London", "chosen") + "\n"},
{"old console not asked", apiCreateAppResult{}, "", ""},
}
for _, c := range cases {
diff --git a/fleets_cli_test.go b/fleets_cli_test.go
index dfaba8325..ed43b284e 100644
--- a/fleets_cli_test.go
+++ b/fleets_cli_test.go
@@ -779,11 +779,14 @@ func TestRunAppsCreatePlacementVerification(t *testing.T) {
})
t.Run("happy path: echo matches", func(t *testing.T) {
- ts := fakeCreateEcho(t, `{"account":"bab","app":"titogo","url":"http://x/a/bab/apps/titogo","placement":"fleet/pi"}`)
+ ts := fakeCreateEcho(t, `{"account":"bab","app":"titogo","url":"http://x/a/bab/apps/titogo","placement":"fleet/pi","region":"uk","region_name":"UK · London","region_source":"timezone","regions_available":2}`)
out, err := run(t, ts.URL)
if err != nil {
t.Fatalf("exited nonzero, want 0:\n%s", out)
}
+ if !strings.Contains(out, "Region: UK · London (from your timezone). Use --region to choose another.\n") {
+ t.Fatalf("output missing the region line:\n%s", out)
+ }
if !strings.Contains(out, "placed on fleet/pi") {
t.Fatalf("output missing the placed confirmation:\n%s", out)
}