Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
66e0d2a
docs: define shared node graph contract
VolkerChristian Sep 3, 2026
3a98698
feat: add standalone shared node graph
VolkerChristian Sep 3, 2026
c20f2c7
feat: add typed two-thread channels
VolkerChristian Sep 3, 2026
95f5b93
feat: integrate shared graph with worker
VolkerChristian Sep 3, 2026
edafa07
feat: preserve render-complete graph ordering
VolkerChristian Sep 3, 2026
c261286
feat: lazily materialize conversation cards
VolkerChristian Sep 3, 2026
3f0d691
fix: keep only current unknown protocol state
VolkerChristian Sep 3, 2026
39411a2
feat: bind thread rows to shared nodes
VolkerChristian Sep 3, 2026
3b49660
feat: render inspector from shared graph
VolkerChristian Sep 3, 2026
0e1a1b3
feat: render conversations from shared nodes
VolkerChristian Sep 3, 2026
3867754
fix: detach coalesced graph removals before release
VolkerChristian Sep 3, 2026
f8105d8
feat: bind shell panes to shared graph
VolkerChristian Sep 3, 2026
0524d37
feat: retain explicit turn roots and history pages
VolkerChristian Sep 3, 2026
b548ce3
fix: bound graph pane refresh and retries
VolkerChristian Sep 3, 2026
ecc4102
fix: bound graph conversation history
VolkerChristian Sep 3, 2026
a455b0d
fix: index visible thread interactions
VolkerChristian Sep 3, 2026
95e7442
fix: bound shared graph inspector rendering
VolkerChristian Sep 3, 2026
e03f60f
refactor: narrow typed widget actions
VolkerChristian Sep 3, 2026
04ad1f9
refactor: cut frontend session to typed channels
VolkerChristian Sep 3, 2026
efa6182
feat: add current thread history adapter
VolkerChristian Sep 3, 2026
9985a31
fix: preserve pre-start typed actions
VolkerChristian Sep 3, 2026
ec0742b
fix: retire completed graph operations
VolkerChristian Sep 3, 2026
32ab197
feat: manage current prompt graph lifecycle
VolkerChristian Sep 3, 2026
ec49d1d
refactor: dispatch typed worker actions directly
VolkerChristian Sep 3, 2026
a0c6114
refactor: remove legacy pane projections
VolkerChristian Sep 3, 2026
2bc6a60
test: cover typed shell integration boundary
VolkerChristian Sep 3, 2026
270c6b6
fix: retain prompts across worker races
VolkerChristian Sep 3, 2026
937e1d7
Restore implementation issues record
VolkerChristian Sep 3, 2026
5c1c1e1
refactor: make conversation rendering graph-only
VolkerChristian Sep 3, 2026
a2b8ff9
test: migrate layout fixtures to shared graph
VolkerChristian Sep 3, 2026
0e9a513
fix: scope protocol entities and realtime state
VolkerChristian Sep 4, 2026
7bb94eb
test: qualify protocol catalog against generated schema
VolkerChristian Sep 4, 2026
e955873
test: pin the newer client protocol delta
VolkerChristian Sep 4, 2026
b34e084
refactor: complete shared node graph cutover
VolkerChristian Sep 4, 2026
2443bc8
docs: finalize shared graph architecture
VolkerChristian Sep 4, 2026
c611654
fix: merge authoritative thread state field by field
VolkerChristian Sep 4, 2026
928ce3c
fix: preserve exact graph relations and action targets
VolkerChristian Sep 4, 2026
7fb96f5
fix: restore bounded graph inspector diagnostics
VolkerChristian Sep 4, 2026
89f195e
fix: project logical agents in inspector
VolkerChristian Sep 4, 2026
b579944
perf: bound shared graph topology reconciliation
VolkerChristian Sep 4, 2026
c04d85b
perf: bound lazy conversation materialization
VolkerChristian Sep 4, 2026
759bbb8
perf: bound graph removal streaming and wake recovery
VolkerChristian Sep 4, 2026
8d7bac2
fix: complete protocol semantic graph coverage
VolkerChristian Sep 4, 2026
0a7d2a5
chore: remove discarded runtime issue record
VolkerChristian Sep 4, 2026
67e0167
test: verify remaining typed UI wire paths
VolkerChristian Sep 4, 2026
14b0215
docs: record final semantic and performance qualification
VolkerChristian Sep 4, 2026
d40a168
fix: survive deferred node retirement in conversation
VolkerChristian Sep 4, 2026
59d9194
fix: stabilize shared graph Qt rendering
VolkerChristian Sep 4, 2026
5e9810c
fix: materialize incoming selected-thread cards promptly
VolkerChristian Sep 4, 2026
b667f0c
fix: commit conversation materialization atomically
VolkerChristian Sep 4, 2026
dd1c308
fix: stabilize selected conversation updates
VolkerChristian Sep 4, 2026
bd1d552
fix: preserve spawned thread ownership on hydration
VolkerChristian Sep 4, 2026
f5ee130
fix: admit enabled steering prompts during hydration
VolkerChristian Sep 4, 2026
461c68b
fix: settle initial history before first paint
VolkerChristian Sep 4, 2026
c928bdb
fix: restore active card emphasis
VolkerChristian Sep 4, 2026
8826ac4
docs: inventory native UI UX qualification
VolkerChristian Sep 4, 2026
bd35b01
fix: stabilize graph-backed conversation presentation
VolkerChristian Sep 4, 2026
6539cc1
checkpoint: preserve graph-backed UI stabilization
VolkerChristian Sep 4, 2026
23ce276
refactor: restore conversation UI behind nodegraph adapter
VolkerChristian Sep 4, 2026
c78add6
fix: preserve prompt targets through UI adapter
VolkerChristian Sep 4, 2026
6c1ed14
refactor: restore thread UI behind nodegraph adapter
VolkerChristian Sep 4, 2026
ded5055
refactor: restore inspector UI behind nodegraph adapter
VolkerChristian Sep 5, 2026
6a2794c
refactor: restore established UI API boundary
VolkerChristian Sep 5, 2026
a932e36
fix: preserve authoritative hydration semantics
VolkerChristian Sep 5, 2026
43e7af3
refactor: complete established UI adapter compatibility
VolkerChristian Sep 5, 2026
07a4731
docs: record prompt and steering qualification
VolkerChristian Sep 5, 2026
09f8144
Optimize graph-driven Qt update boundaries
VolkerChristian Sep 5, 2026
ce369ff
Stage conversation layouts and retain inspector rows
VolkerChristian Sep 5, 2026
0ef81e2
Route inspector and thread row updates narrowly
VolkerChristian Sep 5, 2026
0b786da
Qualify staged Qt rendering smoothness
VolkerChristian Sep 5, 2026
bc5fdc8
Fix retained Markdown line clipping
VolkerChristian Sep 5, 2026
a0c0911
Avoid full layout for arriving conversation cards
VolkerChristian Sep 5, 2026
f79952f
Avoid layout work for command completion
VolkerChristian Sep 5, 2026
d99cb8a
Keep arriving cards responsive during scrolling
VolkerChristian Sep 5, 2026
ed9bccb
Keep acknowledged prompts visually stable
VolkerChristian Sep 5, 2026
6b6fb00
Give Codex updates a yellow identity
VolkerChristian Sep 5, 2026
97d86c1
Open conversation files with desktop applications
VolkerChristian Sep 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 188 additions & 115 deletions CMakeLists.txt

Large diffs are not rendered by default.

39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,34 @@ CodexUI 1.0 is a native Qt 6 Widgets and browser frontend for the AISuite
without introducing another backend, semantic cache, snapshot store, or
persistence authority.

The canonical process has two threads:
The native app-server/UI data path has two threads:

```text
Qt GUI thread
<-> bounded nonblocking Unix socketpair
<-> typed bounded SPSC queues + one eventfd per direction
SNode.C client thread
<-> codex-bridge
<-> Codex app-server
```

The Qt thread owns widgets plus a toolkit-neutral `UiSession`, which owns the
`PresentationModel` and UI/UX state machine. Widgets exchange only semantic
intents and value snapshots with that boundary. `FrontendSession` adapts its
generic presentation client to the unchanged socketpair. The SNode.C thread
owns the event loop, selected transport, `AISuite::OpenAICodex` frontend proxy
SDK, native protocol normalization, and connection/controller telemetry. The
threads exchange only bounded `codexui.presentation` JSONL commands and events.
Both threads share one current `NodeGraph`. The SNode.C worker owns
CodexBridge, native app-server decode/encode, protocol-to-graph updates, and
all graph writes. Qt owns every widget and local interaction mechanic, reads
the graph only through non-blocking access, renders visible nodes in bounded
slices, and sends closed typed actions back to the worker. No app-server JSON,
serialized internal state, mirror model, or socketpair crosses this boundary.

## Applications

`codex-ui` is the canonical visual application. Its production shell renders
the neutral `UiSessionView` API and sends semantic intents; it does not consume
`PresentationModel` directly. There is no parallel legacy UI or alternate
application target.
`codex-ui` is the canonical visual application. Its production shell binds the
existing widgets directly to shared nodes and sends typed node/runtime actions.
There is no parallel legacy UI or alternate application target.

`CodexWebUI` is the browser presentation. It uses the framework-neutral
`@snodec/codex-frontend` SDK from AISuite, connects directly to the bridge over
WebSocket, and follows the same controller, prompt, thread, turn, projection,
and reconnect rules as the native application. Browser-only limitations are
WebSocket, and implements the same visible controller, prompt, thread, turn,
and reconnect behavior in its own TypeScript state path. It does not share the
native in-process graph or its widget binding. Browser-only limitations are
listed in the [1.0 contract](docs/web-1.0-contract.md).

## Build
Expand Down Expand Up @@ -87,10 +86,12 @@ are in [`web/README.md`](web/README.md).

## Architecture

The complete thread model, presentation protocol, authority rules, normalized
event vocabulary, public APIs, shell behavior, implementation report, and test
boundaries are documented in
[`docs/codex-architecture.md`](docs/codex-architecture.md).
The implemented native thread model, node/state authority rules, typed
mailboxes, protocol coverage, widget binding, and qualification boundaries are
documented in
[`docs/two-thread-shared-node-graph.md`](docs/two-thread-shared-node-graph.md).
[`docs/codex-architecture.md`](docs/codex-architecture.md) is a concise product
overview linking the native and browser-specific contracts.

Current message routing, pending-prompt acknowledgment, scrolling, composer
geometry, shell-output, Inspector, and desktop-integration decisions are
Expand Down
47 changes: 27 additions & 20 deletions design/ux-decisions/thread-turn-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ Thread
```

AISuite and the app-server are authoritative for thread, turn, item, and
configuration semantics. CodexUI retains only bounded presentation state and
client-local interaction state.
configuration semantics. CodexUI keeps their current local representation in
one shared `NodeGraph`; Qt retains only bounded widget mechanics, drafts, and
other genuinely local interaction state.

## Thread selection and routing

Expand Down Expand Up @@ -77,28 +78,34 @@ ensures that a later prompt observes the active-turn state published by the
preceding acknowledgment. Queues belonging to different threads are
independent.

Only the correlated `turn.start` or `turn.steer` completion callback can
acknowledge a prompt. A successful callback begins a 500-millisecond accepted
transition. Every submission carries a unique `clientUserMessageId`, allowing
Only the correlated `turn/start` or `turn/steer` completion callback can
acknowledge a prompt. A successful callback immediately ends pending feedback.
Every submission carries a unique `clientUserMessageId`, allowing
the authoritative user item to inherit the local card's stable visual key even
when multiple prompts have identical text. Failure stops the animation and
leaves an explicit error card.

Prompt dispatch waits for once-per-connection-generation thread hydration. A
provider-marked `notLoaded` thread is resumed first. A transient
thread-not-found submission result triggers one resume-and-retry; a repeated
failure becomes the card's terminal error. Failed hydration leaves the composer
draft intact and requires an explicit reload before admission. Dispatch
rechecks connection and recovery ownership at its queued execution boundary, so
a disconnect cannot send and an in-flight resume cannot overlap a hydration
read or another turn operation.
provider-marked `notLoaded` thread is resumed first. Failed hydration leaves
the composer draft intact and requires an explicit reload before admission.
Dispatch rechecks connection and recovery ownership at its queued execution
boundary, so a disconnect cannot send and an in-flight resume cannot overlap a
hydration read or another turn operation.

Once admitted, a non-idempotent prompt is never sent again automatically. A
thread-not-found result is terminal for that dispatch. If thread deletion or a
provider-generation reset races queued or in-flight work, the local prompt is
reparented to explicit recovery state with its exact admitted text and
attachment links retained. Its state records whether failure is definite or
the provider outcome is uncertain; reconnect, reload, and hydration never
resend it. A later attempt requires deliberate user action.

## Start, steer, and interrupt

- An idle loaded thread uses `turn.start`.
- An active thread uses `turn.steer` with the stable active turn ID.
- An idle loaded thread uses `turn/start`.
- An active thread uses `turn/steer` with the stable active turn ID.
- A not-loaded thread is resumed before starting its turn.
- Stop uses `turn.interrupt` for the stable active turn ID.
- Stop uses `turn/interrupt` for the stable active turn ID.

CodexUI does not fabricate turns or infer active identity from row position.

Expand All @@ -113,13 +120,13 @@ window, while Steer adds input to an existing turn.

Operational items remain individual cards inside their turn; there is no
second Activity batch or arbitrary visible grouping. Pending prompts remain
thread-local presentation cards until acknowledgment supplies their
thread-local graph nodes until acknowledgment supplies their
authoritative turn and item position.

`PresentationModel` is the retained normalized source. A pure projection adds
local prompt admissions and emits stable keyed turn sections and cards. Initial
display and all updates use the same reconcile path; retained card widgets are
mutated in place, and a visually identical projection performs no layout work.
The shared `NodeGraph` is the current native source. Local prompt admissions
are nodes in that same graph. Initial display and all updates use stable keyed
turn sections and cards; retained visible widgets are mutated in place, while
an invisible or visually unchanged node performs no widget layout work.

## Thread lifecycle actions

Expand Down
11 changes: 10 additions & 1 deletion docs/app-server-protocol/master-data-model.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# Codex app-server protocol: complete framework-neutral C++ master data model
# Historical Codex app-server protocol and proposed master data model

> **Historical, non-normative design research.** The pinned wire-method
> inventory and schema observations in this document remain useful protocol
> references. Its proposed journal, ledger, reducer, outbox, snapshot/cursor,
> persistence, replay, and adapter runtime are rejected and are not CodexUI's
> implemented architecture. The current native contract is
> [`../two-thread-shared-node-graph.md`](../two-thread-shared-node-graph.md): one
> current shared `NodeGraph`, exactly two relevant threads, two typed SPSC
> queues, and two Linux eventfds.

## Scope and reproducible baseline

Expand Down
Loading
Loading