Skip to content

feat(memory): Phase 2.5 hardening#262

Merged
haofeif merged 4 commits into
mainfrom
feat/memory-phase2.5-hardening
Jun 1, 2026
Merged

feat(memory): Phase 2.5 hardening#262
haofeif merged 4 commits into
mainfrom
feat/memory-phase2.5-hardening

Conversation

@fanhongy

Copy link
Copy Markdown
Contributor

Summary

  • U2: per-scope cap (10 entries / 1000 chars)
  • U3: ISO-8601 Z round-trip lock on index.md
  • U4: durability + concurrent flock tests
  • U5: memory.enabled flag short-circuits recall to ""
  • U6: stable project identity via git remote with cwd-hash alias

61 new tests, 0 regressions (1922 pass full suite).

Test plan

  • uv run pytest test/ --ignore=test/e2e -q — 1922 passed
  • uv run black --check src/ test/ && uv run isort --check-only src/ test/
  • uv run mypy src/ — no new errors

…p, durability tests, enable flag, stable project identity

U2 caps each scope at 10 entries / 1000 chars. U3 locks index.md round-trip
on ISO-8601 Z. U4 adds durability + concurrent flock tests. U5 adds
memory.enabled flag. U6 resolves project identity from git remote with
cwd-hash alias bookkeeping. 61 new tests, 0 regressions.

Copilot AI left a comment

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.

Pull request overview

This PR hardens the memory subsystem with per-scope injection limits, durability/concurrency coverage, a memory.enabled kill switch, and stable project identity resolution based on git remotes with cwd-hash aliases.

Changes:

  • Adds memory injection caps and updates context assembly to enforce per-scope ordering, count, and character limits.
  • Adds memory.enabled settings support and disabled responses for MCP memory tools.
  • Adds project alias persistence and git-remote-based project identity resolution, with extensive new tests.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/cli_agent_orchestrator/constants.py Defines per-scope memory injection limits.
src/cli_agent_orchestrator/services/settings_service.py Adds memory settings accessors and mutation support.
src/cli_agent_orchestrator/services/memory_service.py Implements disable guard, project identity resolution, alias-aware recall, and capped injection.
src/cli_agent_orchestrator/clients/database.py Adds project alias model and helper functions.
src/cli_agent_orchestrator/mcp_server/server.py Surfaces disabled-memory responses from MCP tools.
test/services/test_memory_per_scope_cap.py Adds per-scope injection cap coverage.
test/services/test_memory_service_index_roundtrip.py Adds index writer/parser round-trip and timestamp invariant coverage.
test/services/test_memory_durability_and_concurrent.py Adds durability and concurrent writer coverage.
test/services/test_memory_enabled_flag.py Adds settings flag and disabled MCP behavior coverage.
test/services/test_project_identity.py Adds project identity resolver and alias coverage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli_agent_orchestrator/services/memory_service.py
Comment on lines 1322 to 1325
scope_id = self.resolve_scope_id(scope_val, terminal_context)
project_dir = self._get_project_dir(scope_val, scope_id)
index_path = project_dir / "wiki" / "index.md"

if not index_path.exists():
Comment thread src/cli_agent_orchestrator/clients/database.py Outdated
@haofeif haofeif added the enhancement New feature or request label May 29, 2026
…lias uniqueness

Tighten the injection path-traversal guard to validate against the per-scope
wiki dir instead of the global memory base, closing a cross-project memory
leak from a crafted index entry. Make project_aliases key on alias alone so
reverse lookups are deterministic; upsert by alias and migrate legacy
composite-PK tables. 5 new tests.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Comment thread src/cli_agent_orchestrator/services/memory_service.py Outdated
Comment on lines +386 to +387
source = self._get_project_dir(MemoryScope.PROJECT.value, alias)
dest = self._get_project_dir(MemoryScope.PROJECT.value, canonical_id)
Comment on lines +3 to +6
Every field written through the production writer path (`store()` →
`_regenerate_scope_index()` / `_update_index()`) must be recovered unchanged
by the production reader (`_parse_index()` regex at
`memory_service.py:937-940`).

This guards against silent drift between the writer format string and the
reader regex. Drift would cause entries to vanish from injection (U2) or sort
order to break (the per-scope sort at `memory_service.py:1116` depends on
fanhongy added 2 commits June 1, 2026 11:51
Git remotes can embed credentials (https://user:token@host/...). The raw URL
was recorded as a git_remote alias that nothing ever reads back — the
auth-stripped canonical id and cwd-hash alias cover identity. Drop the write;
add a regression test for credentialed remotes.
@fanhongy

fanhongy commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

No 'high' impact anymore, fine to merge

@haofeif haofeif left a comment

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.

LGTM

@haofeif haofeif merged commit 0abd0f7 into main Jun 1, 2026
12 checks passed
@haofeif haofeif deleted the feat/memory-phase2.5-hardening branch June 1, 2026 11:33
call-me-ram added a commit to call-me-ram/cli-agent-orchestrator that referenced this pull request Jun 3, 2026
Bring the event-driven architecture branch up to date with main (98
commits) and reconcile the rewrite with features that landed after it
forked: eager inbox delivery (awslabs#251), the OpenCode poller, env-var
forwarding (awslabs#259), memory curation (awslabs#254/awslabs#262), CORS auto-derive (awslabs#261),
DNS host validation (awslabs#124), and the self-send guard (awslabs#24).

Highlights:
- Providers adopt the async initialize() + get_status(buffer) contract;
  copilot_cli/opencode_cli converted; kiro keeps colour-only ANSI
  stripping so carriage-return-redraw permission prompts aren't misread
  as idle.
- Event-driven InboxService.deliver_pending with the awslabs#251 eager gate and
  message-sender attribution; OpenCode poller retained as a status-driven
  method; the watchdog (PollingObserver/LogFileHandler) is removed.
- terminal_service.create_terminal is async (FIFO + StatusMonitor wiring);
  session_service.create_session, flow_service.execute_flow, the API
  endpoints, and `cao flow run` updated to await.
- memory_service curated path and the flow CLI fixed to the new contract.

Full unit suite green (1908 passed); black + isort clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants