Fix #564: stale index cards suppress milestone lists; deep link drops state #565
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!565
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/issue-564"
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?
Fixes #564.
Backend (internal/issues)
Stale index cards suppressed the milestone-filtered list forever: ListIssues serves index-first when indexComplete is true, but it checked coverage only, never freshness. A card written before the Milestone field existed in the Card projection (or a lost update) won the fast path indefinitely while counters (separate store) and thread headers stayed right.
card_version(omitempty JSON; fixtures round-trip, law 5). indexComplete returns false when absent/older so the LIST fallback heals the window (header wins).Frontend (web/)
Deep-link choice (the issue's either/or): the LINK carries the promise. milestoneFilterHref emits
?milestone=<id>&state=all(label counts open+closed;allmaps to the omitted wire param so the server returns both). Bare visits keep the #323 open-only default. Thread-sidebar chip routed through the shared helper; #416 dropdown binds verbatim; link survives refresh. No layout change, no new deps.Docs
Amendments appended to docs/features/02_issues.md and docs/go/12_web_ui.md in the same commit (law 12).
Verification
Independent review of
1d7eac2vs #564 acceptance criteria — verdict: APPROVE (2 small review fixes pushed asdc77ee6, same branch).BACKEND (all hold): card_version is additive omitempty JSON on issues/index.json — encoding/json ignores unknown fields both directions, absent reads as 0 = stale = safe-direction fallback; no protobuf touched (only testdata in repo is internal/store/proto, untouched) — law 5 OK. indexComplete gate adds zero store calls (pure in-memory check; fast path still index+counter = 2 GETs); the LIST fallback is failure-path-only — law 6 budgets untouched (no sim/budget file modified, no assertion weakened). RepairIndex: header-diff, PR-kind ride-through, compacted_through respected, bounded CAS (10) via casUpdate, no locks anywhere, nothing held across store calls. Logging/counters nil-safe (tests pin both). Coverage verified: 96.0% statements on internal/issues (≥95% holds).
FRONTEND (coherent end-to-end, traced): milestoneFilterHref ?milestone=&state=all → resolveIssueState(all)=all → issueListState=all→'' (omitted) → SDK qs skips '' → server absent-state = both — landing shows the promised open+closed set. Bare visits unchanged (#323 open default intact, query builder untouched). #416 dropdown binds search.milestone verbatim → selected on landing; all state in URL → refresh-safe. Thread-sidebar chip (Issue.jsx:614) + issues-row chips + both Milestones.jsx links all route through the one helper; no hand-rolled ?milestone= hrefs remain. No package.json change, no new deps — law 1 OK. No layout/CSS change (href-only), so themes + 390px hold by construction; no rendered browser proof (stated, same as PR).
TESTS (genuinely pin the fix): new JS test run against origin/main worktree fails 5/7 (the 2 passing are pre-existing-behavior regression guards: bare-visit default, dropdown binding). Go tests don't compile pre-fix (new symbols) and the gate cases contradict old logic by inspection (old indexComplete returned true for coverage-without-version). No budget assertions weakened.
DOCS: amendments in 02_issues.md + 12_web_ui.md in-commit (law 12); frozen primitives untouched (no route/auth/policy/event/task/CLI registry changes).
REVIEW FIXES pushed (
dc77ee6): (1) RepairIndex had zero production callers — a backfill nobody can invoke, so stale repos (incl. the live one) would pay LIST on every read forever. ListIssues now self-heals a version-stale index best-effort while header truth is in hand (healStaleIndex: small repos only, next-1<=headerScanCap proves full scan coverage; empty scans never stamp an index on issue-less repos; failures reuse the drop channel, never surface). Precedent: updateIndex already does sync CompactIndex maintenance writes. (2) Service.Log was never wired outside tests — newIssuesService now sets svc.Log=slog.Default() (notify.go precedent), so drops are logs in prod, not just counters. Tests added: read-path self-heal + no-stamp-on-empty; -count=3 stress green. Full issues suite -race green, cmd/walhub tests green, node unit 1337/1338 (sole failure is the pre-existing live-server smoke test, fails on pristine1d7eac2too), gofmt/vet/build clean.LIVE-INSTANCE angle: not exercised — repair path verified in unit tests only; no live instance reachable from here. Note the self-heal means the live instance recovers on its next milestone-filtered list read after deploy (no operator step). Themes/390px rendered check still open if you want belt-and-braces, but nothing in this diff can move layout.