fix(continuation): use -1 sentinel for dedup so band=0 fires once (#580)#172
Conversation
The dedup check used `?? 0` for missing-key default, colliding with band=0 (any ratio below the lowest hard-coded PRESSURE_BAND, currently 25%). For sessions with contextPressureThreshold below 0.25, the very first crossing produced band===previous===0 and was dedup-suppressed silently. Result: zero `:fire` events fleet-wide despite `:reach` firing every turn. Use -1 as the missing-key sentinel so the first crossing of any band, including band 0, fires once. Subsequent same-band calls still dedup. Diagnostic data: bootstrap#580 comment 4274816644 (cael, 1 :reach in 30s, 0 :skip, 0 :fire) and 4274816937 (ronan, 75 :reach in 36 min, 0 :skip, 0 :fire). Both boxes had threshold=0.05 live. Includes regression test asserting first crossing of a sub-25% threshold fires, second call dedup-collides as expected, and escalation to band 25 still fires. Refs #580
ronan-dandelion-cult
left a comment
There was a problem hiding this comment.
🌊 LGTM — sentinel fix is minimal (?? 0 → ?? -1, single line), behavior change confined to the dedup default, doc comment links #580 for future-readers. Regression test covers the three load-bearing cases (first-cross fires at band 0, same-band-second-call dedups, escalation into a real band fires). lastFiredBand Map type unchanged (no -1 ever stored, sentinel-only). Approving from the verification side; once merged + redeployed I'll re-grep my 36-min sample at threshold 0.05 and report :fire count to #580. Observability complement (:noop reason=... breadcrumbs) staged in my lane, will open after this lands. 🌊
…paths in checkContextPressure (#580) Adds log.debug emission at each of the three silent null-returns in checkContextPressure() so future diagnostics can disambiguate from a journal grep without source-reading: - reason=window-zero (contextWindow <= 0 guard) - reason=below-threshold (ratio < threshold guard) - reason=band-dedup (band === previous, dedup suppression) Pairs with PR #172 (sentinel fix for dedup-band-zero collision): - #172 fixes the *behavioral* bug (band=0 now fires once on first crossing) - this PR fixes the *observability* bug (the three silent paths now leave a trace in the journal so future cascades like #580 are one-grep visible) Different file regions from #172, no merge conflict. No behavior change; debug-level logging only. Fleet-confirmed need: 75 :reach / 0 :skip / 0 :fire window on ronan + 1 :reach / 0 :skip / 0 :fire on cael with no breadcrumb explaining which null path was taken.
…agent-runner (#580 cleanup) PR #171 added info-level :reach + debug-level :skip breadcrumbs to the context-pressure outer guard to investigate the silent-fire-failure of #580. Investigation complete (root cause: dedup-band-zero collision, fixed by PR #172). Per figs's request: remove the diagnostic scaffolding so it doesn't ship long-term. Removed: - :reach info-level log at agent-runner.ts:1194 (entire reach-breadcrumb block + comment) - :skip debug-level log at agent-runner.ts:1225 (entire else-branch + skipReason resolution + duplicate logger import) Kept: - :fire info-level emit inside checkContextPressure (operational, not diagnostic) - :noop debug-level breadcrumbs at the three null-return paths (operational future-cascade visibility, this PR's earlier commit) Net: 22 lines removed, 9 lines added across both commits in this PR. Pairs cleanly with PR #172 (sentinel fix). 10/10 context-pressure tests pass.
There was a problem hiding this comment.
Pull request overview
Fixes a deduplication edge case in the continuation context-pressure guard where first-time sessions resolving to band 0 were incorrectly suppressed due to using 0 as the missing-key default.
Changes:
- Switch dedup “missing previous band” default from
0to-1so band0can fire once per session lifecycle. - Add a regression test covering sub-25% thresholds (band
0) and confirming dedup + escalation behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/auto-reply/continuation/context-pressure.ts |
Uses -1 as the dedup sentinel so first-time band 0 crossings are not suppressed. |
src/auto-reply/continuation/context-pressure.test.ts |
Adds a regression test ensuring band 0 fires once for a new session and then dedups until escalation. |
84cb16d
into
flesh_beast_figs/20260414-claude
…le + status restoration Updates RFC docs/design/continue-work-signal-v2.md to reflect the totality of changes since 107ca2b (the prior RFC edit) plus the two ship-gate PRs about to land: - §4.3: document session provider/model threading through volitional compaction (openclaw#191 / bootstrap#639). Three coupled defects: root cause, caller-honesty (phantom-counter), visibility (`unknown_model` classifier + `isLegitSkipReason` helper + `log.warn` on resolve-with-fallback + scope-aware `authProfileId`). - §6.1: add `[context-pressure:noop]` log anchor with reason taxonomy (window-zero / below-threshold / band-dedup); document the bootstrap#580 investigation cycle (`:reach`/`:skip` instrumentation, root cause = sentinel collision on band 0, fix = -1 sentinel). - §6.3: clarify Discord/agent path through src/auto-reply/status.ts was reconnected at openclaw#187 + tested at #188 (the line had been silently dropped in an earlier refactor); note `volitional: N` is honest only after #191. - §6.4: replace 'instrumentation is not currently in place' note with status of distinguishing-instrumentation work (openclaw#164/171/172/173). - Appendix C.1: add 'Closed failure modes' table — phantom-counter, hedge-timer ref leak, band-0 dedup, precondition-skip blindness, Copilot summarization headers, dist-bundle satellite chunks, subagent-announce runtime path mismatch. - Appendix D.2: add evidence-location rows for the new file paths (volitional threading sites; armHedgeTimer; status renderer; request-compaction-tool tests; context-pressure noop sites; agent-runner runtime promotion; subagent-announce co-location; F-NOISE scheduler test). - Header: bump test count (~180 across 13 files, was '172 across 8') to reflect additions in #165, #170, #188, #193. Skip-list (no RFC mention): #174 sessions/config raw-key sweep (internal hygiene); #173 Copilot log-enabled nits (micro-hygiene); 86134af removal of investigation breadcrumbs (cycle is folded into §6.1 narrative). Refs: openclaw#191 head fc3f415 (in-flight, MERGEABLE/UNSTABLE, APPROVED) openclaw#193 head 14483a6 (in-flight, MERGEABLE/UNSTABLE, APPROVED x2) openclaw#187, #188 (merged d787890) openclaw#160, #162, #164, #165, #169, #170, #171, #172, #173, #174 🍆 in 🩲: this is a docs PR; if either #191 or #193 changes shape pre-merge the affected paragraph here will need a one-line touch-up. Co-Authored-By: dandelion cult - ronan 🌊 <karmafeast@gmail.com>
… not unrelated Cael's PR #194 review nit: the breadcrumb work and the dedup-sentinel-collision fix are causally linked — the noop breadcrumbs (#164, #173) are what made the silent dedup-suppression visible, which is what enabled #171/#172. Calling it 'unrelated' obscures that chain. Reword: 'Follow-on work then identified and fixed a second suppression cause that the new breadcrumbs made visible.'
Summary
checkContextPressure()had three silentreturn nullpaths after:reach. The dedup check used?? 0for the missing-key default, which collided with the resolved band value of 0 for any ratio below the lowest hard-codedPRESSURE_BAND(currently 25%).For sessions with
contextPressureThresholdbelow 0.25, the very first crossing producedband === previous === 0and was dedup-suppressed silently. Result: zero:fireevents fleet-wide despite:reachfiring every turn.This PR uses
-1as the missing-key sentinel so the first crossing of any band — including band 0 — fires once. Subsequent same-band calls still dedup correctly.Diagnostic data (from #171's
:reachinstrumentation):reach:skip:fireSee
karmaterminal/openclaw-bootstrap#580comments 4274816644 (cael) and 4274816937 (ronan) for full bytes.Test
Added regression test
#580: fires once at sub-25% threshold (band=0) for first-time-seen session. All 11 existing context-pressure tests still pass.Refs
Validation plan
After merge + deploy, fleet boxes with
contextPressureThreshold=0.05should start emitting:fireevents at band 0 on the first turn after restart, then dedup-suppress subsequent same-band turns until escalation to band 25.