Skip to content

fix(narrative): narrative reads the domain remember writes (#721, slice 4) - #915

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/721-narrative-domain-scope
Nov 6, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
fix/721-narrative-domain-scope

Conversation

@cdeust

@cdeust cdeust commented Nov 6, 2026

Copy link
Copy Markdown
Owner

Summary

Refs #721 (tranche 4 — ne ferme pas l'issue).

Cause racine : narrative passait l'argument domain brut à get_memories_for_domain, alors que remember écrit sous resolve_explicit_domain(domain). narrative(domain="cortex-cowork") racontait donc un scope où aucune écriture n'a lieu (remember stocke sous cortex) et domain="SciFact" manquait scifact. Même défaut que celui corrigé pour recall_hierarchical dans #914.

Correctif : le handler résout le domaine avec resolve_explicit_domain avant de lire le store ; un domaine blanc compte comme absence de domaine (lecture des mémoires chaudes, comme sans domain).

Type of change

  • Bug fix

Test plan

  • tests_py/handlers/test_narrative_domain_scope.py (nouveau, 7 tests) : 7 passent avec le correctif, 6 échouent sans (vérifié en retirant le correctif localement).
  • pytest tests_py/core/test_narrative.py tests_py/handlers -k "narrative or domain" : 138 passed, 12 skipped.
  • ruff check / ruff format --check (ruff 0.17.3, version de uv.lock) sur les fichiers modifiés : OK.
  • python scripts/check_craftsmanship.py : OK.

Audit notes

Non vérifié localement : suite PostgreSQL, gate de mutation, benchmarks (torch non téléchargeable dans cette session, hôte download-r2.pytorch.org refusé par le proxy).

Breaking changes

Aucun pour un domaine déjà canonique. Un domain blanc (" ") lit désormais les mémoires chaudes au lieu d'un scope vide.


Generated by Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T18:22:49.055488Z 12b9902 New commits
🔒 Security Review ✅ Completed 2026-11-06T18:24:47.430214Z 12b9902 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Claude finished @cdeust's task in 55s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Nov 6, 2026

Copy link
Copy Markdown

Review 1 of 3 — PR #915

Five reviews were run: code quality, performance, test coverage, documentation accuracy and security. None found a Blocker.

The fix in mcp_server/handlers/narrative.py:82 now reads the same domain remember writes. remember._resolve_domain (remember.py:83) and recall_hierarchical (recall_hierarchical.py:334) both use resolve_explicit_domain too. A blank domain resolves to "" and falls through to get_hot_memories, which is what a call with no domain already did. The domain still reaches the store as a bound parameter (? or %s), so nothing new is injectable. The import from shared is allowed by the layer rules. The CHANGELOG entry, the # source: comment and the test docstring match the code.

I could not run pytest, ruff or the craftsmanship gate in this job because the commands needed approval. CI is the check for those.

Notes, no action before merge

  • Every new test passes brief: True, so the resolved domain that the full-narrative path (narrative.py:102-105) uses as its directory= label is untested.
  • A non-string domain that is truthy (e.g. 123) raises AttributeError at domain_mapping.py:488. The schema declares the field as a string, so this only fails that one call.
  • test_substring_collision_is_not_remapped passes without the fix and adds nothing: the test before it already asserts scifact-comparison.

Verdict: approve

cdeust commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

Merci pour la revue. Les trois notes non bloquantes restent en l'état dans cette PR :


Generated by Claude Code

cdeust commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

CI autopilot : unit (et l'agrégat merge) en échec sur 538082e, run 42261842595.

Les 11929 tests passent ; c'est l'étape mutation qui échoue avec 44 mutants survivants de narrative.handler. Le gate juge toute fonction modifiée et aucun test ne fixait ce que lit le handler (min_heat, limit, la priorité directory > domain > hot) ni ce qu'il renvoie (clés du résumé, étiquette du récit). Le correctif est dans f8e077e (fixup! du commit 538082e) :

  • tests_py/handlers/test_narrative_handler_contract.py : 9 tests du contrat du handler, ramenant 44 survivants à 4 ;
  • les 4 derniers étaient des équivalents par construction (args.get("directory", "") → None, args.get("brief", False) → None, tous faux). Les défauts redondants sont retirés (args.get("directory") or "", bool(args.get("brief"))) plutôt qu'enregistrés comme équivalents.

Reçu local : GITHUB_BASE_REF=main python scripts/ci_mutation_diff.py → 0 surviving mutants, 1 file(s), 0 failed, 0 untested ; 147 tests liés passent, ruff et le gate craftsmanship OK. Non vérifié : la CI de f8e077e, en cours.

Remarque hors périmètre : ci_mutation_diff.run_job passe -- à mutation_check.sh, qui le transmet comme source ; d'où l'avertissement mutmut Following patterns are likely invalid: ['--'] sur chaque run. Sans effet sur le verdict ici.


Generated by Claude Code

@claude

claude Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Claude finished @cdeust's task in 1m 9s —— View job


Review 2 of 3 — PR #915

Review 1 (at 538082e) found no Blockers, so nothing needed fixing. This review covers only f8e077e, the one commit pushed since. Five reviews were run: code quality, performance, test coverage, documentation accuracy and security. None found a Blocker.

In mcp_server/handlers/narrative.py:78, args.get("directory") or "" turns a falsy non-string into "". That takes the same if directory: branch and gives the same directory or domain label as before. In narrative.py:83, bool(args.get("brief")) changes nothing, because if brief: already tested truthiness. directory and domain still reach the store as bound parameters. The new test_narrative_handler_contract.py is 115 lines, and checked by reading, each of its nine assertions matches the handler. Its fixture clears the _build_registry cache before and after each test and swaps in a fake store and fake renderers, so nothing leaks between tests. It also covers the full-narrative label (directory="cortex"), which review 1 noted was untested.

I could not run pytest or ruff in this job because the commands needed approval. When this was posted, unit was still running. This review is posted here because gh pr comment could not be run from this job: writing the comment body to a file needed approval.

Notes, no action before merge

  • No test passes directory=None, a blank domain (" ") or brief=None, and the new tests would pass on the old versions of lines 78 and 83.
  • The name test_directory_reads_every_memory_of_the_directory says "every", but the store returns only the latest version of each memory, plus the global memories.

Verdict: approve

cdeust commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

Merci pour la revue 2. Notes non bloquantes, sans poussée dédiée :

  • domaine blanc : couvert par test_blank_domain_is_no_scope dans test_narrative_domain_scope.py ; directory=None / brief=None ne sont pas des comportements nouveaux (mêmes branches qu'avant), le gate de mutation confirme qu'aucun mutant de ces lignes ne survit ;
  • le nom test_directory_reads_every_memory_of_the_directory est imprécis : renommage repris à la prochaine poussée de code s'il y en a une.

Generated by Claude Code

…ce 4)

narrative passed an explicit `domain` unresolved to
get_memories_for_domain, so narrative(domain="cortex-cowork") narrated a
scope no write used (remember stores it under `cortex`) and
domain="SciFact" missed `scifact`. Resolve it with
resolve_explicit_domain, like remember, recall and recall_hierarchical;
a blank domain counts as no domain.

Refs #721

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018kyZYt3L6vPXmkjY5jpKe3
@cdeust
cdeust force-pushed the fix/721-narrative-domain-scope branch from f8e077e to 12b9902 Compare November 6, 2026 18:21
@claude

claude Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Claude finished @cdeust's task in 37s —— View job


Review 3 of 3 — PR #915

  • List the PR commits
  • Check that 12b9902 has the same content review 2 approved
  • Review whatever differs
  • Post the verdict

Reviews 1 and 2 found no Blockers, so there was nothing to re-check. Since review 2, the branch was squashed: it is now one commit, 12b9902, and f8e077e is no longer on the branch. That commit was not in this checkout, and fetching it or calling the compare API needed approval. So instead of diffing the two commits, I read the whole diff of 12b9902 against origin/main. It contains what reviews 1 and 2 approved, with nothing new:

  • mcp_server/handlers/narrative.py:78-83: args.get("directory") or "", resolve_explicit_domain(args.get("domain") or "") with its # source: comment, and bool(args.get("brief")).
  • The CHANGELOG entry for fix: avoid silently remapping explicit domain identities through substring collisions #721 slice 4, unchanged.
  • tests_py/handlers/test_narrative_domain_scope.py and tests_py/handlers/test_narrative_handler_contract.py, the nine contract tests review 2 read. I found no added assertions or logic.

The squash brought no new code, so I did not run the five-agent pass again. When this was posted, the Pipeline run on 12b9902 (unit tests and the mutation gate) was still running, so its result is not part of this review. This review is posted by updating this comment, because gh pr comment needed approval in this job.

Accepted: the whole PR, all four files in 12b9902. No file or commit carries an open Blocker.

Notes, no action before merge

  • test_directory_reads_every_memory_of_the_directory still says "every"; you planned to rename it in a later push.

Verdict: approve

@github-actions
github-actions Bot merged commit 52697b2 into main Nov 6, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants