# lsp-max Roadmap
**As of:** 2026-06-21
**Baseline commit:** 40c05c2 (branch `claude/compassionate-newton-9nnifc`)
---
## Completed
### Λ_CD Runtime Gate + lsp-max-compositor (committed 1f1e0cf)
- Single-byte ANDON gate file with AcqRel atomics and O(1) state-change counter
- daachorse O(|code|) ANDON prefix classification; papaya + kanal merge pipeline
- Concurrent fan-out to N child LSP servers; dynamic quorum-based debounce
- L7 Speciation state machine: `PARTIAL → CANDIDATE → ADMITTED` via per-server `C_D`
- `CompositorReceipt` per-flush BLAKE3 provenance; child exit watcher; `max/compositorHealth`, `max/compositorState`, `max/diagnosticAck`
- `lsp-max-cli gate check` verb; `PreToolUse` hook wires Λ_CD^runtime enforcement
- Benchmark suite: micro / fanout / backpressure at N∈{5,50,500}
- `anti-llm-cheat-lsp`: centralized victory vocabulary in `config.rs`; Vec/String contains distinction
### ERRC Blue Ocean Innovations (committed 6ee4255)
- `RulePackSnapshot` — Arc<DashMap> O(1) async-safe workspace state clone; mirrors rust-analyzer GlobalStateSnapshot
- `compose_packs()` — topological dependency resolution + conflict detection between packs
- `EvalBudget` — per-rule `Sync` / `Background` latency classification; TOML serde; scan_uri_classified()
- `WorkspaceIndex` + `CrossFileRule` + `WorkspaceRuleEvaluator` — incremental DashMap doc index; workspace_conformance() aggregation; cross-file pattern constraints
### Protocol surface
- Four new `max/` Request types: `MaxRulePacks`, `MaxRulePackStatus`, `MaxRulePackDiff`, `MaxWorkspaceConformance`
- Method constants: `max/rulePacks`, `max/rulePackStatus`, `max/rulePackDiff`, `max/workspaceConformance`
- `RulePackDescriptor`, `RulePackStatusResult`, `RulePackDiffEntry` protocol structs
- `inter_file_dependencies` + `workspace_diagnostics` auto-enabled in `server_capabilities()` when cross-file rules present
### Coverage
- LSP 3.18 coverage matrix (`src/coverage/lsp_coverage.rs`) — watermark calibrated to 75% (22 client-push/transport methods correctly excluded)
- LSIF coverage matrix (`crates/lsp-max-lsif/`) — 18 coverage tests green
- 27 Chicago TDD tests for all ERRC innovations
### LSP 3.18 Full Detection Surface (committed 40c05c2)
- `anti-llm-cheat-lsp/src/rules/lsp318_coverage.rs`: 43 handlers promoted
`Absent → Wired`; `workspace/applyEdit` promoted `Absent → Refuses` (read-only law)
- `anti-llm-cheat-lsp/src/server.rs`: 29 new `LanguageServer` overrides; 9
server-to-client wires in `initialized`; 5 refresh/telemetry calls in
`run_scan_and_publish`
- `anti-llm-cheat-lsp/src/capabilities.rs`: matrix-derived `ServerCapabilities`
updated for all newly-wired methods (willSave, documentLink, color,
onTypeFormatting, typeHierarchy, codeAction/resolve, workspace file-ops,
notebook sync)
- **Coverage state (PARTIAL):** 93/95 methods `Wired` or `Refuses`; only
`exit` and `$/cancelRequest` remain `Absent` (no trait entry point)
### LSIF 0.6 Full Element Surface
- `anti-llm-cheat-lsp/src/rules/lsif06.rs` enumerates all 38 elements
(20 vertices + 18 edges); `modeled_in_crate: true` for every row
- `anti-llm://lsif06-matrix` virtual document renders the live surface
- Example-coverage status: `OPEN` throughout — no transcripts or receipts
produced by the canary crate (correct and honest)
### Infrastructure
- ggen-lsp plugin wired in `.claude/settings.json` (`enabledPlugins`)
- Default model set to `claude-sonnet-4-6`
- `.agents/` added to `.gitignore`
---
## Remaining Work (1 item)
### 1. `anti-llm-cheat-lsp` adoption of `RulePackServer` trait
**What:** `pattern-lsp`, `axum-lsp`, `anti-llm-cheat-lsp` each hand-roll the scanner / rules-loader / publish-diagnostics / conformance loop. `RulePackServer` was built to eliminate exactly this duplication. Nothing uses it yet.
**Status:** `pattern-lsp` ✅ and `axum-lsp` ✅ fully refactored to `RulePackServer` + `WorkspaceIndex`.
**Remaining:** `anti-llm-cheat-lsp` uses `AhoCorasick` + `engine::scan_directory()` + `virtual_docs` module — a fundamentally different architecture. Needs its own approach (replace `AntiLlmEngine` scanner with `RulePackServer::scan_uri()`).
**Files to change:**
- `crates/anti-llm-cheat-lsp/src/engine.rs` — replace `AntiLlmEngine` scanner with `RulePackServer::scan_uri()`
- `crates/anti-llm-cheat-lsp/src/main.rs` — add `index: WorkspaceIndex` field; override `workspace_index()`
**Definition of done:** `anti-llm-cheat-lsp` implements only `rule_packs()`, `grammar()`, `server_name()`, `client()`, `adapter()`. Zero hand-rolled AhoCorasick loops remain in the server path.
---
### 2. `WorkspaceIndex` wiring in examples
**What:** `workspace_index()` defaults to `None` in the `RulePackServer` trait. Cross-file diagnostics are silently disabled in every concrete server until they hold a `WorkspaceIndex` field and override `workspace_index()`.
**Files to change:**
- Each example server struct: add `index: WorkspaceIndex` field
- Each `impl RulePackServer`: override `workspace_index()` to return `Some(&self.index)`
- Each `LanguageServer::did_open` / `did_change` / `did_close`: delegate to `handle_did_open` / `handle_did_change` / `handle_did_close` (which already call `idx.upsert` / `idx.remove`)
**Unlock:** once wired, `publish_cross_file_diagnostics()` and `workspace_conformance()` activate automatically.
---
### 3. JSON-RPC handler wiring for new `max/` methods ✅ DONE
Implemented in `src/language_server/impls/snapshot.rs` and wired via `src/language_server.rs`:
- `max/rulePacks` → `max_rule_packs()` — groups diagnostics by pack_id prefix
- `max/rulePackStatus` → `max_rule_pack_status(pack_id)` — per-pack `RulePackStatusResult`
- `max/rulePackDiff` → `max_rule_pack_diff(params)` — diff against `cleared_diagnostics` set
- `max/workspaceConformance` → `max_workspace_conformance()` — refused-propagates lattice aggregation
---
### 4. ggen SLO: "one `ggen sync` produces a complete lsp-max" ✅ DONE
All required artifacts now exist:
```
ggen/
.specify/specs/lsp-max/
lsp.ttl # OWL ontology: lsp:Server, lsp:RulePack, lsp:Rule, lsp:LawAxis
ggen.toml # Manifest wiring 4 SPARQL→template→output rules
queries/lsp-max/
list_servers.rq # SELECT ?server_name ?diagnostic_source_id ?grammar_crate
list_rules.rq # SELECT all rule fields (pack→rule chain)
templates/lsp-max/
backend.rs.tera # generates src/server.rs (struct + RulePackServer impl)
cli.rs.tera # generates src/main.rs (clap CLI + stdio/TCP entry points)
semantics.rs.tera # generates src/semantics.rs (static_packs() + type re-exports)
build.rs.tera # generates build.rs (tree-sitter compile hook)
```
**Invoke with:**
```bash
ggen sync --manifest .specify/specs/lsp-max/ggen.toml
# → generated/lsp-max/<server_name>/src/{server.rs,main.rs,semantics.rs} + build.rs
```
---
## Priority Order
| 1 | pattern-lsp → RulePackServer | Small | ✅ Done |
| 2 | axum-lsp → RulePackServer + WorkspaceIndex | Small | ✅ Done |
| 3 | max/ handler wiring (4 methods) | Medium | ✅ Done |
| 4 | ggen SLO (ontology + SPARQL + templates + manifest) | Large | ✅ Done |
| 5 | anti-llm-cheat-lsp → RulePackServer | Medium | ⬜ Remaining |
---
## Next priorities (post-1f1e0cf)
| 5 | `anti-llm-cheat-lsp` → `RulePackServer` | Medium | ✅ CANDIDATE |
| 6 | `anti-llm-cheat-lsp` new rule modules (contract, ggen, oracle, trace, complexity) | Medium | ⬜ In progress (untracked files) |
| 7 | `WorkspaceIndex` wiring in `anti-llm-cheat-lsp` | Small | ✅ CANDIDATE |
| 8A | Λ_CD RFC A: `gate list` verb (agent-queryable gate state) | Small | ✅ CANDIDATE |
| 8B | Λ_CD RFC B: per-server speciation receipt chain | Large | ⬜ OPEN |
| 8C | Λ_CD RFC C: `CompositorReceipt` → OCEL accumulation | Medium | ✅ CANDIDATE |
### RFC Backlog Detail (item 8)
Three Λ_CD architectural priorities recorded in AGENTS.md after the 1000x review:
- **A — Agent-boundary enforcement**: `gate list` verb wired in `crates/lsp-max-cli/src/nouns/gate.rs`; returns `active_codes` and `agent_scope`. Per-agent partitioning (scoped block vs global halt) remains OPEN — `agent_scope` is `"global"` in the current release.
- **B — Per-server speciation receipt chain**: `CompositorReceipt::child_evidence: Vec<ChildEvidence>` exists and surfaces in `to_ocel_event()`. Full per-server `C_D` receipt chain wiring (each child emits its own traceable chain linked by `chain_object_id`) is OPEN.
- **C — Compositor receipt → OCEL**: `FlushCoordinator` now accumulates `CompositorReceipt::to_ocel_event()` into `ocel_events: Arc<Mutex<Vec<Value>>>` on every flush. `take_ocel_events()` drains the buffer for export. Process-model mining (conformance against fan-out → merge → admit model) is OPEN.