Public: anyone can read this; the crew can change it.
The new-forge page says what is true about updates: the mode is recorded, nothing acts on it until #1052 #2235
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/2234-the-new-forge-page-says-what-is-true-abo → main 1 commit fork 2 threads · 2 unresolved
6 files
changed +26
−6
src/tui/screens/newforge.ts +1 −1
| @@ -33,7 +33,7 @@ const SPECS: readonly Spec[] = [ | ||
| 33 | 33 | { key: "modelKey", label: "Model key", hint: "Sealed in the child, never shown again. Optional.", secret: true }, |
| 34 | 34 | { key: "modelEndpoint", label: "API base URL", hint: "A gateway for the key; empty for Anthropic. Optional." }, |
| 35 | 35 | { key: "budgetUsd", label: "Budget in dollars", hint: `${MIN_BUDGET_USD}–${MAX_BUDGET_USD}, for the key's whole life. Needed with a key.` }, |
| 36 | { key: "followMode", label: "Follows this forge's code", hint: "tell-me (default) or take-updates. Recorded only; nothing acts on it yet." }, | |
| 36 | { key: "followMode", label: "Follows this forge's code", hint: "tell-me (default) or take-updates. Recorded for now: nothing tells you or takes updates yet." }, | |
| 37 | 37 | ]; |
| 38 | 38 | |
| 39 | 39 | /** The door's "field: reason" refusal, as the field it names and the reason. */ |
src/web/pages/chain.ts +1 −1
| @@ -18,7 +18,7 @@ import { btn, card } from "../ui.ts"; | ||
| 18 | 18 | /** The events that change what the chain page says. */ |
| 19 | 19 | export const CHAIN_LIVE = "forge.severed"; |
| 20 | 20 | |
| 21 | const MODE_WORDS = { "tell-me": "tells when the parent moves", "take-updates": "takes updates" } as const; | |
| 21 | const MODE_WORDS = { "tell-me": "recorded: tell me (nothing tells it yet)", "take-updates": "recorded: take updates (nothing acts on it yet)" } as const; | |
| 22 | 22 | |
| 23 | 23 | function lineRow(l: ChainLine): Html { |
| 24 | 24 | const where = l.host === "" ? "" : ` on ${l.host}`; |
src/web/pages/new-forge.ts +2 −2
| @@ -188,7 +188,7 @@ function formView( | ||
| 188 | 188 | ${values.followMode !== "take-updates" ? html`checked` : null} |
| 189 | 189 | /> |
| 190 | 190 | <span |
| 191 | >Tell me <span class="muted small">is recorded as your choice; nothing tells you yet.</span></span | |
| 191 | >Recorded for now: tell me <span class="muted small">your choice is kept; nothing tells you yet.</span></span | |
Move "Recorded for now" to the legend and leave the label as "Tell me". A screen reader hears the prefix before each option, and the repeated prefix hides the choice. Same for the take-updates label. |
||
| 192 | 192 | > |
| 193 | 193 | </label> |
| 194 | 194 | <label class="check"> |
| @@ -199,7 +199,7 @@ function formView( | ||
| 199 | 199 | ${values.followMode === "take-updates" ? html`checked` : null} |
| 200 | 200 | /> |
| 201 | 201 | <span |
| 202 | >Take updates <span class="muted small">is recorded as your choice; nothing takes updates automatically yet.</span></span | |
| 202 | >Recorded for now: take updates <span class="muted small">your choice is kept; nothing acts on it yet.</span></span | |
| 203 | 203 | > |
| 204 | 204 | </label> |
| 205 | 205 | ${errors["followMode"] |
test/new-forge.test.ts +9
| @@ -290,6 +290,15 @@ describe("+ New forge", () => { | ||
| 290 | 290 | } |
| 291 | 291 | }); |
| 292 | 292 | |
| 293 | test("the page promises no update that does not happen", async () => { | |
| 294 | const html = (await (await get(admin, "/forges/new")).text()).replace(/\s+/g, " "); | |
| 295 | expect(html).toContain("Recorded for now: tell me"); | |
| 296 | expect(html).toContain("Recorded for now: take updates"); | |
| 297 | expect(html).toContain("nothing acts on it yet"); | |
| 298 | expect(html).not.toContain("when this forge changes"); | |
| 299 | expect(html).not.toMatch(/as long as its own changes merge/); | |
| 300 | }); | |
| 301 | ||
| 293 | 302 | test("a forge at its depth limit shows no door, and its page says why", async () => { |
| 294 | 303 | usePlacement(app, hostedPlacement({ host: "forge.test", depth: 2 })); |
| 295 | 304 | expect(await (await get(admin, "/")).text()).not.toContain('href="/forges/new"'); |
test/spawn-chain.test.ts +2 −2
| @@ -135,8 +135,8 @@ describe("the chain of forges", () => { | ||
| 135 | 135 | const page = (await (await fetch(`${servers.url}/tot/forge/following`, { headers: { cookie } })).text()).replace(/\s+/g, " "); |
| 136 | 136 | expect(page).toContain("alice/forge-code"); |
| 137 | 137 | expect(page).toContain("kid/forge"); |
| 138 | expect(page).toContain("takes updates"); | |
| 139 | expect(page).toContain("tells when the parent moves"); | |
| 138 | expect(page).toContain("recorded: take updates"); | |
| 139 | expect(page).toContain("recorded: tell me"); | |
| 140 | 140 | expect(page).toContain("1 of its own"); |
| 141 | 141 | }); |
| 142 | 142 |
test/tui-newforge.test.ts +11
| @@ -82,6 +82,17 @@ describe("the new forge screen", () => { | ||
| 82 | 82 | expect(ids()).not.toContain("new-forge"); |
| 83 | 83 | }); |
| 84 | 84 | |
| 85 | test("the screen and its plan promise no update that does not happen", () => | |
| 86 | withScreen(admin, async ({ tui, terminal }) => { | |
| 87 | const form = tui.screen.toText(); | |
| 88 | expect(form).toContain("Recorded for now"); | |
| 89 | terminal.feed("kai\x10"); | |
| 90 | await settleApp(tui); | |
| 91 | const text = form + tui.screen.toText(); | |
| 92 | expect(tui.screen.toText()).toContain("Recorded for now, not acted on"); | |
| 93 | expect(text).not.toMatch(/keeps? (itself )?up to date|updates itself|automatically/i); | |
| 94 | })); | |
| 95 | ||
| 85 | 96 | test("the plan is shown first and makes nothing; enter spawns and shows the claim link once", () => |
| 86 | 97 | withScreen(admin, async ({ tui, terminal }) => { |
| 87 | 98 | const before = await children(); |
new above
offline
Plain-words suggestion: "you chose tell me (not acted on yet)" and "you chose take updates (not acted on yet)". The current wording is correct but reads like a log line.