751a1f9fff1d6d77c2da690d1369dca64ba04fee
braney
  Sat Sep 19 18:31:42 2026 -0700
sessionDirTester: pin how a saved session's data directory is named

A saved session's custom tracks and region files are moved to a durable
directory named from the user name and the session name.  #10138 widened the
session half of that name from 8 hex characters to 10: 8 characters of md5 is
4 billion values, and the birthday arithmetic over hundreds of thousands of
sessions is not comfortable, since a collision puts one user's files in another
user's session.

Widening a name that is already on disk is the risky half.  Directories written
before the change carry the old width and their files are still in use, so the
cleanup code has to be able to name both, which is why the width is a parameter
rather than a constant in the middle of the function.

The property pinned here is not the hash, it is that the short name is a PREFIX
of the long one.  That is what lets code holding the new name find a directory
written under the old one, and it holds only because both come from the same
md5 truncated to different lengths.  Also pinned: the two-character spreading
directory, the user name appearing as given, and the three calls that must
abort rather than invent a path -- a relative sessionDataDir, and a width of 0
or 33.

None of this is visible.  A session whose directory is named differently does
not report an error, it comes back without its custom track.

Watched to fail and then pass: narrowing the width back to 8 turns it red on
the width line.  Recorded as sandbox-ab in utils/testRegistry.

refs #10138, refs #38391

diff --git src/utils/testRegistry/registry.tsv src/utils/testRegistry/registry.tsv
index 95f1e2053e8..ec5942c01e1 100644
--- src/utils/testRegistry/registry.tsv
+++ src/utils/testRegistry/registry.tsv
@@ -36,31 +36,31 @@
 #   evidence  what has been seen, weakest first: unrecorded, assertion-only, sandbox-ab,
 #             release-ab, caught-regression.  "-" on a row with no test.  The vocabulary is
 #             proof.js's from the docent suite, minus the two levels that need a browser,
 #             so the two tables can be read on one scale.  Every row starts at unrecorded
 #             and earns its way up by measurement, not by argument.
 #   note      what the test holds down.  On a row with no test, what it would have to hold
 #             down, which is the first thing the person who writes it needs.
 #
 # One ticket can have several rows and one test can defend several tickets; both happen
 # here already.  A ticket cannot be both covered and waiting.
 #
 # `testRegistry check` reads every row and fails when one has rotted, so a test cannot be
 # renamed or deleted without coming here.
 #
 #ticket	release	test	docent	why	evidence	note
-10138	504	-	rm10138.docent.yaml	invisible	-	needs one: the session data directory hash went from 8 to 10 hex characters
+10138	504	hg/lib/tests/sessionDirTester.c	rm10138.docent.yaml	invisible	sandbox-ab	the session directory hash is 10 characters and the legacy 8 is a prefix of it
 20824	504	hg/utils/netToBigNet/tests/makefile::simpleTest	-	library	unrecorded	a net converted to bigNet and back, byte compared
 27988	504	-	-	invisible	-	needs one: a server that is not the node hg.conf names has to recognise itself
 36212	504	hg/lib/tests/bedItemRgbTester.c	rm36212.docent.yaml	library	sandbox-ab	an explicit itemRgb on beats the presence of a color setting, in the stanza and from a parent
 37263	504	lib/tests/pathSimplifyTest.c	-	library	unrecorded	dot-dot collapsing, checked against the right answer rather than against the old one
 37969	504	-	rm37969.docent.yaml	library	-	needs one: a quickLifted container must not hide the tracks inside it
 37984	504	lib/tests/hmacTest.c	-	library	sandbox-ab	the pending social identity is signed with hmacMd5, not a plain md5 of salt plus fields
 38086	504	-	-	invisible	-	needs one: a stale cart visibility variable must not hide a new BLAT result track
 38126	504	lib/tests/htmlSanitizeTest.c	rm38126.docent.yaml	library	unrecorded	the allowlist that hub and custom track description HTML is filtered through
 38184	504	-	rm38184.docent.yaml	invisible	-	needs one: db= resolving to the assembly already loaded must keep the session position
 38185	504	hg/hgSession/tests/backupParseTest.c	rm38185.docent.yaml	invisible	unrecorded	an empty pair in a session backup must not eat the variable in front of it
 38185	504	lib/tests/cgiParseTest.c	rm38185.docent.yaml	invisible	unrecorded	an empty CGI pair must not abort the request
 38198	504	-	rm38198.docent.yaml	library	-	needs one: a second lift has to update a track already in the hub
 38225	504	hg/lib/tests/mallocTopPadTester.c	-	perf	sandbox-ab	the hg.conf step size reaches the C library: the heap grows in one 16 MB jump, not the default one
 38233	504	-	-	perf	-	needs one: RefSeq status is asked once per track, not once per gene; the test has to count the queries, not the seconds
 38236	504	-	rm38236.docent.yaml	library	-	needs one: a quickLift chain with no aligned block in the window must not crash