Conversation inbox implementation checkpoint
This is the delivery checkpoint dated 2026-09-22, not a release announcement. The product contract is described in Organizing and continuing conversations.
Implemented
- Complete conversation queries, collapsible partition groups with counts, nested delegated work, descriptions and secondary categories, search, and Open/Closed/All views in the shared inbox and Blazor chat. Collapsed groups are excluded from selection and bulk close.
- Confirmed close and conditional Undo, including running/queued work guards and preservation of delegated children. Owner requests register only on Thread hubs; duplicate default registration processes a close twice and can lose the original Undo receipt.
- Accepted close identities persist after reopening, Undo, new input, and later closes, preventing delayed retries from closing resumed work. Legacy identities use non-null version-zero markers: null dictionary entries are deletions under JSON merge patch and cannot retain retry history.
- Optional preparation and Continue thread / Start new client flows for web and phone, including dictated input, draft preservation and stale-result protection. Deployed adapters leave this capability disabled while the service is absent; Blazor follows normal creation without it.
- Durable external task identities, per-message retry identities, owner-validated reuse, and context/attachment preservation for follow-ups delivered during a running response.
- A distinct
StartPreparedThreadAPI while preserving the existingStartThreadsignature and calls that pass a positional null agent. Preparation contracts and pure candidate/response rules exist, but the preparation service itself is not installed.
Partition grouping
The inbox query is the union of conversations authored by the viewer across readable partitions and all Thread descendants stored under the viewer's home. The synchronized query unions by path, so authored home conversations appear once. The home branch keeps legacy conversations with no content creator and incoming/programmatic conversations stamped with another creator reachable. Both queries explicitly request all results and full inbox fields; normal read-access checks still apply. A read-only cloud audit found 145 distinct accessible Thread records across the two branches (67 authored and 100 home records), representing 116 root paths; neither response was truncated at a tool limit of 200. Those counts are a dated observation, not an application limit. Continuation suggestions retain the narrower authored/open/root rules.
The shared AI/AiThreads landing page embeds the viewer's personal Threads area alongside
its existing harness catalog. The main menu, package entry points, phone inbox and chat therefore
reach the same grouping and housekeeping behavior. New thread opens the personal composer.
The inbox groups a conversation by its original context partition, retaining delegated children
under that conversation. A normal contextual MainNode identifies the partition. For a conversation
stored in its creator's home, the embedded composer's initial ContextPath supplies the context
when available. This covers durable external tasks and ordinary chats opened from a read-only
page. Later messages carry their own context without replacing the initial composer context, so
following a reference in another partition does not move the conversation between groups.
Grouping is a read-only projection: it never rewrites the thread path or MainNode. The latter
participates in satellite write authorization, while reads inherit access from the stored path;
changing it only to obtain a display group would change security semantics. See
Access control. A reuse integration case pins the distinction
between the home-owned thread, its initial context, and a later message's different context.
First-message retry verification
Browser and phone clients can create a thread with a pending first message and a stable message id without computing a payload fingerprint. The server retains that fingerprint in the same write that removes pending input, at round-start ingestion and inline inbox completion. A retry while the input is still pending verifies against that payload and retains its fingerprint as well. This permits an unchanged retry after ingestion and rejects a different payload under the same id. Existing fingerprints survive explicit edits and resubmissions. An already-ingested legacy id with neither a fingerprint nor its original pending payload is rejected as unverifiable; it is never acknowledged as a successful retry, reopened, or queued again automatically.
Independent release scope
The server inbox, partition groups, confirmed closing with Undo, Blazor message submission, and durable external-task reuse API can ship through the module pipeline independently. They introduce no model data flow. Current web and phone adapters expose no preparation capability, and Blazor checks for the service before entering that flow; a normal new conversation starts immediately. The optional client protocol remains available for a later approved integration. React and native submission changes additionally require delivery of their client bundles, as described below.
Concurrent main changes already used AI 1.13. This release therefore starts the AI 1.14 series;
Chat and MCP require AI@^1.14.0 so their new calls cannot bind to the older engine.
Remaining AI integration
The naming audit found a built-in ThreadNamer definition but no production call from normal thread creation in this checkout or its local platform sibling. Both the C# node builder and browser SDK currently derive the initial title by truncating the first prompt. A utility model tier does not identify a provider destination: the installed model and credential configuration decide that. Consequently this change cannot rely on an existing first-prompt naming call as evidence that the new description and matching data flow is already installed or approved.
The configured AI-provider connection needs explicit approval for the first prompt and existing conversation metadata. Automatic approval review rejected that connection; it has not been added. The preparation request handler and service are consequently absent. First-prompt summaries, related-work suggestions and metadata enrichment must not be described as delivered.
After approval, implement the read-only, tool-free ThreadNamer preparation service and its message handler, update the built-in agent prompt and drift ledger, and connect first-create MCP metadata and explicit continuation choices. Fill missing descriptions on the chosen existing conversations from their first prompt while preserving manual metadata. Partition grouping already works without AI categorization or a backfill. A stable external task's already-mapped conversation continues directly; semantic matching is for a genuinely new task. If an external task explicitly chooses an older conversation, persist that choice for reconnects; do not overwrite another task's origin or let the next call create a second conversation at the default derived path.
For that later integration, complete service and caller-identity tests, rerun the affected checks, and follow the normal PR/review/green-checks/merge/CD workflow. Verify both new-conversation choices and the mobile entry point before marking the full workflow complete. The independent Blazor preparation branch also needs a full rendered chat harness covering both choices, preserved drafts and a failed continuation; the rendered inbox tests exercise the shipped inbox but do not substitute for that future branch's integration coverage.
No production conversation has been renamed, categorized, closed, or deleted during implementation. The release entry is Conversations grouped by partition. This module page remains the durable implementation and delivery record.
Validation at this checkpoint
| Check | Result |
|---|---|
| AI inbox, rendered landing page/layout, lifecycle, reuse, preparation rules and content drift | 141 passed |
| Blazor chat, including four real rendered inbox cases and nine Undo receipt transitions | 57 passed |
| MCP argument, real close retry and module registration | 29 passed |
| Complete browser SDK, including wire contracts and thread transport | 99 passed |
| React conversation submission and controls | 49 passed |
| Full phone client suite with its own locked dependencies, including renderer, composer, live binding, speech and adapters | 277 passed, plus 3 added NavLink cases |
| Full Next portal suite with its own locked dependencies, including four web adapter cases | 136 passed |
| Client TypeScript checks | Passed |
| Full node compilation gate | 104 clean, no debt, no unverifiable types |
The focused .NET suites used local core checkout b1aa8a9e57. The full node compilation gate used
the resolved sealed platform 3.0.0-ci.9141 (6b3fda2a4), with image reference digest
7acbaea84e332bedbfb7f84e8eb2cd4a69abe8a35b36dd9e389da41e46395d2b and local module references.
CI against its resolved platform and production behavior remain delivery gates; these local
results do not replace them.
Phone adapter checks run in the native package; web adapter checks run in the Next portal package. Importing the phone source into the web suite required Expo before CI installed native dependencies. The checks retain the same six cases without coupling those independent package installations.
The PR uses the supported platform:newest label for its fresh complete CI run. The earlier run
resolved 3.0.0-ci.9081, which cannot compile main's existing GitHubIssueStateReason use in
Observability. Platform resolution records that compatibility gap;
the label selects the newest sealed platform without bypassing any test or required context.
Live audit and release evidence
A read-only cloud metadata audit on 2026-09-22 confirmed that the authored and home queries each
returned explicit coverage with no truncation. Their union retained home conversations absent
from the authored query, and grouping delegated records by root substantially reduced repeated
rows. No conversation content or permissions were changed. The MCP search response exposes only
its fixed metadata fields, even when select requests MainNode or composer context; storage-path
partition counts therefore cannot verify the inbox's actual context-partition grouping. Full
conversation bodies were not retrieved to work around that limitation.
Compiled AI, Chat and MCP updates have an independent delivery path: Catalog publication lands
the tested module bundles, the content bake seals its publication and notifies Memex, and normal
module-set adoption activates the landed generations through a controlled restart. A new portal
image rebuild is not required for this path; image copies of these modules are seeds. Publication
alone is not activation evidence: verify the loaded module source commit and framework identity,
plus production behavior. A different framework identity can cause the running image's seed to
remain selected, requiring normal adoption of the matching published platform. The separate
portal-image dispatcher failure to obtain its App's Actions:write permission does not itself
block Catalog publication or justify changing deployment permissions.
Catalog PR run 35722446745
at b71f9fb87 completed successfully with all eight required contexts explicitly successful.
It compiled and rendered against sealed platform 3.0.0-ci.9172 (92174c2ed), and executed the full
AI suite: 2,173 passed, three existing skips and no failures. That run also passed the native/web
client checks, all eight module test batches and the portal host tests. The final smoke review
subsequently found classic chat's Undo receipt handling needed the same no-op and partial-failure
preservation as the shared inbox; that follow-up must pass its own exact-head CI before release.
Its focused run passed all 13 cases (the nine new receipt transitions plus four rendered inbox
cases), and both Blazor module and test builds completed with zero warnings or errors.
Integration against platform 3.0.0-ci.9186 exposed an older hierarchy-query fixture that declared
its Project type as Markdown. The fixture now creates a typed NodeTypeDefinition through the
canonical node factory, preserving the original hierarchy assertions and permissions. All 26
query-integration tests passed locally with zero build warnings or errors.
A main-branch run 35739005506
separately timed out in the NugetPackages.md executable example. Its preserved request and phase
traces place the wait before compilation, in Humanizer package resolution; routing reached both
owners promptly. Humanizer 2.14.1 has 48 direct dependencies, and resolver metadata reads happen
before installed-package checks. The trace cannot identify the particular slow feed operation.
The identical-platform example had passed previously, supporting one bounded diagnostic rerun
with unchanged timeouts and assertions. A recurrence needs resolver-stage evidence, not repeated
retries; a failed current main remains a release blocker.
Client delivery and native control parity
The shared server layout uses NavLink for New thread, Open and child destinations. Older native
clients already implement this control's title/URL navigation, so the server inbox remains usable
without waiting for a new phone bundle. Rendered server-area tests pin those wire destinations,
and native tests exercise the existing NavLink leaf for all three paths.
Navigation entrypoints use AI/AiThreads and {viewer}/Threads, which both clients resolve.
The /area/ form is valid for MCP area reads and classic web navigation, but the installed native
shell treats the first unresolved segment as the area: AI/area/AiThreads incorrectly selects an
area named area. The server AI menu and harness tiles therefore emit the universal route. The
existing phone reaches it through its hamburger menu, AI → Threads, without a new bundle.
Its historical home Threads tile still opens {viewer}/Chat; the new direct inbox shortcut is a
client-bundle change. Production web checks confirmed both universal routes render their intended
areas before release; resolver-to-render tests cover the installed native split contract.
Older native Button and CheckBox controls ignored
disabled. The native leaf pack now resolves button targets through the shell's current-address
navigation, emits an optional server click once, and blocks disabled input. Tests render the real
pack, covering composer/root/child/relative navigation, external links, click ordering, and controls
that become enabled through a binding update. These general renderer improvements still require
a fresh client bundle. Independently, the shared inbox enforces one pending Close/Undo operation
per rendered instance on the server, ignores an empty bulk close, and preserves existing Undo
receipts after a no-op or refused close. Completion updates read state inside the layout host's
serialized update, so two queued results cannot overwrite a newly confirmed receipt with an old
snapshot. Undo removes only submitted receipts confirmed reopened or stale; failed and unconfirmed attempts remain retryable, and an older response cannot clear a newer receipt. Real click and queued-completion tests cover repeated taps, partial failures, and stale responses.
Classic Blazor chat applies the same receipt rules inside its renderer-dispatched completion. It captures the exact tokens submitted to Undo, retains the previous receipt after an empty or refused close, and keeps failed or unconfirmed Undo attempts. A delayed completion cannot discard a newer receipt for the same path or a receipt it never attempted.
Compiled module publication does not deliver TypeScript client sources. The Next portal image
workflow bundles clients/react and clients/grpc-web, then publishes a separately versioned image;
the target deployment must adopt that image through its supported control-plane deployment path.
Publishing the image alone does not prove the browser serves it.
The native app statically bundles the same shared sources with its own controls and composer. Its CI installs, typechecks, tests and exports for a smoke check; it does not distribute a phone binary. The repository defines development, simulator, preview and production EAS profiles but no OTA publishing configuration or native distribution workflow. Native navigation and submission fixes therefore require a fresh bundle through the installation's actual distribution channel, followed by verification in that installed app. The LocalMesh release build's RN web export and the private Vite example are separate consumers, not evidence of cloud or phone delivery.