Skip to content

fix(diagnostics): every stderr line about one namespace names it (#239) - #245

Merged
nissa-seru merged 9 commits into
anima-research:mainfrom
nissa-seru:fix/239-diagnostics-namespace
Oct 19, 2026
Merged

nissa-seru merged 9 commits into
anima-research:mainfrom
nissa-seru:fix/239-diagnostics-namespace

Conversation

@nissa-seru

@nissa-seru nissa-seru commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Every stderr line about one namespace now names it, as ns=<namespace> at the end of its message's first line, through one helper, so the lines of several agents in one process can be told apart. JSON diagnostics and the compression log's entries carry a namespace field instead.

Fixes #239.

Problem

The strategy knows its namespace, but none of its stderr diagnostics print it, and neither do the manager's. In a process hosting several adaptive agents, where agent-framework gives each its own agents/<name> namespace on one store, their lines interleave and can't be told apart. The issue names [plan-vs-actual], [kv-overlap], [kv-unified] and [kv-escalation]. The same holds for every line about one namespace's work: the strategy's other lines ([autobiographical], [compression-quarantine], [estimator-calibration], [merge-quarantine], [cm-cache] and the rest), the manager's, and the planner's and picker's lines that run inside a compile.

Changes

One helper, src/diagnostics.ts. namespaceDiagnostics(() => namespace) gives error and warn functions that end the first line of each message with ns=<namespace>, after its fields, as the issue suggests. A grep for a line's prefix still matches. Arguments after the message, such as an error, print after it as before, and a % in a namespace prints as written. The helper reads the namespace and console as each line is logged. A strategy learns its namespace at initialize, and until then a line names none. A line about what no one namespace owns goes to console as it is. console is a Diagnostics too, so every parameter that takes one defaults to it. The package exports the type for persistMintRequestPreimage's parameter.

Where each line's namespace comes from, by file:

  • strategies/autobiographical.ts: 106 of its 109 stderr lines go through this.diag, which names the strategy's namespace. Its two JSON lines, config:effective and compression:quarantine-alert, carry a namespace field instead of a suffix, since a suffix would break their JSON. config:effective is emitted before this.ns is set, so it takes the namespace from the context the strategy initializes with. The compression log (CONTEXT_MANAGER_COMPRESSION_LOG) is one file per process, so its entries gain namespace, and its write failure names it too. diag is protected, as ns is, so a subclass can log through it to name the namespace.
  • strategies/windowed-passthrough.ts: its persisted-anchor line names its namespace.
  • context-manager.ts: the manager's lines name its namespace, default when it has none. These are a sharded addMessage failing partway, a compression hold timing out, a strategy hook failing, an onMessage listener throwing, [cm-cache] compile: select, and summaries it can't describe. The [debugLogContext] entry gains namespace. The two [message-store] lines at open, about retuning the message slot's snapshot cadence, name the slot by its ID. An isolated slot is one agent's, so its lines name its namespace too. The shared slot is the store's, so its lines name none. The failure line now names the slot as well, and a % in it prints as written.
  • fold-journal.ts: a receipt listener's failure names the journal's namespace, and so do the three fallbacks that treat this journal's branch as unrecorded. The lines about the store's identity record, the index's record warnings and "can't tell where the journal stands" name none. Each is reported once per store object and is about the store's records as a whole, whichever manager reads them first.
  • mint-preimage.ts: persistMintRequestPreimage takes the minting strategy's diagnostics as an optional fourth argument, so its three lines name its namespace. It still never throws, unless the diagnostics it's given do.
  • adaptive/kv-control.ts: reportOverlap takes the strategy's diagnostics. So does the planner, through ControlPlanParams.diagnostics, for its [kv-timing] and [kv-diag] lines, and KvStableStrategy passes them on through its options. replayControlled and the replay scripts, which replay one agent's turns outside any manager, give none, and their lines are as before.
  • adaptive/picker.ts: Picker takes its owner's diagnostics for [picker-unrealizable] and [picker-dead-ids]. The strategy's pickers name its namespace; the replay's names none.
  • well-formed-content.ts, message-store.ts, context-log.ts: the line about content that doesn't match ContentBlock names the namespace whose state was read. MessageStore and ContextLog name the namespace they're given, so an isolated message slot, an auxiliary slot of one namespace and a namespaced context log name it, whether ContextManager.open or a caller builds them. The shared message slot and a context log with no namespace name none. message-store.ts's [cm-cache] lines go through the store's diagnostics too, beside their slot's state ID, which the write-through failure now names as well.
  • describe-thrown.ts: logThrown takes the diagnostics to log through.

A reader that took a line's end as its last field, such as [kv-overlap]'s sample=, now finds ns= there, and the changelog fragment says so.

What each part is for

  • namespaceDiagnostics is the one place a line's suffix is made, after its fields at the end of the message's first line. It reads the namespace and console as each line is logged, so a strategy names its namespace from initialize on, and a test that replaces console.error sees the lines. Without it, every site would build the suffix itself.
  • Its % handling is one branch with a test. A namespace is a host's string, such as agents/<name>. When an error follows the message, console.error reads the message as a format string, so a %s in a namespace would print the error in its place.
  • The Diagnostics type and its export name the parameter that persistMintRequestPreimage, a public function, now takes. console is one, so a caller passes nothing new. It's a type, with no runtime cost.
  • The diagnostics passed to the planner, reportOverlap, the picker, logThrown, the fold journal's fallbacks and persistMintRequestPreimage let the lines they log for one namespace's work name it. Each is an optional parameter or option that defaults to console, so a caller outside a manager, such as the replay scripts, is unchanged.
  • MessageStore and ContextLog name the namespace they're given, from the option they already take, so a store built outside ContextManager.open names it too.
  • diag is protected, as ns is, so a subclass can log through it and name the namespace. connectome-host's FrontdeskStrategy is one such subclass. The cost is a protected member, and a subclass's own diag now conflicts with it, as the changelog says.
  • The namespace fields of config:effective, compression:quarantine-alert, [debugLogContext] and the compression log's entries do the suffix's job where a suffix would break the JSON. A test reads each one.
  • The strategy's diagnostics passed to persistMintRequestPreimage have a test of their own, in which the strategy mints while the store refuses the preimage and the failure's line names its namespace.
  • The compression log writes namespace in every entry, as the JSON lines do, a manager opened with namespace: '' included.
  • The strategy's diagnostics passed to its pickers have no test of their own. The picker's own test shows that a picker given diagnostics names the namespace (test/adaptive/picker.test.ts). The strategy's pickers log only on a solver bug or a frontier entry left by store surgery, so a test of that one argument would have to build a broken solver or a damaged store.
  • Left out:
    • AsyncLocalStorage would have spared passing diagnostics through the planner, the picker and the stores, but then every line's namespace would rest on a context that nothing at the call site shows.
    • Wrapping each message in a function instead of logging through an object would have reindented every message built by concatenation, so each site's diff would no longer be one token.
    • Naming only the four lines the issue lists would leave the rest of a namespace's lines as hard to tell apart as they are today.
    • A diagnostics option on MessageStore and ContextLog, set by ContextManager.open, would repeat what each store already knows, its namespace.

Tests

npm test on this branch, which has main merged in at c0efbfce (Linux, Node 24.19.0): 2204 pass / 0 fail. main at c0efbfce: 2187 pass / 0 fail. The difference is the 17 new tests.

  • test/diagnostics.test.ts checks the suffix on a one-line and on a multi-line message, that the namespace and console are read as each line is logged with the rest of the arguments passed on to error and warn, that a line names no namespace before there is one, and that a namespace holding %s prints as written before an argument that follows. It takes the Diagnostics type from the package's entry point.
  • A compile in agents/tern (test/production-budget.test.ts) ends its [kv-overlap] and [plan-vs-actual] lines with ns=agents/tern, and every [kv-timing] line too, with KV_TIMING set, through the planner.
  • The escalation and a superseded [kv-unified] submission each name agents/wren (overbudget-diagnostics, kv-unified-strategy-integration).
  • Two managers on one store, default and beta, exhaust a compression each, and each quarantine alert names its own namespace (compression-recall-curve).
  • The manager's lines: its hold timeout (compression-hold-timeout) and its onMessage listener (compile-provenance) name default, a manager opened in agents/tern names that (compile-provenance), and so does its compile's [cm-cache] line with CM_CACHE_DIAG set (manager-diagnostics).
  • A message slot's lines (manager-diagnostics): an isolated slot's cadence retune at open, its failure, and its [cm-cache] lines name its namespace, and the shared slot's name none. The cache-miss and write-through lines are checked in a child process started with CM_CACHE_DIAG set, since message-store.ts reads that flag when it loads. The failure line prints a slot holding %s as written, agents/100%s/messages.
  • The config report names default from a manager without a namespace and agents/tern from one in it.
  • The halted model's test checks the compression log entry's namespace as well as its stderr line. With the log's path a directory, the write failure names agents/tern.
  • A strategy minting a merge while the store refuses the preimage's blob logs the failure with ns=default, its manager's namespace (mint-preimage).
  • The fold journal's listener names agents/tester, and so does each fallback that treats its branch as unrecorded: a newest record of another format, one with no envelope, a broken chain, members its units don't cover, and a layout that doesn't rebuild.
  • An isolated message slot's content line names agents/tern, and the shared slot's names none. A context log names the namespace it's given, and one with none names none.
  • The windowed strategy's anchor reset, a mint's preimage failure, a picker's unrealizable and dead frontier entries, and the [debugLogContext] entry each name theirs.
  • Nine existing assertions that compared a line's end now expect ns=default, in fold-diff-strategy, compression-recall-curve, compression-serialized-media-wire, merge-disposition, production-budget and strategy-persistence. With feat(diagnostics): log compile time on the plan-vs-actual line #200 merged in, so do its four that anchor the [plan-vs-actual] line's end (kv-unified-strategy-integration), and with fix(strategy): the speculative drain's timer lets no error out #247, its test of a throw from the drain's next tick (drain-timer).
  • Red-first, on the first commit: with main's src/ and the new src/diagnostics.ts kept, every changed test file fails at the tests that name a namespace, and three of them also fail to typecheck at the new arguments they pass. test/diagnostics.test.ts, the helper's own, passes.
  • Removals: each diagnostics object the change makes or passes, each JSON field, and each new behaviour of the helper and the stores was removed or inverted alone and run against the tests that should catch it. That's 68 removal runs over the branch's commits. Each piece of the final change fails a test at its last removal, or the typecheck for the Diagnostics export, except the strategy's diagnostics passed to its pickers, under "Not verified", whose removal passes the whole suite. A single line's call through the same diagnostics, or a single compression log call's this.ns, has no test of its own.

Not verified

  • Nothing ran against a real store. The change touches only what diagnostics print, and the tests read the lines from captured stderr and the compression log's file.
  • The strategy passing its diagnostics to its pickers has no test of its own, and removing it passes the whole suite. "What each part is for" says why.
  • Lines no test turns on: the planner's [kv-diag] lines, whose flag KV_DIAG_GROUP its module reads when it loads.

Companion PRs

This branch changes most of autobiographical.ts' stderr lines, MessageStore's constructor and its calls that bump a slot's write version, so it conflicts with open pull requests that change the same lines. It has main merged in at c0efbfce, which holds #138, #200, #158, #246, #248 and #247, and its merge commits resolve #138's, #200's and #248's conflicts as the first item below describes. Trial merges at f19b5741, with main at c0efbfce and each pull request's head as of 11:44 UTC on October 19:

Outside the hunks, a console.error or console.warn line that a pull request adds merges cleanly but names no namespace, so it should go through the file's this.diag instead. #215 adds one in autobiographical.ts and one in context-manager.ts, #213 adds two in autobiographical.ts, #219 adds one there, and #160 adds one in context-manager.ts. A logCompressionCall without the namespace doesn't build, so tsc names any that a pull request adds.

This branch's side of each conflict is the mechanical one, this.diag for console.

  • Changelog fragment added: changelog.d/239-diagnostics-namespace.changed.md

— Cordelia-1930 (Claude Opus 5.5). Oscar-1005 (Claude Opus 5.5) decided which lines the fix covers, and Phoebe-2419 (Claude Opus 5.5) read the change. An internal review read it as well. Checked and opened by Fiona-2757 (Claude Opus 5.5) through the shared nissa-seru account.

🤖 Written using Anthropic's Claude Opus 5.5 through the Rookery's tooling.

Cordelia-1930 and others added 5 commits October 19, 2026 03:58
…it, through one helper (anima-research#239)

The strategy knows its namespace, but none of its stderr diagnostics
printed it, nor did the manager's, so in a process hosting several
adaptive agents (agent-framework gives each its own `agents/<name>`
namespace on one store) their lines interleave and can't be told apart.
anima-research#239 names the four per-compile lines; the same holds for every line that
reports one namespace's work.

src/diagnostics.ts: `namespaceDiagnostics(() => namespace)` gives `error`
and `warn` that end a line's first line with ` ns=<namespace>`, after its
fields, as anima-research#239 suggests, so a grep for a line's prefix still matches. It
reads the namespace, and `console`, as each line is logged. A strategy
learns its namespace at initialize, and until then a line names none. A
line about what no one namespace owns goes to `console` as it is, and
`console` is a `Diagnostics` too, so each parameter that takes one
defaults to it.

Where each line's namespace comes from:
- strategies/autobiographical.ts: 92 of its 95 stderr lines go through
  `this.diag`. `config:effective` (from the context it initializes with,
  since it's emitted before `this.ns` is set) and
  `compression:quarantine-alert` are JSON, so they carry a `namespace`
  field instead, as does every compression log entry
  (CONTEXT_MANAGER_COMPRESSION_LOG, one file per process), whose write
  failure names it too.
- strategies/windowed-passthrough.ts: the persisted-anchor reset.
- context-manager.ts: the manager's lines, `default` when it has no
  namespace, and the `[debugLogContext]` entry's `namespace`. The two
  `[message-store]` cadence lines at open are about the store's slot and
  name none.
- fold-journal.ts: a receipt listener's failure. The store identity
  record, the journal index's record warnings and "can't tell where the
  journal stands" are reported once per store object, about the store's
  journal as a whole, and name none.
- mint-preimage.ts: persistMintRequestPreimage takes the minting
  strategy's diagnostics (an optional fourth argument).
- adaptive/kv-control.ts: reportOverlap and the planner
  (ControlPlanParams.diagnostics, for [kv-timing] and [kv-diag]) take the
  strategy's; KvStableStrategy passes its own through its options;
  replayControlled and the replay scripts give none.
- adaptive/picker.ts: Picker takes its owner's, for [picker-unrealizable]
  and [picker-dead-ids].
- well-formed-content.ts, message-store.ts, context-log.ts: the line about
  content that doesn't match ContentBlock names the namespace whose state
  was read: an isolated message slot's and the context log's, through the
  `diagnostics` option ContextManager.open gives them; the shared slot and
  an auxiliary slot with no namespace name none.
- describe-thrown.ts: logThrown takes the diagnostics to log through.

changelog.d/239-diagnostics-namespace.changed.md says what a reader of
these lines will notice: ` ns=` now ends a line that took its last field
to the end, as `[kv-overlap]`'s `sample=` did.

Tests:
- test/diagnostics.test.ts: the suffix on one- and multi-line messages,
  the namespace and console read per line, the rest passed on, no suffix
  before a namespace.
- test/production-budget.test.ts: a compile in `agents/tern` ends its
  [kv-overlap], [plan-vs-actual] and, with KV_TIMING, every [kv-timing]
  line with ` ns=agents/tern`.
- overbudget-diagnostics (the escalation, `agents/wren`) and
  kv-unified-strategy-integration (a superseded submission).
- One line or entry each: the hold timeout and an onMessage listener
  (`ns=default`), the journal's listener, the windowed anchor reset, a
  mint preimage failure, a picker's dead ids, the config report's and the
  compression log entry's `namespace` beside the halted model's line, and
  test/debug-log-context.test.ts for the [debugLogContext] entry.
- test/malformed-content.test.ts: an isolated slot's content line names
  `agents/tern` and the shared slot's names none; a ContextLog's line names
  the namespace of the diagnostics it's given.
- Nine existing assertions that compared a line's end, in
  fold-diff-strategy, compression-recall-curve,
  compression-serialized-media-wire, merge-disposition, production-budget
  and strategy-persistence, now expect ` ns=default`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… whose they are (anima-research#239)

Answers an internal review of the first commit (28 issues).

- MessageStore and ContextLog name the namespace they're given on their
  lines, and have no diagnostics option: a slot or log of one namespace
  names it, and the shared message slot and a log with no namespace name
  none. ContextManager.open passes them nothing new, and a store built
  directly, as scripts/inspect-store does, names its namespace too. A
  manager with no namespace now gets context-log lines that name none,
  as its shared message slot's do, where the first commit said
  ns=default.
- The fold journal's three fallbacks in loadLatest, each about this
  journal's branch ("branch main is treated as unrecorded"), go through
  its diagnostics and name its namespace. Its index warnings and "can't
  tell where the journal stands" stay as they are: they're about the
  store's records, once per store.
- Both snapshot-cadence lines at open name the message slot by its ID;
  the failure line named nothing. The cache's write-through failure names
  its slot (stateId=), as its other line does.
- namespaceDiagnostics doubles a '%' in the namespace when arguments
  follow the message, which console reads as a format string, so the name
  prints as written. Its doc says the suffix ends the message, with any
  arguments after it printing after it.
- logCompressionCall names no namespace, in its entry or its write
  failure, until the strategy has one, as the helper does.
- persistMintRequestPreimage's doc says it never throws unless its logger
  does, and the Diagnostics type is exported, since that public parameter
  takes one.

Tests:
- compression-recall-curve: two namespaces' quarantine alerts each name
  their own (default, beta).
- compile-provenance: a manager in agents/tern names it on its listener
  line.
- compression-model-required: with the log path a directory, the write
  failure names agents/tern.
- picker: the unrealizable line names its owner's namespace too.
- config-provenance: a report initialized in agents/tern names it.
- diagnostics: warn passes its arguments on; a namespace holding %s
  prints as written, before an argument that follows.
- fold-journal: the layout-doesn't-rebuild fallback names agents/tester,
  and so does each unreadable newest record's (another format, a broken
  chain, members its units don't cover).
- malformed-content: a context log names the namespace it's given.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n three more lines (anima-research#239)

Answers an internal review of the second commit (15 issues).

- The snapshot-cadence failure line at open passes the slot's ID after
  the message rather than inside it. Console reads the first argument as
  a format string when an error follows, so a '%' in a namespace would
  have been read as a placeholder.
- namespaceDiagnostics' doc and the changelog say the suffix ends the
  message's first line, which is where withNamespace puts it; the
  changelog says compression log entries carry `namespace` once the
  strategy has one.

Tests:
- test/manager-diagnostics.test.ts (was debug-log-context): the
  debugLogContext entry; the compile's `[cm-cache] compile: select` line
  names agents/tern with CM_CACHE_DIAG set, which the manager reads on
  each compile; and when retuning an isolated slot's cadence fails at
  open, the line names agents/100%s/messages as written.
- fold-journal: a newest record with no envelope, and one of an older
  format, each report a fallback naming agents/tester (the shadowed
  branch's line among them).
- diagnostics: the helper is made before console is mocked, so the test
  shows console is read per line; warn escapes a '%' in a namespace as
  error does; the Diagnostics type comes from the package's entry point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…name its namespace (anima-research#239)

An isolated slot is one agent's, so a filter on its namespace should find
its lines. The shared slot's lines stay as they are.

- MessageStore's `[cm-cache]` lines (the write-version bump, the cache
  miss and the write-through failure) go through the store's
  diagnostics, beside the slot's state ID they already print.
- The two snapshot-cadence lines at open go through the slot's namespace
  where the slot is isolated. The failure line puts the slot back in its
  message, with a '%' doubled since an error follows it, so the suffix
  lands after the slot rather than before it.
- The changelog separates the lines that name the manager's namespace
  from those that name a slot's. It also notes the strategy's protected
  `diag`, which a subclass can log through and which a subclass's own
  member named `diag` now conflicts with.

Tests (test/manager-diagnostics.test.ts):
- With CM_CACHE_DIAG set, which the write-version line reads at each
  write, an isolated slot's line names agents/tern and the shared slot's
  names none.
- Reopening a store retunes its slot. An isolated slot's line names
  agents/tern, and the shared slot's names none. When the retune fails,
  the line prints agents/100%s/messages and its suffix as written, and
  the shared slot's again names none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in a child process (anima-research#239)

Answers an internal review of the last two rounds (8 issues).

- MessageStore's cache-miss and write-through lines print only when
  CM_CACHE_DIAG is set as message-store.ts loads, so no test in the
  suite's process reached them. A new test in
  test/manager-diagnostics.test.ts runs a child process started with the
  flag, as inspect-store's test runs its script. There an isolated slot's
  lines name agents/tern and the shared slot's name none. The test of
  the write-version lines is now named for them.
- The Diagnostics doc says that a message followed by arguments is a
  format string, as console's is, so a value put into it that may hold a
  '%' is doubled first.
- The changelog says only the compression log's entries wait for the
  strategy's namespace. config:effective, the quarantine alert and
  [debugLogContext] carry one from the start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5 Tier: apex

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Adds namespace labels to stderr diagnostics through one helper. Structured diagnostics and compression-log entries gain a namespace field.

  • Strategy and planner diagnostics now identify their namespace.
  • Manager and store diagnostics identify the namespace they describe.

Reviews (1) · Last reviewed commit: "fix(diagnostics): an isolated message sl..." · Reviewed by Greptile

Cordelia-1930 and others added 3 commits October 19, 2026 06:37
main now holds anima-research#138, anima-research#200, anima-research#158 and release 0.16.0. anima-research#138 and anima-research#200
conflict with this branch in src/strategies/autobiographical.ts, in 17
places, and anima-research#158 merges cleanly.
- Each conflict keeps main's change, with this.diag where main has
  console, and this.ns as the last argument of each logCompressionCall.
- anima-research#138's stderr lines outside the conflicts merged cleanly but named no
  namespace, so they go through this.diag too. Its new
  logCompressionCall calls take this.ns, which tsc requires.
- anima-research#200's [plan-vs-actual] line keeps its messages=, compileMs=, solveMs=
  and dryRun= fields, and the helper puts ns= after them.

In all, 26 console calls in the file now go through this.diag, and 12
logCompressionCall calls gain this.ns. The two JSON lines,
config:effective and compression:quarantine-alert, stay on console with
their namespace field, as before.

Five assertions change for the suffix. anima-research#200's four that anchor the
[plan-vs-actual] line's end now expect ns=default after its fields and
any overrun note (kv-unified-strategy-integration). This branch's check
of the line's namespace now allows anima-research#200's fields after solver=
(production-budget).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d bound the child (anima-research#239)

The child process's script imported src/index.js by its filesystem
path, which an ES module import reads as a URL. From a checkout whose
path holds a '#', the import took the rest of the path as a fragment
and found no module, so the test failed before it checked either cache
line. The script now imports the URL's href. From a copy of the
checkout at a path holding '#', the test passes, and with the
filesystem path back it fails at the import (ERR_MODULE_NOT_FOUND).

The spawnSync call had no timeout, so a child that stalled would have
held the whole test run until CI's job timeout, which ci.yml leaves at
GitHub's default. The child now has 60 seconds, and the test fails
with the spawn's error when that runs out: with the bound at 1 ms, it
fails with ETIMEDOUT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the strategy's preimage failure line is tested (anima-research#239)

The compression log left namespace out of an entry when it was empty,
while the JSON lines config:effective, compression:quarantine-alert and
[debugLogContext] always carry the field. A quarantine alert's entry
already carried it from its payload. The namespace is empty only for a
manager opened with namespace '', since an unnamed manager's is
'default', and before initialize, when no compression runs. Every entry
now carries namespace, as the JSON lines do, and the changelog fragment
no longer qualifies it.

A new test in mint-preimage has the strategy mint a merge while the
store refuses the preimage's blob. It checks that the failure's line
ends with ns=default, the namespace of the manager that minted. With
the strategy's diagnostics left out of its persistMintRequestPreimage
call, the test fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main now holds anima-research#246, anima-research#248 and anima-research#247. anima-research#248 conflicts with this branch in
src/strategies/autobiographical.ts, in 2 places, and anima-research#246 and anima-research#247 merge
cleanly.
- Each conflict keeps main's change, with this.diag where main has
  console, and this.ns as the last argument of logCompressionCall.
- Two stderr lines merged cleanly but named no namespace, so they go
  through this.diag too: anima-research#247's speculative-drain error from the drain's
  timer, and anima-research#248's warning that merge discovery after a failed
  compression attempt failed.

One assertion changes for the suffix: anima-research#247's test of a throw from the
drain's next tick now expects ns=default at the end of its line
(drain-timer).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nissa-seru
nissa-seru merged commit cc599f1 into anima-research:main Oct 19, 2026
7 checks passed
nissa-seru pushed a commit to nissa-seru/context-manager that referenced this pull request Oct 19, 2026
…search#213 review R1-1)

Anarchid's review R1 of anima-research#213 at 52bfcd3 (R1-1) asked for main to be
merged in and the hold's three log lines sent through the strategy's
namespace diagnostics, which main gained with anima-research#239 and anima-research#245.

Conflicts, each resolved by keeping both sides:
- src/strategies/autobiographical.ts, pinAtLevel's doc: main's wording,
  which drops "EXACTLY" and gives kv-stable's exceptions (a chunk whose
  summaries stop below the level, a summary that doesn't list it), with
  this branch's parenthesis on kv-unified's hold.
- src/types/strategy.ts, PinLevelOptions.level's doc: main's kv-stable
  exceptions, and kv-unified's "once a summary supplies it".
- test/strategy-persistence.test.ts: main added a test (a kv-unified
  submission kept in flight across a reload) directly above the test this
  branch rewrites; main's test stays, followed by this branch's "holds"
  test in place of main's unchanged "refuses as infeasible" one.

Beyond the conflicts: the hold report's two console.warn calls, three
lines, now go through this.diag.warn, so they end with ` ns=<namespace>`
like every other strategy line on main, and the hold test's six exact
assertions expect ` ns=default`. The prefix and `includes` checks match
as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru pushed a commit to ian-de-marcellus/context-manager that referenced this pull request Oct 19, 2026
main has moved on since 1c4fce9 merged it at c0efbfc: anima-research#245 routes the
strategy's diagnostics through this.diag, which names the namespace at the
end of a line, and passes the namespace to its events; anima-research#257 takes the
kv-unified scorer's floors and the object prune's appends in loops. Four
regions in src/strategies/autobiographical.ts conflicted, all anima-research#245's, and
each keeps both sides:

- refuseCrossedMerge and quarantineMerge: main's `}, this.ns)` on the
  merge:topology-refused and merge:quarantined events, then this branch's
  merge check;
- clearMergeQuarantine: main's this.diag.warn for the cleared line, then
  this branch's queueing of each held group;
- the merge-quarantine klaxon: this branch's line, which counts the records
  that hold their sources, through main's this.diag.error.

This branch's two other warnings, the topology record's clear in
enqueueMerge and executeMerge's skip of an entry holding a held source, now
go through this.diag.warn too, as anima-research#245 has the strategy's lines do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru pushed a commit to nissa-seru/context-manager that referenced this pull request Oct 19, 2026
main gained anima-research#245, which routes the strategy's stderr diagnostics
through `this.diag`. Its line in `select`'s dry-run path met this
change's hold of the tool-pruning decision there; the resolution keeps
both: `this.diag.error(...)` for the diagnostic and
`this.withToolPruning(store, () => this.selectPath(...))` for the
return. This change adds no diagnostic lines of its own, so nothing else
needed routing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Strategy diagnostic lines ([plan-vs-actual], [kv-overlap], …) don't say which context manager logged them

1 participant