Skip to content

stitch2d testing branch: hosted CI run (draft, do not merge) - #2

Draft
v-thampy wants to merge 1135 commits into
mainfrom
stitch2d
Draft

v-thampy wants to merge 1135 commits into
mainfrom
stitch2d

Conversation

@v-thampy

Copy link
Copy Markdown
Owner

Draft, not for merge. This PR exists only to run pr.yml's hosted jobs on the integrated testing branch stitch2d (0dfaa4e3).

The run of interest is windows-pixi-native, whose new step runs tests/core/test_windows_finite_publication.py on GitHub's Windows runner (local NTFS). It covers Average, Stitch and RSM finite publication without directory descriptors. It does not replace the maintainer's own Windows NTFS and SMB qualification.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L1UPY7Ep5ASRCWzUByxzNf

v-thampy and others added 30 commits October 12, 2026 03:27
GE3's four-frame series Run reached the page in one 125 ms drain together
with its terminal, so no frame was drawn while the Run went and a ring
context keyed on the frame survived (probes p08, p09). The row now drives a
live Int 2D Run on a watched directory: each frame is written only after the
previous one is drawn with its own image and LaB6's rings while Stop is still
enabled, and the rings are listed once, before and after Stop.

The frames carry no metadata sidecar: a sidecar read that overlaps a new
arrival fails the live Run with "metadata discovery changed during read"
(pre-existing at 305df40, ledgered separately as
LIVE-METADATA-DISCOVERY-RACE). Test only; the series-Run helper is replaced
by the live one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
Tests only, before any production change. HR1: a .txt read during which
another frame lands beside the image returns the image's own sidecar.
HR2 and HR3 (preservation): a candidate created during an Auto read is
still refused at once; a directory that changes during every read is still
refused after a bounded number of reads. GR1: a real live Run keeps going
when the next frame lands inside a metadata read on the Run's own thread.
Each change is a real file created inside the reader's discovery window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…he fix)

The frozen HR2 asserted that a candidate sidecar created during an Auto
read is refused at once. Auto records only the candidates that exist when a
read begins (probe p02), so a created candidate is visible only as a
directory change, exactly like an unrelated arrival. HR2 now pins what the
guard can tell apart and keeps refusing at once: a recorded candidate that
is rewritten during the read. Tests only; the production fix is not yet
committed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
LIVE-METADATA-DISCOVERY-RACE, pre-existing at 305df40: a live directory
Run whose images carry metadata sidecars stopped with "metadata discovery
changed during read: <directory>" whenever an image arrived while the Run
read an earlier frame's metadata. The reader records the image's directory
(the true dependency of a case-insensitive sidecar lookup) and refused any
read during which it changed; every arrival changes it.

- MetadataDiscoveryChanged(OSError): raised, with the unchanged message,
  when the only discovery inputs that changed are directories that stayed
  directories.
- _with_discovery_revisions classifies every change instead of raising at
  the first: directory-only changes raise the typed error, any other change
  keeps the plain OSError.
- read_image_metadata_observed reads again after the typed error, five
  reads in all with 5, 10, 20 and 40 ms pauses, and returns the first read
  whose inputs held still, with that read's own recorded revisions; the
  fifth refusal propagates.

Still refused at once: a recorded candidate that changes, a recorded
directory replaced or removed, and the selected source changing during the
read (test_p36_average's transient-foreign-bytes row pins it). A sidecar
created mid-read was never recorded as a candidate, so its creation is a
directory change and is read again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…GS2)

Tests only, before the M2 production change. A real live Run's validation
is held at its entry until Stop is pressed, then runs for real: GS1 holds
the loop's re-check of a settled group, GS2 the construct-time check of a
newly arrived frame. Both expect a STOPPED terminal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
GS1 and GS2 held the live loop's validation at its entry, where the alias
check already raises "admission cancelled" and the Run ends STOPPED, so both
passed on their parents (probe p05). The defect lies past that check: a Stop
during the per-image qualification surfaces as InterruptedError("source
qualification cancelled") and the Run ends FAILED. Both rows now hold the
first metadata read inside the selected validation. GS1 (settled re-check)
is the fail-before row; GS2 (construct-time check) is a preservation row,
since _construct's own re-validation already turns it into a stop. Tests
only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
LIVE-STOP-DURING-REVALIDATION, pre-existing at 305df40: pressing Stop
while the live loop re-validated a settled group could end the Run FAILED
("source qualification cancelled") instead of STOPPED. Past its alias
check (which raises "admission cancelled"), the execution graph's
per-image qualification signals cancellation with InterruptedError, and
validate_planned_source passed it through, so the executor's top level,
which treats "admission cancelled" as a stop, recorded a failure.

validate_planned_source now translates that InterruptedError into
RuntimeError("admission cancelled"), exactly as _qualify_for_admission
does for admission. Every other exception keeps its path. _construct's
existing cancellation handler now receives the token it expects at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
Test-only. Headless rows at the qualification boundary and real live Runs that keep every drained event and read the durable output after Stop. At 1cfccd7, C1, C2, C5, Q1-Q5 and Q9 fail behaviourally; C3, C4, Q7, P1 and P2 pass (discriminators and preservation).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…Q4c (before any production edit)

The maintainer chose that a live Auto frame waits one poll, so a sidecar landing just after its image is read. Q3e and Q4c fail at 1cfccd7 (same-extent); Q3f passes there and guards that absence still means no metadata. _published can now wait for a given member count; rows that call it without one are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
… output (LIVE-QUALIFY-REFUSAL)

A metadata file that changes while qualification reads it is a typed source-revision change (MetadataSourceChanged in the reader, MetadataRevisionChanged at _qualify_tiff), so a live Run reads it again at its next poll; other OSErrors, parse failures and oversized inputs stay terminal, and Average's graph requalification reports it as AVERAGE_SOURCE_DRIFT. A live frame waits until its sidecar holds still across a poll: an explicit sidecar must exist, and under Auto a frame waits one poll (the maintainer's choice). When a published frame's metadata changes or appears, at any extent, that output stops growing for the Run: published frames, metadata and lineage are kept, later frames are counted skipped, and the reason stays in every later status. O07's alias row now expects the one Auto readiness wait first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…uisition keeps publishing)

Test-only, added after the first implementation (1928391) from self-review: with whole-group readiness, frames arriving faster than the 0.1 s poll held the whole scan back until the acquisition paused, which 1cfccd7 does not do. P3 guards that each frame waits only for its own metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…ng the whole group (LIVE-QUALIFY-REFUSAL)

Found in self-review before handback (P3): with whole-group readiness, frames arriving faster than the 0.1 s poll held a scan back until the acquisition paused. Admission now takes the leading members whose metadata is ready; a later ready member still waits behind an earlier pending one. A partial attempt publishes its prefix but does not settle the group, so the waiting frame is retried next poll, and an attempt that adds nothing beyond the published frames is skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
S1-S9 (headless: SPEC growth keeps an admitted graph valid and undrifted, a
rewrite does not, one SPEC state per qualification, nothing new persisted,
no grouping inference while live) and L1-L8 (live Runs: row after or before
its image, an image never reduced with another point's row, a rewritten
published row, a later scan, Auto beside a SPEC file, a fast acquisition, a
missing SPEC file).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…EC extent

A live frame under SPEC metadata waits for its own complete SPEC row; a live
Run never infers images per point. An ordinary SPEC TIFF qualification reads
its scan once (read_spec_points) and captures the SPEC file once; each member
carries, in memory only, the extent of SPEC bytes it was read from. Alias,
member, deferred-state and published-drift checks accept a SPEC file that
has only grown past that extent; a rewrite still changes it. Persisted
records, the execution identity and Append digests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…n Append (test-only)

Self-review after the first implementation: an image whose SPEC row never
comes keeps its group re-admitting at the published extent, and once a later
scan grows the SPEC file, Append mode refuses that admission as
"same-extent source identity changed" and the Run fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…al stitch2d)

Composes the paused first implementation with Codex's ratified B1-B3
fixes before the kickoff's CR1-CR5 dispositions. No conflicts; no edit
beyond the merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…ter review (test-only)

C1-C4 (headless): a live qualification waits for a missing row with a
typed SourceRevisionChanged and never borrows one; a complete line that
is not a row is refused with a ValueError naming it; published rows that
are gone or invalid are admitted without metadata so the published-
metadata fence reports them; a SPEC file truncated during the read leaves
the process alive. R1-R10 (live Runs): a row removed after readiness, a
malformed new row, a row rewritten before the reduction read; the SPEC
file removed, a covered row or header rewritten, and a raw rewrite with
its row while a frame waits; Stop inside the currency check and inside
JIT revalidation; progressive publication; a saved live output replays
and Appends unchanged inputs and refuses both after the SPEC file grows.
No production change; the frozen S, L and P1 files are not edited.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…rrency, a bytes SPEC read

Codex's pre-writer review (CR1, CR2, CR6), on the composed cc5af3d:
- Live qualification and its re-checks hold each member to its own valid
  SPEC row (a complete line of the declared column count of numbers, read
  the same way by silx) and never fall back to the finite per-image
  reader. A published member whose row is gone or invalid makes every
  member come back without metadata, for the published-metadata fence; a
  new member whose row is not there yet is the existing typed retry; a
  complete line that is not a row at or before it is refused, naming the
  file, scan and row.
- The admitted row values stay in memory; a live Run's reduction read must
  consume exactly them, and a metadata file changing under that read is
  retried next poll instead of failing the Run.
- SPEC readiness exempts the frames the Run already published (B1's rule).
- When nothing beyond the published frames is ready while a frame waits,
  the attempt waits without admission while the published graph still
  validates exactly; Stop inside that check stops the Run; any other
  outcome is admitted as before (B1, B2 unchanged).
- The scan read copies the file once instead of mapping it, so a SPEC file
  truncated or rewritten during the read cannot fault the process.
Finite reads are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
…uments through (test-only)

test_dependency_graph_state_cannot_rebaseline_after_jit_freeze replaces
_directory_items with a double that copied its signature; the candidate's
new published_members keyword made it a TypeError in the terminal
battery. The double now forwards keyword arguments; its assertions are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D7yaNDFtysn6idFk6L3AAu
v-thampy and others added 30 commits October 16, 2026 18:20
…YCLE)

The six scattering calibration files closed their CalibrationDialogs and
Stitch/RSM pages but never retired or deleted them. One process therefore
kept 203,471 widgets / 14,688 top-levels / 3.2 GiB alive after their 169
tests (diagnostic D2 at e52045c). Per-test DeferredDelete delivery cannot
delete what was never scheduled for deletion.

This extends the maintainer's D5 option 3 (6d61f0d). Each test deletes what
it built once it is clean, through a small per-file _dispose. The helper
polls the owner's own cleanup receipt to CLEAN, bounded at 30 s, asserts
CLEAN with the receipt as diagnostic, then calls deleteLater(); the boundary
delivers.
- Standalone dialogs use dialog.shutdown().
- Page-mounted dialogs are retired by their page: StitchPage.shutdown(), or
  RSMPage.close_page() dispatched explicitly in turned_detector, whose
  _window helper now returns the page. The page deletion takes its window
  along.
- Existing close gestures, barrier releases and body assertions are kept,
  including guided's immediate-CLEAN assertion.
- Rows that already delete their windows (the QMainWindow Escape row and two
  guided rows) are unchanged.
- Guided rows that had no try/finally get one around their unchanged body.

Also included, under the pre-writer's option (i): the stale bounds pin goes
from 6 to exactly 7. Since 6a7e9f1 a session that records resume is
version 7.

Codex pre-writer N-f0270e27: PASS WITH AMENDMENTS. Design N-25a21f03: A.

QT-TEST-LIFECYCLE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
CalibrationDialog._restore_session_when_ready re-arms a 20 ms
QTimer.singleShot while a resumed session waits for metadata, a worker or
the beam probe. The timer had no context object. shutdown() and close()
clear the pending resume, so a later firing returns immediately. But a
timer already armed kept its callable, and with it the dialog wrapper and
the parentless widgets that wrapper holds, alive past the window's deletion
until it fired.

Diagnostic P5g: the bounds session row (version-7 resume) left 477 widgets
/ 141 top-levels at its boundary without this change and 0/0 with it, with
no added wait.

Giving the timer the dialog as its context makes Qt cancel delivery when
the window is destroyed. The 20 ms delay, readiness conditions, resume
identity fence and restoration body are unchanged. Pre-existing since
eb6c94a (2026-10-15).

Codex design N-25a21f03: A.

