Skip to content

fix(providers): retain native Claude and Grok input identities - #346

Merged
lukemaj merged 1 commit into
mainfrom
fix/observer-95-native-prompt-refs
Oct 15, 2026
Merged

lukemaj merged 1 commit into
mainfrom
fix/observer-95-native-prompt-refs

Conversation

@lukemaj

@lukemaj lukemaj commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What: New Claude and Grok turns retain native user-message identities that Observer 1.2.2 can join.
Why: Claude stored an assistant cursor and Grok stored a synthetic ordinal in the field used for input attribution.
So what: Merged at 127238c after both reviews and green CI; planner deployment and real-run acceptance are queued, and task resources are retired.

Refs #344 and toolboxmd/agent-observer#95.

Claude now persists the offered input UUID in nativeTurnRef and its assistant cursor in optional nativeConversationHeadRef. Fork and rollback consume the assistant cursor with a legacy-only fallback. Usage and compaction updates retain both references. Grok persists prompt:N from a valid root-session input echo's reported _meta.promptIndex; orchestration IDs remain unchanged, and missing or synthetic references remain unmatched. Observer joins and historical data are unchanged.

Proof

Exact base: f49ece39e8b302c8bffa9b17a385d66ec989b851; head: f8a82618c56222d61ece60c24efebb9f80165097.

  • Final regression set on an isolated exact-baseline source copy: 5 failed, 2 passed for the wrong reference/cursor behavior. On candidate: 7 passed. Covers user/agent inputs, usage/compaction updates, fork/rollback, historical cursor fallback, explicit null cursor, numeric zero, invalid/missing metadata, child-session exclusion and synthetic input exclusion.
  • Complete typecheck: 32 workspaces passed.
  • Complete vp check: passed, 6,013 formatted files, 0 lint errors and 974 existing warnings.
  • Complete configured knip:check: passed.
  • Complete CI passed on this exact head: run 38673300064. Workspace tests, web, all six server shards, Rust, lint, typecheck, build, release smoke, transfer report and final Check all succeeded.
  • CI server shards: 7,391 passed, 33 skipped; web: 6,980 passed; workspace totals are recorded in the linked Issue handoff. Rust: 38 passed across all three documented crates.
  • Local full recursive coverage was attempted. Two unchanged failures independently reproduce on exact baseline: Unicode terminal-label handling (fix(shared): preserve legacy terminal labels after supplementary Unicode letters #345) and a cgroup test assuming system Node (test(acp): remove the cgroup wrapper test assumption of system Node #348). Desktop's initial lazy dependency extraction failed; retry passed 1,557 tests, 1 skipped. The duplicate local serial server run was stopped once complete exact-head CI passed; it is not reported as a local full-suite pass.
  • Local Rust could not execute because cargo is absent (exit 127); the exact-head CI Rust job supplies complete crate proof. No toolchain installation was performed.
  • Full diff self-review and git diff --check passed. Source/consumer map and exact commands: #344 evidence, candidate proof.

This is forward adapter proof, not actual-runtime attribution acceptance. Observer95 still needs real user AND agent Claude/Grok runs after planner-owned deployment, the complete identity chain and resulting created_by, plus forward join counts and correction coverage. No merge, deployment or product installation by this implementation child. No version bump under Chromeria policy. No feature-map part owns this integration defect; no map or user-documentation change applies.

Elon record

Requirements and who asked: The user requests fixing Observer95 at the existing adapter owner, preserving native cursor semantics and exact joins, full proof, independent Sol/Grok reviews and no installation.
Deleted: Text/hash joins, ordinal inference, historical backfill, new component, unnecessary Observer release, installation and deployment by this child.
Bottleneck: Adapter persistence emits identities absent from native user records; runtime acceptance waits for the planner's separately owned deployment.
Checked myself: Live base, complete Observer95 and 1.2.2 import, copied ledger counts, all nativeTurnRef consumers, current upstream main, exact-baseline red cases and candidate green/full checks.

Implemented by gpt-6.1-sol, high reasoning effort, through the Codex harness in T3 Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.9 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB +7 B (+0.1%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB +7 B (+0.6%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB 0 B (0.0%) 29.3 KiB ✅
Claude Live turn messages 2 2 0 (0.0%) 8 ✅

Baseline: f49ece3 · PR result: f8a8261 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@lukemaj

lukemaj commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent Sol review passes the forward Claude/Grok identity fix at f8a82618c56222d61ece60c24efebb9f80165097, with no reproduced blocking defect.
Why: The native input reference remains distinct from Claude's assistant cursor, and Grok uses the root echo's authoritative numeric prompt index.
So what: This supplies the Sol review only; the dispatcher retains merge ownership, and Observer95 stays open for planner-owned deployment and actual user/agent runtime acceptance.

Reviewed base f49ece39e8b302c8bffa9b17a385d66ec989b851 through frozen head f8a82618c56222d61ece60c24efebb9f80165097. Live PR head was rechecked unchanged immediately before this comment. Read the complete six-file diff, #344 body/comments, Observer95 body/comments, PR body/comments, repository instructions/direction, canonical verification/code-review procedures and explicit impact analysis. No prior-round findings. Verdict: PASS, under the requested reproduced-wrong-behavior blocking bar. No actionable additional concern requires a new follow-up.

Contract and consumer impact

  • Claude input and cursor owners: ClaudeAdapterV2.ts:4210 retains the UUID actually offered to the SDK in every provider-turn payload. Internal provider-turn/item/delta identities still derive from the original synthetic attempt identity. Assistant snapshots update the separate cursor; usage and compaction now share the payload builder, so neither overwrites the input identity.
  • Native operations: resolveClaudeForkUpToMessageId and resolveClaudeRollbackResumeSessionAt consume the new assistant cursor. Only an absent field falls back to the historical nativeTurnRef. Explicit null does not become the input UUID. Fork calls still receive upToMessageId; rollback returns the assistant head for query startup's existing resumeSessionAt path. Existing no-cursor safety behavior is retained.
  • Grok / other ACP flavors: root-session routing precedes extraction in provider-acp/adapter.ts. Child-session notifications, provider continuations, settled turns and task wake notifications cannot fill the reference. Grok alone supplies the new extraction hook. Its user_message_chunk._meta.promptIndex must be a safe nonnegative number, including zero; synthetic/hidden echoes and malformed indices are rejected. Missing identity stays synthetic/unmatched. No ordinal, text/hash, completion-ID or positional inference, and no historical backfill.
  • Generic consumers: ProviderEventIngestor.runsOffNativeBranch uses strong references only when a provider-thread event carries retainedNativeTurnIds; Claude/ACP do not emit that branch-reconciliation signal. Orchestrator.contextSourcePointForRun copies the reference as provenance, and no native operation consumes that copied providerTurnRef.
  • Persistence and clients: OrchestrationV2ProviderTurnJson derives from the changed shared schema; ProjectionStore's JSON encode/decode and provider-turn upsert retain it. Absent, explicit null and populated cursor remain distinguishable through serialization. Web, Electron, mobile and remote clients consume the shared contract. There is no surface-specific writer or UI change.
  • All other native-reference owners: Codex fork/rollback and native turn lookup, Pi tree capture/rewind, both OpenCode adapters' prompt/boundary/revert helpers, and Cursor/Muse producers retain their existing adapter-local reference semantics. Existing provider-thread-level nativeConversationHeadRef producers/consumers, including session import and orchestration resets, are unchanged. The new provider-turn field is produced/consumed only by Claude. Searched all nativeTurnRef, nativeConversationHeadRef, nativeId dereferences and providerTurnRef consumers across apps/packages, and followed the external Observer consumer.
  • Observer 1.2.2: inspected exact released source a42c729c531e0d6580a59a77d7d824a9197fa7f7. _import_prompt_origins already accepts weak/strong native refs and maps Claude UUIDs and Grok session plus prompt:N to the existing native keys. The optional assistant cursor is ignored by that join. No Observer join change or release is needed for this forward contract.

Checks I executed

All execution used disk-backed isolated copies under /home/luke/tmp/chromeria-observer95-sol-yzqp3a4u, PYTHONDONTWRITEBYTECODE=1 and TMPDIR=/home/luke/tmp. Existing dependencies were copied, with no installation. The six candidate files were byte-compared against the exact frozen git objects.

  1. node node_modules/vite-plus/bin/vp test run apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts: 400/400 passed. This includes actual fork/rollback consumer calls, legacy fallback, explicit null rollback, user/agent UUID retention across usage/compaction, Grok zero/nonzero indices and child/synthetic/malformed exclusions. Log: sol-adapters.log.
  2. node node_modules/vite-plus/bin/vp test run apps/server/src/orchestration-v2/ProviderEventIngestor.test.ts packages/contracts/src/orchestrationV2.test.ts: 57 passed. Log: sol-consumers.log (the initial extra probe at repository root failed dependency resolution, without affecting these two passing suites).
  3. Two independent disposable probes, rerun in the correct server package resolution scope: 2 passed. Exercised actual JSON schema encode/decode plus upsertProviderTurn for absent/null/distinct cursors and usage preservation; exercised Grok's real extraction hook for zero, positive, missing, null, string, boolean, negative, fractional, nonfinite/unsafe indices and separate synthetic/hidden flags. Log: sol-contract.log. No candidate implementation was changed.
  4. Unchanged Observer 1.2.2 python -m unittest tests.test_t3_v2: 11 passed. An additional disk-backed fabricated-contract check of its actual import/join passed 4/4 Claude/Grok user/agent cases, including prompt:0; unmatched ordinal/cursor keys remained unknown. The first custom probe lacked adapter mirror-table setup; adding the normal _ensure_tables fixture setup resolved that harness error. These are contract checks, not native runtime acceptance.
  5. Exact-base-to-head git diff --check: passed. Author worktree remained clean and on the frozen head; no source/ref/worktree or live-ledger edits, checkout/switch/reset/pull, browser use, installation, deployment or merge was performed by this reviewer.

Evidence inspected and reused, not rerun by me

  • Author red/green and full static proof, with raw artifacts under /home/luke/tmp/chromeria-95: final regression baseline 5 failed / 2 passed, candidate 7 passed. I read the actual baseline failures and confirmed both substituted baseline test files match the final candidate tests. The failures are wrong UUID/index/cursor assertions, not setup errors.
  • Full typecheck 32 workspaces, complete vp check (6,013 formatted files, 0 errors, 974 warnings) and configured knip:check: author evidence inspected. Desktop retry 1,557 passed / 1 skipped after the initial Electron extraction failure.
  • The author's independent-per-workspace local recursive run is still incomplete at inspection. Shared Unicode failure reproduces on exact baseline and is already tracked in #345; it is not a regression attributed to this PR. I do not call the local complete suite passing.
  • Exact-head CI run 38673300064 completed success. Verified run SHA, job states, workflow commands and test/Rust log output. Lint/knip, typecheck, build, recursive non-server tests, web, all six server shards, Rust, release smoke and aggregate Check succeeded. Local cargo absence is not local Rust proof; CI supplies that evidence. This review does not waive the complete proof/CI gate.
  • Upstream search record: no matching fix found; this is not a port claim.

Runtime limit and existing follow-ups

This reviews the forward adapter repair only. Observer95 remains open: actual human and agent Claude/Grok runs must be checked after separately authorized planner-owned deployment, including the full message/run/attempt/provider-turn/native-record identity chain, resulting created_by, join counts and correction coverage. The copied corpus lacks a human Grok acceptance run. Historical unmatched records remain unknown. No claim of deployed or production attribution success is made.

Elon record

Requirements and who asked: The user requested independent exact-head Sol review of #344/Observer95, preserving Claude native operations and authoritative Grok input identity, with reproduced behavior as the blocking bar.
Deleted: Implementation changes, delegation, inferred/history backfill attribution, unrelated parser repair, installation, deployment and production acceptance claims.
Bottleneck: Adapter identity correctness is reviewable here; actual runtime acceptance waits on the planner's deployment and new real runs.
Checked myself: Complete diff and consumer map, 459 passing candidate tests/probes, 11 released Observer tests and four fabricated join cases, author red/green/static evidence and exact-head completed CI.

Independent reviewer: review/sol, gpt-6.1-sol with high reasoning effort, Codex harness in T3 Code.

@lukemaj

lukemaj commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

What: PR #346 is frozen and ready for independent review at f8a82618c56222d61ece60c24efebb9f80165097, with complete exact-head CI green.
Why: The adapters now expose native input identities while Claude retains its separate assistant cursor for native history operations.
So what: Dispatcher obtains independent read-only Sol and Grok reviews with each reviewer's own exact-head status, then owns merge; planner thread 080890dd-885c-4498-819c-e7814a394f89 owns deployment and real-run acceptance.

Canonical handoff

Exact-head proof

Complete CI run 38673300064 succeeded for the frozen head. Read the actual job logs and summaries, not only the rollup:

Coverage Result
Workspace tests (Test) 11,522 passed, 12 skipped
Web tests 6,980 passed
Server shard 1 726 passed
Server shard 2 686 passed, 6 skipped
Server shard 3 1,397 passed, 1 skipped
Server shard 4 1,625 passed, 2 skipped
Server shard 5 1,754 passed, 14 skipped
Server shard 6 1,203 passed, 10 skipped
Rust crates 38 passed across resource-monitor, kde-snap-shot and hyprland-snap-shot
Lint, typecheck, build, release smoke, transfer report, final Check Passed
Mobile native static analysis Skipped by the workflow because no native sources changed

Total JavaScript tests: 25,893 passed, 45 skipped, 0 failed. Rust adds 38 passing tests. This is complete repository CI proof, not affected-only proof.

Local proof also passed: final seven-case regression set, full 32-workspace typecheck, vp check (6,013 formatted files, zero lint errors), configured knip:check, full diff self-review and git diff --check. The same final regression set on a private exact-baseline source copy failed in five discriminating cases and passed two controls.

Local complete recursive tests were attempted. After initial copied dependency omissions were repaired, every workspace script was run without stopping the later workspaces on the shared failure. The duplicate local serial server run was stopped after complete exact-head CI passed, so it is not claimed as a local full-suite pass. Its two unchanged failures also reproduce on the exact baseline: #345 (Unicode terminal labels, local Node 26.8.2) and #348 (cgroup test assumes Node in /usr/bin:/bin). Desktop's initial lazy dependency extraction failed; its retry passed 1,557 tests, one skipped. Local Rust could not run because cargo is absent; the complete CI Rust job supplies that coverage. No toolchain or Chromeria/Observer product installation was performed.

Private proof files, baseline source copies and copied native evidence remain under /home/luke/tmp/chromeria-95 and the original /home/luke/tmp/observer-review/... paths; originals are preserved and no private text is published.

Remaining gates and authority

No independent-review status has been authored or relayed by this implementation child. Dispatcher must obtain BOTH independent read-only Sol and Grok reviews on this exact head, with each reviewer posting its own findings and status. CI is green, but this is not merge approval by the author. The child does not merge, deploy, install or delegate.

Observer95 remains open for actual user AND agent Claude/Grok runs after planner-owned deployment. Show the real message -> run -> attempt -> provider-turn -> native-user-record chain and resulting created_by, forward native join counts and correction population coverage. The copied corpus lacks user Grok runs and there is no installation authority here, so no actual-runtime acceptance is claimed. Historical counts stay Claude 0/877, Grok 0/583 and Codex 835/860; no backfill or attribution invention. Observer 1.2.2's current joins already accept the forward references, so an Observer release is unnecessary.

Main checkout remains read-only at da7034eb8a465303710bccd91d55ea2618da4110, including the same user-owned untracked scripts/__pycache__/. No browser/computer use. No current feature-map part owns this integration defect, so no map change applies. Workspace and branch are retained for review and dispatcher-owned delivery/finalization.

@lukemaj

lukemaj commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent Grok review finds no blocking defect on f8a82618c56222d61ece60c24efebb9f80165097.
Why: Claude now stores the offered prompt UUID in nativeTurnRef and the assistant cursor in optional nativeConversationHeadRef; Grok stores prompt:N from the root input echo.
So what: This review passes. It does not merge, deploy, or accept runtime attribution. Observer #95 stays open for real user and agent Claude/Grok runs after the planner deploys.

Verdict: pass. Base f49ece39e8b302c8bffa9b17a385d66ec989b851. Head was still that SHA, and the author worktree was clean, when this comment was posted.

Contract

Claude providerTurnPayload is the only provider-turn writer. Start, usage, compaction, and the terminal update all keep promptUuid, and fall back to the synthetic turn: id only when that UUID is null (continuation turns). nativeConversationHeadRef is the assistant cursor, or explicit null before one exists. Fork and rollback use that field when it is present. Explicit null does not fall back to the input UUID. An absent field, which is what old rows have, still reads nativeTurnRef. Both resolvers are what forkThread and rollbackThread call, and the new tests drive those methods.

Grok reads user_message_chunk._meta.promptIndex and accepts a safe integer including zero. It rejects non-numbers, negatives, syntheticPrompt, and hideFromScrollback. A child-session notification returns before that extractor. Continuations and wake notifications are also excluded. A missing index stays the old weak session:turn:ordinal id. The first accepted echo wins; later chunks do not replace it.

Observer 1.2.2 (a42c729) joins nativeTurnRef at strength strong or weak, prefixes Claude as claude:<id> and Grok as grok:<session>:<id>, and leaves unmatched ids unknown. No Observer change and no historical backfill are in this diff. Codex, OpenCode, Pi, Cursor, and Muse writers are unchanged.

runsOffNativeBranch only treats a strong ref as a branch cursor, and only Pi emits retainedNativeTurnIds. Claude stays weak. Grok's new strong prompt:N does not enter that path. contextSourcePointForRun copies nativeTurnRef into provenance; nothing else reads providerTurnRef. Projection upsert keeps the incoming turn fields and only fills a missing tokenUsage from the previous row, so a later prompt id or assistant cursor replaces the stored payload.

Evidence

Executed here: full six-file diff, production consumer map, Observer import, fork/rollback call path, child-session gate, projection upsert, and git diff --check (clean). No tests were re-run, and nothing was installed or deployed.

Reused author logs, after reading them: baseline copy /home/luke/tmp/chromeria-95/baseline failed 5 and passed 2 (red-final.log); candidate worktree passed 7 (green-final-3.log, ended before the commit). vp check reported 6,013 files formatted, 0 lint errors, 974 warnings. The typecheck and knip logs show clean vp run footers and no TypeScript error lines. Desktop retry log: 1,557 passed, 1 skipped. The shared Unicode failure is the unchanged baseline case in #345.

Observed gh pr checks on this SHA: Test, Test Server 1-6, Test Web, Typecheck, Lint, Rust, Build, and Release Smoke passed. Label and fingerprint jobs were still pending. Local cargo is absent; CI Rust is the Rust proof. The local recursive driver was interrupted (KeyboardInterrupt) before server, web, infra, and scripts were recorded. Its partial server log shows processTree.test.ts failing to find node on the default PATH. That test is outside this diff, and the CI server shards passed.

Runtime acceptance is not claimed. The copied corpus has no human Grok run, and historical Claude/Grok joins stay unmatched until new runs exist after deployment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant