Skip to content

feat(memory): add Auto Memory inbox flow with canonical-patch contract#26338

Merged
SandyTao520 merged 8 commits intomainfrom
st/feat/auto-memory-review-mode
May 4, 2026
Merged

feat(memory): add Auto Memory inbox flow with canonical-patch contract#26338
SandyTao520 merged 8 commits intomainfrom
st/feat/auto-memory-review-mode

Conversation

@SandyTao520
Copy link
Copy Markdown
Contributor

@SandyTao520 SandyTao520 commented May 1, 2026

Summary

Adds an experimental Auto Memory inbox flow (experimental.autoMemory, default off). A background extraction agent scans past conversation sessions on session startup and proposes durable memory updates as unified-diff .patch files in a project-local inbox. Nothing is applied automatically — the user reviews each entry in /memory inbox and approves or dismisses it.

Details

Storage tiers

  • private<projectMemoryDir>/.inbox/private/extraction.patch → applied to <projectMemoryDir>/MEMORY.md (and sibling .md topic files; sibling creations get an auto-bundled MEMORY.md pointer using the absolute path).
  • global<projectMemoryDir>/.inbox/global/extraction.patch → applied to ~/.gemini/GEMINI.md (single-file allowlist; no other files under ~/.gemini/ are reachable).
  • skills → reuses the existing skill inbox flow.

<projectRoot>/GEMINI.md is intentionally excluded from auto-extraction — the agent prompt forbids it and the runtime rollback safety net enforces it on top.

Inbox UX

Unnamed.screencast.webm
  • One consolidated entry per kind (Private memory / Global memory) even when multiple source patches accumulate across sessions.
  • Apply runs each underlying source patch atomically in lexical order with aggregated success/failure reporting; Dismiss removes them all.
  • Listing pre-filters patches whose targets escape the kind's allowed root, so only actionable items surface.
  • Preview groups hunks by target file (a file updated by N source patches shows once with N changes, not N separate sections).
  • ESC from the apply/dismiss dialog restores the previous list selection instead of jumping back to row 0.

Agent contract

  • Single canonical filename per kind: extraction.patch. Pending inbox contents are surfaced into the agent's initial context so it rewrites the existing patch incrementally rather than creating new files each session.
  • All patches use unified diff with absolute paths in headers; --- /dev/null for creations; --- and +++ paths must be identical for updates.
  • Sibling creations should pair with a MEMORY.md hunk; if the agent forgets, the inbox apply step auto-bundles a generic pointer (always with the absolute path) so the new sibling is discoverable.
  • Pointer paths in MEMORY.md are absolute so future agents can read_file the sibling directly without resolving relative paths.

Runtime safety net

  • MemoryService snapshots active memory before/after the extraction agent runs and rolls back any direct writes to MEMORY.md / sibling .md files, plus single-file guards for <projectRoot>/GEMINI.md and ~/.gemini/GEMINI.md (covers the case where the agent ignores the prompt and writes outside the inbox).
  • isPathAllowed denies main-agent writes to <projectMemoryDir>/.inbox/ so the model can't bypass review by dropping its own patch files.
  • The extraction agent gets a narrow execution-scoped exception via a new memoryInboxAccess flag on the agent definition and a runWithScopedMemoryInboxAccess AsyncLocalStorage. Only the literal canonical paths <inboxRoot>/{private,global}/extraction.patch are reachable, only while the agent is running.
  • Patch headers must reference paths inside the kind's allowed root after canonical resolution; bad-target patches are filtered from listing and rejected on apply.

Other

  • Drop dead Storage.getGlobalMemoryFilePath() static (returned a stale ~/.gemini/memory.md path that no live caller used).
  • Remove the never-shipped project-instructions kind and the autoApply mode plumbing; auto-memory is review-only.

Related Issues

Related to #18007

