Skip to content

fix(parser): keep Codex exec automated and tag roborev - #1855

Merged
mariusvniekerk merged 5 commits into
mainfrom
t3code/investigate-codex-subagents
Sep 20, 2026
Merged

mariusvniekerk merged 5 commits into
mainfrom
t3code/investigate-codex-subagents

Conversation

@mariusvniekerk

@mariusvniekerk mariusvniekerk commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

Every codex exec session is automated. originator=codex_exec is stored as
session_kind=non-interactive.

Roborev reviews are a more specific kind of that work. When
thread_source=roborev (from codex exec --thread-source roborev), the
session is stored as session_kind=roborev so they are identifiable as code
review while remaining automated.

Interactive TUI and desktop sessions stay interactive. Native spawn_agent
children still use source.subagent plus parent_thread_id.

Companion roborev change: kenn-io/roborev#1205

Evidence

  • Before: exec sessions with a non-matching first message were
    interactive. thread_source=roborev was ignored.
  • After: originator=codex_exec is automated. thread_source=roborev
    is automated and kind roborev.
go test -tags fts5 ./internal/parser -run 'TestParseCodexSession_ExecOriginator|TestParseCodexSession_RoborevThreadSource'
go test -tags fts5 ./internal/db -run 'TestIsAutomatedSessionMetadata|TestCurrentDataVersionCodexExecSessionKind'

Existing Codex-format rows reparse at data version 112.

Merge danger

Door: two-way. Revert restores prompt-only classification for exec
sessions that do not match a built-in prefix.

Blast radius: every Codex exec session becomes automated, including
one-shot codex exec that is not roborev. Roborev-tagged sessions keep
the more specific kind.

Roborev now starts many Codex workers by pointing them at a prompt file
instead of an inline reviewer prompt. Those first messages miss the
built-in automation prefixes, so `codex exec` sessions were stored as
ordinary conversations and filled the session list.

`originator=codex_exec` already identifies a non-interactive invocation.
Persist it as session_kind non-interactive so the same metadata path
Grok uses marks these sessions automated, including when they have more
than one user turn.

Existing Codex-format rows reparse at data version 112. Native
spawn_agent children still use source.subagent and parent_thread_id.
@roborev-ci

roborev-ci Bot commented Sep 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (0cb707d)

Verdict: Changes require fixes for 1 finding.

High

  • internal/parser/codex.go:424: The new SessionKindNonInteractive marker is not honored when normal transcript automation is recomputed; updateSessionAutomationFromMessagesTx can overwrite metadata-based is_automated=true with false, leaving Roborev prompt-file sessions classified as non-automated. Include agent/session_kind in the shared automation-state query and OR IsAutomatedSessionMetadata into the result; add an end-to-end sync assertion for a Codex exec prompt without a built-in automation prefix.

    Reported by: codex


Reviewers: 2 done | Synthesis: codex, 5s | Total: 4m7s

Roborev will pass --thread-source roborev on Codex exec. Persist that
tag as session_kind=roborev and classify those sessions as automated.

Do not treat every originator=codex_exec session as automated. That
would include human one-shots.
@mariusvniekerk mariusvniekerk changed the title fix(parser): classify Codex exec sessions as automated fix(parser): treat Codex thread_source=roborev as automated Sep 19, 2026
@roborev-ci

roborev-ci Bot commented Sep 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (baec5d4)

Verdict: Changes require fixes for 1 finding.

High

  • internal/db/messages.go:2429: Full parses call updateSessionAutomationFromMessagesTx, whose sessionAutomationStateTx derives is_automated only from message text and overwrites the metadata-based classification. A thread_source=roborev session with a generic prompt can therefore end up with is_automated=false despite session_kind='roborev'. Include agent and session_kind in the automation-state query and OR IsAutomatedSessionMetadata(agent, sessionKind) into the computed result; add an observable sync test covering the full replacement path.

    Reported by: codex


Reviewers: 2 done | Synthesis: codex, 6s | Total: 2m19s

codex exec is non-interactive work. Restore originator=codex_exec as
session_kind=non-interactive so those sessions stay automated.

When thread_source is roborev, store session_kind=roborev instead so
roborev reviews are identifiable as code review on top of that.
@mariusvniekerk mariusvniekerk changed the title fix(parser): treat Codex thread_source=roborev as automated fix(parser): keep Codex exec automated and tag roborev Sep 19, 2026
@roborev-ci

