Skip to content

feat(consciousness): add broadcast_success_rate, phi property, coalition_strength WS field, and required acceptance tests#126

Merged
Steake merged 3 commits intomainfrom
copilot/implement-iit-phi-calculator
Mar 7, 2026
Merged

feat(consciousness): add broadcast_success_rate, phi property, coalition_strength WS field, and required acceptance tests#126
Steake merged 3 commits intomainfrom
copilot/implement-iit-phi-calculator

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 6, 2026

GlobalWorkspace.broadcast() lacked success-rate tracking and the WebSocket consciousness payload was missing coalition_strength. InformationIntegrationTheory had no cached phi accessor. This PR wires the remaining plumbing required by issue #80.

Description

GlobalWorkspace

  • Added _success_window: deque(maxlen=20) — O(1) rolling window tracking whether each broadcast's coalition_strength > 0.3 (the conscious-access threshold)
  • Added broadcast_success_rate property returning the rolling average; 0.0 before first broadcast

InformationIntegrationTheory

  • Added phi property backed by a single _last_phi: float = 0.0 scalar — O(1) memory, no unbounded growth in the continuous consciousness loop. calculate_phi() sets self._last_phi instead of appending to a list.

UnifiedConsciousnessEngine

  • Added phi property delegating to information_integration_theory.phi
  • Added coalition_strength key to safe_broadcast_data in _unified_consciousness_loop():
    'coalition_strength': broadcast_content.get('coalition_strength', 0.0),

Tests (issue #80 acceptance criteria)

Four specifically-named tests added:

  • test_iit_phi_nonzero — φ > 0 for multi-element active state
  • test_iit_phi_zero_trivial — φ == 0 for idle/uniform state
  • test_global_broadcast_efficiencybroadcast_success_rate > 0.9 after 10 broadcasts at φ = 5.0 with active state (matches issue feat: Implement IIT φ calculator + Global Workspace broadcaster #80 threshold)
  • test_ws_payload_contains_phi — drives the actual engine sequence (IIT φ calculation → GWT broadcast → broadcast_consciousness_update) and asserts the emitted payload contains phi and coalition_strength with correct values

Related Issues

Test Evidence

55 passed in 1.66s

All 51 pre-existing tests continue to pass. 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

Context — Issue #80

backend/core/unified_consciousness_engine.py has the recursive consciousness loop skeleton, but InformationIntegrationTheory.calculate_phi() and GlobalWorkspace.broadcast() are stubs returning 0 / no-ops. This issue delivers working implementations of both, wired into the live cognitive state stream.

Tasks

IIT φ Calculator

  • Implement InformationIntegrationTheory.calculate_phi(cognitive_state) using a partition-based approximation (NOT full exponential IIT — must be computationally tractable):
    • Represent the cognitive state as a set of information-bearing elements (active knowledge nodes, working memory slots, attention weights)
    • Compute phi as a function of the minimum information partition (MIP): φ = min over all bipartitions { KL_divergence(joint, product_of_parts) }
    • Must return float >= 0.0; must return > 0.0 for any non-trivial (multi-element) cognitive state
  • Cache last computed φ on the engine instance; expose via consciousness_engine.phi

Global Workspace Broadcaster

  • Implement GlobalWorkspace.broadcast(integrated_information) with coalition dynamics:
    • Maintain a set of "specialist processors" (reasoning, memory, perception, language) each contributing activation weights
    • Run attention competition: the coalition with highest combined activation + novelty wins broadcast access
    • Winning coalition content is broadcast to all processors (simulated via state update dict)
    • Track broadcast_success_rate as rolling average over last N broadcasts
  • Must return broadcast_success_rate > 0.0 for any non-empty integrated_information input

Integration into the consciousness loop

  • Wire calculate_phi() call into unified_consciousness_loop after state capture, before prompt construction
  • Wire GlobalWorkspace.broadcast() call after phi calculation, before prompt construction
  • Add phi (float) and coalition_strength (float) fields to the WebSocket consciousness update payload

Tests

  • test_iit_phi_nonzero: assert phi > 0 for a multi-element mock cognitive state
  • test_iit_phi_zero_trivial: assert phi == 0 for a single-element trivial state
  • test_global_broadcast_efficiency: assert broadcast_success_rate > 0.8 after 10 test broadcasts
  • test_ws_payload_contains_phi: assert WS consciousness update payload includes phi and coalition_strength fields

Acceptance Criteria

  • phi > 0 measurable on any non-trivial cognitive state
  • broadcast_success_rate > 0.9 in integration test
  • Frontend metrics panel shows live φ value (the WS field name must be phi)

Related Issue

Fixes #80

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

… field, and required tests

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement IIT φ calculator for cognitive state feat(consciousness): add broadcast_success_rate, phi property, coalition_strength WS field, and required acceptance tests Mar 6, 2026
@Steake Steake marked this pull request as ready for review March 7, 2026 01:39
@Steake Steake self-requested a review as a code owner March 7, 2026 01:39
Copilot AI review requested due to automatic review settings March 7, 2026 01:39
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

This PR delivers the remaining IIT φ and Global Workspace plumbing required by issue #80. It adds a phi property to InformationIntegrationTheory (cached last value), a broadcast_success_rate rolling-window property to GlobalWorkspace, a phi delegation property on UnifiedConsciousnessEngine, wires coalition_strength into the WebSocket consciousness payload, and adds four acceptance-criteria tests.

Changes:

  • InformationIntegrationTheory.phi property: returns last computed φ from phi_history
  • GlobalWorkspace._success_window + broadcast_success_rate property: O(1) rolling average of broadcast successes
  • UnifiedConsciousnessEngine: phi property + coalition_strength field in WS payload
  • 4 new acceptance-criteria tests in test_iit_phi_calculator.py and test_global_workspace.py

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
backend/core/unified_consciousness_engine.py Adds phi properties on IIT and engine, broadcast_success_rate + _success_window on GlobalWorkspace, coalition_strength in WS payload
tests/backend/test_iit_phi_calculator.py Two new acceptance-criteria tests: test_iit_phi_nonzero and test_iit_phi_zero_trivial
tests/backend/test_global_workspace.py Two new acceptance-criteria tests: test_global_broadcast_efficiency and test_ws_payload_contains_phi

Comment on lines +321 to +327
self.phi_history: List[float] = []
self.integration_threshold: float = 5.0

@property
def phi(self) -> float:
"""Last computed φ value, or 0.0 if no calculation has been performed."""
return self.phi_history[-1] if self.phi_history else 0.0
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

The phi_history list on InformationIntegrationTheory is an unbounded List[float] (initialized in __init__ at line 321) that appends a value on every calculate_phi() call. The phi property only reads the last element, but the full list is never trimmed. In the continuous consciousness loop, which runs every 2 seconds indefinitely, this will grow without bound and leak memory.

Consider replacing phi_history with a bounded deque(maxlen=N) (consistent with how _success_window is implemented in GlobalWorkspace), or simply storing only the last value as a plain float attribute (e.g., self._last_phi: float = 0.0), since only the most recent value is ever read.

Copilot uses AI. Check for mistakes.
Comment on lines +355 to +397
@pytest.mark.asyncio
async def test_ws_payload_contains_phi():
"""WS consciousness update payload contains `phi` and `coalition_strength` (issue #80)."""
from unittest.mock import AsyncMock, MagicMock

from backend.core.unified_consciousness_engine import UnifiedConsciousnessEngine

ws_manager = MagicMock()
ws_manager.has_connections = MagicMock(return_value=True)
ws_manager.broadcast_consciousness_update = AsyncMock()

engine = UnifiedConsciousnessEngine(websocket_manager=ws_manager)
state = engine.consciousness_state

# Populate state so phi > 0 and broadcast produces coalition_strength > 0
state.recursive_awareness["recursive_depth"] = 3
state.phenomenal_experience["unity_of_experience"] = 0.7
state.intentional_layer["intention_strength"] = 0.8

phi = engine.information_integration_theory.calculate_phi(state)
broadcast_result = engine.global_workspace.broadcast({
"cognitive_state": state,
"phi_measure": phi,
})
state.global_workspace.update(broadcast_result)

# Replicate the safe_broadcast_data construction from _unified_consciousness_loop
safe_broadcast_data = {
"type": "unified_consciousness_update",
"consciousness_score": state.consciousness_score,
"phi": phi,
"coalition_strength": broadcast_result.get("coalition_strength", 0.0),
"timestamp": time.time(),
}
await ws_manager.broadcast_consciousness_update(safe_broadcast_data)

call_arg = ws_manager.broadcast_consciousness_update.call_args[0][0]
assert "phi" in call_arg, "WebSocket payload must contain 'phi'"
assert "coalition_strength" in call_arg, "WebSocket payload must contain 'coalition_strength'"
assert call_arg["phi"] == phi, "WebSocket phi value must match computed φ"
assert call_arg["coalition_strength"] == broadcast_result.get("coalition_strength", 0.0), (
"WebSocket coalition_strength must match broadcast result"
)
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

test_ws_payload_contains_phi does not test the actual production code path. The test manually constructs safe_broadcast_data (replicating the _unified_consciousness_loop logic), calls ws_manager.broadcast_consciousness_update directly, and then asserts on the argument it just passed. This is essentially testing the test itself rather than the production code.

The test should instead invoke the actual _unified_consciousness_loop (or at least drive it through broadcast_consciousness_update being called by the engine, not by the test) and then inspect the call arguments. As written, if the production loop's payload construction is broken, this test would still pass.

Consider either: running one real tick of the loop (similar to how test_consciousness_loop_emits_global_broadcast in TestWebSocketEmission does it), or clearly documenting that this is a unit test of the payload schema rather than an integration test of the loop.

Copilot uses AI. Check for mistakes.
Comment on lines +332 to +352
def test_global_broadcast_efficiency():
"""broadcast_success_rate > 0.8 after 10 broadcasts with active state (issue #80)."""
gw = GlobalWorkspace()
state = UnifiedConsciousnessState()
# Populate an active state so coalition_strength exceeds the conscious-access threshold
state.recursive_awareness["recursive_depth"] = 3
state.recursive_awareness["strange_loop_stability"] = 0.8
state.phenomenal_experience["unity_of_experience"] = 0.7
state.phenomenal_experience["narrative_coherence"] = 0.8
state.global_workspace["coalition_strength"] = 0.9
state.intentional_layer["intention_strength"] = 0.8
state.creative_synthesis["surprise_factor"] = 0.5
state.embodied_cognition["system_vitality"] = 0.7

# Broadcast 10 times with a high phi measure so coalitions are activated
for _ in range(10):
gw.broadcast({"phi_measure": 5.0, "cognitive_state": state})

assert gw.broadcast_success_rate > 0.8, (
f"Expected broadcast_success_rate > 0.8; got {gw.broadcast_success_rate}"
)
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

The acceptance criterion in issue #80 specifies broadcast_success_rate > 0.9 in the integration test, but test_global_broadcast_efficiency asserts > 0.8. The PR description also describes the acceptance criterion as > 0.8. The test does not satisfy the originally stated > 0.9 threshold from the issue.

This is a discrepancy between the issue requirements and the test implementation. Either the test threshold should be raised to > 0.9 to match the issue, or the issue's acceptance criteria should be formally revised and noted in the PR.

Copilot uses AI. Check for mistakes.
@Steake
Copy link
Copy Markdown
Owner

Steake commented Mar 7, 2026

@copilot apply changes based on the comments in this thread

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 7, 2026

🧪 CI — Python 3.10

�[31mERROR�[0m tests/test_cognitive_subsystem_activation.py::�[1mTestEndToEndFlow::test_context_engine_round_trip�[0m - ModuleNotFoundError: No module named 'requests'
�[31mERROR�[0m tests/test_cognitive_subsystem_activation.py::�[1mTestEndToEndFlow::test_nlg_pipeline_process�[0m - ModuleNotFoundError: No module named 'requests'
�[31m====== �[31m�[1m4 failed�[0m, �[32m956 passed�[0m, �[33m81 skipped�[0m, �[33m65 warnings�[0m, �[31m�[1m22 errors�[0m�[31m in 34.72s�[0m�[31m ======�[0m

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 7, 2026

🧪 CI — Python 3.11

�[31mERROR�[0m tests/test_cognitive_subsystem_activation.py::�[1mTestEndToEndFlow::test_context_engine_round_trip�[0m - ModuleNotFoundError: No module named 'requests'
�[31mERROR�[0m tests/test_cognitive_subsystem_activation.py::�[1mTestEndToEndFlow::test_nlg_pipeline_process�[0m - ModuleNotFoundError: No module named 'requests'
�[31m====== �[31m�[1m4 failed�[0m, �[32m956 passed�[0m, �[33m81 skipped�[0m, �[33m65 warnings�[0m, �[31m�[1m22 errors�[0m�[31m in 37.06s�[0m�[31m ======�[0m

…path in WS test

Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot apply changes based on the comments in this thread

Applied all three changes in commit a4f4393:

  1. Bounded phi storage: Replaced the unbounded phi_history: List[float] with a single _last_phi: float = 0.0 scalar — O(1) memory, no leak in the continuous loop. phi property now returns self._last_phi.

  2. Threshold raised to > 0.9: test_global_broadcast_efficiency now asserts broadcast_success_rate > 0.9 matching issue feat: Implement IIT φ calculator + Global Workspace broadcaster #80's acceptance criterion.

  3. test_ws_payload_contains_phi tests production path: Rewrote to drive the actual engine sequence (IIT φ calculation → GWT broadcast → engine calls broadcast_consciousness_update) rather than constructing the payload in the test itself. A bug in the production payload construction will now cause this test to fail.

@Steake Steake merged commit 55262b4 into main Mar 7, 2026
2 checks passed
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: Implement IIT φ calculator + Global Workspace broadcaster

3 participants