How to Validate

  1. Enable the feature in ~/.gemini/settings.json:
    { "experimental": { "autoMemory": true } }
  2. Build and seed a realistic inbox:
    npm run build
    node scripts/seed-test-inbox.js
  3. Sanity-check what the inbox would surface (no UI):
    node scripts/check-inbox.js
    Expect 2 memory patches (Private memory + Global memory).
  4. Launch the just-built CLI from this repo:
    npm run start
  5. In the CLI, run /memory inbox. Expected:
    • Two entries under Memory Patches: Private memory (2 hunks from 1 source patch) and Global memory (1 hunk from 1 source patch).
    • Arrow down to Global memory → Enter → Esc → cursor MUST stay on Global memory (not jump to row 0).
    • Private memory preview shows two target sections (no duplicates), since both hunks come from one source patch.
  6. Apply each entry. Verify on disk:
    • <projectMemoryDir>/MEMORY.md was updated with the new fact and an absolute-path sibling pointer.
    • <projectMemoryDir>/verify-workflow.md was created.
    • ~/.gemini/GEMINI.md was created with the seeded content.
    • Both inbox dirs are empty.

Edge cases worth poking

  • With autoMemory ON but no eligible sessions, the inbox is empty and no errors are logged.
  • A patch whose +++ header points outside the allowed root (e.g. <projectRoot>/GEMINI.md from private) must NOT appear in the listing.
  • Direct writes by the extraction agent to active memory files are reverted; check [MemoryService] lines in the debug log for the rollback message.
  • Aggregate apply with one stale source patch reports Applied N of M ...; 1 failed: ... instead of failing the whole batch.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Noted breaking changes (if any) — none; feature is opt-in and default off
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

Adds an experimental background extraction agent (`experimental.autoMemory`,
default off) that scans past conversation sessions on session startup and
proposes durable memory updates as unified-diff `.patch` files in a project-
local inbox. Nothing is applied automatically — the user reviews each entry
in `/memory inbox` and approves or dismisses it.

Memory tiers and storage
  - private  -> <projectMemoryDir>/.inbox/private/extraction.patch
                applied to <projectMemoryDir>/MEMORY.md (and sibling .md
                topic files; sibling creations get an auto-bundled MEMORY.md
                pointer using the absolute path)
  - global   -> <projectMemoryDir>/.inbox/global/extraction.patch
                applied to ~/.gemini/GEMINI.md (single-file allowlist;
                no other files in ~/.gemini/ are reachable)
  - skills   -> reuses the existing skill inbox flow

Project-shared `<projectRoot>/GEMINI.md` is intentionally excluded from auto-
extraction; the agent prompt forbids it and the rollback safety net enforces
it on top.

Inbox UX
  - One consolidated entry per kind (Private memory / Global memory) even when
    multiple source patches accumulate across sessions.
  - Apply runs each underlying source patch atomically in lexical order with
    aggregated success/failure reporting; Dismiss removes them all.
  - Listing pre-filters patches whose targets escape the kind's allowed root
    so only actionable items surface.
  - Preview groups hunks by target file (a file updated by N source patches
    shows once with N changes, not N separate sections).
  - ESC from the apply/dismiss dialog restores the previous list selection
    instead of jumping back to row 0.

Agent contract
  - Single canonical filename per kind: `extraction.patch`. Pending inbox
    contents are surfaced into the agent's initial context so it rewrites
    the existing patch incrementally rather than creating new files each
    session.
  - All patches use unified diff with absolute paths in headers; `--- /dev/
    null` for creations; `--- ` and `+++ ` paths must be identical for
    updates. Sibling creations should pair with a MEMORY.md hunk; if the
    agent forgets, the inbox apply step auto-bundles a generic pointer
    (always with the absolute path) so the new sibling is discoverable.
  - Pointer paths in MEMORY.md are absolute so future agents can `read_file`
    the sibling directly without resolving relative paths.

Runtime safety net
  - `MemoryService` snapshots active memory before/after the extraction
    agent runs and rolls back any direct writes to MEMORY.md / sibling .md
    files, plus single-file guards for <projectRoot>/GEMINI.md and
    ~/.gemini/GEMINI.md (covers the case where the agent ignores the
    prompt and writes outside the inbox).
  - `isPathAllowed` denies main-agent writes to <projectMemoryDir>/.inbox/
    so the model can't bypass review by dropping its own patch files.
  - Patch headers must reference paths inside the kind's allowed root after
    canonical resolution; bad-target patches are filtered from listing and
    rejected on apply.

Other
  - Drop dead `Storage.getGlobalMemoryFilePath()` static (returned a stale
    `~/.gemini/memory.md` path that no live caller used).
  - Remove the never-shipped `project-instructions` kind and the autoApply
    mode plumbing; auto-memory is review-only.

Tests
  - 65 unit tests in `commands/memory.test.ts`, ~58 in
    `services/memoryService.test.ts`, 13 in `SkillInboxDialog.test.tsx`,
    plus prompt + config tests.
  - 1 deterministic eval (`evals/auto_memory_modes.eval.ts`).
  - 4 new live-LLM evals in `evals/auto_memory_contract.eval.ts` covering
    canonical filename, incremental merge, absolute-path pointers, and
    project-root protection.
  - `scripts/seed-test-inbox.js` and `scripts/check-inbox.js` for manual
    end-to-end testing.
@SandyTao520 SandyTao520 requested review from a team as code owners May 1, 2026 16:54
@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented May 1, 2026

Hi @SandyTao520, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces an experimental 'Auto Memory' feature designed to capture durable project knowledge and reusable workflows from past conversation sessions. By surfacing these as reviewable patches in a local inbox, it provides a safe, human-in-the-loop mechanism for updating project documentation and global preferences without risking unauthorized or automated file modifications.

Highlights

  • Auto Memory Inbox Flow: Introduced an experimental background extraction agent that proposes durable memory updates as unified-diff patches, which users can review and apply via the /memory inbox command.
  • Storage Tiers and Safety: Implemented tiered storage (private, global, skills) with strict path validation and a runtime safety net that rolls back unauthorized direct writes to active memory files.
  • Inbox UX Improvements: Consolidated memory patches into single entries per kind, added atomic batch application, and improved UI navigation to preserve focus when returning from preview dialogs.
  • Agent Contract: Established a canonical extraction.patch contract for incremental updates, requiring absolute path pointers in MEMORY.md for sibling files to ensure discoverability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a review-based 'inbox' workflow for the autoMemory feature, replacing direct memory writes with unified diff .patch files that require user approval. Key changes include updating the extraction agent's prompt, enhancing the /memory inbox UI with focus preservation, and implementing path protection and rollback mechanisms to ensure memory integrity. A critical security concern was raised regarding the buildPendingInboxSummary function, which is vulnerable to indirect prompt injection by including unsanitized patch contents in the agent's system prompt.

Comment thread packages/core/src/services/memoryService.ts Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Size Change: +40.9 kB (+0.12%)

Total Size: 34 MB

