carlos / platform Public

Merge origin/main into customer fleets

Brings PR #63 up to date with main (934414c), which has since landed the
console redesign (#68), the app pages rework (#89), release versioning,
`carlos deploy`, the instances API go-live, exec-instance metrics (#121)
and the #69/#70 db-path fixes.

Seven files conflicted; every one resolves to BOTH sides composed, never
either side picked:

- main.go — main's three-role usage rewrite kept, with the branch's
  `fleets` verb added under "Your deployment" and `apps` regaining its
  place/-place lines. The dispatch table auto-merged with `fleets` intact.
- apps.go — apps create keeps the branch's `place2` argument and adopts
  main's `printUsing` helper.
- internal/console/server.go — fleets routes sit beside the new app
  Settings routes; the fleet page struct fields sit beside Overview /
  InstanceRows / Confirm / Settings; both `provision` and `registry`
  imported. main's new `claimReserved` return updated for the branch's
  two-value claimApp signature.
- internal/console/apiinstances.go — instance create now runs main's
  sibling-apex refusal FIRST (cheap, refuses a bad host before any store
  read), then the branch's fleet-placement lookup, which still overrides
  the request body's region.
- internal/registry/registry.go — the route table gains BOTH new columns
  (`unit` from main, `fleet_box` from the branch): 33 in routeCols,
  scanRoute, the placeholder row and the Upsert argument list, with both
  keep-existing-on-zero CASE arms and the doc comment updated to seven
  such columns.
- internal/host/agent.go — main's adoptLoop(reg, svc) / fastConvergeLoop
  (canaryAdoptLoop's new name) with the branch's startup
  publishResidentFleetBindings pass kept ahead of them.
- internal/host/metrics_loop.go — metricsLoop takes main's activator
  service for the exec-children probe while resolving its box label
  through the branch's metricsBoxLabel.

Fingerprint is the one place both sides rewrote the same function, so it
is composed rather than merged: main's content-accurate sha256 over the
actual column VALUES (which subsumes the branch's rev-counter trick — a
rotated 64-char token hash is visible because its bytes changed, not
because a counter moved) now also hashes `db_path` (#69), `region` and
`fleet_box`, and folds the fleets and fleet_boxes tables in under their
own section markers. Every invariant both sides bought survives: a
same-length version bump, a token rotation, a detach and an unattended
failover restamp all move the fingerprint, and the poll's payload is
fixed-size no matter how many routes are fleet-placed.

TestFingerprintStableWithoutFleetRoutes asserted the OLD aggregate's
string shape (a trailing ':' proving the placement projection was scoped).
There is no projection to scope now, so the assertion is ported to what
still carries its intent: the digest is "<count>:<64 hex>" regardless of
table size, which closes the unbounded-payload hole structurally.

templates/fleetdetail.html auto-merged silently but was written against
the pre-#68 layout, so it is ported by hand to current conventions: flash
banners first, a .pagehead block (eyebrow / h1 / lede) in place of the
bare h1, the placed-app link moved from {{.Base}} to {{.Nav}} like every
other app link on main, and Detach given the `linkish danger` class the
redesign uses for destructive row actions. Form actions stay on
{{.Base}}, which is already the convention. No other fleets template
exists; the handler already builds its page through main's accountPage
helper. Existing fleet-page render tests cover the result.

go build / go vet / go test ./... -count=1: all 21 packages green.
Co-Authored-By: Claude <noreply@anthropic.com>
Paul Campbell 6629c5243772f0d155433d7ffc0ade171de99543 parent 7ce6cb7parent 934414c
151 files changed, +26069 −1301
  • .github/workflows/ci.yml +107 −0
  • CLAUDE.md +57 −3
  • README.md +14 −3
  • accounts.go +37 −30
  • apimode.go +325 −5
  • apimode_test.go +191 −24
  • appconfig_cli.go +24 −25
  • apps.go +15 −13
  • auth.go +17 −14
  • cli.go +625 −85
  • cli_test.go +493 −8
  • cmd/console/main.go +56 −10
  • color.go +222 −0
  • color_test.go +128 −0
  • deploy.go +475 −0
  • deploy_e2e_test.go +439 −0
  • deploy_test.go +400 −0
  • docs/superpowers/plans/2026-08-06-console-redesign.md +1342 −0
  • docs/superpowers/plans/2026-08-06-issues-69-70-db-path.md +380 −0
  • docs/superpowers/plans/2026-08-08-carlos-deploy.md +894 −0
  • docs/superpowers/plans/2026-08-08-release-versioning.md +1592 −0
  • docs/superpowers/specs/2026-08-04-instance-provisioning-design.md +98 −0
  • docs/superpowers/specs/2026-08-06-console-redesign-design.md +184 −0
  • docs/superpowers/specs/2026-08-07-console-app-pages-design.md +144 −0
  • docs/superpowers/specs/2026-08-08-carlos-deploy-design.md +310 −0
  • docs/superpowers/specs/2026-08-08-exec-instance-metrics-design.md +152 −0
  • docs/superpowers/specs/2026-08-08-instance-socket-consumers-design.md +161 −0
  • docs/superpowers/specs/2026-08-08-release-versioning-design.md +130 −0
  • e2e_test.go +133 −1
  • go.mod +1 −1
  • instances_cli.go +206 −26
  • instances_e2e_test.go +142 −0
  • internal/activator/activator.go +29 −0
  • internal/activator/activator_test.go +271 −1
  • internal/activator/backend_exec.go +36 −0
  • internal/appconfig/sync.go +7 −7
  • internal/caps/converge.go +1 −1
  • internal/console/apicli.go +211 −9
  • internal/console/apicli_test.go +225 −0
  • internal/console/apiconfig.go +12 −0
  • internal/console/apiinstances.go +255 −4
  • internal/console/apiinstances_test.go +83 −0
  • internal/console/apiinstancesenable_test.go +293 −0
  • internal/console/apirestart_test.go +177 −0
  • internal/console/apiversion.go +230 −0
  • internal/console/apiversion_test.go +339 −0
  • internal/console/appsettings.go +450 −0
  • internal/console/appsettings_test.go +657 −0
  • internal/console/attachhint_test.go +132 −0
  • internal/console/authcli.go +26 −5
  • internal/console/authcli_test.go +33 −4
  • internal/console/bakecontrols_test.go +6 −6
  • internal/console/confirm.go +233 −0
  • internal/console/confirm_test.go +314 −0
  • internal/console/deletion_test.go +8 −0
  • internal/console/icons.go +13 −0
  • internal/console/ladder_test.go +44 −32
  • internal/console/metricsview.go +121 −29
  • internal/console/metricsview_test.go +162 −0
  • internal/console/overview.go +192 −0
  • internal/console/overview_test.go +317 −0
  • internal/console/ownership.go +23 −7
  • internal/console/serialbump.go +40 −0
  • internal/console/serialbump_test.go +506 −0
  • internal/console/server.go +551 −62
  • internal/console/server_account_test.go +63 −8
  • internal/console/server_test.go +744 −78
  • internal/console/store.go +91 −0
  • internal/console/templates/account_settings.html +32 −0
  • internal/console/templates/app.html +0 −207
  • internal/console/templates/app_activity.html +18 −0
  • internal/console/templates/app_instances.html +53 −0
  • internal/console/templates/app_new.html +17 −0
  • internal/console/templates/app_overview.html +79 −0
  • internal/console/templates/app_releases.html +147 −0
  • internal/console/templates/app_settings.html +101 −0
  • internal/console/templates/appnav.html +13 −0
  • internal/console/templates/apps.html +1 −74
  • internal/console/templates/cli_approve.html +2 −2
  • internal/console/templates/confirm_action.html +23 −0
  • internal/console/templates/fleetdetail.html +8 −4
  • internal/console/templates/home.html +6 −2
  • internal/console/templates/ladder.html +14 −26
  • internal/console/templates/layout.html +103 −25
  • internal/console/templates/{cli_tokens.html => settings.html} +10 −5
  • internal/console/templates/team.html +64 −0
  • internal/console/view.go +72 −1
  • internal/edge/edge.go +45 −0
  • internal/edge/edge_test.go +63 −0
  • internal/edge/static.go +39 −13
  • internal/edge/static_test.go +222 −0
  • internal/host/agent.go +687 −68
  • internal/host/agent_test.go +812 −0
  • internal/host/bootstrap.go +151 −37
  • internal/host/host_test.go +144 −7
  • internal/host/metrics_loop.go +19 −6
  • internal/host/metrics_probes.go +75 −4
  • internal/host/metrics_probes_test.go +58 −0
  • internal/host/probes.go +20 −1
  • internal/host/restart.go +650 −0
  • internal/host/restart_test.go +706 −0
  • internal/host/stage_relay_test.go +79 −0
  • internal/host/units/carlos-restart.path +27 −0
  • internal/host/units/carlos-restart.service +53 −0
  • internal/host/units/carlos-stage.path +26 −0
  • internal/host/units/carlos-stage.service +52 −0
  • internal/lease/endpoint.go +130 −0
  • internal/lease/endpoint_test.go +263 −0
  • internal/lease/lease.go +19 −19
  • internal/lease/lease_test.go +7 −3
  • internal/metrics/pidparse.go +101 −0
  • internal/metrics/pidparse_test.go +83 −0
  • internal/provision/provision.go +31 −5
  • internal/provision/provision_test.go +40 −0
  • internal/registry/fleets_test.go +19 −10
  • internal/registry/registry.go +236 −87
  • internal/registry/registry_test.go +293 −1
  • internal/release/adopt.go +185 −47
  • internal/release/adopt_test.go +135 −5
  • internal/release/golden_test.go +201 −0
  • internal/release/ladder_test.go +284 −0
  • internal/release/materialize.go +66 −0
  • internal/release/materialize_test.go +181 −0
  • internal/release/release.go +72 −0
  • internal/release/release_test.go +51 −0
  • internal/release/restartgen.go +107 −0
  • internal/release/restartgen_test.go +135 −0
  • internal/release/semver.go +105 −0
  • internal/release/semver_test.go +57 −0
  • internal/release/serial.go +74 −0
  • internal/release/serial_test.go +56 −0
  • internal/release/stage_blocked_test.go +60 −0
  • internal/release/store.go +12 −9
  • internal/release/store_rgw_test.go +169 −0
  • internal/release/tag.go +187 −0
  • internal/release/tag_test.go +202 −0
  • internal/release/target.go +151 −0
  • internal/release/target_test.go +153 −0
  • internal/release/versions.go +22 −0
  • internal/release/versions_test.go +41 −0
  • internal/s3compat/s3compat.go +181 −0
  • internal/s3compat/s3compat_test.go +235 −0
  • internal/status/contract_test.go +43 −15
  • internal/status/dryrun.go +71 −14
  • internal/status/fleet.go +14 −8
  • internal/status/snapshot.go +60 −16
  • internal/status/status_test.go +113 −0
  • main.go +84 −79
  • restart.go +86 −0
  • restart_test.go +153 −0
  • testdata/echoapp/main.go +21 −0
.github/workflows/ci.yml

Loading diff…

CLAUDE.md

Loading diff…

README.md

Loading diff…

accounts.go

Loading diff…

apimode.go

Loading diff…

apimode_test.go

Loading diff…

appconfig_cli.go

Loading diff…

apps.go

Loading diff…

auth.go

Loading diff…

cli.go

Loading diff…

cli_test.go

Loading diff…

cmd/console/main.go

Loading diff…

color.go

Loading diff…

color_test.go

Loading diff…

deploy.go

Loading diff…

deploy_e2e_test.go

Loading diff…

deploy_test.go

Loading diff…

docs/superpowers/plans/2026-08-06-console-redesign.md

Loading diff…

docs/superpowers/plans/2026-08-06-issues-69-70-db-path.md

Loading diff…

docs/superpowers/plans/2026-08-08-carlos-deploy.md

Loading diff…

docs/superpowers/plans/2026-08-08-release-versioning.md

Loading diff…

docs/superpowers/specs/2026-08-04-instance-provisioning-design.md

Loading diff…

docs/superpowers/specs/2026-08-06-console-redesign-design.md

Loading diff…

docs/superpowers/specs/2026-08-07-console-app-pages-design.md

Loading diff…

docs/superpowers/specs/2026-08-08-carlos-deploy-design.md

Loading diff…

docs/superpowers/specs/2026-08-08-exec-instance-metrics-design.md

Loading diff…

docs/superpowers/specs/2026-08-08-instance-socket-consumers-design.md

Loading diff…

docs/superpowers/specs/2026-08-08-release-versioning-design.md

Loading diff…

e2e_test.go

Loading diff…

go.mod

Loading diff…

instances_cli.go

Loading diff…

instances_e2e_test.go

Loading diff…

internal/activator/activator.go

Loading diff…

internal/activator/activator_test.go

Loading diff…

internal/activator/backend_exec.go

Loading diff…

internal/appconfig/sync.go

Loading diff…

internal/caps/converge.go

Loading diff…

internal/console/apicli.go

Loading diff…

internal/console/apicli_test.go

Loading diff…

internal/console/apiconfig.go

Loading diff…

internal/console/apiinstances.go

Loading diff…

internal/console/apiinstances_test.go

Loading diff…

internal/console/apiinstancesenable_test.go

Loading diff…

internal/console/apirestart_test.go

Loading diff…

internal/console/apiversion.go

Loading diff…

internal/console/apiversion_test.go

Loading diff…

internal/console/appsettings.go

Loading diff…

internal/console/appsettings_test.go

Loading diff…

internal/console/attachhint_test.go

Loading diff…

internal/console/authcli.go

Loading diff…

internal/console/authcli_test.go

Loading diff…

internal/console/bakecontrols_test.go

Loading diff…

internal/console/confirm.go

Loading diff…

internal/console/confirm_test.go

Loading diff…

internal/console/deletion_test.go

Loading diff…

internal/console/icons.go

Loading diff…

internal/console/ladder_test.go

Loading diff…

internal/console/metricsview.go

Loading diff…

internal/console/metricsview_test.go

Loading diff…

internal/console/overview.go

Loading diff…

internal/console/overview_test.go

Loading diff…

internal/console/ownership.go

Loading diff…

internal/console/serialbump.go

Loading diff…

internal/console/serialbump_test.go

Loading diff…

internal/console/server.go

Loading diff…

internal/console/server_account_test.go

Loading diff…

internal/console/server_test.go

Loading diff…

internal/console/store.go

Loading diff…

internal/console/templates/account_settings.html

Loading diff…

internal/console/templates/app.html

Loading diff…

internal/console/templates/app_activity.html

Loading diff…

internal/console/templates/app_instances.html

Loading diff…

internal/console/templates/app_new.html

Loading diff…

internal/console/templates/app_overview.html

Loading diff…

internal/console/templates/app_releases.html

Loading diff…

internal/console/templates/app_settings.html

Loading diff…

internal/console/templates/appnav.html

Loading diff…

internal/console/templates/apps.html

Loading diff…

internal/console/templates/cli_approve.html

Loading diff…

internal/console/templates/confirm_action.html

Loading diff…

internal/console/templates/fleetdetail.html

Loading diff…

internal/console/templates/home.html

Loading diff…

internal/console/templates/ladder.html

Loading diff…

internal/console/templates/layout.html

Loading diff…

internal/console/templates/{cli_tokens.html => settings.html}

Loading diff…

internal/console/templates/team.html

Loading diff…

internal/console/view.go

Loading diff…

internal/edge/edge.go

Loading diff…

internal/edge/edge_test.go

Loading diff…

internal/edge/static.go

Loading diff…

internal/edge/static_test.go

Loading diff…

internal/host/agent.go

Loading diff…

internal/host/agent_test.go

Loading diff…

internal/host/bootstrap.go

Loading diff…

internal/host/host_test.go

Loading diff…

internal/host/metrics_loop.go

Loading diff…

internal/host/metrics_probes.go

Loading diff…

internal/host/metrics_probes_test.go

Loading diff…

internal/host/probes.go

Loading diff…

internal/host/restart.go

Loading diff…

internal/host/restart_test.go

Loading diff…

internal/host/stage_relay_test.go

Loading diff…

internal/host/units/carlos-restart.path

Loading diff…

internal/host/units/carlos-restart.service

Loading diff…

internal/host/units/carlos-stage.path

Loading diff…

internal/host/units/carlos-stage.service

Loading diff…

internal/lease/endpoint.go

Loading diff…

internal/lease/endpoint_test.go

Loading diff…

internal/lease/lease.go

Loading diff…

internal/lease/lease_test.go

Loading diff…

internal/metrics/pidparse.go

Loading diff…

internal/metrics/pidparse_test.go

Loading diff…

internal/provision/provision.go

Loading diff…

internal/provision/provision_test.go

Loading diff…

internal/registry/fleets_test.go

Loading diff…

internal/registry/registry.go

Loading diff…

internal/registry/registry_test.go

Loading diff…

internal/release/adopt.go

Loading diff…

internal/release/adopt_test.go

Loading diff…

internal/release/golden_test.go

Loading diff…

internal/release/ladder_test.go

Loading diff…

internal/release/materialize.go

Loading diff…

internal/release/materialize_test.go

Loading diff…

internal/release/release.go

Loading diff…

internal/release/release_test.go

Loading diff…

internal/release/restartgen.go

Loading diff…

internal/release/restartgen_test.go

Loading diff…

internal/release/semver.go

Loading diff…

internal/release/semver_test.go

Loading diff…

internal/release/serial.go

Loading diff…

internal/release/serial_test.go

Loading diff…

internal/release/stage_blocked_test.go

Loading diff…

internal/release/store.go

Loading diff…

internal/release/store_rgw_test.go

Loading diff…

internal/release/tag.go

Loading diff…

internal/release/tag_test.go

Loading diff…

internal/release/target.go

Loading diff…

internal/release/target_test.go

Loading diff…

internal/release/versions.go

Loading diff…

internal/release/versions_test.go

Loading diff…

internal/s3compat/s3compat.go

Loading diff…

internal/s3compat/s3compat_test.go

Loading diff…

internal/status/contract_test.go

Loading diff…

internal/status/dryrun.go

Loading diff…

internal/status/fleet.go

Loading diff…

internal/status/snapshot.go

Loading diff…

internal/status/status_test.go

Loading diff…

main.go

Loading diff…

restart.go

Loading diff…

restart_test.go

Loading diff…

testdata/echoapp/main.go

Loading diff…