refactor(openclaw): drive the adapter only through HarnessClient - #959
Closed
chughtapan wants to merge 2 commits into
Closed
refactor(openclaw): drive the adapter only through HarnessClient#959chughtapan wants to merge 2 commits into
chughtapan wants to merge 2 commits into
Conversation
The plugin chose between a HarnessClient and a directly constructed MoltZapService at runtime, and only the second arm was reachable in production, because nothing could compute a daemon endpoint. The slot now carries its port, so the account id alone resolves a client. startAccount acquires that client unconditionally and drains it. The legacy arm goes with everything that existed to serve it: the gateway service and core constructors, the inbound bridge that synthesized a turn from a raw core message, connection-status reporting, the outbound dispatcher, the active-service map, and the legacy half of the gateway lifecycle. The directory section goes with it. Serving listPeers and listGroups through the client would publish agent and conversation search on the adapter-facing surface, which the accepted HarnessClient record keeps as MCP management operations. A harness-backed account already returned empty lists, so this makes an existing silent gap explicit. Proactive sends into an existing conversation and MoltZapService.sendToAgent go too. Repeated proactive DMs to one agent no longer share a conversation; that regression is tracked separately. The docker suites and their container harness are deleted rather than carried: they were gated behind an image that has no Dockerfile here and no CI step builds one, so they had never executed. No integration suite remained in the package afterward, so its setup and config go as well. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P76aaa1STr3WPZ3nDascta
This was referenced Aug 5, 2026
Owner
Author
|
Superseded by #974, which collapses this stack into one PR against |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plan step 10. Stacked on #955. −4297 / +991 across 26 files. This is the cutover the whole stack was built toward.
The dual path is gone
startGatewayAccountEffectchose between aHarnessClientand a directly constructedMoltZapServiceby testing whether a dep was injected. Only the second arm was ever reachable in production, because nothing could compute a daemon endpoint. #954 gave the slot its port and #955 gave it a client, so the account id alone now resolves one:The legacy arm goes with everything that existed to serve it — the gateway service and core constructors, the inbound bridge that synthesized a turn from a raw core message, connection-status reporting,
dispatchOutbound, theactiveClientsmap,OpenClawClientService, and the legacy half ofopenclaw-gateway-lifecycle.ts(which drops to 48 lines). The JSDoc mermaid flow is rewritten for the single path, per the repo rule that a flow change updates its diagram in the same PR.Capability drops — taken deliberately, not discovered
The
directorysection. ServinglistPeers/listGroupsthrough the client would publish agent and conversation search on the adapter-facing surface, which20260801-harness-client-owns-runtime-contextkeeps as "MCP management operations, not adapter-facing service methods." A harness-backed account already returned[]for both, so this makes an existing silent gap explicit rather than introducing one.Proactive
conv:<id>outbound andMoltZapService.sendToAgent. Repeated proactive DMs to one agent no longer share a conversation — tracked in #957 with the fix recipe, not left as a bullet here.TARGET_PREFIX_CONVERSATIONsurvives:originatingTargetlabels every inbound turn's reply-to address with it, so target parsing outlives proactive sending.MoltZapService.sendalso survives —channel-core.ts → sendReplydelegates to it andmoltzapd.tswiresreply: core.sendReply.bind(core). Generic send dies on the adapter surface, not inside the daemon.The docker suites had never run
Deleted rather than carried, along with their whole harness.
moltzap-eval-agent:localhas no Dockerfile in this repo andci.ymlcontains zero docker references, soisImageAvailable()always failed,containerAIdwas"", and both suitesdescribe.skipIf-ed unconditionally. They produced green checkmarks for nothing.With them gone no integration suite remained in the package, so
vitest.integration.config.mjs, its globalSetup,test-helpers.ts, and thetest:integrationscript went too — a setup that provisions nothing is worse than no setup.Gates
returns nothing — including generated
MODULE.mdand the package's ownAGENTS.md, which still described wrappingMoltZapChannelCoreand binding a Unix socket.docs:generatewas cached and had to be forced with--skip-nx-cacheto catch the stale diagram.pnpm nx run workspace:precommit— exit 0 (the gate that includeslint:sloppy-code-guard)typecheckandtypecheck:tests— 0 errors@moltzap/openclaw-channel:test— 71 passed / 8 filesDeviation from the plan, for your call
The plan says delete
deps.harnessClientForAccount. It also says rewrite the tests ontocreateHarnessFixture, which requires injection. Those contradict.I kept it as the single DI seam. With legacy gone it no longer selects a backing — there is exactly one production path, and this is dependency injection rather than runtime generation selection. Deleting it would have forced every gateway test to spawn a real daemon, trading ~1100 lines of fast unit coverage for integration-only proof.
Worth an explicit ruling rather than my judgment.
ADR conformance (R-pass)
20260801-harness-client-owns-runtime-contextCONFORMS20260728-model-surface-is-start-reply-listenCONFORMSstartConversationonly;conv:<id>sending andsendToAgentdeleted.MoltZapService.sendsurvives strictly inside the daemon reply path.20260801-harness-is-one-profile-slot-daemonCONFORMSLedger row 6 (
ConversationWithParticipantsdocumented as daemon-local yet publicly exported) is not resolved here — it lives inpackages/clientand is settled by #958's wire narrowing.🤖 Generated with Claude Code
https://claude.ai/code/session_01P76aaa1STr3WPZ3nDascta