@@ -347,7 +347,11 @@ search request contains only copied, recursively frozen plain data:
347347The ` AbortSignal ` is passed separately. Providers never receive a session,
348348revision, ` EditorState ` , DOM object, credential object, or arbitrary live host
349349context. Connection identity belongs in the catalog scope; live resources stay
350- inside the provider closure. The provider object is caller-owned. The service
350+ inside the provider closure. The scope is an opaque host-generated identity
351+ that includes the live connection incarnation, not merely a reusable display
352+ name. Rebinding a marimo engine variable to a different connection therefore
353+ uses a new scope even when the variable name is unchanged. The provider object
354+ is caller-owned. The service
351355captures its own-data callbacks once and owns searches, subscriptions, and
352356their cleanup, but does not imply provider-wide disposal. Provider callbacks
353357are closure functions with a declared ` this: void ` contract and are invoked
@@ -389,15 +393,23 @@ Search responses distinguish:
389393- loading; and
390394- failed with a closed code and retry policy.
391395
392- A terminal ` loading ` response is not cached. A provider that later becomes
393- ready must publish a strictly higher epoch through its subscription; same-epoch
394- duplicate invalidation is not a readiness signal. A still-pending search
395- promise can instead resolve ready under the service-owned response/refresh
396- rules below. Every completion result carrying ` catalog-loading ` , whether caused
397- by terminal loading or soft expiry, also carries a checked remaining
398- completion-intent lease. For terminal loading that lease is independent of
399- in-flight work ownership and is keyed to the exact session, query, and captured
400- observed or unobserved epoch.
396+ A terminal ` loading ` response is not cached. It installs a bounded barrier for
397+ the exact request key and captured epoch. When the provider has a live
398+ subscription, matching requests observe loading without invoking it again
399+ until a strictly higher epoch retires the barrier. Same-epoch duplicate
400+ invalidation is not a readiness signal. Without a subscription, a later
401+ explicit request may become the single shared probe behind that barrier. The
402+ probe uses the normal queue and execution budgets and may publish readiness
403+ only with a strictly higher epoch; a same-epoch ready response cannot cross the
404+ loading barrier. A still-pending original search promise can instead resolve
405+ ready before returning terminal loading under the service-owned
406+ response/refresh rules below.
407+
408+ Every completion result carrying ` catalog-loading ` , whether caused by terminal
409+ loading or soft expiry, also carries a checked remaining completion-intent
410+ lease. For terminal loading that lease is independent of in-flight work
411+ ownership and is keyed to the exact session, query, scope incarnation, and
412+ captured observed or unobserved epoch.
401413
402414Partial positive entities may be offered. A partial or absent result never
403415proves that a relation does not exist. A complete empty search means only that
@@ -501,9 +513,12 @@ searches remain usable; only the epoch observation is a duplicate. A terminal
501513` loading ` response requires a higher epoch before that exact search can become
502514ready. Providers without subscriptions may return ` loading ` , but they cannot
503515cause automatic refresh; a later explicit request must observe the higher
504- epoch. Failed responses are attempt evidence: ` next-request ` may recover at
505- the same epoch, while ` after-invalidation ` and ` never ` create bounded retry
506- gates rather than cached search results.
516+ epoch through the single shared probe. Failed responses are attempt evidence,
517+ not cache entries. ` next-request ` installs no gate and may recover at the same
518+ epoch. ` after-invalidation ` blocks the exact request until a strictly higher
519+ epoch. ` never ` blocks it for the remaining scope incarnation and is retired
520+ only with that incarnation or the service. Retry gates are bounded internal
521+ metadata; they never acquire result authority or extend work deadlines.
507522
508523The service reference-counts one provider subscription per provider
509524configuration and scope, then fans invalidation out to subscribed sessions.
@@ -733,8 +748,10 @@ and CTE evidence is composed first and never waits past the remaining response
733748budget. On soft expiry the request settles ready, possibly empty, with
734749` isIncomplete: true ` , ` catalog-loading ` , and bounded remaining
735750completion-intent lease metadata; its session may atomically retag the request
736- consumer as a service-owned refresh observer. The intent lease is no longer
737- than the remaining work lease.
751+ consumer as a service-owned refresh observer. The transfer removes consumer
752+ authority and installs observer authority as one serialized mutation, with no
753+ zero-owner interval in which shared work can be aborted or a settlement can be
754+ lost. The intent lease is no longer than the remaining work lease.
738755That bounded refresh lease can retain the shared operation only until its
739756existing hard deadline and active/queued service limits. With no consumers or
740757live observers, the service removes and aborts the work. An observer is bound
@@ -754,24 +771,44 @@ refresh notification and leaves the already-returned incomplete result valid.
754771No optional catalog promise can keep ` complete() ` pending indefinitely or
755772block the local baseline past its product response budget.
756773
757- The first implementation increment of this section is intentionally
758- package-private. It combines an authenticated provider with the epoch
759- coordinator and owns the fixed 8-active/64-queued scheduler, exact-key
760- in-flight sharing, one latest-wins consumer per owner, independent
761- cancellation, absolute queue and execution deadlines, response decoding, and
762- epoch publication. An owner captures its scope and dialect when prepared, so
763- individual requests cannot substitute provider, scope, dialect, or epoch
764- authority. The authenticated dialect runtime owns its canonical provider ID;
765- callers cannot pair an unrelated ID and runtime. Establishing the first
766- baseline re-keys other joinable unobserved work in that scope, allowing
767- newly-observed consumers to join it without duplicating a provider call.
768-
769- Cache entries, loading/retry policy, refresh observers and their leases, the
770- 40 ms completion-response budget, pagination composition, ranking, session
771- composition, and CodeMirror integration do not belong to that increment. They
772- remain explicit follow-up increments; the coordinator must not expose a
773- premature public surface that makes those deferred semantics difficult to add
774- or test.
774+ Terminal loading has no work consumer to transfer. The subsequent session
775+ composition increment owns its independent intent, retaining only the bounded
776+ exact key, scope incarnation, captured epoch, and lease. A higher accepted
777+ response or invalidation retires it and emits only the normal higher-epoch
778+ ` catalog ` revision. By contrast, a compatible same-epoch pending-work
779+ settlement emits exactly one ` catalog-availability ` notification. A higher
780+ epoch retires both kinds of observer and never emits a second availability
781+ notification.
782+
783+ The package-private coordinator is delivered in two increments. The first
784+ combines an authenticated provider with the epoch coordinator and owns the
785+ fixed 8-active/64-queued scheduler, exact-key in-flight sharing, one
786+ latest-wins consumer per owner, independent cancellation, absolute queue and
787+ execution deadlines, response decoding, and epoch publication. The second is
788+ one combined cache/loading/retry/observer increment over that scheduler. It
789+ adds the ready-page cache, terminal-loading barriers and probes, retry gates,
790+ and atomic consumer-to-observer transfer. The session increment then adds
791+ independent terminal-loading intents together with the revision events they
792+ own; splitting the store states would permit stale cache hits or missed
793+ readiness transitions, while placing a session event lease in the scheduler
794+ would invert ownership.
795+
796+ An owner captures its scope and dialect when prepared, so individual requests
797+ cannot substitute provider, scope, dialect, or epoch authority. The
798+ authenticated dialect runtime owns its canonical provider ID; callers cannot
799+ pair an unrelated ID and runtime. Establishing the first baseline re-keys other
800+ joinable unobserved work in that scope, allowing newly-observed consumers to
801+ join it without duplicating a provider call.
802+
803+ The combined increment exposes only package-private lifecycle outcomes and
804+ observer primitives. Selection of the 40 ms completion-response budget,
805+ session revision ownership, conversion of readiness into session events,
806+ pagination composition, ranking, and CodeMirror menu refresh remain subsequent
807+ increments. A marimo adapter will map connection replacement, deferred
808+ schema/table resolution, local-table changes, and DuckDB catalog DDL to higher
809+ epochs. Its unresolved ` schemas_resolved ` , ` tables_resolved ` , and
810+ ` child_schemas_resolved ` states map to terminal loading, not complete-empty
811+ catalog evidence.
775812
776813The exact structural cache and shared-work key contains:
777814
@@ -792,15 +829,34 @@ to its epoch. Only decoded ready responses are cached under their response
792829epoch. Loading, failure, malformed, timeout, cancellation, supersession, queue
793830overload, and disposal outcomes are not cached. Complete-empty results are
794831reused only for the exact key and never prove an unknown-object diagnostic.
795- Partial and paginated entries retain incomplete coverage; pages combine only
796- for the identical base key and epoch, and each continuation remains a distinct
797- request key. Higher-epoch results may be cached only after older scope entries
798- are cleared and never publish to the revision that observed the older epoch.
799-
800- Decoded entity IDs are unique for ` (provider configuration, scope, epoch) `
801- across every page composed into one result. A repeated ID, even with otherwise
802- identical data, makes the page chain malformed before ranking or caching; array
803- and page order therefore cannot resolve conflicting identity records.
832+ Partial and paginated entries retain incomplete coverage. This increment
833+ caches individual decoded pages only; each continuation is a distinct request
834+ key, and automatic page following or composition remains deferred.
835+ Higher-epoch results may be cached only after older scope entries are cleared
836+ and never publish to the revision that observed the older epoch.
837+
838+ Cache retention is bounded simultaneously to 256 entries and 2 MiB of
839+ deterministically estimated retained bytes, including the copied structural key
840+ and frozen decoded page. A successful exact-key lookup and an insertion each
841+ receive the next service-owned access sequence. Before an insertion becomes
842+ visible, least-recently used entries are evicted in ascending access sequence
843+ until both bounds hold. A page whose own estimate exceeds the byte bound
844+ remains usable for its attached consumers but is not cached. Epoch retirement
845+ removes incompatible entries before admission, and eviction invokes no
846+ provider or host callback.
847+
848+ Loading and retry gates share the bounds but are correctness state, not cache
849+ entries. Their admission evicts ready pages first; an admitted gate is never
850+ evicted before its epoch or scope-incarnation retirement rule. If the bounds
851+ contain only live gates and cannot admit another, the producing request fails
852+ closed as overloaded and the policy store remains overloaded until its provider
853+ configuration is replaced. This configuration-level quarantine prevents a
854+ later request from publishing across the barrier that could not be retained.
855+
856+ Decoded entity IDs are unique within each cached page for `(provider
857+ configuration, scope, epoch)`. Cross-page uniqueness is checked later by the
858+ pagination-composition increment; array or page order can never resolve
859+ conflicting identity records.
804860
805861### Initial resource budgets
806862
@@ -973,8 +1029,9 @@ Mixed cached assets fail the exact version check and retire the generation.
97310295 . Add the service-owned scoped epoch/subscription coordinator and its hostile
9741030 lifecycle contract suite. It does not invoke provider search or retain
9751031 result pages.
976- 6 . Add catalog search scheduling, cache, in-flight sharing, cancellation,
977- retry gates, and availability observers over the proven epoch coordinator.
1032+ 6 . Add catalog search scheduling and in-flight sharing, then one combined
1033+ package-private cache/loading/retry/availability-observer increment over the
1034+ proven epoch coordinator.
97810357 . Add the session completion method and deterministic composition.
97910368 . Add the separate CodeMirror adapter and packed/browser fixtures.
98010379 . Add the pinned packed/browser/runtime marimo fixture and 1/10/50-editor
0 commit comments