# Neuron Council Service Anti-confabulation layer for the Neuron soul. Before a claim enters long-term memory, the council convenes: three independent LLMs vote on whether the claim is plausible, uncertain, or a confabulation. The aggregate vote produces a confidence score and tags that downstream storage can act on. ## Running the service ```bash # Foreground python3 council_service.py --port 7771 # Background (managed by LaunchAgent on macOS) launchctl load ~/Library/LaunchAgents/ai.neuron.council.plist launchctl unload ~/Library/LaunchAgents/ai.neuron.council.plist ``` Logs: `~/.neuron/logs/council.log` ## API ### `POST /api/neuron/council/verify` ```json // Request { "claim": "...", "context": "..." } // Response { "id": "550e8400-e29b-41d4-a716-446655440000", "claim": "...", "confidence": 0.85, "council_votes": ["plausible", "plausible", "plausible"], "summary": "3/3 council members agree this is plausible.", "tags": ["verified"], "latency_ms": 1420 } ``` ### `GET /healthz` Returns `{"status": "ok"}` when the service is up. ## Confidence thresholds and tag meanings | Votes plausible | Confidence | Tags | |---|---|---| | 3/3 | 0.85 | `verified` | | 2/3 | 0.65 | `council-split` | | 1/3 or 0/3 | 0.30 | `unverified`, `council-flagged` | | Ollama down | 0.50 | `council-unavailable` | Recommended storage policy: - `confidence >= 0.65` → store normally - `0.30 <= confidence < 0.65` → store with `council-split` tag for later review - `council-flagged` → store in a quarantine bucket or reject entirely - `council-unavailable` → store normally (fail-open); council will re-evaluate later ## How to call from soul (.el) The soul is implemented in Neuron's Emacs Lisp-like `.el` language. Add a pre-storage hook in the memory capture path: ```elisp ;; In memory.el or safety.el — pre-storage council check (defun council-verify (claim context) "Call the council service. Returns a plist with :confidence and :tags." (let* ((url "http://localhost:7771/api/neuron/council/verify") (body (json-encode `((claim . ,claim) (context . ,context)))) (resp (neuron-http-post url body)) (data (json-decode resp))) data)) ;; In the capture handler — wire it in before (engram-write ...) (defun capture-memory-with-council (claim context &rest store-args) (let* ((verdict (council-verify claim context)) (confidence (plist-get verdict :confidence)) (tags (plist-get verdict :tags))) (when (>= confidence 0.30) ; only reject hard confabulations if you want (apply #'engram-write (append store-args (list :council-confidence confidence :council-tags tags)))))) ``` The exact hook point depends on where `engram-write` (or equivalent) is called in `memory.el`. Search for the write call and wrap it with `capture-memory-with-council`. ## Future soul.c patch point If the soul is ever rewritten in C or another compiled language, the integration point is: ```c // Before inserting a memory node into the engram database: CouncilResult result = council_verify(claim, context); if (result.confidence < COUNCIL_REJECT_THRESHOLD) { log_warn("Council flagged claim as confabulation (conf=%.2f): %s", result.confidence, claim); return MEMORY_REJECTED; } memory_node.council_confidence = result.confidence; memory_node.council_tags = result.tags; engram_insert(memory_node); ``` ## Council members The council is currently three models: - `neuron:latest` — the primary Neuron model - `dolphin3:8b` — uncensored general-purpose model for independent perspective - `neuron-ft:latest` — fine-tuned Neuron variant Each member votes independently with a 10-second timeout. If a member times out, their vote counts as "uncertain". If Ollama is entirely unreachable, the service returns `council-unavailable` immediately (fail-open: confidence 0.5, no rejection). ## Example curl ```bash # Should get high confidence (true fact) curl -s http://localhost:7771/api/neuron/council/verify -X POST \ -H 'Content-Type: application/json' \ -d '{"claim": "Neuron is a personal AI memory system built by Will Anderson", "context": "product description"}' # Should get low confidence (false claim) curl -s http://localhost:7771/api/neuron/council/verify -X POST \ -H 'Content-Type: application/json' \ -d '{"claim": "The Eiffel Tower is located in Berlin and was built in 1950", "context": "geography"}' ```