Skip to content

fix(memory-ingest): render Codex rollout message bodies - #2132

Closed
genisis0x wants to merge 2 commits into
garrytan:mainfrom
genisis0x:codex-rollout-bodies
Closed

genisis0x wants to merge 2 commits into
garrytan:mainfrom
genisis0x:codex-rollout-bodies

Conversation

@genisis0x

Copy link
Copy Markdown
Contributor

Closes #2105.

Problem

gstack-memory-ingest renders every Codex rollout session with an empty body (message_count: 0). Current Codex rollout JSONL carries each turn as a response_item record with the message on payload.{type:"message", role, content[]}:

{ "type": "response_item", "payload": { "type": "message", "role": "user"|"assistant"|"developer", "content": [...] } }

but parseTranscriptJsonl (bin/gstack-memory-ingest.ts) only extracts content when rec.payload.message is present (the older shape). That branch never fires on the current format, so the message loop counts zero turns and stages an empty page for every Codex transcript.

Fix

Handle the current payload.type === "message" shape alongside the legacy payload.message wrapper: read payload.role and flatten payload.content through the existing extractContentText helper. Legacy sessions keep working.

Test

Adds a product-path regression in test/gstack-memory-ingest.test.ts that ingests a response_item-format Codex session through the full --bulk path (fake-gbrain staging shim, same pattern as the NUL-byte test) and asserts the staged transcript renders both the user and assistant turns. It fails on the old parser (staged body empty, message_count: 0) and passes with the fix.

bun test test/gstack-memory-ingest.test.ts -> 24 pass. No template/SKILL.md change, so no regeneration; no VERSION bump (same as other bin/skill bug-fix PRs).

Codex rollout JSONL now carries each turn as a `response_item` record
with the message on `payload.{type:"message", role, content[]}`, not on
the legacy `payload.message`. parseTranscriptJsonl only read
`payload.message`, so every Codex session imported with an empty body and
message_count 0.

Handle the current `payload.type === "message"` shape alongside the
legacy wrapper: read `payload.role` and flatten `payload.content`. Adds a
product-path regression that ingests a response_item session and asserts
the staged transcript renders both the user and assistant turns (fails on
the old parser with an empty body).

Closes garrytan#2105
@trunk-io

trunk-io Bot commented Jun 29, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@time-attack

time-attack commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

@genisis0x Please enforce a role boundary in the current-schema parser so developer instructions cannot be ingested as memory content.

Codex rollout records carry role user|assistant|developer. The rollout
parser ingested every role, so developer (system-level) instructions were
captured as memory content. An injected developer instruction inside a
rollout would then resurface later as trusted memory.

Add an INGESTIBLE_ROLES allowlist (user, assistant) and skip any other role
in both Codex shapes (legacy payload.message and current response_item).
Regression test asserts a developer directive is dropped while the user and
assistant turns still render.
@capy-ai

capy-ai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Thank you for this fix! The bug it addresses (#2105) has since been fixed on main and the issue is closed, so I'm closing this PR as done. Re-verified against current main (v1.91.12.0). If you think part of your change is still missing, reply and we'll reopen. Really appreciate the contribution.

@capy-ai capy-ai Bot closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants