94 lines
11 KiB
Markdown
94 lines
11 KiB
Markdown
|
|
# Zulip navigation/search source contrast — 2026-09-27
|
|||
|
|
|
|||
|
|
LEARN-0014; Codex author-model review. [Protocol](../evolution/cycles/2026-09-27-zulip-navigation.md)
|
|||
|
|
committed as `f3ac569` before source inspection. Stream B, group
|
|||
|
|
B-independent-navigation-source-v1. **Static source evidence only**: no application
|
|||
|
|
build, browser run, upstream test execution or inference call.
|
|||
|
|
|
|||
|
|
Pinned Zulip revision `5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c`, deliberately reused
|
|||
|
|
from the earlier recovery review, not claimed latest. [Source manifest](ZulipNavigationSources.json)
|
|||
|
|
records twelve files, raw SHA256 and reviewed line ranges. This is one independently
|
|||
|
|
developed application family, already known to this research through different paths;
|
|||
|
|
it is not twelve independent uses or an independent review of our conclusions.
|
|||
|
|
|
|||
|
|
## Located claims
|
|||
|
|
|
|||
|
|
| Claim | Exact pinned locators | Observed code | Interpretation / limit |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| ZN01 | [hash reconstruction](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/hashchange.ts#L171-L235), [history metadata](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/browser_history.ts#L168-L195), [save guard](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/narrow_history.ts#L10-L63) | Hash terms select a message view; history state supplies message pointer/offset. Saving selection checks URL/filter agreement first. | Addressability and within-session continuation are separate contracts; these paths require the client. No no-script or direct-load runtime claim. |
|
|||
|
|
| ZN02 | [fetch continuation](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_view.ts#L830-L878), [selection guard](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_view.ts#L1413-L1481), [current-list lifecycle](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_lists.ts#L24-L64) | Main narrow-fetch continuation returns when its captured message list is no longer current; selected-message rendering also checks list identity. | Partial support for protecting current selection/hash effects without requiring a global navigation counter. Not a proof for all callbacks. |
|
|||
|
|
| ZN03 | [success routing](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_fetch.ts#L213-L280), [processing](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_fetch.ts#L159-L210), [preserved view policy](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_list.ts#L152-L199), [list updates](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_list.ts#L269-L326) | For a noncurrent, nonpreserved list, success switches to data-only processing instead of discarding the response. Preserved combined-feed views are an explicit exception. Other message/sidebar processing still occurs. | Leaving a view does not make its data useless. Cache/data applicability differs from permission to affect active navigation. Not a claim that inactive results have zero UI effects. |
|
|||
|
|
| ZN04 | [error and connection feedback](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_fetch.ts#L418-L508) | Success and HTTP 400 close shared connection feedback before the noncurrent-list error guard. Errors for noncurrent, non-combined lists return before further processing/retry; other errors have backoff/retry handling. | Feedback has scopes too. Global connection evidence and view-specific errors are different; helper internals and runtime correctness were not audited. |
|
|||
|
|
| ZN05 | [query dispatch](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search.ts#L60-L95), [suggestion callback](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search.ts#L151-L212), [suggestion construction](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search_suggestion.ts#L1530-L1636), [IME/Enter handling](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search.ts#L290-L335) | Committed search passes parsed terms to an injected callback and blurs search; the inspected suggestion provider synchronously returns a list. Enter/IME handling distinguishes composing or selecting a suggestion from submitting search. | Do not treat every keystroke as a remote query race. Callback wiring and all imported suggestion-helper internals are outside this twelve-file slice. |
|
|||
|
|
| ZN06 | [search continuation](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search.ts#L396-L437), [close focused search](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/search.ts#L470-L483), [editing focus restore](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_list_view.ts#L345-L392) | Search entry focuses search; exit may keep a narrow, redirect or focus the app. Editing focus capture records message/selection; restoration checks selected-message identity, then schedules focus work. | Non-modal task continuation differs from return to a modal invoker. A pre-timeout identity check is not proof of completion-time focus ownership or AT behavior. |
|
|||
|
|
| ZN07 | [target-message lookup](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_view.ts#L662-L699), [anchor navigation](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_view.ts#L1002-L1074) | An auxiliary target lookup re-enters show from success/error callbacks. The anchor fetch continuation creates/uses the then-current list through a closure. These branches have no visible captured-current-list guard like ZN02. | Concrete unverified paths prevent a whole-app ownership guarantee. No reproduced race, exploit or vendor bug claim; unseen transport/caller behavior may constrain execution. |
|
|||
|
|
| ZN08 | [preserved-list reuse](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/message_view.ts#L175-L194), [filter source](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/src/narrow_state.ts#L14-L67), [inspected upstream test](https://github.com/zulip/zulip/blob/5b06fa3d34f28fa01f459fbf3ba053e3c0858e9c/web/tests/message_fetch.test.cjs#L1-L40) | A preserved combined-feed list may be reused; narrow state derives from the current view. The inspected test covers date-anchor parameter handling. | List identity is not equivalent to a monotonically increasing navigation generation. This test file supplies no executed or inspected competing-navigation coverage; the rest of the suite was not reviewed. |
|
|||
|
|
|
|||
|
|
## Bounded trace and counterexample to overgeneralization
|
|||
|
|
|
|||
|
|
The hash path parses route terms and calls message_view.show. That function constructs
|
|||
|
|
or restores a list, updates the hash when required and makes the list current. A needed
|
|||
|
|
message fetch captures that list. When it completes, data/fetch state can still be
|
|||
|
|
processed, while the main view continuation checks current-list identity before changing
|
|||
|
|
selected-view state. See ZN01–ZN03. This is a trace across located functions, not a
|
|||
|
|
running-session observation. Search dispatch itself is located, but the initializer
|
|||
|
|
that supplies its injected navigation callback was not included; do not infer its
|
|||
|
|
complete wiring from the naming alone.
|
|||
|
|
|
|||
|
|
The meaningful contrast is **applicability per effect**:
|
|||
|
|
|
|||
|
|
| Effect | Located decision / remaining uncertainty |
|
|||
|
|
| --- | --- |
|
|||
|
|
| Populate cached message data | Can remain useful after leaving a view; cache consistency/retention internals not audited |
|
|||
|
|
| Update a preserved rendered list | Explicit conditional combined-feed exception; not a universal discard rule |
|
|||
|
|
| Change selected view/hash/message position | Main continuation and selection paths check current list identity |
|
|||
|
|
| Update shared connection feedback | Some updates precede view-specific error applicability checks |
|
|||
|
|
| Move input focus | Search-task policy and editing selection context are distinct; timer completion still untested |
|
|||
|
|
|
|||
|
|
Our earlier generation guard is one implementation of a selected-view policy. It must
|
|||
|
|
not become a requirement to drop an entire response or every side effect whenever a
|
|||
|
|
newer navigation exists. Nor does Zulip's list identity establish that all effects are
|
|||
|
|
safe: ZN07 and deferred focus in ZN06 are explicit limits requiring additional evidence.
|
|||
|
|
A preserved object can become current again; object identity and latest-intent generation
|
|||
|
|
encode different policies. Freshness, authorization and data consistency are not proven
|
|||
|
|
by either identity mechanism.
|
|||
|
|
|
|||
|
|
## Pattern disposition: revision without promotion
|
|||
|
|
|
|||
|
|
Revise URL-addressable State to make client-fragment reconstruction an explicit option,
|
|||
|
|
with its required client/runtime contract, separate from server-visible path/query
|
|||
|
|
resolution. Hash-based addressability does not establish progressive enhancement.
|
|||
|
|
|
|||
|
|
Refine Progressive Enhancement's asynchronous-navigation obligation to decide result
|
|||
|
|
applicability per effect: cache data, current selection, global versus local feedback,
|
|||
|
|
and focus. Zulip is a static implementation contrast for that obligation, **not a
|
|||
|
|
verified no-script application or a full known use of Progressive Enhancement**.
|
|||
|
|
Focus Return gains only a non-modal scope contrast, not an additional complete modal use.
|
|||
|
|
|
|||
|
|
This is one consequential revision, with corroborating identity guards and limiting
|
|||
|
|
branches recorded together. CAND-0009/0010/0016 remain draft/hypothesis; independent
|
|||
|
|
full-contract use counts stay unassessed. Independent implementation provenance is
|
|||
|
|
stronger than another authored fixture variant, but the review remains author-model.
|
|||
|
|
No new canonical identity, relation, pattern, M1/M2 acceptance or usefulness finding.
|
|||
|
|
|
|||
|
|
## Scope closure and follow-up
|
|||
|
|
|
|||
|
|
The twelve-file cap is reached; no further callees were fetched. Files were inspected
|
|||
|
|
at the manifest's ranges, not exhaustively audited. The raw GitHub URLs supplied the
|
|||
|
|
source after the browsing tool could not open the commit page; retrieval hashes are
|
|||
|
|
preserved. No upstream code or frozen evaluation artifact changed. A source test was
|
|||
|
|
read, not executed. The earlier htmx fixture remains paused.
|
|||
|
|
|
|||
|
|
[Effort receipt](../evolution/cycles/2026-09-27-zulip-navigation-effort.json) records
|
|||
|
|
active source work versus repository-check execution, with final administration
|
|||
|
|
excluded and token/cost unknown. This source-review protocol is a separate comparison
|
|||
|
|
group; four distinct prospective protocols still do not provide a diminishing-returns
|
|||
|
|
window. Full language usefulness and independent human/AT review remain unresolved.
|
|||
|
|
|
|||
|
|
WP-0003 T01 follow-up: before trusting ZN07 or delayed focus, preregister a narrowly
|
|||
|
|
scoped upstream call-path/test study of the target lookup and anchor continuation;
|
|||
|
|
include callback wiring/transport context, preserve negative findings, and do not
|
|||
|
|
report a bug until reproduced or otherwise established. Broader evidence collection
|
|||
|
|
can proceed without expanding our local adapter. T02 retains independent review and
|
|||
|
|
the offline case branch. WP-0006 T03 retains comparable-window/review-date work.
|