Skip to content

Every message has its own number: messages split from turns - #877

Open
lydakis wants to merge 14 commits into
mainfrom
claude/project-thread-iwxbk6
Open

lydakis wants to merge 14 commits into
mainfrom
claude/project-thread-iwxbk6

Conversation

@lydakis

@lydakis lydakis commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

Every submission is now a row of its own in a new messages table, with its own number. That holds whether the message opens a turn, waits in line, is steered into a running turn or is attached to the next one. turns holds runs only. A turn's number is the number of the message that opened it, and both come from one store-wide sequence, so BOT/N names exactly one message everywhere.

What changes

  • Store. A new messages table holds each message's:

    • words, sender, quotes and pictures;
    • delivery, effort and folder;
    • status: queued, attached, ready, taken, withdrawn or failed;
    • the turn that took it in.

    turns keeps only what a run has: status, usage, timing and waits.

  • Migration. The schema 91 migration copies every old turn row into a message and keeps only real runs in turns. For each steered or attached message, it finds the turn it joined from its steered event, or else from the run that was going when it was taken. Parked waits' handles move to BOT/N.

  • Protocol 64.

    • submit answers with message and handle (BOT/N), and with turn only when the message opened one.
    • A new messages op lists a bot's messages: number, turn, status, delivery, node, sent and taken times, sender, effort, folder and a preview.
    • turns lists runs only.
    • queued, attached, held and message_ended events name the message. A message taken into a running turn shows up as that turn's steered event, with the message and its node.
    • wait on a message's handle resolves when the message is taken, withdrawn or failed. For a message that opened a turn, it resolves when that turn ends.
  • The model sees each message's number. After a message's words, as a separate content part, comes [Message BOT/N.]. When there is a sender, it adds written by P, sent by O, or written by the agent X in X/T, not by a person. The words stay the first part.

  • Quotes name one message. --quote BOT/N (and BOT/N:reply) copies exactly that message's words, even when it was attached or steered into a turn with others. Quotes use {bot, message, reply?}.

  • A declined request's messages. A message that joined a request declined by a provider's classifier goes back in line as a new message, with its own number, as it was sent. Its place in the declined turn says it was sent again.

  • Sonny.

    • Each message shows its own BOT/N under the mouse, before its time.
    • Handles are BOT/N everywhere.
    • The lookout quotes the person's words by message number.
    • A steer reads as taken rather than as a turn of its own.
  • CLI. agent messages --bot B lists messages. agent run prints BOT/N and says when a message was taken into a running turn.

  • Docs, skills and benches use the new names and shapes.

Versions

This PR uses protocol 64 and schema 91. Another change in this release takes those numbers first, so this PR moves to protocol 65 and schema 92 (migration 91 to 92) when it rebases on that change.

Testing

  • cargo test --workspace, cargo clippy --workspace --all-targets -D warnings and cargo fmt: green.
  • Every Python runtime suite (AGENT_TEST_RUNTIME=1 python -m tests.run, 51 suites): green. The Rust contract tests build schema-90 stores to cover the migration.
  • Two new indexes keep the messages reads on index lookups: messages(node) and turns(started_ms). The query-plan bench finds no new table scans.
  • Performance, recorded in docs/DAEMON_MEASUREMENTS.md:
    • Store alone. A new submission costs what it costs on main (73 µs against 67 to 81 µs). A duplicate resend is about three times cheaper than on main (7 µs against 20 to 26 µs).
    • Daemon screen against main. Store work counts are identical and the gate warns on no row. CPU rows move within the runners' spread.
    • Memory. Peak memory is about 0.85 MiB higher at the team store-load point. Of that, about 0.14 MiB is the larger binary; the rest comes from the larger schema and more cached statements.
    • Upgrade. The worst case, a 72,000-turn, 76 MiB schema-90 store, upgrades in 2.3 s.

🤖 Generated with Claude Code

Messages leave turns: each submission (queued, steered, attached) is its
own row with its own number, and a turn is a run that took messages in.
The model reads each message's number in a line after its words, BOT/N
names one message everywhere, and a quote copies exactly that message.
Schema 91 splits stored turns; protocol 64.

Work in progress: Sonny, skills, docs and Python suites follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lookout quotes the person's words by message number, the bench
providers accept the number line after a message's words, and the
long-task and lookout benches read steers from the messages listing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ges table

A message that joined a declined request is read from the messages
table and goes back in line as a message with its own number. Message
views now carry the folder each message runs in. The lookout and
Sonny changes from main read messages by number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-11T09:23:06.973568Z 18f059f New commits
🔒 Security Review ✅ Completed 2026-11-11T05:18:31.367556Z 7090032 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70900327a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sonny/src/lookout/mod.rs Resolved
Comment thread sonny/src/acp.rs Resolved
Comment thread src/store/db.rs Resolved
Comment thread src/server/mod.rs Resolved
Comment thread src/store/db.rs Resolved
…ation ties

- ACP answers a prompt that ended in line (withdrawn or failed) before
  any turn took it.
- The lookout stops waiting on a message once a running turn takes it in;
  that turn's end tells its sender.
- Retention takes the events of messages older than the kept turns that
  ended in line, through an index of events in line.
- The migration reads a steer's turn from its node's run, else from the
  one run it could have joined; when two could have, it names none.
- The demo models read handles in the BOT/N form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…benches

The screen runs the head's benches against the base daemon too, which
names the number turn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 969af18f58

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/store/db.rs Resolved
Comment thread src/client.rs Resolved
… bench read both protocols

A retry of a message another turn took in, after retention removed its
steered event, now ends from the wait answer instead of waiting for an
event that will never come. The lifecycle bench's provider accepts a
request without the message line, as the older base daemon sends it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A schema-90 turn parked on another turn's handle kept the old
`turn:BOT/N` form, which the new parser rejects, so it would resume with
invalid_handle on startup. The migration now rewrites those handles and
leaves process handles as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e52175be95

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sonny/src/lookout/mod.rs Resolved
Comment thread src/store/db.rs Resolved
…line began

A retried submission reads its earlier message with a cached statement
that also says whether it opened a turn, instead of preparing a join and
asking again. A message that starts at once is written as taken by the
turn it opens, so it never passes through the line's indexes. In the
store alone this brings a new submission back to main's cost and makes a
retry about three times cheaper than main.

The lookout notes where a message that ends in line began by its number,
so a bounce owed for it survives a reconnect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The upgrade's fallback for a message whose steered event retention took
counted every earlier run of its bot for each message. A bot's runs
follow one another, so only the last two to start by the time it was
taken in can have been going; an index on (bot, started_ms) finds them.
Same answers, ties included; a 72,000-turn store upgrades in 2.3 s
instead of 21 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fca7159627

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sonny/src/trigger.rs Resolved
Comment thread src/store/db.rs Resolved
Comment thread src/store/db.rs Resolved
…er prompts as taken

A task opened as a thread reads its brief from its first message, which
a task still waiting for room has before any turn. A trigger's reply,
and a shadow's report, name the turn that ran the message only when one
did; one withdrawn or failed in line says so in its words. A turn's
prompts read in the order it took its messages in, by their nodes, and
each answers what was said before its own steered event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recovery can take the steer into the next turn before the new client
reads the stream, so its steered event is in the store but never on
the client's stream. Ask wait for the message instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e09a9efc43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/store/db.rs Resolved
A turn can take its messages out of the order they were sent in, so
the schema 90 upgrade no longer walks a turn's prompts in send order.
A message whose words one unmatched prompt and one unmatched message
of that turn share gets that prompt's node; where two could match,
neither is named rather than guess.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: deac9f4d56

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/server/mod.rs Resolved
Comment thread src/store/db.rs Resolved
Comment thread sonny/src/main.rs Resolved
remove_task refuses while one of the task's messages waits in line, so
it cannot start in a folder already removed. A commons invite counts
as sent by its message number, so one queued behind a busy agent is
kept. The window keeps the words of a queued prompt that failed in
line, with why it never ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants