Why
Stage 3 of #113. The lists, counts and search already read the index; the pages
that still read the metadata branch were the detail views and the activity feed.
The request refreshes the index before any read (Ensure), so those pages can
use the same rows without a new staleness risk.
What changed
index.Store.Issueandindex.Store.Requestassemble one record from its row, its comments and (for a change) its closes and approvals. The two orderings the branch has were stored so a rebuilt record matches the one read from git:request_closes.positionkeeps the author’s order, and comments/approvals are read in the id/principal order git’s path listing gives.- The issue page reads its issue, comments, labels, assignees and number from the index. Its one remaining git read is the backlink search.
- A change page reads its one request from the index for a GET. A write request still reads git, because it has no memo — it may have just changed the record, and must not be answered by the version it replaced.
- The activity feed builds its issue, change, comment and approval events from the index. State changes still come from the metadata log (a reopened issue is two events and the file only knows the last); the latest commit and tags still come from git.
Git calls per page (fixture: 40 files, 30 issues, 30 changes)
| page | before | after |
|---|---|---|
| issue view | 7 | 3 |
| change view | 12 | 9 |
| activity | whole-tree reads | one log, one commit, one tag listing |
The issue page’s remaining call is log --grep for backlinks; the change page’s
are the diff and the merge check. Both are content work, not duplicate lookups.
Checks
./vole workflow check,gofmt,go vet ./..., full-racesuite withGOFLAGS=-tags=sqlite_fts5.- New tests compare the index-assembled issue and change with what
metadatareads from git, field for field, including labels, assignees, replies, an anchored comment, two closes in file order, and an approval. A third test pins that a second push’s body edit is visible afterEnsure. - Existing activity and issue/change integration tests pass unchanged.
Still open (stage 3 follow-ups)
- The persistent
cat-filepool stays undecided: #99’s load harness is not built yet, and these are call counts, not throughput. The remaining calls per page are 3–9, mostly content work. - Indexing state changes during the refresh would remove the activity page’s metadata log. It needs a events table derived from commit subjects; its own change.
- A push-time refresh from the pre-receive hook would remove the one
rev-parseeach read and each search still pays. Also its own change.