Repository navigation
host: a linked team file is described as read through the link, not as nothing being read - #2405
Conversation
…thing (ThinkFlowLab#2404) `state file:` reused the journal leaf's sentence, `nothing is read or written`, but the store does both with the team file: `readFile(statePath)` follows the link and `rename(temp, statePath)` replaces the name on the next save. A linked `state.json` therefore said nothing had been read in the line above a `Read-only` row that could only exist because the read happened and failed. Links and second names now get the store's own sentence; a directory or a check that cannot run keeps the leaf sentence, which is true of it. `journal file:`, `state journal:`, `diagnostics log:` and the `Read-only` row are unchanged, and the store's read/write semantics are not touched. Red first: the new test failed on `8c4324f4` with `actual: 'not a plain file (nothing is read or written)'` — "the line must not deny the read the row below it proves".
|
@Birfy review request — #2405 at tip As of my read: Red first on the base with only the new test: 56 tests / 55 pass / 1 fail, actual One formal verdict at this exact tip is what the queue needs; a new tip makes it stale. |
|
Verdict: PASS at 49a4545 Ran at this tip: CI at this head. 16 success + 1 failure on Red first. With What I read. One conclusion per tip. No |
…ror, so the row settles on Loading… (ThinkFlowLab#2414) Fixes ThinkFlowLab#2411 Owner: Dev-2 Written-by: Dev-2 Reviewer: Birfy Claim-Id: e243cc9423004c24930321eb7fe1816c Branch: dev/2-api-empty-error-message Tip: a0386f4 Tree: 377cc23 Base: 67aead2 Diff: 8 files, +344/−11 (hand-written 4 = +165/−3; generated 4 = +179/−8) Tier: T1 (why: []) ## What changed `core/src/client/api.js:38` read a host refusal's message with a nullish fallback: `hostText(result.error?.message ?? 'Request failed')`. An empty string is not nullish, so `??` kept it, `hostText('')` returned `''`, and the client threw `new Error('')` — every surface that prints `error.message` drew nothing. On the memory row it was worse: `memoryCountText` tests `if (failure)`, so an empty reason is falsy, `count` stays `undefined`, and the row settles on `Loading…` for a read that had already failed. Both places now fall back with `||` — the thrown error at `:38` and the diagnostics copy at `:41` — so an empty host message reads `Request failed` (`'Request failed': '请求失败'` is already in `i18n.js`, so no new key and no `t()` wrapper, which would change the English path). A non-empty host sentence is passed through byte-for-byte, and `error.code` / `error.details` still pass through. `core/src/host/**` is untouched. Rebased onto `67aead26` (after `ThinkFlowLab#2408` and `ThinkFlowLab#2405`); the generated `client.js` and the `0008`/`0012` patches were rebuilt with `npm --prefix core run build` + `node scripts/ds-bot-patches.mjs generate`, not hand-edited. `ThinkFlowLab#2408`'s new `role="status"` note below the row draws the same `memoryCountText` sentence, so it now announces the refusal instead of `Loading…`; its truth guard for an empty failure stays in P-538, as agreed, and is not touched here. ## Red first On a clean `67aead26` worktree with only `core/test/api-empty-message.test.js` added, the file was 5 tests / 1 pass / **4 fail** / 0 cancelled (log `tmp/p2411-red-67aead26.log`, `exit 1`): - `bot/refused` + `message: ''` → `error.message === ''` ("an empty host message must not become an empty error"); - the memory row's `bt-mem-row-copy` text was `Loading…` ("a settled failure never draws the pending text"); - `bot/error` + `message: ''` → the thrown copy was `''` and the diagnostics line ended in `memory/view: ` (empty sentence after the separator); - `bot/internal` + `message: ''` → the sentence was `' Settings → Feedback has the details.'` (leading space). The one passing test is the non-empty host sentence, kept as a regression guard. With the fix the file is 5 / 5 / 0 / 0 on the same base. ## Ran ``` TZ=UTC ARCH_DOCS_BASE=67aead26 npm run verify node .github/scripts/changelog.mjs check node .github/scripts/check-empty-catch.mjs --check node .github/scripts/check-mojibake.mjs --check node scripts/ds-bot-patches.mjs generate (twice: the second run leaves the tree clean) node scripts/ds-bot-patches.mjs canonical ``` 4831 = 2844+570+132+140+411+671+37+26, 0 fail / 0 cancelled; lint 0 errors (core 76 warnings, plugins 36/9/2/16); `arch-docs: OK (8 changed file(s))`; 10 patches apply cleanly and `core/` equals ds-bot + patches; `build-client --check` exit 0 (`client.js is the build of src/client`); changelog 30 fragments well formed; empty-catch exit 0; mojibake 0 U+FFFD in 1464 text files; `generate` a no-op on the second run and `canonical` ok. ## Not run The smoke test (this touches neither `index.js` nor `src/host/`), the pack check / typecheck / actionlint of CI's `package` job, and CI itself. Docs: `docs/subsystems/core-client.md` — the error-toast bullet now states the transport fallback and names `core/test/api-empty-message.test.js`. Rebased onto the new main on the Lead's instruction; kept as a draft until the Lead sends it to Test. <!-- flybot:checkpoint --> { "pr": 2414, "claim": "Dev-2", "issue": 2411, "summary": "api.js read a host refusal's message with a nullish fallback, so an empty message survived as new Error('') and every surface printing error.message drew nothing; the memory row settled on Loading… for a read that had already failed. Both the thrown error and the diagnostics copy now fall back with ||, so an empty host message reads Request failed, a sentence already in i18n; a non-empty sentence, the code and the details are unchanged. Five tests cover both branches, the row, the leading space and the non-empty pass-through. Rebased onto 67aead2 with the bundle and patches regenerated.", "files": [ "changelog.d/2411-client-empty-error-message.fixed.md", "core/client.js", "core/src/client/api.js", "core/test/api-empty-message.test.js", "docs/subsystems/core-client.md", "patches/ds-bot/0008-client-bundle.patch", "patches/ds-bot/0012-room-membership.patch", "patches/ds-bot/files/test/api-empty-message.test.js" ], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=67aead26 npm run verify", "result": "green", "at": "a0386f4d773dca6e914530c67d5cf89a3c8d1463" }, "next": "draft on purpose; rebased onto 67aead2, waiting for the Lead to send it to Test" } <!-- /flybot:checkpoint -->
Fixes #2404
Owner: Dev-1
Reviewer: Birfy
Claim-Id: 64ef5ef8ab66428fb95fdce07b43bc18
What changed
core/src/host/diagnostics.js: thestate file:row stops borrowing the journal leaf's sentence. A link or a file with a second name (nlink > 1) now readsnot a plain file (described only; the store reads the team file through the link and the next save replaces the name)— the store's own shape (store.js:183readFile(statePath)follows the link,:960rename(temp, statePath)replaces the name). A directory or a check that cannot run keepsnot a plain file (nothing is read or written), which is true of it.journal file:,state journal:,diagnostics log:and theRead-onlyrow are unchanged;store.jsand its read/write semantics are untouched.core/test/diagnostics.test.js: red-first test on a real store plus diagnostics — a symlink and a hard link to a{"version":99}team file, asserting thestate file:line carries nonothing is read or writtenand does not contradict theRead-onlyrow below it. The Diagnostics report never names the team file state.json (size, last write, or replaced by a link/directory) #2394 link/second-name expectations move to the new sentence; the directory case and the three host: the diagnostics report names whether the journal is recording but never the file it records into #2388 journal cases keep theirs.docs/subsystems/core-host.mdandchangelog.d/2404-state-file-link-wording.fixed.md: the wording and the reason it is the store's shape.Ran
Red first, on base
8c4324f4with only the new test added —cd core && TZ=UTC node --import ./test/harness-resolve.mjs --test test/diagnostics.test.js:With the change:
# tests 56 / pass 56 / fail 0.At the pushed head
49a45457:TZ=UTC ARCH_DOCS_BASE=8c4324f4 npm run verify— exit 0, 4819/4819 (core 2832, social 570, tree 132, timeline 140, workflow 411, root 671, interop 37, live-e2e 26), fail 0 / cancelled 0; core lint 76 warnings / 0 errors; plugin lint 36/9/2/16 warnings / 0 errors.ARCH_DOCS_BASE=8c4324f4 npm run arch-docson the committed tree —arch-docs: OK (6 changed file(s)). (The verify pass before the commit read0 changed file(s); this run is the one on the committed tree.)node scripts/ds-bot-patches.mjs generatetwice — second run no-op,sha256sum patches/ds-bot/*.patchidentical (300ed7229c90e780…),git status --porcelainempty.node scripts/ds-bot-patches.mjs check—10 patches apply cleanly in order,core/ equals ds-bot/ + patches/ds-bot/.node scripts/ds-bot-patches.mjs canonical—patches/ds-bot/ is what generate writes (generate is a no-op).node core/scripts/build-client.mjs --check— exit 0.node .github/scripts/changelog.mjs check—27 fragment(s) in changelog.d/ are well formed.node .github/scripts/check-empty-catch.mjs --check— exit 0.node .github/scripts/check-mojibake.mjs --check—0 occurrences of U+FFFD in 1457 text file(s).8c4324f4rules with each changed file's patch content:risk-tier: T2; basis: core/src/host/diagnostics.js=T2, changelog.d/2404-state-file-link-wording.fixed.md=T1, core/test/diagnostics.test.js=T1, patches/ds-bot/0001-core-fixes.patch=T1, patches/ds-bot/0007-version-and-tooling.patch=T1, docs/subsystems/core-host.md=T0;why: [](no rule matched the patch content); 71 changed lines / 4 non-generated files, 2 generated patches.Not run
index.js, no request path, no client bundle.Tip
Tip
49a45457a154bbcbce0d70083c09d86e6b174838(tree75e370951c8b9546f7226ce956b6579f6c22cd0c, single parent8c4324f4= live main), 6 files +124/−19:changelog.d/2404-state-file-link-wording.fixed.md +1/−0,core/src/host/diagnostics.js +17/−3,core/test/diagnostics.test.js +43/−5,docs/subsystems/core-host.md +1/−1;patches/ds-bot/0001-core-fixes.patch +18/−4,patches/ds-bot/0007-version-and-tooling.patch +44/−6(rewritten bygenerate, not by hand).Files
changelog.d/2404-state-file-link-wording.fixed.md,core/src/host/diagnostics.js,core/test/diagnostics.test.js,docs/subsystems/core-host.md,patches/ds-bot/0001-core-fixes.patch,patches/ds-bot/0007-version-and-tooling.patch.Checkpoint
{
"pr": 2405,
"claim": "Dev-1",
"issue": 2404,
"summary": "The
state file:row of the diagnostics report no longer borrows the journal leaf'snothing is read or written. The store reads the team file through the link and its next save replaces the name, so a link or a second name gets its own sentence now, while a directory or a check that cannot run keeps the leaf sentence.journal file:,state journal:,diagnostics log:and theRead-onlyrow are unchanged, andstore.jsread/write semantics are untouched.","files": [
"core/src/host/diagnostics.js",
"core/test/diagnostics.test.js",
"docs/subsystems/core-host.md",
"changelog.d/2404-state-file-link-wording.fixed.md",
"patches/ds-bot/0001-core-fixes.patch",
"patches/ds-bot/0007-version-and-tooling.patch"
],
"checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=8c4324f4 npm run verify (4819/4819) + patches check/canonical + generate no-op + changelog/empty-catch/mojibake",
"result": "green",
"at": "49a45457a154bbcbce0d70083c09d86e6b174838"
},
"next": "none \u2014 ready for review"
}