Files
blackroad-operating-system/qlm_lab/ingestion/git.py
Claude e478add607 Add complete QLM (Quantum Language Model) implementation
This commit introduces the QLM system - a stateful semantic layer for
tracking HI (Human Intelligence), AI (Agent Intelligence), and QI
(Quantum/Emergent Intelligence) in BlackRoad OS.

Core Features:
- HI/AI/QI intelligence layer modeling
- Event-driven state management
- QI emergence detection (agent self-correction, feedback loops, etc.)
- HI-AI alignment scoring
- Operator-facing query interface
- Reality ingestion (git, CI, agent logs)

Components Added:
- qlm_lab/models.py: Core data models (Actor, QLMEvent, QIEmergence, etc.)
- qlm_lab/state.py: State management and transition tracking
- qlm_lab/api.py: Public QLMInterface API
- qlm_lab/ingestion/: Git, CI, and agent log connectors
- qlm_lab/experiments/: Alignment and emergence validation
- qlm_lab/visualization.py: Timeline, actor graph, alignment plots
- qlm_lab/demo.py: Interactive demo script
- tests/test_qlm_core.py: Comprehensive test suite
- docs/QLM.md: Complete documentation (concepts, API, integration)

Usage:
  from qlm_lab.api import QLMInterface

  qlm = QLMInterface()
  qlm.record_operator_intent("Build feature X")
  qlm.record_agent_execution("agent-1", "Implement X", "task-1")
  summary = qlm.get_summary(days=7)

Run:
  python -m qlm_lab.demo
  python -m qlm_lab.experiments.alignment_detection
  pytest tests/test_qlm_core.py -v

Integrates with:
- cognitive/intent_graph.py (intent tracking)
- cognitive/agent_coordination.py (multi-agent coordination)
- operator_engine/scheduler.py (background analysis)

Next steps: Integrate with FastAPI backend, add Prism Console UI,
implement Lucidia language runtime.
2025-11-18 08:15:06 +00:00

241 lines
6.8 KiB
Python

"""
Git Connector - Ingest git history into QLM
Converts git commits into QLM events:
- Commits by humans → OPERATOR_INTENT or HI events
- Commits by bots/agents → AGENT_EXECUTION events
- Merge commits → coordination events
"""
import subprocess
import re
from datetime import datetime
from typing import List, Optional, Dict, Any
import logging
from qlm_lab.models import (
QLMEvent,
EventType,
IntelligenceType,
ActorType,
ActorRole,
Actor,
)
from qlm_lab.api import QLMInterface
logger = logging.getLogger(__name__)
class GitConnector:
"""
Connects QLM to git repository history.
Usage:
connector = GitConnector(repo_path="/path/to/repo", qlm=qlm_interface)
events = connector.ingest_recent_commits(days=7)
"""
def __init__(self, repo_path: str, qlm: QLMInterface):
"""
Args:
repo_path: Path to git repository
qlm: QLMInterface instance
"""
self.repo_path = repo_path
self.qlm = qlm
# Patterns to detect agent commits
self.agent_patterns = [
r"^claude/", # Claude branches
r"^copilot/", # Copilot branches
r"^codex/", # Codex branches
r"\[bot\]", # Bot commit messages
r"\[agent\]", # Agent commit messages
]
def is_agent_commit(self, commit_data: Dict[str, str]) -> bool:
"""Determine if a commit was made by an agent"""
# Check author name/email
author = commit_data.get("author", "").lower()
if any(
pattern in author
for pattern in ["bot", "agent", "claude", "copilot", "codex"]
):
return True
# Check branch name
branch = commit_data.get("branch", "")
for pattern in self.agent_patterns:
if re.search(pattern, branch):
return True
# Check commit message
message = commit_data.get("message", "")
if "[agent]" in message.lower() or "[bot]" in message.lower():
return True
return False
def get_git_log(
self, since: Optional[str] = None, until: Optional[str] = None
) -> List[Dict[str, Any]]:
"""
Get git log as structured data.
Args:
since: Start date (e.g., "7 days ago")
until: End date (e.g., "now")
Returns:
List of commit dictionaries
"""
cmd = [
"git",
"-C",
self.repo_path,
"log",
"--pretty=format:%H|%an|%ae|%at|%s|%b",
"--all",
]
if since:
cmd.append(f"--since={since}")
if until:
cmd.append(f"--until={until}")
try:
result = subprocess.run(
cmd, capture_output=True, text=True, check=True, timeout=30
)
commits = []
for line in result.stdout.strip().split("\n"):
if not line:
continue
parts = line.split("|", 5)
if len(parts) < 5:
continue
commit_hash, author_name, author_email, timestamp, subject = parts[:5]
body = parts[5] if len(parts) > 5 else ""
commits.append(
{
"hash": commit_hash,
"author": author_name,
"email": author_email,
"timestamp": int(timestamp),
"subject": subject,
"body": body,
"message": f"{subject}\n{body}".strip(),
}
)
return commits
except subprocess.CalledProcessError as e:
logger.error(f"Git log failed: {e}")
return []
except subprocess.TimeoutExpired:
logger.error("Git log timed out")
return []
def ingest_commit(self, commit: Dict[str, Any]) -> Optional[QLMEvent]:
"""
Ingest a single commit into QLM.
Args:
commit: Commit data from get_git_log()
Returns:
Created QLMEvent or None
"""
is_agent = self.is_agent_commit(commit)
# Determine actor
author = commit["author"]
actor_id = (
f"agent-{author.lower().replace(' ', '-')}"
if is_agent
else f"human-{author.lower().replace(' ', '-')}"
)
# Register actor if not exists
actor_type = ActorType.AGENT if is_agent else ActorType.HUMAN
# Create event
if is_agent:
# Agent commit = AGENT_EXECUTION
event = self.qlm.record_agent_execution(
agent_id=actor_id,
task_description=commit["subject"],
metadata={
"commit_hash": commit["hash"],
"commit_message": commit["message"],
"timestamp": commit["timestamp"],
"author": author,
},
)
else:
# Human commit = OPERATOR_INTENT (assuming commits reflect intent)
event = self.qlm.record_operator_intent(
intent=commit["subject"],
description=commit["body"],
metadata={
"commit_hash": commit["hash"],
"timestamp": commit["timestamp"],
"author": author,
},
)
logger.info(f"Ingested commit: {commit['hash'][:8]} - {commit['subject']}")
return event
def ingest_recent_commits(self, days: int = 7) -> List[QLMEvent]:
"""
Ingest recent commits into QLM.
Args:
days: Number of days to look back
Returns:
List of created QLMEvents
"""
logger.info(f"Ingesting git commits from last {days} days...")
commits = self.get_git_log(since=f"{days} days ago")
events = []
for commit in commits:
event = self.ingest_commit(commit)
if event:
events.append(event)
logger.info(f"Ingested {len(events)} commits")
return events
def ingest_commit_range(
self, since: str, until: Optional[str] = None
) -> List[QLMEvent]:
"""
Ingest commits in a specific range.
Args:
since: Start date (e.g., "2024-01-01")
until: End date (default: now)
Returns:
List of created QLMEvents
"""
commits = self.get_git_log(since=since, until=until)
events = []
for commit in commits:
event = self.ingest_commit(commit)
if event:
events.append(event)
logger.info(f"Ingested {len(events)} commits from {since} to {until or 'now'}")
return events