Fix #605: Code-review toggle stuck on loading for unset docs #610
No reviewers
Labels
No labels
actions
bug
cli
duplicate
enhancement
fork
forum
git storage
help wanted
insights
invalid
issues
moderation
oidc
ownership transfer
packages
pr/merge protection rules
projects
pull requests
question
releases
sponsorships
tags
webhooks
wiki
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crueber/walhub!610
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/issue-605"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Option A sentinel split: unseeded is undefined (signals, prefill, Show/disabled gates); null keeps meaning seeded-but-unset → checked. extractSelfApproval/withSelfApproval untouched. Tests: new settings-review-sentinel-605.test.js (5 tests) + settings-review-586 sentinel pin update; full-minus-smoke 1564/1564 green; vite build + esbuild SDK green; go vet clean. Docs: 12_web_ui.md FIXED (Forgejo #605) same commit. No new deps; Tailwind untouched; 390px reasoned (sentinel-only, no layout change).
Independent review — verdict: APPROVE (no fix commit; working tree left untouched)
Checked the full
origin/main..origin/fix/issue-605diff in/tmp/walhub-605against every acceptance bullet of #605. All green.1. Sentinel swap is complete — no missed
getSelf() === null/!== nullreads.Grep over
web/src/pages/Settings.jsxfinds exactly fourgetSelf()reads, all on the new sentinel: signal initcreateSignal(undefined)x2 (value + base), prefillgetSelf() === undefined,<Show when={getSelf() !== undefined}>,disabled={getSelf() === undefined}. Zero remaininggetSelf() === null/!== nullstrings anywhere in the file. (The other=== nullsentinels in the file —getText/getVis/getFlags— belong to sibling knobs whose extractors never return null-for-unset, so they are not the same bug.) The bug cannot reintroduce through a missed read.2.
extractSelfApproval/withSelfApprovalbyte-identical — contract preserved.git diff origin/maintouches nothing underweb/src/lib/;repoReview.jsis unchanged since #586 (ae42bd6). null-for-unset and the append/replace paths are intact.3.
checked/allowedexpressions unchanged (!== false); PUT round-trip traced.checked={getSelf() !== false}andconst allowed = getSelf() !== falseare byte-identical to pre-fix. Render matrix: unset (null) → checked,true→ checked,false→ unchecked — as required. Round-trip note (deliberate, no surprise): saving an untouched unset knob writesallow_self_approval = trueexplicitly viawithSelfApproval(current, true)rather than omitting the key. Both readings are semantically identical under the default-ON contract, and the choice is forced by the existingallowedexpression rather than new logic — fine as-is.selfDirty()(getSelf() !== getSelfBase()) load trace:undefined/undefined→ not dirty while loading; effect seeds both to the same value (null/nullfor unset) → still clean; only the toggle'sonChange(booleans only) can diverge them → "unsaved changes" appears exactly on user edit. No dirty-check surprise.4. No-clobber preserved — the effect cannot reseed after user edit.
The gate is
doc !== undefined && getSelf() === undefined, and the only writers are the effect itself (writes seed values, neverundefined), the boolean-onlyonChange, and save/failure-reseed (booleans or fresh seeds, neverundefined). Once seeded, the condition can never go true again — user edits are safe.5. Explicit true/false render correctly — same
!== falseexpression covers both without branching (pinned by the new test).6. Docs amendment (law 12):
docs/go/12_web_ui.mdgains theFIXED (Forgejo #605)entry in the same change. No new deps (law 1): the new test imports onlynode:test,node:assert/strict,node:module,node:fs.7. Tests fail pre-fix, pass post-fix. New
settings-review-sentinel-605.test.js(5 tests) + updatedsettings-review-586pin pass on the branch (7/7 with the 586 file). I temporarily restoredorigin/main'sSettings.jsxand re-ran the new file: it fails (assertion error on the sentinel pins), then restored the fix byte-for-byte (git statusclean apart from untrackedweb/node_modules). Full unit suite: 1566/1567 pass; the single failure issmoke.test.js("built SPA shell served at / and /setup", 403 vs 200) — it requires a live server on:8080(something else is answering in this environment) and is excluded by the project's own "unit files minus smoke" convention; this diff touches no server code, so it is unrelated and pre-existing.No defects found — nothing to fix, no commit pushed.