QT-TEST-LIFECYCLE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
HOSTED-REDS-20261017 test-only families (Codex pre-writer N-ccf76dd2):
- F2: the P3 ProbeSource.to_scan double takes the executor's cancelled=.
- F4: the lattice fraction-reason contract splits: its store half stays
  in tests/core (no GUI import); its two shared-table blocks move
  verbatim to test_results_table.py, reusing the core helpers.
- F6: the threshold session pin is version 7, as for bounds.
- F7: the guided rough-geometry and geometry rows retire the dialog
  through the bounded _close receipt retry, as the frame-table row does.
- F8: P1 records each guideline bar, the failures and whether bars were
  enforced; the final bar assertion is enforced only with CI absent
  (maintainer: report-only on hosted CI). Every functional assertion,
  BARS value and quantile is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
HOSTED-REDS-20261017 F1 frozen regressions on the real projection
builder (red at the parent for the four discriminating cases):
- a native 2-theta pattern with Share on keeps 2-theta unless Int 2D
  draws a complete cake, whose Q it then shares;
- a nonresident derived GI map (no cake drawn, display retained) keeps
  its native q_ip trace; resident, Share follows the derived cake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
Stitch keeps ScientificPreferences.share_axis on for every result since
c1dbc3a, and the shared builder then forced the plot axis onto the
image axis even when no cake was drawn (Stitch 1D, a thumbnail-only or
nonresident frame), overriding an explicit 2-theta, a native 2-theta
result or a GI cut. Sharing now applies only in Int 2D with a complete
cake, as ScientificView already links it (HOSTED-REDS-20261017 F1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
HOSTED-REDS-20261017 F1 test completion (Codex F1_AMENDMENT, option a):
a shared Stitch 2D map holds the plot axis (LF-011's default; the plot
selector is disabled while linked and Share is reached through Options,
LF-013), so the GI-cut, chi and read-back rows turn Share off before
their first independent selection, as a user must. Every science
assertion is unchanged. The positive Options row now also pins the plot
selector disabled while shared, enabled after Off and disabled after On.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
HOSTED-REDS-20261017 F3 frozen regressions, driven by real Qt focus and
the real metadata worker (red at the parent for both roles): focus
leaving a calibrant or direct-beam source field its role's last read
already used starts no read; a changed value, an edit undone before
leaving, Return and choosing the same file again still read, and one
role's read never stands for the other's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
A calibration source field's editingFinished started a metadata read on
every focus-out, so leaving an unchanged field (a checklist row moving
focus, a tab, another window) re-read the source and made the window
busy (HOSTED-REDS-20261017 F3; exposed by b8c3444's re-activation).
Each role now records the inputs of its last applied read; any edit to
them or a new read clears it. A commit reads on Return or on inputs
other than those, so a change, an edit undone before leaving and both
roles stay independent, and the file picker, Read metadata and pending
requests still read through their own routes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FMHuUzRBTwyehRCsUNBxp
…t-only)

The eight W18/W40, W20 and W23-regular rows fail only on hosted Linux. Print
the reservation, closed and replacement (dev, ino, mode, size, mtime, ctime)
tuples, the mount type, the refusal and the facts publish returns, without
changing any assertion of the original unlink/recreate rows. W49 and W50 add
controls beside them: a held descriptor keeps the original inode allocated,
so the replacement cannot reuse its identity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
Codex's pre-push review counts the /proc/mounts reader as evidence machinery.
The filesystem type is recorded as unmeasured; every inode/state, refusal,
post-abort and hook receipt, every original assertion and W49/W50 stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
W51 replaces the candidate as soon as reservation returns and requires the
session's and publisher's first use to refuse it, preserve the foreign bytes
and name no orphan. W52 proves the real exclusive creation descriptor stays
open across the substitution (original dev/inode, st_nlink 0) and closes once
at retirement. W53 covers retirement on abort, on a publisher writer failure
and after a faulted h5py close, with a really-closed pin reported ambiguous
once. The close-fault test's reservation arm now binds to the creation
descriptor on POSIX; Windows keeps its immediate reservation close.

Parent polarity at 53673dc on macOS: W52 and W53 fail (the creation
descriptor is closed during reservation), the reservation arm fails, W51 and
the other close-fault arms pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
Descriptor numbers recur. In W53-writer the publisher's source check closed
descriptor 13 just before reservation created the pin with that number, so
closes.count(pin) saw 2. The spy now starts its close record when it records
the creation descriptor. Parent polarity at 53673dc is unchanged: W52/W53
and the reservation arm fail for the same reasons, W51 passes on macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
Hosted Linux handed a freed inode number to the next file created, so a
candidate replaced by unlink-and-recreate carried the reservation's
(st_dev, st_ino). Cleanup, fsync and final-name observation compare only that
pair: the foreign file was deleted, named as our orphan, or published as a
successful terminal.

On POSIX both reservation helpers now return the exclusive creation descriptor
still open. It keeps the inode allocated, so no other file can carry the pair
while the guards compare it. A failed admission cleans up while pinned and then
closes once. The session holds the pin from reserve (or adopt) to _release; the
publisher holds it through writing, validation and cleanup and closes it in
close_parent, or hands it to adopt. A close fault is reported once. Windows
keeps its immediate close (a held CRT handle would block the final rename) and
returns no pin. The identity comparisons themselves are unchanged.

Pre-existing: the identity-only guards date from 70012f9 and 8d16052.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
…nds (test-only)

The two hosted reds of test_saved_stitch_2d_navigation_keeps_the_requested_curves
were the folder catalog landing between reading the rows and a footer step. The
original rows now read their paths after the catalog lands. New rows hold the
real folder read on an Event: ResultDirectoryBrowser lists a not-yet-catalogued
result where the catalog will (exact-name tie-break, ".." first, no GUI-thread
stat; arrival order with no folder); a Stitch run's rows, footer step and
no-selection fit batch keep the held order after the catalog lands; RSM's rows
and lineout batch likewise. The six RSM stand-ins now list in folder order.

Parent polarity at 77e1b9c (macOS): the owner row, both Stitch rows, the RSM
pin and the RSM batch row fail on their ordering assertions after the gate
entered; the two original navigation rows pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
…election batch (test-only)

The run leaves its result selected, so _fit_batch batches that selection, as
designed. The gated Stitch row now clears the selection before reading the
held rows and the no-selection batch. Parent polarity at 77e1b9c is
unchanged: the row fails on the row-order assertion after the catalog lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
After a run, Stitch and RSM listed new results in arrival order until the
background folder read landed and re-sorted the rows by name, so a row could
move under a click and the footer's previous/next stepped through a different
order than the one just shown (both hosted reds of the Stitch 2D navigation
test). ResultDirectoryBrowser.entries now sorts an active folder's rows with
the catalog's own key, browser_catalog.catalog_order_key: ".." first, natural
name, then the exact name (scan02 and scan2 no longer fall back on read or
arrival order). With no folder, rows keep arrival order. No filesystem call on
the GUI thread.

Pre-existing: the ordering rule is unchanged since before 9e82766.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
Codex's ORACLE_RULING (145f65fb): these rows picked results by row position
assuming stitched order, which held only until the folder catalog re-read.
With rows in folder order from the start, the shown-only residency row binds
first, missing and latest to the page's stitched order and keeps the exact
visible tuple; the pin row selects a listed result other than the pinned one;
the GI/plain row uses the GI run's own target and the plain family; the frame
inspector switches to a listed result other than the current one; the RSM row
revisits two, three, two by identity. Every original behavior assertion stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
"Finite-result saves on POSIX preserve file identity..." now says what users
see: on Linux and macOS, Stitch, RSM, Average and Reintegrate saves no longer
delete or publish a file another process put in their place. "First-seen
files still require confirmation" read like a dialog; a newly seen file is
processed once a second directory listing confirms it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe
…nly)

Codex's terminal review of STITCH-BROWSE-ORDER-20261017 recorded two
non-blocking test-completion residuals:
- The gated Stitch and RSM rows now keep a real selection across the catalog
  landing and assert the current result, the selection, resident key/payload
  identity and the selected batch survive it; the no-selection batch follows
  the rows; a multi-result selection batches in Qt's selected order.
- The rows assert the catalog actually landed with the held results, and
  _held_catalog raises if a held read is never released instead of reading
  late.

Candidate: the three files 20 passed. Pre-fix product (77e1b9c src): the
gated rows still fail at the row-order assertion, after the landing check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01467C8Z5X76RUS1xk16SZBe

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant