Skip to content

fix(continual-learning): write memory to AGENTS.local.md in team repos - #372

Open
Liqiuyue9597 wants to merge 5 commits into
cursor:mainfrom
Liqiuyue9597:team-safe-agents-local
Open

Liqiuyue9597 wants to merge 5 commits into
cursor:mainfrom
Liqiuyue9597:team-safe-agents-local

Conversation

@Liqiuyue9597

@Liqiuyue9597 Liqiuyue9597 commented Sep 14, 2026 •

Copy link
Copy Markdown

Summary

Make continual-learning safe to enable in team repositories.

The marketplace plugin currently writes learned bullets into the workspace AGENTS.md and keeps cadence/index under .cursor/hooks/state/. On a shared repo those paths are owned by every contributor, so personal preferences end up in the team's instructions and the state files show up in git status.

This PR changes the defaults to user-scoped locations under ~/.cursor/projects/<workspace-slug>/ (the same layout Cursor already uses for agent-transcripts/). Writes inside the repo stay strictly opt-in.

Related: #74. Same default memory path, with three differences intended as follow-ups to that PR:

  • Keep existing headings (## Learned User Preferences / ## Learned Workspace Facts). Do not rename facts to (local), which would miss existing AGENTS.local.md files.
  • Copy legacy .cursor/hooks/state/* into the user-scoped dir; do not delete originals when they are git-tracked.
  • Add a preToolUse deny hook so Learned-section edits to tracked AGENTS.md / CLAUDE.md / GEMINI.md are blocked even if the updater ignores the prompt. The hook allows the write when CONTINUAL_LEARNING_WORKSPACE_FILE is set and the path is gitignored, or CONTINUAL_LEARNING_ALLOW_SHARED=1.

What changes

  • Default memory file: ~/.cursor/projects/<slug>/AGENTS.local.md
  • Default state dir: ~/.cursor/projects/<slug>/continual-learning/ (cadence.json, index.json)
  • Stop hook embeds resolved absolute paths in followup_message and tells the updater not to write the repo AGENTS.md
  • Opt-in shared file via CONTINUAL_LEARNING_WORKSPACE_FILE, refused when the path is tracked and not gitignored unless CONTINUAL_LEARNING_ALLOW_SHARED=1
  • preToolUse deny for Learned-section writes to tracked agent files, with the same allow exception

Backwards compatibility

  • Default memory path changes from workspace AGENTS.md to the user-scoped file. Restore the old behavior with CONTINUAL_LEARNING_WORKSPACE_FILE=<abs path to AGENTS.md> and CONTINUAL_LEARNING_ALLOW_SHARED=1.
  • Existing cadence env vars and CONTINUOUS_LEARNING_* aliases are unchanged.
  • Existing heading names are unchanged.

Test plan

  • bun build --target bun continual-learning/hooks/continual-learning-stop.ts bundles
  • Deny hook blocks Learned writes to repo AGENTS.md by default
  • Deny hook allows the write when CONTINUAL_LEARNING_WORKSPACE_FILE matches and CONTINUAL_LEARNING_ALLOW_SHARED=1
  • Deny hook still blocks when ALLOW_SHARED is set but the path is a different file

Note

Medium Risk
Changes default memory and state locations and adds hook-level write blocking; misconfiguration could surprise users, but opt-in env vars restore prior shared-file behavior.

Overview
Continual Learning 1.1.0 makes team repos safe by default: learned bullets and cadence/index state move out of the workspace into ~/.cursor/projects/<slug>/ (AGENTS.local.md and continual-learning/), while Cursor still stacks that file with the repo AGENTS.md.

The stop hook now resolves those absolute paths in the followup, routes preferences/facts to the user file (optional shared workspace file via env), and migrates legacy .cursor/hooks/state/* into the user dir without deleting tracked originals.

A new preToolUse hook blocks Write/StrReplace that add ## Learned User Preferences / ## Learned Workspace Facts to tracked AGENTS.md, CLAUDE.md, or GEMINI.md, unless CONTINUAL_LEARNING_WORKSPACE_FILE is allowed (gitignored or CONTINUAL_LEARNING_ALLOW_SHARED=1). Subagent/skill/docs copy is updated to match; heading names are unchanged.

Reviewed by Cursor Bugbot for commit 03c1507. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread continual-learning/hooks/block-repo-agents-md.mjs
Comment thread continual-learning/.cursor-plugin/plugin.json
Comment thread continual-learning/hooks/continual-learning-stop.ts Outdated
Comment thread continual-learning/hooks/lib/memory-targets.ts
@Liqiuyue9597

Copy link
Copy Markdown
Author

Thanks — all four review findings are addressed in a43311e.

  • Repo-write block misses relative paths (high): isInsideGitWorkTree now runs dirname(resolve(filePath)), so a workspace-relative AGENTS.md resolves to its directory instead of being handed to git -C as a file. Verified that both continual-learning/AGENTS.md and its absolute form are denied.
  • Followup blocks opted-in workspace file (medium): the followup now branches. With no allowed workspace file it still says "user memory file only"; with an opted-in, non-blocked file it routes team-shareable workspace facts there and keeps everything else in the user file.
  • Marketplace listing copy diverges (medium): the plugin-local marketplace.json was dropped (it was only needed to install the branch locally), and the root marketplace entry now describes the user-scoped AGENTS.local.md target.
  • Helper takes interchangeable string arguments (low): isPathTeamShared, isGitTracked, and isGitIgnored take named arguments.

Hook behavior checked manually: deny for relative and absolute repo AGENTS.md; allow when CONTINUAL_LEARNING_WORKSPACE_FILE matches and CONTINUAL_LEARNING_ALLOW_SHARED=1; still deny when ALLOW_SHARED is set but the path is a different file; pass-through for AGENTS.local.md and for edits with no Learned section. bun build --target bun on the stop hook succeeds.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread .cursor-plugin/marketplace.json Outdated
@Liqiuyue9597

Copy link
Copy Markdown
Author

The remaining listing-copy mismatch is fixed in 341d9e9: the root marketplace continual-learning description now matches continual-learning/.cursor-plugin/plugin.json verbatim.

@deanrie

deanrie commented Oct 7, 2026

Copy link
Copy Markdown

Filed the underlying problem internally (continual-learning writing personal memory into the repo's tracked AGENTS.md and its state under .cursor/hooks/state/ by default) with this PR and #74 attached, so both approaches are in front of the maintainers. Note the branch shows a merge-state recompute right now; worth a rebase when you get a moment.

Default learned bullets to the user-scoped file and deny Learned-section
edits to tracked AGENTS.md, so marketplace upgrades no longer dirty the
team conventions file.
…vior

Drop the local-only marketplace manifest from git, align README/CHANGELOG
with official plugin tone, and let the deny hook honor an explicitly
allowed shared workspace file.
Resolve relative paths before probing the git work tree so the deny hook
also fires for workspace-relative AGENTS.md. Let the followup route
workspace facts to an opted-in shared file instead of contradicting it,
align the marketplace listing with the new default target, and take
named arguments in the git helpers.
Keep the root marketplace description identical to the plugin manifest
so listing copy stays in sync.
@Liqiuyue9597
Liqiuyue9597 force-pushed the team-safe-agents-local branch from 341d9e9 to 8134ba5 Compare October 8, 2026 03:08

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Reviewed by Cursor Bugbot for commit 8134ba5. Configure here.

Comment thread continual-learning/hooks/block-repo-agents-md.mjs
expanded = expanded === "~" ? homedir() : join(homedir(), expanded.slice(2));
}
return isAbsolute(expanded) ? expanded : resolve(workspaceCwd, expanded);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

expandPath args are interchangeable

Low Severity · Bugbot Rules

expandPath takes two string parameters (value and workspaceCwd), so swapping them at a call site typechecks and would resolve env paths against the wrong base.

Fix in Cursor Fix in Web

Triggered by team rule: No ambiguous args at callsite in typescript

Reviewed by Cursor Bugbot for commit 8134ba5. Configure here.

Cursor Write payloads put the file body in content, so the repo-write
guard never saw a full overwrite of a tracked AGENTS.md.
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