UAT: LspRegistry is in-memory only — all LSP server registrations lost on process restart, no persistence mechanism #3031

Open
opened 2026-04-05 04:07:45 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/lsp-registry-persistence
  • Commit Message: fix(lsp): persist LspRegistry entries to disk so registrations survive process restart
  • Milestone: v3.6.0
  • Parent Epic: #824

Background

Discovered during UAT testing of the LSP Integration feature area via the agents lsp add/list CLI commands.

The specification describes a "global, namespaced registry" managed via CLI commands (agents lsp add/remove/list/show). The implication of a "global" registry is that registrations persist across sessions so users do not need to re-register servers every time they start the CLI.

Actual behaviour:

  1. LspRegistry in src/cleveragents/lsp/registry.py is a pure in-memory dict with no persistence layer.
  2. The CLI module src/cleveragents/cli/commands/lsp.py uses a module-level singleton _registry: LspRegistry | None = None that is created fresh on each process start.
  3. When a user runs agents lsp add --config pyright.yaml, the server is registered in memory only.
  4. When the process exits and restarts, the registry is empty again.
  5. There is no database table, file, or any other persistence mechanism for LSP server registrations.
  6. The agents lsp list command will always show an empty list after a process restart, even if servers were previously registered.

This makes the CLI commands agents lsp add/remove/list/show effectively useless for any real workflow since registrations do not survive process restarts.

Affected code locations:

  • src/cleveragents/lsp/registry.py — in-memory only implementation
  • src/cleveragents/cli/commands/lsp.py — module-level singleton with no persistence
  • No database migration or schema for LSP server configs exists

Subtasks

  • Audit src/cleveragents/lsp/registry.py and src/cleveragents/cli/commands/lsp.py to fully understand the current in-memory implementation
  • Design a persistence strategy for LspRegistry entries (e.g. SQLite via the existing Repository/Unit-of-Work pattern, or a well-defined JSON/TOML config file in the user data directory) that aligns with the spec's "global, namespaced registry" description
  • Implement the chosen persistence backend — add any required database migration or schema if using SQLite, or define the config file path/format if using a file-based approach
  • Refactor LspRegistry to load existing entries from the persistence layer on initialisation and write-through on every add/remove mutation
  • Update the CLI singleton in src/cleveragents/cli/commands/lsp.py so the registry is initialised from the persisted store on first access
  • Write Behave unit-test scenarios (in features/) covering: registry survives a simulated restart, add persists an entry, remove deletes the entry from the store, list reflects the persisted state after reload
  • Write Robot Framework integration tests (in robot/) that exercise agents lsp add, process exit, process restart, and agents lsp list against a real persistence layer (no mocks)
  • Add or update ASV benchmark(s) in benchmarks/ for registry load and write-through performance
  • Run nox -e coverage_report and confirm coverage remains ≥ 97%
  • Run all default nox sessions (nox) and fix any lint, typecheck, or test failures

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • LspRegistry loads persisted entries on initialisation and durably stores every add/remove mutation so that registrations survive process restarts.
  • agents lsp list correctly reflects previously registered servers after a process restart.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(lsp): persist LspRegistry entries to disk so registrations survive process restart), followed by a blank line, then additional lines providing relevant implementation details.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/lsp-registry-persistence).
  • The commit is submitted as a pull request to master, reviewed by at least two contributors, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage ≥ 97%.

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/lsp-registry-persistence` - **Commit Message**: `fix(lsp): persist LspRegistry entries to disk so registrations survive process restart` - **Milestone**: v3.6.0 - **Parent Epic**: #824 ## Background Discovered during UAT testing of the LSP Integration feature area via the `agents lsp add/list` CLI commands. The specification describes a "global, namespaced registry" managed via CLI commands (`agents lsp add/remove/list/show`). The implication of a "global" registry is that registrations persist across sessions so users do not need to re-register servers every time they start the CLI. **Actual behaviour:** 1. `LspRegistry` in `src/cleveragents/lsp/registry.py` is a pure in-memory `dict` with no persistence layer. 2. The CLI module `src/cleveragents/cli/commands/lsp.py` uses a module-level singleton `_registry: LspRegistry | None = None` that is created fresh on each process start. 3. When a user runs `agents lsp add --config pyright.yaml`, the server is registered in memory only. 4. When the process exits and restarts, the registry is empty again. 5. There is no database table, file, or any other persistence mechanism for LSP server registrations. 6. The `agents lsp list` command will always show an empty list after a process restart, even if servers were previously registered. This makes the CLI commands `agents lsp add/remove/list/show` effectively useless for any real workflow since registrations do not survive process restarts. **Affected code locations:** - `src/cleveragents/lsp/registry.py` — in-memory only implementation - `src/cleveragents/cli/commands/lsp.py` — module-level singleton with no persistence - No database migration or schema for LSP server configs exists ## Subtasks - [ ] Audit `src/cleveragents/lsp/registry.py` and `src/cleveragents/cli/commands/lsp.py` to fully understand the current in-memory implementation - [ ] Design a persistence strategy for `LspRegistry` entries (e.g. SQLite via the existing Repository/Unit-of-Work pattern, or a well-defined JSON/TOML config file in the user data directory) that aligns with the spec's "global, namespaced registry" description - [ ] Implement the chosen persistence backend — add any required database migration or schema if using SQLite, or define the config file path/format if using a file-based approach - [ ] Refactor `LspRegistry` to load existing entries from the persistence layer on initialisation and write-through on every `add`/`remove` mutation - [ ] Update the CLI singleton in `src/cleveragents/cli/commands/lsp.py` so the registry is initialised from the persisted store on first access - [ ] Write Behave unit-test scenarios (in `features/`) covering: registry survives a simulated restart, `add` persists an entry, `remove` deletes the entry from the store, `list` reflects the persisted state after reload - [ ] Write Robot Framework integration tests (in `robot/`) that exercise `agents lsp add`, process exit, process restart, and `agents lsp list` against a real persistence layer (no mocks) - [ ] Add or update ASV benchmark(s) in `benchmarks/` for registry load and write-through performance - [ ] Run `nox -e coverage_report` and confirm coverage remains ≥ 97% - [ ] Run all default `nox` sessions (`nox`) and fix any lint, typecheck, or test failures ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - `LspRegistry` loads persisted entries on initialisation and durably stores every `add`/`remove` mutation so that registrations survive process restarts. - `agents lsp list` correctly reflects previously registered servers after a process restart. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(lsp): persist LspRegistry entries to disk so registrations survive process restart`), followed by a blank line, then additional lines providing relevant implementation details. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/lsp-registry-persistence`). - The commit is submitted as a **pull request** to `master`, reviewed by at least two contributors, and **merged** before this issue is marked done. - All nox stages pass. - Coverage ≥ 97%. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-05 04:08:21 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing labels: State/Unverified, Type/Bug
  • Reason: Issue was missing State/* and Type/* labels per CONTRIBUTING.md. Inferred Type/Bug from the "UAT:" prefix. Applied State/Unverified as default. Kept existing Priority/Medium label.

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

Label compliance fix applied: - Added missing labels: `State/Unverified`, `Type/Bug` - Reason: Issue was missing `State/*` and `Type/*` labels per CONTRIBUTING.md. Inferred `Type/Bug` from the "UAT:" prefix. Applied `State/Unverified` as default. Kept existing `Priority/Medium` label. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#824 Epic: LSP Functional Runtime
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3031
No description provided.