beads: the board names every clipped table it draws from
The board raised its truncation flag for a clipped issues or dependencies
table and for nothing else, so a clipped labels table took the pills off
every card and the options out of the label filter in silence, and a
clipped custom_statuses table could put a card in the wrong lane with the
counts still reading as facts.
The flag could not grow to hold that. It is paired with a count line —
"the first N of M issues" — so it can only mean the reads that decide N
and M; widening it would have made a bool that means four different
things and a number that no longer follows from it. Data.Truncated and
ShownOf are therefore byte-for-byte what they were (mcpsrv's list_issues
reads them as they are), and the wider fact is a new field: Clipped, one
entry per clipped table the board reads, in read order, each naming the
table, the rows read against the rows that exist, and what the board lost
by the rest.
The banner follows. The count line now prints only when the issues read
was actually short — "the first 4 of 4 issues" was a wrong sentence, not
a warning — and every other clipped table gets its own line beneath it.
The detail pane keeps its single sentence from 82d997d; a pane that never
drew a lane has no use for a board's list.
TestBoardTruncationIsUnchanged is now TestBoardTruncationFlagIsUnchanged:
the flag is what it was, which is the claim that survives. Its "comments
does not flip the board" subtest survives as "a clip in a table the board
does not read" and now also asserts comments reaches neither the flag nor
the list, plus a new subtest pinning that labels and custom_statuses are
reported without touching the flag.
docs: spell out the clipped-read answers
web: the detail pane says when its read was clipped
The board has always carried a truncation banner; the detail pane it
shares a template with carried nothing, so an issue assembled from
tables clipped at 2000 rows looked complete, and an id in the tail of a
big tracker was answered "Issue not found." — which the page cannot
know.
Two lines, both in the banner's idiom. A pane built from a clipped read
says so and names the tracker's true size when the issues table itself
was cut; a miss over such a read says the id was not among the rows
read, which is not the same as saying it does not exist. A complete read
keeps the plain "Issue not found.", and the board's own banner is
untouched.
mcpsrv: report the projection's clip on get_issue and list_milestones
Max clips every table read at 2000 rows. list_issues has always said so
(table_truncated, table_total); the other two answers computed over the
same read said nothing, so a rollup over a prefix of the tracker read as
arithmetic about the whole of it, and an id in the tail of a big tracker
was answered "no such issue" — a claim neither read can support.
get_issue now carries the two fields on every answer and splits the
miss: a complete read keeps the plain refusal, a clipped one says the id
was not among the rows read, names the cap and the true total, and ships
the payload (issue: null beside table_truncated) so the two misses are
one field apart rather than one adjective apart. list_milestones carries
the same two fields.
beads: report a clipped read from the remaining projections
docs: read_rows answers strings or null
beads: stop flattening a stored NULL string
mcpsrv: answer a real NULL as null
web: stop printing store paths to the owner
web: stop printing browse errors to the reader
The overview rendered the browse layer's own error text into the page, under
"Could not read history: " — dolt internals and the store's path on our disk,
which nothing else on this surface discloses and which a reader can do nothing
with.
The page now carries a fixed sentence and the reason goes to the log with the
database id (slog + scribe.Err). The view field is a bool rather than a message,
so no error string can reach the template by being assigned to it later. The
empty-database state the page already reported ("No commits.") is untouched:
that is a fact about the database, not a failure.
web: tell a database outage from a missing database
loadRepoForBrowse turned any error from GetRepoByOwnerAndName into a 404, so a
metadata store that could not answer told every reader on the instance that
their database does not exist — for as long as Postgres was down, in the voice
reserved for "there is nothing here". loadRepoForAdmin did the same on the
settings page.
Both classify through repoLookupFailed now: db.ErrNotFound keeps the 404, and
it stays the same 404 the visibility rule renders for a PRIVATE database the
caller may not see, so a masked database and a missing one remain
indistinguishable. Anything else is a 500 through the shared error page, with
the cause logged (slog + scribe.Err) and never rendered.
beads: report a clipped read from every projection
mcpsrv: name the cursor a commit-log miss was asked about
browse: say which cells are actually NULL
mcpsrv: a bad commit-log cursor is a miss, not a fault
web: link issue ids to the tracker that owns them
mcpsrv: answer what is ready across every tracker
browse: report an unparseable start hash as a missing ref
remoteapi: gofmt the integration test
doltsrht: serve /mcp on the web listener