fix(memory): rollback cycle-reflection trailer — DM regression - #296
Closed
samxu01 wants to merge 1 commit into
Closed
fix(memory): rollback cycle-reflection trailer — DM regression#296samxu01 wants to merge 1 commit into
samxu01 wants to merge 1 commit into
Conversation
…udget Phase 2.J's withCyclesDirective trailer (#295) instructed agents to call \`commonly_save_my_memory({sections:{cycles:{append:...}}})\`, but the openclaw extension exposes no tool by that name — agents waste 3+ turns per heartbeat hunting for it before falling back to the real \`commonly_write_agent_memory\`. The wasted budget caused Nova to go silent on Sam's '@nova hey' (06:01 UTC) and 'hey' (06:21 UTC) DMs immediately after the trailer rolled out via reprovision-all. Verified in /state/agents/nova/sessions/*.jsonl: 3× attempted tool calls for the missing 'commonly_save_my_memory' before 1× successful 'commonly_write_agent_memory'. This commit makes withCyclesDirective a no-op so HEARTBEAT.md reverts to its pre-Phase-2.J shape on the next reprovision-all. The helper + its four call-sites stay in place so re-enabling is a one-line flip once the forward fix ships. Forward fix path (separate branch): add \`commonly_log_cycle(content, podId?)\` to the Team-Commonly/openclaw extension, build + push the gateway image, then update the trailer to instruct agents to call the new tool name. After that, this no-op gets reverted in one line.
samxu01
added a commit
that referenced
this pull request
May 4, 2026
Phase 2.J's withCyclesDirective trailer (PR #295) instructed agents to call commonly_save_my_memory({sections:{cycles:{append:...}}}), but no openclaw extension tool with that name exists today. Agents waste 3+ turn-budget tool calls per heartbeat hunting for it before falling back to the real commonly_write_agent_memory, which exhausts their budget before they can post a chat reply. Verified on Nova: silent on Sam's "hey Nova" (06:01 UTC) and "hey" (06:21 UTC) DMs immediately after the trailer rolled out via reprovision-all. Pre-rollout, Nova was responding cleanly to four prior pings within minutes. Session log /state/agents/nova/sessions/*.jsonl confirms 3× attempted 'commonly_save_my_memory' tool calls (missing tool name) before 1× successful 'commonly_write_agent_memory' fallback. This commit makes withCyclesDirective a no-op so HEARTBEAT.md reverts to its pre-Phase-2.J shape on the next reprovision-all. The helper + its four call-sites stay in place so re-enabling is a one-line flip once the openclaw extension exposes a real cycles-write tool. Forward fix path (separate branch): add commonly_log_cycle(content, podId?) to Team-Commonly/openclaw fork, build + push gateway image, update trailer to call the new tool name, flip this back to the real implementation, reprovision-all + observe.
Contributor
Author
|
Squash-merged to main as b8681a3. |
4 tasks
samxu01
added a commit
that referenced
this pull request
May 9, 2026
…_log_cycle (#307) Phase 2.J's withCyclesDirective trailer was rolled back in e4b1dd9 / PR #296 because it instructed agents to call: commonly_save_my_memory({sections:{cycles:{append:...}}}) That tool neither accepts the `cycles` section nor the nested `{sections:{...}}` envelope — agents wasted 3+ tool-call turns per heartbeat hunting for the missing surface before falling back to commonly_write_agent_memory, exhausting their turn budget and dropping DM responses (Nova on 2026-05-04). Forward fix: - Bumps `_external/clawdbot` to a67f0df6 (Team-Commonly/openclaw#7) — adds a dedicated `commonly_log_cycle({content, podId?})` tool that maps directly onto the kernel's {cycles:{append:{content,podId?}}} contract via /memory/sync, mode: 'patch'. Append-only by construction. - Rewrites CYCLES_REFLECTION_TRAILER to call commonly_log_cycle directly, no nested envelope, no missing surface. - Restores withCyclesDirective from no-op to template + trailer. - Replaces the rollback comment block with a re-enable note that preserves the failure-mode archaeology for future readers. After Deploy Dev + reprovision-all, dev agents should produce cycles[] writes inside the next heartbeat window — closing the empirical gap from the original Phase 2 observation (0 agent-authored cycle entries across 25 deployed agents in the +10min window). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
samxu01
pushed a commit
that referenced
this pull request
Aug 4, 2026
…and tell them to skip Taking this branch over: unowned for 4h past the pod's 30-minute threshold, green-lit by @ux-lead. Merged main to clear the ADR-016 conflict (union of both refinements; every distinct claim on each side preserved). Three things folded in. 1. The cue's new comment ends 'an instruction must name a tool that can serve it', and the cue it ships names commonly_log_cycle -- which serves MCP seats and NOT moltbots. The openclaw extension declares 25 commonly_* tools without it at the tip, at the ref _external/clawdbot pins, and in the running gateway image. Both channels reach a moltbot in one turn (this cue and its HEARTBEAT.md, injected by extensions/commonly/src/channel.ts) and since 2026-05-09 both have named something it cannot execute. That is the fleet's 87-day cycles silence. So the cue now tells a caller without the tool to SKIP rather than substitute. Naming one tool makes a diligent agent exhaust that tool's schema and conclude the capability is absent -- the turn-burn that forced the #296 rollback. Comment records the surface split so the next reader does not inherit 'names a tool that exists' as unconditional. 2. First test for this cue, and it had none through two rewrites in one day. Asserts the DELIVERED payload via AgentEventService.enqueue, not the source constant, so extracting the string cannot make it pass vacuously. Includes a length control against an empty cue satisfying the negative assertions. Mutation-checked: dropping the skip clause reds exactly one test. 3. The sync handler's comment named the wrong hazard -- 'do not send cycles through sync', which every shipped caller does safely. The real condition is cycles MIXED with syncable sections in a resend. Cycles-only payloads return at the branch three lines below, before computeSyncDedupKey. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
samxu01
pushed a commit
that referenced
this pull request
Aug 4, 2026
This branch and #804 fixed the same bug independently — a cue naming a call shape no tool can emit. #804 merged first, so this branch's remaining value is the extraction: the cue moves to services/heartbeatCue.ts with a test that pins the delivery surfaces, not just the constant. The merge caught a regression this refactor would otherwise have shipped. #804's wording gained a final clause that this branch's extracted copy predates: 'If commonly_log_cycle is not in your tool list, skip the write and move on: no other memory tool can append to cycles, so do not substitute one.' commonly_log_cycle reaches MCP seats and not moltbots, so without that clause a diligent agent exhausts the tool's schema and concludes the capability is absent — the turn-burn that forced the #296 rollback. Extracting the older text would have silently reverted #804 for the whole moltbot fleet while every test stayed green, because the suite pins the module and the module would have been self-consistently wrong. Ported main's live text into the constant verbatim and verified the two are identical after normalization. Net behavior change: none. An extraction is a move, never an edit — now stated in the constant's comment. 24/24 heartbeat tests pass, including main's skip-clause assertion against the extracted module.
This was referenced Aug 5, 2026
lilyshen0722
added a commit
that referenced
this pull request
Aug 5, 2026
) * fix(ax): the tool-contract guard skipped the strongest cue surface The guard reads the presets.ts cycles trailer and the inline mention cues. It did not read backend/services/heartbeatCue.ts — which by ADR-012 s10.3's own reasoning is the strongest agent-facing surface we ship, reaching every agent on every tick. That gap had already been paid for. The heartbeat cue named commonly_save_my_memory for a `cycles` write from 2026-05-03 (#293) to 2026-08-04 (#804/#818) — a tool that refuses the section by design — and neither repo's suite could see the other, so both stayed green for three months. A peer re-derived the same contradiction from source on 2026-08-05, hours after it was fixed, which is what surfaced the omission. Adds the cue as a required-tool source. The constant interpolates ${CYCLES_WRITER_TOOL}, so it is resolved from the same file rather than restated here — a restated name is the drift this script exists to catch. No namedForOtherDrivers exemption: #840 reconciled the lineages and the pin declares commonly_log_cycle, so this is a hard requirement and a future bump that drops it goes red instead of the fleet going quiet. Two assertions the name-matching check cannot make, because existence is not capability — the #295 cue would PASS a declares-the-tool check against today's pin, since commonly_save_my_memory is declared at :526 right above a description saying `cycles` is intentionally unavailable there: - the cue names exactly one writer tool, so a cue that also names a second (the #295 shape, and the shape a well-meaning "mention both" edit reproduces) fails - the escape-hatch clause survives. It looks redundant now that the pin has the tool and would be the first thing an editor cuts; deleting it re-arms the turn-burn that forced the #296 rollback the next time a bump drops it. Mutation-verified: each of the three fails exactly its own assertion, with measured anchors and byte-identical restores. CLAUDE.md's pin-skew entry described the divergence in the present tense and prescribed the fix #840 had already executed. It cost a wrong claim in the sprint pod nine hours later. Dated, struck, and led with the resolution; verified against the running gateway container rather than the source tree. AX entry 21: remediation text quotes the defect verbatim, so a repo accumulates copies of what is no longer true in the surfaces agents grep first. Six verbatim copies of the dead cue, zero live ones — and the only two queued events matching it were the peer's own reports about it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: the cycles silence is moltbot-scoped, and dated by measurement The pin-skew entry asserted the skew caused "the fleet's" cycles silence with an undocumented ~87-day figure. Measured against the memory collection 2026-08-05: moltbots (agentName=openclaw) 22 docs with entries, newest 2026-05-24T08:49:56Z non-moltbot seats 13 docs with entries, newest same evening The moltbot cutoff falls on the exact day of the d6e63b2 bundled-skills bump that dropped commonly_log_cycle — so the root cause is corroborated by a source independent of the submodule log, rather than inferred from it. Two corrections this forces. The silence is moltbot-scoped, not fleet-wide: MCP and wrapper seats wrote cycles throughout, including during the outage being debugged. And every moltbot array sits at the 40-entry cap — they are FULL, not empty — so a recovery check looking for "cycles appear" reads healthy off both the cap and the unaffected seats. It has to filter to agentName=openclaw and require an entry newer than 05-24. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.
Summary
Phase 2.J's `withCyclesDirective` trailer (PR #295) is causing live agents to skip DM responses. Rolling back ASAP — the trailer instructs agents to call `commonly_save_my_memory({sections:{cycles:{append:...}}})`, but no openclaw extension tool with that name exists. Agents waste 3+ turn-budget tool calls per heartbeat hunting for it before falling back to the real `commonly_write_agent_memory`, which exhausts their budget before they can post a chat reply.
Evidence
Nova went silent on Sam immediately after Phase 2.J reprovision-all rolled the trailer to the gateway PVC at ~05:30 UTC:
Reprovision-all completed ~05:30 UTC. First missed DM was 06:01 UTC.
Session log `/state/agents/nova/sessions/*.jsonl` confirms: 3× attempted `commonly_save_my_memory` (the missing tool name from the trailer), 1× successful `commonly_write_agent_memory` fallback.
Fix
`withCyclesDirective` is now a no-op. HEARTBEAT.md will revert to its pre-Phase-2.J shape on the next reprovision-all. The helper + the four call-sites stay in place so re-enabling is a one-line flip once the openclaw extension exposes a real cycles-write tool.
Forward path (separate branch)
Test plan
🤖 Generated with Claude Code