Skip to content

fix(acp): persist session identity receipts for both runtimes - #4721

Open
PAB55 wants to merge 1 commit into
block:mainfrom
PAB55:fix/session-identity-receipts
Open

fix(acp): persist session identity receipts for both runtimes#4721
PAB55 wants to merge 1 commit into
block:mainfrom
PAB55:fix/session-identity-receipts

Conversation

@PAB55

@PAB55 PAB55 commented Aug 4, 2026

Copy link
Copy Markdown

Problem

buzz-acp does not persist which agent identity a session belongs to. Neither runtime carries it natively:

  • Codex — none of the 18 session_meta fields or 19 turn_context fields contains a pubkey, agent id, or auth tag (enumerated across 320+ rollout-*.jsonl files). agent_nickname appears only alongside parent_thread_id, so it names a child, never the managed root.
  • Claude — no common persisted identity field.

The practical consequence is that per-session usage records cannot be attributed to the agent that produced them. Recovering identity from persona prose is the only option today, and it is unreliable by construction.

Change

At the common post-session/new boundary — covering both Codex and Claude — append one versioned JSONL receipt to a Desktop-provided, pair-scoped sidecar path:

{"schema_version":1,"session_id":"","agent_pubkey":"","harness":"","recorded_at":""}

Five fields, nothing else. No channel id, message, prompt, credential, model, or cost content.

  • Path arrives as reserved BUZZ_ACP_SESSION_IDENTITY_LOG; persona/agent env cannot redirect it.
  • Created 0600, with a re-check that repairs a pre-existing loose mode; sync_data on write.
  • Invalid identifiers are rejected before creation; #[serde(deny_unknown_fields)].
  • Persistence failure emits buzz_acp::session_identity warning telemetry and does not fail the ACP session.

Purely additive: 9 files, 477 insertions, 0 deletions.

Verification

buzz-acp: 660 unit + 9 integration tests pass. Desktop library: 2,014 pass. Warning-denied Clippy, rustfmt, and clean-tree checks pass.

Beyond the suites, the writer was exercised against a real runtime in an isolated harness with a throwaway identity:

  • two Codex turns in one process produced exactly one receipt;
  • after a restart, two further turns produced exactly one new receipt, first line byte-identical;
  • 2/2 receipts joined to their rollout by filename UUID;
  • mode 0600, zero persona-marker hits.

Codex joining is specified against the rollout filename UUID rather than session_meta.id, because 2 of 323 observed rollouts were truncated before writing a header — the filename is present on all of them.

Notes

The harness starts a new session after a process restart, so this does not attempt same-session continuity across restarts; that would be a separate resume feature.

🤖 Generated with Claude Code

Co-authored-by: Link <nathanclark28@gmail.com>
Signed-off-by: Link <nathanclark28@gmail.com>
@PAB55
PAB55 requested a review from a team as a code owner August 4, 2026 14:20
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.

1 participant