roborev-ci Bot commented Sep 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (75dc51b)

Verdict: Changes require fixes for 1 finding.

Medium

  • internal/parser/codex.go:424: A later session_meta record with originator=codex_exec unconditionally overwrites an earlier SessionKindRoborev, so a roborev review can lose its specific classification and appear only as non-interactive. Preserve SessionKindRoborev precedence when assigning the non-interactive kind, and add a regression test with roborev metadata followed by an exec metadata record.

    Reported by: codex


Reviewers: 2 done | Synthesis: codex, 4s | Total: 4m2s

mariusvniekerk added a commit to kenn-io/roborev that referenced this pull request Sep 19, 2026
Codex review sessions currently store `thread_source=user`, so they look
like
human `codex exec` one-shots. This passes `--thread-source roborev` on
`codex exec`. That value is written into
`session_meta.payload.thread_source`.

Older Codex CLIs that reject the flag keep the previous invocation.

Droid reviews also get `--tag roborev` for Factory session logs.
AgentsView
does not parse Droid yet.

Companion AgentsView change: kenn-io/agentsview#1855

## Evidence

- **Before:** `codex-proxy exec` without the flag stored
`thread_source=user`.
- **After:** `codex-proxy exec --thread-source roborev` stored
  `thread_source=roborev`. Unit tests cover arg construction and the
  capability probe.

```
go test ./internal/agent -run 'TestCodex|TestDroid'
```

## Merge danger

**Door:** two-way. Revert drops the flags.

**Blast radius:** Codex 0.153+ review sessions get a new
`thread_source`.
Do not use `--thread-source subagent`; that is Codex lineage, not a
roborev
tag.
Main adopted the shared Go lint policy on the same Codex exec tests.
Keep the session_kind assertions that mark exec as non-interactive, and
use assert.Len so the lint policy still holds.

Classification is unchanged: originator=codex_exec is automated, and
thread_source=roborev stays the more specific roborev kind.
@roborev-ci

roborev-ci Bot commented Sep 19, 2026

Copy link
Copy Markdown

roborev: Combined Review (b197d19)

Verdict: No findings at or above medium severity.


Reviewers: 2 done | Synthesis: codex | Total: 3m57s

Windows CI failed this test with WSAEADDRINUSE after FindAvailablePort
probed and closed the chosen port. The rewrite check does not need a
second listen on that port.
@roborev-ci

roborev-ci Bot commented Sep 20, 2026

Copy link
Copy Markdown

roborev: Combined Review (9349221)

Verdict: No findings at or above medium severity.


Reviewers: 2 done | Synthesis: codex | Total: 3m49s

@mariusvniekerk
mariusvniekerk merged commit 2f81cf4 into main Sep 20, 2026
17 checks passed
@mariusvniekerk
mariusvniekerk deleted the t3code/investigate-codex-subagents branch September 20, 2026 02:22
mariusvniekerk pushed a commit that referenced this pull request Oct 9, 2026
…tive (#2158)

Activity's Interactive peak now matches the conversations you were having: `claude -p`, `codex exec`, and Grok workers that another agent launched count as Subagents. With 27 synthetic sessions active at once, the Interactive peak drops from 24 to 9. Known subagents keep that category even when scripted or their parent disappears. Audits preserve stored automation flags in usage-only archives.

Automation requires script evidence, a roborev tag or an `[automated]` prompt match, changing #1855. Workers show as sidebar roots until #2115 links parents. Audits repair stored non-interactive workers and later imports. Readable sources reparse once; deleted Claude transcripts can prevent historical repair.

| | Light | Dark |
| --- | --- | --- |
| Before | ![Light before, synthetic sessions](https://github.com/user-attachments/assets/f4a881c4-263f-4437-9f4a-5b9de0b73768) | ![Dark before, synthetic sessions](https://github.com/user-attachments/assets/3f5ca400-af15-4bcf-9892-c0bf1fa483d9) |
| After | ![Light after, synthetic sessions](https://github.com/user-attachments/assets/10793391-5a7f-41fb-8fd8-ec9d4602c0ad) | ![Dark after, synthetic sessions](https://github.com/user-attachments/assets/993b076a-ef62-4805-b9c9-e8c049bc4218) |

Closes #2154


Co-authored-by: Rod Boev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant