Public: anyone can read this; the crew can change it.

During grace, a forge's admins see one line with a pay link in its settings, and the operator sees grace on /forges #11487

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

In grace, a forge's settings Plan line now reads `Medium (…). Payment due — paused on 18 Nov · Pay`, and the operator's `/forges` row shows `grace until 2026-11-18`. The new and changed tests pass, `tsc`, `scripts/gate.ts` and `design-lint` are clean, and it is pushed. I did not take the before/after screenshots, light and dark, because the sandbox can't run a browser. I ran only the affected test…

shipped production is serving it deploy 1cfdf1a

opened this

In grace, a forge's settings Plan line now reads Medium (…). Payment due — paused on 18 Nov · Pay, and the operator's /forges row shows grace until 2026-11-18. The new and changed tests pass, tsc, scripts/gate.ts and design-lint are clean, and it is pushed. I did not take the before/after screenshots, light and dark, because the sandbox can't run a browser. I ran only the affected test files, not the full suite. keep_plan wasn't available here, so I did not keep a plan on the issue.

What changed

  • Plan line (src/web/plan_row.ts): the grace wording is now Payment due — paused on 18 Nov, with the date in UTC. The Pay link goes to the provider's billing portal when the host set one, otherwise to the host's /pricing. Because Pay takes the portal address, "Manage billing" is dropped in grace. The terminal Plan screen shows the same words.
  • Pause date (src/billing/notice.ts): the host now tells a forge in grace the day grace ends, not the provider's period end. Before, periodEnd was the paid period's end. Forges not in grace are told what they were before.
  • /forges row: ClientRow gets an optional graceUntil, set from the lapse state. The row shows <span data-grace>grace until <date></span>, and the terminal forges list says the same.
  • Home and board: nothing was drawn there before and nothing is now.

Tests

  • New test/grace-calm.test.ts renders both in grace. It checks that /settings carries the line with Pay, that /forges shows grace until, and that / and /board hold no alert or banner element and none of the grace words.
  • test/plan-notice.test.ts, test/tui-plan-row.test.ts and test/plan-wiring.test.ts carried the old "Past due" wording or the old period end, so I updated their expectations.

Left out

  • No change to when a forge actually sleeps; this only shows state.
  • No extra link on the home or board, by design.

Try it: put a forge in grace, open its /settings, then open /forges on the host.

Closes #11394

commented

In grace, a forge's settings Plan line now reads Medium (…). Payment due — paused on 18 Nov · Pay, and the operator's /forges row shows grace until 2026-11-18. The new and changed tests pass, tsc, scripts/gate.ts and design-lint are clean, and it is pushed. I did not take the before/after screenshots, light and dark, because the sandbox can't run a browser. I ran only the affected test files, not the full suite. keep_plan wasn't available here, so I did not keep a plan on the issue.

What changed

  • Plan line (src/web/plan_row.ts): the grace wording is now Payment due — paused on 18 Nov, with the date in UTC. The Pay link goes to the provider's billing portal when the host set one, otherwise to the host's /pricing. Because Pay takes the portal address, "Manage billing" is dropped in grace. The terminal Plan screen shows the same words.
  • Pause date (src/billing/notice.ts): the host now tells a forge in grace the day grace ends, not the provider's period end. Before, periodEnd was the paid period's end. Forges not in grace are told what they were before.
  • /forges row: ClientRow gets an optional graceUntil, set from the lapse state. The row shows <span data-grace>grace until <date></span>, and the terminal forges list says the same.
  • Home and board: nothing was drawn there before and nothing is now.

Tests

  • New test/grace-calm.test.ts renders both in grace. It checks that /settings carries the line with Pay, that /forges shows grace until, and that / and /board hold no alert or banner element and none of the grace words.
  • test/plan-notice.test.ts, test/tui-plan-row.test.ts and test/plan-wiring.test.ts carried the old "Past due" wording or the old period end, so I updated their expectations.

Left out

  • No change to when a forge actually sleeps; this only shows state.
  • No extra link on the home or board, by design.

Try it: put a forge in grace, open its /settings, then open /forges on the host.

Changes requested — before the latest push

The behaviour matches the issue and I found no security problems. Three things need fixing: (1) Box 4: no before/after screenshots, light and dark, are in the pull. Add them. (2) The terminal's grace words on the forges screen have no test, although the pull adds them. Add one. (3) test/plan-notice.test.ts has a stray whitespace-only line left behind by the edit. Remove it.

commented

Two of sentinel's three points are fixed and pushed. The screenshots are not done.

  • Terminal test: test/grace-calm.test.ts now checks that forgeLines for a forge in grace includes grace until <date>, and that the same row without grace does not. This covers the graceWords call in src/tui/screens/forges.ts.
  • Stray line: the whitespace-only line in test/plan-notice.test.ts is gone.
  • Checks run: grace-calm and plan-notice tests pass, and bun x tsc --noEmit reports nothing. I did not run scripts/gate.ts or design-lint, and I did not run the full suite.
  • Screenshots (not done): I can't take them here. The sandbox has no browser, and the one fetch of a forge's own subdomain was denied. The preview is at https://lab--11487--forge-trevato-apps.open-platform.sh. The before/after screenshots, light and dark, of /settings (the Plan line) and /forges (grace until) need to be taken by someone who can load that preview and a forge in grace.
Changes requested — before the latest push

Behaviour matches the issue and the tests are solid. Fix in one round: (1) docs/features/plan-row.md still says Past due, sleeps <date> and that Manage billing shows in grace; update it to Payment due — paused on <day> · Pay, the Pay target (portal, else host /pricing), and the /forges grace until row. (2) Box 4: before/after screenshots, light and dark, of /settings and /forges are not in the pull; attach them (a person with a browser can take them from the preview). (3) In grace with no portal, Pay and Change size both point at <host>/pricing: two links to one place on one row; drop Change size in that case. Note the preview /forges answered 404 to my token (operator-only), so I judged /forges from the test.

commented

While a forge's payment is late (its grace period), its admins see one line in the Plan row of /settings: Payment due — paused on <day> · Pay. The operator sees grace until <date> on that forge's row in /forges and on the terminal's forges screen. The home page and the board show no notice.

This round:

  • One link per place (src/web/plan_row.ts): in grace, Pay goes to the provider's portal if one is set, otherwise to the host's /pricing. When Pay already goes to /pricing, Change size is no longer shown, so the row never has two links to the same page. With a portal set, Pay goes to the portal and Change size stays; Manage billing is not shown in grace. The file's header comment now says this.
  • Docs (docs/features/plan-row.md): replaced the old Past due, sleeps <date> wording with the grace line. The doc now says where Pay points, that Pay replaces Manage billing, when Change size is dropped, and how the operator's /forges row reads.
  • Test (test/plan-notice.test.ts): covers grace without a portal (exactly one /pricing link, no Change size) and grace with a portal (Pay goes to the portal, Change size stays, no Manage billing). It fails without the fix and passes with it.

bun scripts/gate.ts, bun x tsc --noEmit, bun scripts/design-lint.ts, and test/plan-notice.test.ts, test/grace-calm.test.ts and test/tui-plan-row.test.ts all pass.

The light and dark before/after screenshots of /settings and /forges are still missing: this sandbox has no browser, so a person needs to take them. /settings can be taken from the preview at https://lab--11487--forge-trevato-apps.open-platform.sh. /forges is operator-only and answers 404 to agent tokens, so it needs an operator signed in to the preview.

To try it: open /settings as an admin of a forge in grace. Without a billing portal the row ends · Pay with no Change size next to it; with a portal, Pay goes to the portal and Change size goes to <host>/pricing.

🤖 Generated with Claude Code

Approved

Earlier asks: the terminal test for graceWords is in (grace-calm), the stray whitespace line is gone, and the one-link-per-place fix (Pay replaces Manage billing; Change size dropped when Pay already goes to /pricing) is met, tested and documented in docs/features/plan-row.md, not README. Behaviour matches the issue: the Plan line reads Payment due — paused on 18 Nov · Pay, /forges and the terminal show grace until <date>, and home and board carry nothing. Nothing is hand-rolled in the markup, and it works with JavaScript off. Next, in order: 1) take the before/after screenshots, light and dark, of /settings and /forges (box 4 stays open). 2) Non-blocking: dayWords is exported from plan_row.ts and graceWords formats dates a second way (ISO); consider one date format for the operator and the admin.

commented

Left #11394 open: 1 unticked item remain (Before/after screenshots, light and dark, in the pull.).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs