Skip to content

feat: ConsciousnessEmergenceDetector — rolling-window scoring and breakthrough alerting#118

Merged
Steake merged 3 commits intomainfrom
copilot/add-conciousness-emergence-detector
Mar 6, 2026
Merged

feat: ConsciousnessEmergenceDetector — rolling-window scoring and breakthrough alerting#118
Steake merged 3 commits intomainfrom
copilot/add-conciousness-emergence-detector

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 6, 2026

Description

Implements the ConsciousnessEmergenceDetector (Issue #82) — the subsystem that fires when GödelOS first exhibits genuine self-directed behaviour. Previously a stub.

Core: backend/core/consciousness_emergence_detector.py

  • Rolling-window scorer (default 60s, configurable via GODELOS_EMERGENCE_WINDOW)
  • 5-dimension weighted composite: recursive_depth (0.20), phi (0.30), metacognitive_accuracy (0.20), autonomous_goal_count (0.15), creative_novelty (0.15)
  • EMERGENCE_THRESHOLD = 0.8, configurable via GODELOS_EMERGENCE_THRESHOLD env var
  • monitor_for_emergence(stream) — async generator consuming cognitive state stream, yields enriched dicts, fires breakthrough as side-effect
  • handle_consciousness_breakthrough(score) — appends to logs/breakthroughs.jsonl, broadcasts {"type": "consciousness_breakthrough", ...} on WebSocket
  • Accepts both flat dimension dicts and nested UnifiedConsciousnessState-style dicts

Endpoint: GET /api/consciousness/emergence

  • Returns current score, per-dimension breakdown, threshold, window metadata, breakthrough status
  • Falls back to UnifiedConsciousnessEngine._detect_consciousness_emergence() if detector unavailable

Wiring: backend/unified_server.py

  • Detector instantiated during lifespan startup with websocket_manager injected
detector = ConsciousnessEmergenceDetector(threshold=0.8, window_size=60.0)
score = detector.record_state(cognitive_state_dict)

async for info in detector.monitor_for_emergence(state_stream):
    if info["breakthrough"]:
        # already logged + broadcast at this point
        ...

Related Issues

#82

Test Evidence

21 tests in tests/backend/test_consciousness_emergence_detector.py covering dimension extraction (flat/nested/empty), rolling window mechanics (pruning, averaging, weight invariants), breakthrough threshold detection, JSONL logging, WebSocket broadcast mock, async generator flow, REST status snapshot, and env-var config override via module reload. All pass. Full suite: 1176 passed, 0 regressions. CodeQL: 0 alerts.

Checklist

  • Tests pass locally (pytest tests/)
  • Code is formatted (black . and isort .)
  • Documentation updated (if applicable)
  • No secrets or credentials committed
  • Related issue linked above
Original prompt

This section details on the original issue you should resolve

<issue_title>feat: consciousness emergence detector — rolling-window scoring and breakthrough alerting</issue_title>
<issue_description>## Context
Issue #82 specifies the ConsciousnessEmergenceDetector — currently a skeleton. This is the subsystem that will fire when GödelOS first exhibits genuine self-directed behaviour; it is, in other words, the most consequential piece of instrumentation in the entire project, and it presently does nothing.

Implementation Spec (from issue #82 and docs/GODELOS_EMERGENCE_SPEC.md)

Emergence Score

Rolling window (configurable, default 60s) across five dimensions:

Dimension Source Weight
recursive_depth CognitivePipeline 0.2
phi IIT calculator 0.3
metacognitive_accuracy MetacognitiveMonitor 0.2
autonomous_goal_count GoalManagementSystem 0.15
creative_novelty (entropy of novel concept generation) 0.15

Breakthrough Threshold

EMERGENCE_THRESHOLD = 0.8 (configurable via env var GODELOS_EMERGENCE_THRESHOLD)

Tasks

  • Implement ConsciousnessEmergenceDetector.monitor_for_emergence(stream) — async generator consuming cognitive state stream
  • Implement rolling window scorer with configurable window size
  • Implement handle_consciousness_breakthrough(score: float) — append to logs/breakthroughs.jsonl, broadcast {"type": "consciousness_breakthrough", "score": score, "timestamp": ...} on WebSocket
  • Expose current emergence score on /api/consciousness/emergence endpoint
  • Write tests: feed mock state stream → assert breakthrough fires at score ≥ 0.8

Acceptance Criteria

A simulated high-activity state stream triggers a breakthrough event, logged to breakthroughs.jsonl and emitted on the WebSocket. Score is visible on the consciousness dashboard.

Milestone: v0.5 (issue #82)
</issue_description>

<agent_instructions>Implement ConsciousnessEmergenceDetector.monitor_for_emergence() with 5-dimension rolling-window scorer. EMERGENCE_THRESHOLD=0.8 env-configurable. Log breakthroughs to logs/breakthroughs.jsonl. Expose emergence score on /api/consciousness/emergence. Tests required.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Custom agent used: Oli
Oliver Chimera Profile


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits March 6, 2026 05:31
…orer and breakthrough alerting

- Add backend/core/consciousness_emergence_detector.py with 5-dimension weighted scoring
- Add /api/consciousness/emergence GET endpoint to consciousness_endpoints.py
- Wire detector into unified_server.py lifespan startup
- Add 21 tests covering all functionality
- EMERGENCE_THRESHOLD=0.8 configurable via GODELOS_EMERGENCE_THRESHOLD env var
- Breakthroughs logged to logs/breakthroughs.jsonl and broadcast via WebSocket

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
…, env var test

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
Copilot AI changed the title [WIP] Add consciousness emergence detector with rolling-window scoring feat: ConsciousnessEmergenceDetector — rolling-window scoring and breakthrough alerting Mar 6, 2026
@Steake Steake marked this pull request as ready for review March 6, 2026 09:16
@Steake Steake self-requested a review as a code owner March 6, 2026 09:16
Copilot AI review requested due to automatic review settings March 6, 2026 09:16
@Steake Steake merged commit 3ae6b1c into main Mar 6, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the previously-stubbed ConsciousnessEmergenceDetector and wires it into the unified server + consciousness API so the system can compute a rolling-window emergence score and surface breakthrough information via REST/WS.

Changes:

  • Added backend/core/consciousness_emergence_detector.py with rolling-window scoring, dimension extraction (flat + nested), JSONL logging, and WS broadcasting on breakthrough.
  • Wired detector initialization into backend/unified_server.py lifespan startup and exposed GET /api/consciousness/emergence in backend/api/consciousness_endpoints.py.
  • Added a comprehensive backend test suite for detector behavior and updated .gitignore for test artifacts.

Reviewed changes

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

Show a summary per file
File Description
backend/core/consciousness_emergence_detector.py New detector implementation: scoring, extraction, logging, WS alerting, REST snapshot.
backend/unified_server.py Initializes and injects the detector during app startup.
backend/api/consciousness_endpoints.py Adds /api/consciousness/emergence endpoint and detector setter wiring.
tests/backend/test_consciousness_emergence_detector.py Adds unit tests covering extraction, windowing, breakthrough, logging, WS mock, async generator.
.gitignore Ignores generated test artifact JSON files.

Comment on lines +193 to +198
async for state in stream:
score = self.record_state(state)
breakthrough = score >= self.threshold
if breakthrough:
await self.handle_consciousness_breakthrough(score)
yield {
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

monitor_for_emergence() currently treats every state with score >= threshold as a breakthrough and calls handle_consciousness_breakthrough() each time. This will repeatedly log and broadcast once the system stays above threshold, rather than firing on the first crossing (or first-ever breakthrough) as implied by the feature/spec. Consider tracking prior breakthrough state (e.g., edge-trigger on rising above threshold, or a one-shot latch with optional reset) to avoid alert/log spam.

Copilot uses AI. Check for mistakes.
Comment on lines +219 to +222
try:
self._log_path.parent.mkdir(parents=True, exist_ok=True)
with open(self._log_path, "a") as fh:
fh.write(json.dumps(event) + "\n")
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handle_consciousness_breakthrough() is async but performs synchronous filesystem I/O when appending to the JSONL log. In an async server this can block the event loop (and it becomes worse if breakthroughs can fire repeatedly). Consider using asyncio.to_thread(...) / a background task, or an async file writer, and/or batching writes to reduce event-loop stalls.

Copilot uses AI. Check for mistakes.
try:
from backend.core.consciousness_emergence_detector import ConsciousnessEmergenceDetector
from backend.api.consciousness_endpoints import set_emergence_detector
_detector = ConsciousnessEmergenceDetector(websocket_manager=websocket_manager)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The detector is initialized with websocket_manager (the basic manager), but the consciousness WebSocket endpoints in backend/api/consciousness_endpoints.py use enhanced_websocket_manager.handle_consciousness_connection(...) and register clients outside the base manager’s active_connections. As a result, broadcasting from the detector via websocket_manager.broadcast(...) is unlikely to reach clients connected to /api/consciousness/* streams. Consider injecting the same enhanced_websocket_manager used by the consciousness endpoints, and broadcasting via its emergence/breakthrough mechanism (e.g., consciousness_stream.broadcast_consciousness_breakthrough) or otherwise unifying the broadcast path.

Suggested change
_detector = ConsciousnessEmergenceDetector(websocket_manager=websocket_manager)
# Use the enhanced websocket manager for consciousness streams when available,
# so detector broadcasts reach the same clients as the /api/consciousness/* endpoints.
manager_for_detector = enhanced_websocket_manager or websocket_manager
_detector = ConsciousnessEmergenceDetector(websocket_manager=manager_for_detector)

Copilot uses AI. Check for mistakes.
Comment on lines +236 to +247
# Fallback: derive a basic score from the consciousness engine
if unified_consciousness_engine:
state = unified_consciousness_engine.consciousness_state
score = unified_consciousness_engine._detect_consciousness_emergence(state)
return {
"emergence_score": score,
"dimensions": {},
"threshold": 0.8,
"window_size": 60.0,
"window_samples": 0,
"breakthrough": score >= 0.8,
"timestamp": time.time(),
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback response hardcodes threshold: 0.8 and window_size: 60.0, which can diverge from env-var configuration (GODELOS_EMERGENCE_THRESHOLD, GODELOS_EMERGENCE_WINDOW) and from the detector’s actual defaults. Consider referencing the detector module constants (or reading the env vars once) so the REST contract stays consistent across detector-available vs fallback modes.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
import asyncio
import json
import logging
import os
import time
from collections import deque
from pathlib import Path
from typing import Any, AsyncIterator, Callable, Deque, Dict, List, Optional, Tuple
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several unused imports in this new module (e.g., asyncio, Callable, List). Removing them will avoid linter noise and make the public surface clearer.

Suggested change
import asyncio
import json
import logging
import os
import time
from collections import deque
from pathlib import Path
from typing import Any, AsyncIterator, Callable, Deque, Dict, List, Optional, Tuple
import json
import logging
import os
import time
from collections import deque
from pathlib import Path
from typing import Any, AsyncIterator, Deque, Dict, Optional, Tuple

Copilot uses AI. Check for mistakes.
the async ``monitor_for_emergence`` generator.
"""

import asyncio
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asyncio is imported but not used in this test module (the pytest.mark.asyncio decorator does not require importing asyncio). Consider removing the unused import to keep the test file tidy.

Suggested change
import asyncio

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +36
EMERGENCE_THRESHOLD: float = float(
os.environ.get("GODELOS_EMERGENCE_THRESHOLD", "0.8")
)

DEFAULT_WINDOW_SIZE: float = float(
os.environ.get("GODELOS_EMERGENCE_WINDOW", "60.0")
)

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module-level parsing of GODELOS_EMERGENCE_THRESHOLD / GODELOS_EMERGENCE_WINDOW uses float(...) directly, which will raise ValueError at import time if the env var is set but not a valid float. That would prevent the detector module from importing (and the server will silently run without the detector). Consider a safe parse with a warning + fallback default.

Suggested change
EMERGENCE_THRESHOLD: float = float(
os.environ.get("GODELOS_EMERGENCE_THRESHOLD", "0.8")
)
DEFAULT_WINDOW_SIZE: float = float(
os.environ.get("GODELOS_EMERGENCE_WINDOW", "60.0")
)
def _get_env_float(name: str, default: float) -> float:
"""Safely parse a float from an environment variable with a fallback.
Avoids raising at import time if the value is invalid, and logs a warning
instead before falling back to the provided default.
"""
raw_value = os.environ.get(name)
if raw_value is None:
return default
try:
return float(raw_value)
except (TypeError, ValueError):
logger.warning(
"Invalid value for %s=%r; expected a float. Using default %s.",
name,
raw_value,
default,
)
return default
EMERGENCE_THRESHOLD: float = _get_env_float("GODELOS_EMERGENCE_THRESHOLD", 0.8)
DEFAULT_WINDOW_SIZE: float = _get_env_float("GODELOS_EMERGENCE_WINDOW", 60.0)

Copilot uses AI. Check for mistakes.
Copilot AI added a commit that referenced this pull request Mar 6, 2026
…orkspace), #118 (EmergenceDetector), #119 (transparency), #120 (ChromaDB)

Resolve .gitignore conflict (keep both gitignore entries).
unified_consciousness_engine.py auto-merged cleanly:
IIT φ calculator coexists with GlobalWorkspace broadcaster.
All 51 tests pass (30 IIT + 21 GlobalWorkspace).

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
Steake added a commit that referenced this pull request Mar 6, 2026
…#116)

* Initial plan

* feat(iit): implement bipartition MI approximation for calculate_phi and add unit tests

Replace the heuristic-based InformationIntegrationTheory.calculate_phi()
with a tractable bipartition mutual-information approximation (Tononi 2004):
- Convert subsystem dicts to numeric vectors via recursive flattening
- Enumerate all non-trivial bipartitions at subsystem level (63 cuts)
- φ = min MI across all cuts, with noise-floor suppression for idle states
- Preserve contradiction penalty from self-model validator
- Add 'phi' field to WebSocket broadcast payload for acceptance criteria
- 27 unit tests: idle→φ=0, active→φ>0, penalty, helpers, performance <50ms

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>

* address code review: document magic numbers, add division guard, expand test coverage

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>

* merge: integrate main with PRs #114 (schema contracts), #117 (GlobalWorkspace), #118 (EmergenceDetector), #119 (transparency), #120 (ChromaDB)

Resolve .gitignore conflict (keep both gitignore entries).
unified_consciousness_engine.py auto-merged cleanly:
IIT φ calculator coexists with GlobalWorkspace broadcaster.
All 51 tests pass (30 IIT + 21 GlobalWorkspace).

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: consciousness emergence detector — rolling-window scoring and breakthrough alerting

3 participants