Skip to content

fix(advisor): enable Claude Messages replay consultation - #8484

Draft
lidge-jun wants to merge 14 commits into
devfrom
codex/carry-8449-advisor-replay
Draft

lidge-jun wants to merge 14 commits into
devfrom
codex/carry-8449-advisor-replay

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

Carries #8449 onto dev: translated Claude Messages requests now resolve the Advisor factory and activity feed through their live configuration, including current consent. The CLI, agent reference and localized documentation state that revocation blocks consultations not yet dispatched but cannot cancel an already dispatched consultation or retract context sent.

The contributor branch tip contained the disclosure follow-up, but the original PR API remained at an older head. This carry preserves the full series and contributor credit.

Co-authored-by: fivetaku fivetaku@naver.com

Verification

  • Maintainer: HOME=<temporary> OPENCODEX_HOME=<temporary>/ocx bun test tests/advisor/advisor-settings.test.ts tests/advisor/advisor-messages-replay-config.test.ts tests/ci-workflows/skill-ocx.test.ts — 41 pass, 0 fail.
  • Carry preparation reports typecheck, skill surface check, privacy scan and docs build passed; these have not all been independently rerun by the maintainer on this head.
  • Carry preparation reports two repository-wide file-size failures on unchanged base files: scripts/test-layout/layout.json (2,000 lines) and structure/providers/anthropic-account-pool.md (603 lines). Both line counts match base 00680193cb. This PR does not modify either file; no passing ratchet is claimed.
  • test:changed was still running when the preparation task ended; its process handle is unavailable to the maintainer, so its result is unknown.
  • NOT RUN: full suite, Windows/macOS, live provider requests, final independent and security reviews, hosted CI. Draft until review and exact-head checks are assessed.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

fivetaku and others added 5 commits November 11, 2026 02:32
The Advisor factory slot is keyed by the live config object, but
/v1/messages hands the Responses pipeline a freshly spread replay config
(buildClaudeReplayConfig plus cacheRetention). The lookup in
createRegisteredAdvisorPlan therefore never matched on that path: Claude
Code clients got no synthetic advisor tool and no preflight consultation
even with the Advisor enabled, while /v1/chat/completions worked.

Link request-scoped config views to their live config in a WeakMap and
resolve the live factory at lookup time, so disable/re-activation still
applies and nothing is stored on the config object (it stays cloneable).

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted-by: claude-code:claude-ocx-teamclaude--claude-opus-5-5
Agent-Trace: da2ff2a0-1c04-49d7-a520-c190d1055028
Management writes replace the live config's advisor object, so the
shallow Messages replay view kept the copied reference and a consent
revocation after the copy did not reach the plan. The linked view now
reads `advisor` through to the live config; other request-scoped
overrides are unchanged and the view stays structuredClone-able.

- test: the Messages request runs the preflight pass; consent revoked
  on the live config after the copy blocks the consultation.
- docs: list translated /v1/messages as a supported Advisor client path
  with the same policy and consent rules.

Co-Authored-By: Claude <noreply@anthropic.com>
Assisted-by: claude-code:claude-ocx-teamclaude--claude-opus-5-5
Agent-Trace: 657cca3c-0740-4292-871c-c1a96c1ae4c9
Resolve request-scoped replay views to the live config for activity storage,
and clarify the boundary of consent revocation after dispatch. Exercise the
translated request, management activity feed, and consent timing.

Co-authored-by: fivetaku <fivetaku@naver.com>
The seven translated Advisor pages said `ocx advisor consent --revoke`
stops sending immediately. The English page states the actual boundary: a
revocation blocks consultations that have not been dispatched yet, and a
dispatched consultation cannot be cancelled nor can context that already
left the proxy be retracted.

Translate that distinction in ko, ja, zh-cn, zh-tw, fr, ru and tr without
changing surrounding wording or facts.
@coderabbitai

coderabbitai Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Nov 10, 2026
# Conflicts:
#	tests/helpers/responses-core-source.ts
…e copy

The previous regression kept its own copy of the write-and-exit sequence, so
reverting the actual production default path still passed all six cases: the
tests were watching code the adapter never runs. That is the finding this
addresses.

The fixture now has one `writeReplayAndExit`. Production calls it with no
hooks, and the probe calls it with hooks, so an observation and the bytes a
real turn depends on travel through the same statements. A new default-path
case spawns the fixture exactly as `turn.ts` does — three standard descriptors,
no probe environment — and drives production `readJsonLines` to prove all three
frames and the whole replayed text arrive with a zero exit. With only that
production path reverted and every probe left intact, the default-path case
fails with the production reader's malformed-frame error and the reader-release
case fails waiting for a mark the reverted sequence never emits; the other five
stay green, so their green was never evidence for the fix.

The command channel is gone. A descriptor one fd above the mark channel
intermittently never delivered a command, and commands over stdin cannot be
serviced while a multi-megabyte parent write holds that pipe, so the fixture
now reports marks on stderr and needs no descriptor beyond the standard three.
That removes the platform capability check and the skip it implied: nothing
here silently passes on a platform that cannot pass a fourth descriptor.

The control is measured in bytes from the fixture's own report rather than
assuming a destination size, and it stays small enough that no plausible
destination fails to take it in one piece. The vacuous `streamError` assertion
is gone; the accepted state and the completion callback's own error are
asserted from the marks that carry them. The EPIPE case asserts the write was
queued and then failed with EPIPE, and the malformed case waits for the child's
own `malformed-written` mark before asserting the reader rejected it.

Test plumbing fixes found while doing this: waiters are kept until they settle
instead of being dropped on the first chunk, and `close` is subscribed at spawn
so a cleanup cannot wait for an event that already fired.

Not claimed: the hosted `Unexpected EOF` root cause remains unestablished, the
observations describe this platform's buffering rather than a portable pipe
threshold, and this was verified on macOS only — not Windows or Linux.

Co-authored-by: JUN <jun@lidgeai.com>
An independent review found the comments claiming more than the cases prove.

The fixture said a `false` write return proves the kernel destination cannot
take the bytes. It does not: Bun buffers internally, so the return value
describes the runtime's own queue, and its semantics differ from a kernel
pipe's. The same comment said no later turn can change an unsettled callback,
which is false as soon as a reader drains; that case is now stated as the
single turn it observes. The control comment and test name called the size
difference pipe capacity; they now say the buffering and size behavior observed
here, and the byte bound is a guard on the fixture's own reported count rather
than a threshold claim.

Red-green is unchanged and re-measured on this tree. Reverting only the
production write-and-exit in the fixture fails the default-path case with the
production reader's malformed-frame error and fails the reader-release case
waiting for a mark the reverted sequence never emits; with the fix restored all
seven pass.

Not claimed: no pass-count guarantee across platforms, and no hosted
`Unexpected EOF` root cause. Verified on macOS only.

Co-authored-by: JUN <jun@lidgeai.com>
@lidge-jun lidge-jun added the ci:full Run the four full Ubuntu test shards on this pull request label Nov 12, 2026

This branch has not been deployed

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

Labels

bug Something isn't working ci:full Run the four full Ubuntu test shards on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants