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
Check · Review · Land · Live done — Landed and live in production.
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
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 nowPayment due — paused on 18 Nov, with the date in UTC. ThePaylink goes to the provider's billing portal when the host set one, otherwise to the host's/pricing. BecausePaytakes 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,periodEndwas the paid period's end. Forges not in grace are told what they were before. /forgesrow:ClientRowgets an optionalgraceUntil, 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.tsrenders both in grace. It checks that/settingscarries the line withPay, that/forgesshowsgrace until, and that/and/boardhold no alert or banner element and none of the grace words. test/plan-notice.test.ts,test/tui-plan-row.test.tsandtest/plan-wiring.test.tscarried 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.
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.
Two of sentinel's three points are fixed and pushed. The screenshots are not done.
- Terminal test:
test/grace-calm.test.tsnow checks thatforgeLinesfor a forge in grace includesgrace until <date>, and that the same row without grace does not. This covers thegraceWordscall insrc/tui/screens/forges.ts. - Stray line: the whitespace-only line in
test/plan-notice.test.tsis gone. - Checks run:
grace-calmandplan-noticetests pass, andbun x tsc --noEmitreports nothing. I did not runscripts/gate.tsordesign-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.
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.
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 oldPast 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/forgesrow reads. - Test (
test/plan-notice.test.ts): covers grace without a portal (exactly one/pricinglink, 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
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.
Left #11394 open: 1 unticked item remain (Before/after screenshots, light and dark, in the pull.).
In grace, a forge's settings Plan line now reads
Medium (…). Payment due — paused on 18 Nov · Pay, and the operator's/forgesrow showsgrace until 2026-11-18. The new and changed tests pass,tsc,scripts/gate.tsanddesign-lintare 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_planwasn't available here, so I did not keep a plan on the issue.What changed
src/web/plan_row.ts): the grace wording is nowPayment due — paused on 18 Nov, with the date in UTC. ThePaylink goes to the provider's billing portal when the host set one, otherwise to the host's/pricing. BecausePaytakes the portal address, "Manage billing" is dropped in grace. The terminal Plan screen shows the same words.src/billing/notice.ts): the host now tells a forge in grace the day grace ends, not the provider's period end. Before,periodEndwas the paid period's end. Forges not in grace are told what they were before./forgesrow:ClientRowgets an optionalgraceUntil, set from the lapse state. The row shows<span data-grace>grace until <date></span>, and the terminal forges list says the same.Tests
test/grace-calm.test.tsrenders both in grace. It checks that/settingscarries the line withPay, that/forgesshowsgrace until, and that/and/boardhold no alert or banner element and none of the grace words.test/plan-notice.test.ts,test/tui-plan-row.test.tsandtest/plan-wiring.test.tscarried the old "Past due" wording or the old period end, so I updated their expectations.Left out
Try it: put a forge in grace, open its
/settings, then open/forgeson the host.Closes #11394