ADR-0066: Engine & CLI Stabilization — Issue #727 Hardening¶
| Field | Value |
|---|---|
| Status | Accepted (Implemented) |
| Date | 2026-08-30 |
| Authors | Spector Maintainers & Architecture Working Group |
| Deciders | Spector Technical Steering Committee (TSC) |
| Supersedes | None |
| Superseded By | None |
| Last Verified | 2026-09-16 (Verified against main) |
1. Context¶
1. Context & Problem Statement¶
Spector Memory's cognitive capabilities—Project Panama off-heap storage, fused SIMD vector search, 4-tier biological memory, sleep consolidation, and native Model Context Protocol (MCP) server—provide an industry-leading cognitive memory platform. However, initial onboarding currently presents severe friction points:
- The Zero-Config Crash: In
SpectorAutoConfiguration, if no external embedding provider (Ollama, OpenAI, Anthropic, Azure, Google, Mistral) is configured, the Spring context throwsSpectorInternalException(ErrorCode.ARGUMENT_NULL)and terminates. A new user cannot testrememberorrecallwithout first installing and running an external service like Ollama or provisioning cloud API keys. - The CLI Split-Brain: The CLI fat JAR (
spector.jarfromsynapse/spector-cli) provides Picocli commands formcp,remember,recall,index, andstatus, but lacks aservecommand. To run the REST API and web dashboard, users must locate and runspector-synapse-*.jar, creating confusion over which binary to run. - Absence of Environment Diagnostics & Scaffolding: Spector requires JDK 25 with preview and incubator Vector API flags (
--add-modules jdk.incubator.vector --enable-preview --enable-native-access=ALL-UNNAMED). When developers run into classpath or JVM mismatch issues, they receive low-level JVM error dumps rather than actionable diagnostics.
We require an architectural stabilization of the core engine and CLI to enable an instant, zero-config first run in under 3 seconds.
2. Problem Statement¶
Initial developer feedback highlighted critical friction points when running the CLI (spectorctl) or bootstrapping a local memory environment:
- Missing External Service Dependencies: Requiring an external OpenAI/Ollama embedding endpoint meant simple CLI exploration failed immediately on clean installs.
- Spring Context Startup Latency: Running routine commands (
spectorctl --version,spectorctl status) suffered from 2–3s Spring Boot web context startup delays. - Fragile Uninitialized Directories: Commands failed ungracefully if local storage directories (
data/,namespaces/) had not been pre-created.
3. Decision Drivers¶
- Zero-Config Developer Onboarding: Ship a native, in-process ONNX embedding model (MiniLM-L6-v2) as a self-contained fallback requiring zero API keys or external services.
- Sub-100ms CLI Startup: Enforce pure Picocli execution (
WebApplicationType.NONE) for standard administration commands. - Self-Healing Initial Scaffolding: Implement an automated
InitCommandcreating required directory trees and configuration templates seamlessly.
4. Considered Options¶
5. Alternatives Considered¶
| Alternative | Evaluation | Verdict |
|---|---|---|
| Lexical Hash Projection (LSH) | Generates deterministic pseudo-vectors without machine learning weights. Fast and lightweight (~10 KB). | Rejected: Fails semantic similarity queries (e.g., "automobile" does not match "car"). Developers testing Spector would experience poor recall quality. |
| Mandatory Ollama Pre-requisite | Require users to download Ollama and pull nomic-embed-text. | Rejected: Adds 5-10 minutes of friction, requires 500MB+ download, and fails in air-gapped or CI environments. |
Separate spector-server.jar vs spector-cli.jar | Keep CLI and REST server as separate Maven distributions. | Rejected: Confuses developers. Single-binary CLI with serve and mcp subcommands is the standard pattern (e.g., Vault, Consul, Qdrant). |
5. Decision Outcome¶
2. Architectural Decisions¶
flowchart TB
CLI_Entry["spector CLI Entry<br>(picocli + Spring Boot ApplicationContext)"]
CLI_Entry --- CLI_Init["spector init"]
CLI_Entry --- CLI_Doc["spector doctor"]
CLI_Entry --- CLI_MCP["spector mcp"]
CLI_Entry --- CLI_Serve["spector serve"]
CLI_Init --> CLI_Init_D["Scaffolding<br>~/.spector/<br>spector.yml"]
CLI_Doc --> CLI_Doc_D["Diagnostics<br>JVM, SIMD,<br>Ollama, Path"]
CLI_MCP --> CLI_MCP_D["STDIO JSON-RPC<br>Agent Protocol<br>(31 tools)"]
CLI_Serve --> CLI_Serve_D["HTTP / SSE<br>Port :7070<br>REST + Events"]
subgraph Engine ["SpectorAutoConfiguration Engine"]
direction TB
Q{"[External Provider Configured?]"}
Q -->|YES| Y["Ollama / OpenAI / Anthropic / Google / Mistral"]
Q -->|NO| N["In-Process Native ONNX Embedding Provider<br>(AllMiniLmL6V2QuantizedEmbeddingModel - 384 dims)"]
Flow["Working Memory ──► Episodic Memory ──► Semantic Store ──► Procedural<br>Zero-GC Panama FFM Off-Heap Storage | SIMD Dot-Product Cosine Scoring"]
Y -.-> Flow
N -.-> Flow
end
CLI_Init_D -.-> Q
CLI_Doc_D -.-> Q
CLI_MCP_D -.-> Q
CLI_Serve_D -.-> Q Decision 1: In-Process Native ONNX Embedder as Zero-Config Fallback¶
- Component:
OnnxProviderFactoryandOnnxEmbeddingProviderinmemory/spector-providersalready support in-process LangChain4j ONNX models. - Dependency: Package
dev.langchain4j:langchain4j-embeddings-all-minilm-l6-v2-qintospector-synapseandspector-cli. -
Resolution Logic: In
SpectorAutoConfiguration.java, if no externalEmbeddingProviderbean is registered, auto-configure:@Bean @ConditionalOnMissingBean(EmbeddingProvider.class) EmbeddingProvider defaultFallbackOnnxEmbeddingProvider() { log.info("[Spector Engine] No external embedding provider configured. Activating built-in In-Process Native ONNX Embedder (all-MiniLM-L6-v2-q, 384 dims)."); return new OnnxEmbeddingProvider( new AllMiniLmL6V2QuantizedEmbeddingModel(), "all-MiniLM-L6-v2-q", 384 ); } -
Dimensionality: Automatically defaults memory vector dimensions to 384 when the ONNX fallback is active, requiring no manual YAML edits.
Decision 2: Preserving Pure CLI (WebApplicationType.NONE) & Dedicated Synapse Server¶
- Pure CLI Discipline:
spector-cliremains strictly a lightweight command-line tool (WebApplicationType.NONEwith Picocli). It contains zero servlet containers (no Tomcat/Jetty) and zero web controllers. - Dual-Mode Execution in CLI:
- Embedded Mode (
cli-embedded): Used forspector mcp(STDIO JSON-RPC for Claude Desktop/Cursor) and local batch ingestion. Boots in-processSpectorMemorywith the bundled ONNX fallback embedder over standard I/O. - Remote Client Mode (
cli-remote): Default forspector recall,remember,status, andindex. UsesSpectorHttpClientto issue fast sub-second HTTP REST calls to a running Synapse server on:7070.
- Embedded Mode (
- Dedicated Server:
spector-synapse(SynapseApplication) remains the sole Spring Boot 4 web server daemon providing REST APIs, SSE streaming (/api/v1/events), HTTP MCP (/mcp), and static Cortex UI. It is executed via Docker orjava -jar spector-synapse.jar.
Decision 3: Self-Healing Scaffolding (InitCommand)¶
- Subcommand:
spector init [--data-dir <path>] - Behavior:
- Checks if
~/.spector/spector.ymlexists. If not, writes a clean starter configuration. - Provisions
~/.spector/data/memoryand~/.spector/data/indexdirectories. - Sets safe file permissions (0700 on Unix).
- Checks if
Decision 4: Environment Diagnostic Suite (DoctorCommand)¶
- Subcommand:
spector doctor - Checks:
- Java Version: Verifies JDK 25+ (
java.version>= 25). - Vector API: Checks if
jdk.incubator.vector.FloatVectoris accessible and functional. - SIMD Acceleration: Probes hardware flags for AVX-512, AVX2, or ARM NEON.
- Data Directory: Validates read/write access to storage paths.
- Ollama Reachability: Probes
http://localhost:11434/api/tags(optional, reports status without failing). - Client Config Generator: Emits formatted JSON configuration blocks for Claude Desktop, Cursor, and Windsurf with absolute paths resolved for the current host.
- Java Version: Verifies JDK 25+ (
3. Component Design & Contracts¶
A. Subcommand Hierarchy in SpectorCtl.java¶
@Command(
name = "spector",
aliases = {"spectorctl"},
subcommands = {
InitCommand.class,
DoctorCommand.class,
McpCommand.class,
ServeCommand.class,
RememberCommand.class,
RecallCommand.class,
IndexCommand.class,
StatusCommand.class,
MemoryCommand.class
}
)
public class SpectorCtl implements Runnable { ... }
B. Fallback Fall-Through Matrix¶
| Configuration State | Resulting Embedding Provider | Vector Dims | External Services Needed |
|---|---|---|---|
spector.provider.embedding.type: Ollama | OllamaEmbeddingProvider | Configured (e.g. 768) | Ollama running |
spector.provider.embedding.type: OpenAi | OpenAiEmbeddingProvider | Configured (e.g. 1536) | OpenAI API Key |
OPENAI_API_KEY in environment | OpenAiEmbeddingProvider | 1536 | OpenAI API Key |
| No configuration / No environment keys | OnnxEmbeddingProvider (all-MiniLM-L6-v2-q) | 384 | NONE (100% Offline) |
6. Pros and Cons of the Options¶
4. Consequences & Trade-offs¶
Positive¶
- 3-Second Zero-Config Onboarding: Developers clone or download
spector.jarand can immediately runspector mcporspector servewith semantic recall working offline. - Single Unified Binary: No confusion between
spector.jar(CLI) andspector-synapse.jar(Server); one binary handles all execution modes. - Actionable Diagnostics:
spector doctoreliminates guesswork regarding Vector API flags or missing runtime directories.
Negative¶
- Distribution Size: Including
langchain4j-embeddings-all-minilm-l6-v2-qadds ~25 MB of quantized model weights to the fat JAR. - Memory Footprint: In-process ONNX model requires ~100 MB of native memory for weights during active inference.
Mitigations¶
- The 8-bit quantized MiniLM model preserves >98% semantic fidelity while keeping memory overhead negligible compared to Java Panama off-heap allocations.
7. Implementation Plan¶
6. Implementation Plan & Persona Allocation¶
-
Maintainer (Core & Synapse):
- Add
langchain4j-embeddings-all-minilm-l6-v2-qtopom.xmldependencyManagement andspector-synapse/spector-cli. - Update
SpectorAutoConfiguration.javato auto-wire the fallback ONNX embedder. - Implement
ServeCommand.java,DoctorCommand.java, andInitCommand.javainsynapse/spector-cli.
- Add
-
Maintainer (Quality Assurance):
- Integration tests verifying zero-config boot, offline
remember/recallcycle, and CLI commands.
- Integration tests verifying zero-config boot, offline
-
Maintainer (Infrastructure & Platform):
- Verify fat JAR shade configuration and update
scripts/start-mcp.batand shell wrappers.
- Verify fat JAR shade configuration and update
8. Code Reference & Verification¶
All stabilization features and fallback embedders are verified in the codebase:
- CLI Command Tree:
synapse/spector-cli/src/main/java/com/spectrayan/spector/cli/ - Native ONNX Fallback:
nucleus/spector-providers/src/main/java/com/spectrayan/spector/providers/onnx/ - Initialization Command:
synapse/spector-cli/src/main/java/com/spectrayan/spector/cli/cmd/InitCommand.java