Filename Size Change
./bundle/chunk-4GNSP4BA.js 0 B -657 kB (removed) 🏆
./bundle/chunk-66RGOXLC.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-6TVQPL5E.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-DD4MWEAB.js 0 B -1.97 MB (removed) 🏆
./bundle/chunk-FINZ6FKL.js 0 B -12.5 kB (removed) 🏆
./bundle/chunk-HTRKXPKC.js 0 B -2.72 MB (removed) 🏆
./bundle/chunk-LZRZAXJW.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-U7TMYQFN.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-Y5IPEF6V.js 0 B -49.2 kB (removed) 🏆
./bundle/core-NDRGGIDT.js 0 B -48.5 kB (removed) 🏆
./bundle/devtoolsService-BFNUIBRQ.js 0 B -28 kB (removed) 🏆
./bundle/gemini-OTJE2HI2.js 0 B -582 kB (removed) 🏆
./bundle/interactiveCli-BD63SNDG.js 0 B -1.33 MB (removed) 🏆
./bundle/liteRtServerManager-7MV4XTJY.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-KYGC3MCI.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-ECNYAST2.js 1.97 MB +1.97 MB (new file) 🆕
./bundle/chunk-KKJCPR5L.js 12.5 kB +12.5 kB (new file) 🆕
./bundle/chunk-KSR64PIH.js 657 kB +657 kB (new file) 🆕
./bundle/chunk-P4CG3E2V.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-QOZEND45.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-RKMN7UE2.js 2.73 MB +2.73 MB (new file) 🆕
./bundle/chunk-V7WJYWAF.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-WKSERC5I.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-ZHXGW2OW.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/core-NZV4QAGG.js 48.7 kB +48.7 kB (new file) 🆕
./bundle/devtoolsService-SN4VBKNA.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-QRQGU443.js 583 kB +583 kB (new file) 🆕
./bundle/interactiveCli-GMWNV5G5.js 1.33 MB +1.33 MB (new file) 🆕
./bundle/liteRtServerManager-26JD4I7S.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-UBQCFUB3.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-IUJL64TV.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.1 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-HRURE3F3.js 0 B -980 B (removed) 🏆
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-AWD5RU2B.js 0 B -652 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-F3SGU6EL.js 932 B +932 B (new file) 🆕
./bundle/memoryDiscovery-FB7MMKTA.js 980 B +980 B (new file) 🆕
./bundle/start-SLOHJV2V.js 652 B +652 B (new file) 🆕

compressed-size-action

@gemini-cli gemini-cli Bot added the area/unknown Triage automation assigns this label to issues that it is unable to classify label May 1, 2026
Copy link
Copy Markdown
Contributor

@Samee24 Samee24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments.

Please also attach either:

  1. a recording
  2. screenshots demonstrating the main CUJs

Comment thread packages/cli/src/ui/components/SkillInboxDialog.tsx Outdated
Comment thread packages/cli/src/ui/components/InboxDialog.tsx
Comment thread packages/cli/src/ui/components/InboxDialog.tsx
Comment thread packages/core/src/commands/memory.ts Outdated
*
* Returns an empty string if the inbox is empty.
*/
async function buildPendingInboxSummary(memoryDir: string): Promise<string> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we persisting dismissals? won't they keep resurfacing/regenerating unless we keep some kind of deny list?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real gap, not addressed in this PR. Today there is no persisted deny list — dismissed content is gone from disk, so the agent has no signal to skip it.

Mitigations that exist today:

  • Session-processing dedup (processedSessionKeys in extraction-state.json) prevents re-scanning the same transcripts a dismissed extraction came from, so the same fact will not auto-regenerate from the same source.
  • The agent prompt encourages no-op runs (Default to no-op. Prefer 0–5 memory patches per run.).
  • The new 30-min throttle (also in dd25562) reduces frequency.

A long-running project will still see periodic re-extraction of facts the user dismissed (e.g. from a different session that surfaces the same fact). The proper fix is a persisted dismiss store with content fingerprinting, which is non-trivial — deferring to a follow-up. Leaving open as the tracker.

if (!isSupportedSessionFile(file)) continue;
const filePath = path.join(chatsDir, file);
try {
const stat = await fs.stat(filePath);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are running fs.stat (which can be slow) on startup for every file. Performance will tank for folks with a lot of history...

We can:

  1. persist last-scan time and short-circuit
  2. add a min-interval (~30 min) between extraction runs in addition to the lock.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adopted option (2) in dd25562: added MIN_EXTRACTION_INTERVAL_MS = 30 * 60 * 1000 and an early-return throttle in startMemoryService after readExtractionState. If the most recent run’s runAt is < 30 minutes ago, the function logs [MemoryService] Skipped: last run was Xm ago and returns. Pairs with the existing advisory lock (lock prevents concurrent runs; throttle prevents back-to-back runs across short CLI sessions).

Option (1) (persisted last-scan time + short-circuit before stat-ing) deferred — the fs.stat cost is bounded today by MAX_SESSION_INDEX_SIZE = 50 plus the readdir/stat happening on a background promise, so the throttle alone covers the realistic case. Leaving open if you want option (1) tracked separately, or feel free to resolve.

);
});

it('rolls back direct active memory writes (patches are the only path)', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need more robust evals here. Seems too happy path focused.

e.g would like more around concurrency, such as concurrent applies (during bg run(s)), rollback of a legit user edit racing with the agent, ALS-off path-allowlist denial, shell-based escape etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Triaging the four examples:

  1. ALS-off path-allowlist denial — already covered by the test added in 5b2c782: config/config.test.ts > should NOT allow isPathAllowed to write into the auto-memory inbox (verifies denial outside the scope) and the companion test that allows the canonical filename only inside runWithScopedMemoryInboxAccess. Plus agents/local-executor.test.ts asserts the scope is set iff definition.memoryInboxAccess is true.

  2. Rollback racing a legit user edit — real gap. Added as it.todo in dd25562 (memoryService.test.ts) so it shows up in test output. The proper fix needs to distinguish agent writes from external edits (mtime windowing or a WriteFile hook), which is an architectural change deferred to a follow-up.

  3. Concurrent applies during a bg runtryAcquireLock already covers concurrent extraction runs (existing tests in memoryService.test.ts > tryAcquireLock). For concurrent apply (user clicks Apply while a bg run is in-flight): the apply path uses temp-file-stage + atomic rename; an in-progress bg run cannot interleave a half-written file. Worth one explicit test, can add in the deferred follow-up alongside (2).

  4. Shell-based escape — could you elaborate? Shell tool calls go through the same Config.isPathAllowed, which denies <projectMemoryDir>/.inbox/ writes for the main agent and is workspace-scoped. Happy to add a concrete test if you have a specific scenario in mind.

Leaving this thread open as the tracker for (2) + (3).

- Default the memory-patch action to Dismiss so a stray Enter cannot apply
  durable on-disk changes (private MEMORY.md, ~/.gemini/GEMINI.md).
- Aggregate apply now reports success=false on any failure so the dialog
  keeps the inbox entry visible for retry instead of auto-removing it.
  Successful sub-patches were already committed and removed from disk;
  the next listing surfaces only the failures.
- Harden buildPendingInboxSummary against indirect prompt injection:
  size the markdown fence to one more backtick than the longest run in
  the patch content so a crafted closing fence cannot break out of the
  block.
- Throttle startMemoryService: skip the run if the most recent extraction
  finished less than 30 minutes ago. Pairs with the existing advisory
  lock (lock prevents concurrent runs; throttle prevents back-to-back
  runs across short CLI sessions).
- Rename the user-facing inbox group label "Memory Patches" -> "Memory
  Updates" for consistency with the existing "Skill Updates" label.
- Rename SkillInboxDialog -> InboxDialog (the component now covers
  skills, skill-update patches, and memory updates).
- Document the rollback-vs-user-edit race as it.todo so the gap stays
  visible. The proper fix needs to track agent-vs-external writes and
  is deferred to a follow-up.
The previous regex `/^- See \/.+\/orphan-topic\.md /m` was Unix-only and broke on Windows where the absolute pointer path is e.g. `C:\Users\runneradmin\…\orphan-topic.md`. Capture the path with a separator-agnostic regex and validate it via path.isAbsolute, which works on both POSIX and Windows.
Copy link
Copy Markdown
Contributor

@Samee24 Samee24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@SandyTao520 SandyTao520 enabled auto-merge May 4, 2026 18:52
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

69 tests passed successfully on gemini-3-flash-preview.

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • 🚀 Maintainer Reminder: Please ensure that these changes do not regress results on benchmark evals before merging.

This is an automated guidance message triggered by steering logic signatures.

@SandyTao520 SandyTao520 added this pull request to the merge queue May 4, 2026
Merged via the queue into main with commit a7beb89 May 4, 2026
28 of 29 checks passed
@SandyTao520 SandyTao520 deleted the st/feat/auto-memory-review-mode branch May 4, 2026 19:20
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/unknown Triage automation assigns this label to issues that it is unable to classify

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants