Skip to content

fix(cor-573): CLI 503 → scheduled-maintenance copy#1503

Draft
dvydra wants to merge 3 commits into
mainfrom
danielv/cor-573-user-facing-maintenance-signal-cli
Draft

fix(cor-573): CLI 503 → scheduled-maintenance copy#1503
dvydra wants to merge 3 commits into
mainfrom
danielv/cor-573-user-facing-maintenance-signal-cli

Conversation

@dvydra

@dvydra dvydra commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/645

COR-573 (CLI surface) — scheduled-maintenance 503 copy

Part of COR-573 — User-facing maintenance signal, split per surface. This is the CLI surface (1 of 3); siblings cover the SPA banner and the incident.io statuspage.

What

When the control plane returns HTTP 503 — a draining/maintenance host, i.e. the COR-562 cutover scenario — the entire CLI printed the raw control-plane request failed with status 503. renderCoreError now special-cases 503 to a friendly, shared message:

Entire is under scheduled maintenance — please try again shortly

Changes

  • internal/coreapi/client.go — new HTTPStatus(err) (int, bool) helper, alongside APIError.
  • cmd/entire/cli/corecmd.gorenderCoreError 503 branch + shared maintenanceMessage const (//nolint:staticcheck — user-facing copy kept verbatim across surfaces).
  • cmd/entire/cli/corecmd_test.goTestRenderCoreError_ScheduledMaintenance (bare 503 + 503-with-body) and TestRenderCoreError_PassThrough (nil + transport error).

Coordination

  • Copy is verbatim-shared with the Cloudflare edge 503 page (COR-566) and the SPA banner (COR-573 sibling). Convergence tracked in entiredb#2121.
  • Touches entireio/cli alongside COR-572 (client timeout). My change is in renderCoreError; COR-572 is in coreapi.New() — distinct functions, no file-region overlap.

Verification

  • go test ./cmd/entire/cli/
  • mise run lint → 0 issues ✓

NO MERGE / NO DEPLOY — draft only.

🤖 Generated with Claude Code


Note

Low Risk
User-facing error copy only; no auth, transport, or API behavior changes beyond 503 messaging.

Overview
Control-plane commands no longer print generic control-plane request failed with status 503 when the API returns 503. renderCoreError now maps that status to shared user-facing copy: Entire is under scheduled maintenance — please try again shortly (aligned with COR-566 edge and the SPA banner), including when a problem-detail body is present.

coreapi.HTTPStatus was added so the CLI can detect API status codes without parsing APIError text. Tests cover 503 (bare and with body), nil, and transport passthrough.

Reviewed by Cursor Bugbot for commit 058e835. Configure here.

dvydra and others added 2 commits June 23, 2026 15:33
renderCoreError special-cases an HTTP 503 from the control plane to a
friendly "Entire is under scheduled maintenance" message instead of the raw
ogen status string, so a draining/maintenance host (the COR-562 cutover
scenario) reads cleanly. Adds coreapi.HTTPStatus to extract the status code.
Copy is shared verbatim with the edge 503 page (COR-566) and the SPA banner.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 23, 2026 05:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the user-facing error output for control-plane commands by mapping HTTP 503 Service Unavailable responses (scheduled maintenance / draining hosts) to a friendly, shared message instead of the generic control-plane request failed with status 503.

Changes:

  • Added coreapi.HTTPStatus(err) (int, bool) to extract an HTTP status code from control-plane API errors without parsing text.
  • Updated renderCoreError to special-case 503 and return the scheduled-maintenance copy (even when a problem-detail body is present).
  • Added unit tests covering 503 (with/without body) plus nil and transport-error passthrough.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
internal/coreapi/client.go Adds HTTPStatus helper to detect whether an error is a core API status error and extract its status code.
cmd/entire/cli/corecmd.go Special-cases 503 in renderCoreError to return the shared maintenance message; keeps other API errors mapped via APIError.
cmd/entire/cli/corecmd_test.go Adds tests asserting 503 maps to the maintenance message and that nil/transport errors pass through unchanged.

Drop the " — please try again shortly" suffix so the CLI 503 message is
byte-identical to the COR-566 edge page <h1> and the SPA banner heading
(per the COR-573 spec: special-case 503 with the bare headline). Add a
boundary comment: a draining/black-holed host (COR-572) times out rather
than returning 503, so only an explicit 503 maps to the maintenance copy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dvydra

dvydra commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Copy is now the bare canonical headline (per COR-573 spec). Dropped the — please try again shortly suffix, so the CLI 503 message is byte-identical to the COR-566 edge <h1> and the SPA banner heading: Entire is under scheduled maintenance.

If you'd prefer a CLI-specific suffix, say so and I'll apply the same suffix to the SPA banner + edge page so all three stay identical — your call.

Drain-path boundary: a black-holed/draining host (COR-572) surfaces as a timeout, not a 503, so this copy only fires on an explicit 503 (e.g. behind the COR-566 edge page). Timeouts are deliberately left as generic errors — not mapped to maintenance. Open architecture question for you: is the CLI's core endpoint behind the edge-503 hosts? If not, a window-scoped timeout→maintenance mapping may be worth adding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants