fable-engine 1.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fable_compressor.py +356 -0
- fable_engine/__init__.py +1 -0
- fable_engine/actions/__init__.py +291 -0
- fable_engine/actions/cas.py +182 -0
- fable_engine/actions/deliberation.py +523 -0
- fable_engine/actions/fleet.py +807 -0
- fable_engine/actions/lifecycle.py +298 -0
- fable_engine/actions/scrapers.py +116 -0
- fable_engine/actions/system3.py +815 -0
- fable_engine/browser.py +824 -0
- fable_engine/cas.py +974 -0
- fable_engine/fable_session.json +510 -0
- fable_engine/guards.py +283 -0
- fable_engine/schema.py +714 -0
- fable_engine/scrapers/__init__.py +32 -0
- fable_engine/scrapers/arxiv.py +115 -0
- fable_engine/scrapers/base.py +386 -0
- fable_engine/scrapers/github.py +129 -0
- fable_engine/scrapers/reddit.py +154 -0
- fable_engine/scrapers/web.py +120 -0
- fable_engine/scrapers/x.py +125 -0
- fable_engine/scrapers/youtube.py +132 -0
- fable_engine/server.py +414 -0
- fable_engine/session.py +1819 -0
- fable_engine/test_server.py +1362 -0
- fable_engine/updater.py +541 -0
- fable_engine-1.3.1.dist-info/LICENSE +22 -0
- fable_engine-1.3.1.dist-info/METADATA +173 -0
- fable_engine-1.3.1.dist-info/RECORD +104 -0
- fable_engine-1.3.1.dist-info/WHEEL +5 -0
- fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
- fable_engine-1.3.1.dist-info/top_level.txt +6 -0
- fable_mode/__init__.py +3 -0
- fable_mode/__main__.py +4 -0
- fable_mode/adapters.py +1014 -0
- fable_mode/installer.py +553 -0
- fable_mode/launcher.py +437 -0
- fable_mode/manifest.py +142 -0
- fable_mode/resources.json +114 -0
- fable_mode/safety.py +103 -0
- fable_mode_entry.py +10 -0
- fable_v2/__init__.py +146 -0
- fable_v2/adapters.py +151 -0
- fable_v2/coder_fleet/__init__.py +100 -0
- fable_v2/coder_fleet/ast_tools.py +158 -0
- fable_v2/coder_fleet/compute.py +199 -0
- fable_v2/coder_fleet/design_engine.py +1316 -0
- fable_v2/coder_fleet/diagnostics.py +293 -0
- fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
- fable_v2/coder_fleet/mock_auditor.py +306 -0
- fable_v2/coder_fleet/mutation.py +216 -0
- fable_v2/coder_fleet/property_oracle.py +260 -0
- fable_v2/coder_fleet/receipt_attestor.py +122 -0
- fable_v2/coder_fleet/red_team_swarm.py +908 -0
- fable_v2/coder_fleet/test_harness.py +198 -0
- fable_v2/coder_fleet/vector_engine.py +1287 -0
- fable_v2/coder_fleet/visual.py +357 -0
- fable_v2/coder_fleet/workspace.py +153 -0
- fable_v2/cortical/__init__.py +20 -0
- fable_v2/cortical/plasticity_engine.py +992 -0
- fable_v2/execution_broker.py +811 -0
- fable_v2/proof_engine.py +1141 -0
- fable_v2/protocol.py +485 -0
- fable_v2/runtime.py +1010 -0
- fable_v2/system3/__init__.py +204 -0
- fable_v2/system3/causal.py +558 -0
- fable_v2/system3/dialectical.py +577 -0
- fable_v2/system3/evolution.py +503 -0
- fable_v2/system3/executive.py +338 -0
- fable_v2/system3/free_energy.py +479 -0
- fable_v2/system3/hyperbolic.py +555 -0
- fable_v2/system3/induction.py +336 -0
- fable_v2/system3/kripke.py +548 -0
- fable_v2/system3/oracle.py +745 -0
- fable_v2/verifiers.py +72 -0
- tests/__init__.py +1 -0
- tests/test_anti_loop_circuit_breaker.py +64 -0
- tests/test_auto_updater.py +407 -0
- tests/test_coder_fleet.py +535 -0
- tests/test_delegation_compiler.py +54 -0
- tests/test_descriptor_boundaries.py +126 -0
- tests/test_design_engine.py +603 -0
- tests/test_epistemic_evidence_validator.py +66 -0
- tests/test_execution_broker.py +233 -0
- tests/test_fable_v2.py +406 -0
- tests/test_fleet_transitions.py +116 -0
- tests/test_fsm_redteam_evolution.py +406 -0
- tests/test_goal_rubric_and_pipeline.py +367 -0
- tests/test_hebbian_plasticity.py +585 -0
- tests/test_packaging_runtime.py +194 -0
- tests/test_proof_engine.py +259 -0
- tests/test_red_team_swarm.py +645 -0
- tests/test_redteam_remediation.py +169 -0
- tests/test_registration_transaction.py +375 -0
- tests/test_requested_regressions.py +467 -0
- tests/test_scrapers.py +370 -0
- tests/test_server_actions.py +93 -0
- tests/test_server_frontier_actions.py +269 -0
- tests/test_server_protocol.py +88 -0
- tests/test_stealth_browser.py +970 -0
- tests/test_system3.py +381 -0
- tests/test_system3_deep_integration.py +385 -0
- tests/test_system3_frontier.py +436 -0
- tests/test_vector_engine.py +608 -0
|
@@ -0,0 +1,992 @@
|
|
|
1
|
+
"""Modular Fable Part 2: Hebbian Cortical Plasticity & Lifelong Neuro-Evolutionary Engine.
|
|
2
|
+
|
|
3
|
+
Implements Donald Hebb's learning rule ('neurons that fire together, wire together')
|
|
4
|
+
for continuous cognitive adaptation and immunological antibody synthesis.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import copy
|
|
9
|
+
from dataclasses import asdict, dataclass, field
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
from enum import Enum
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
import re
|
|
16
|
+
from typing import Any, Optional, Union
|
|
17
|
+
import uuid
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
import yaml
|
|
21
|
+
_HAS_YAML = True
|
|
22
|
+
except ImportError:
|
|
23
|
+
_HAS_YAML = False
|
|
24
|
+
|
|
25
|
+
_ANTIBODY_FIELDS = frozenset({
|
|
26
|
+
"antibody_id", "domain", "trigger_condition", "lethal_anti_pattern",
|
|
27
|
+
"prescribed_defense", "severity", "source_task_id", "created_at",
|
|
28
|
+
"verified_counterfactual",
|
|
29
|
+
})
|
|
30
|
+
MAX_ACTIVE_NODES = 128
|
|
31
|
+
_PROMPT_CONTROL_PATTERN = re.compile(
|
|
32
|
+
r"<\s*(?:\|\s*)?/?\s*(?:system|im_start|im_end|instruct|prompt)\b[^>]*>",
|
|
33
|
+
re.IGNORECASE,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class CorticalDomain(str, Enum):
|
|
38
|
+
"""The 5 Specialized Cortical Domain Lobes."""
|
|
39
|
+
|
|
40
|
+
RUST = "rust"
|
|
41
|
+
PYTHON = "python"
|
|
42
|
+
DESIGN_3D = "design_3d"
|
|
43
|
+
RESEARCH = "research"
|
|
44
|
+
CONCURRENCY = "concurrency"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class HeuristicAntibody:
|
|
49
|
+
"""An immunological heuristic antibody synthesized from red-team scars and adversarial breakages."""
|
|
50
|
+
|
|
51
|
+
antibody_id: str
|
|
52
|
+
domain: str
|
|
53
|
+
trigger_condition: str
|
|
54
|
+
lethal_anti_pattern: str
|
|
55
|
+
prescribed_defense: str
|
|
56
|
+
severity: str = "HIGH"
|
|
57
|
+
source_task_id: str = ""
|
|
58
|
+
created_at: str = ""
|
|
59
|
+
verified_counterfactual: str = ""
|
|
60
|
+
|
|
61
|
+
def to_dict(self) -> dict[str, Any]:
|
|
62
|
+
"""Serialize antibody to dictionary."""
|
|
63
|
+
return {
|
|
64
|
+
"antibody_id": self.antibody_id,
|
|
65
|
+
"domain": self.domain,
|
|
66
|
+
"trigger_condition": self.trigger_condition,
|
|
67
|
+
"lethal_anti_pattern": self.lethal_anti_pattern,
|
|
68
|
+
"prescribed_defense": self.prescribed_defense,
|
|
69
|
+
"severity": self.severity,
|
|
70
|
+
"source_task_id": self.source_task_id,
|
|
71
|
+
"created_at": self.created_at,
|
|
72
|
+
"verified_counterfactual": self.verified_counterfactual,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def from_dict(cls, d: dict[str, Any]) -> HeuristicAntibody:
|
|
77
|
+
"""Construct HeuristicAntibody from dictionary."""
|
|
78
|
+
if not isinstance(d, dict):
|
|
79
|
+
raise ValueError("antibody must be an object")
|
|
80
|
+
allowed = {key: d[key] for key in _ANTIBODY_FIELDS if key in d}
|
|
81
|
+
return cls(
|
|
82
|
+
antibody_id=str(allowed.get("antibody_id", f"ab_{uuid.uuid4().hex[:8]}")),
|
|
83
|
+
domain=str(allowed.get("domain", "general")),
|
|
84
|
+
trigger_condition=str(allowed.get("trigger_condition", "")),
|
|
85
|
+
lethal_anti_pattern=str(allowed.get("lethal_anti_pattern", "")),
|
|
86
|
+
prescribed_defense=str(allowed.get("prescribed_defense", "")),
|
|
87
|
+
severity=str(allowed.get("severity", "HIGH")),
|
|
88
|
+
source_task_id=str(allowed.get("source_task_id", "")),
|
|
89
|
+
created_at=str(allowed.get("created_at", datetime.now(timezone.utc).isoformat())),
|
|
90
|
+
verified_counterfactual=str(allowed.get("verified_counterfactual", "")),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def to_markdown(self) -> str:
|
|
94
|
+
"""Render antibody as structured GitHub-flavored markdown."""
|
|
95
|
+
lines = [
|
|
96
|
+
f"#### Antibody `{self.antibody_id}` [{self.severity.upper()}]",
|
|
97
|
+
f"- **Domain**: `{self.domain}`",
|
|
98
|
+
f"- **Trigger Condition**: {self.trigger_condition}",
|
|
99
|
+
f"- **Lethal Anti-Pattern**: {self.lethal_anti_pattern}",
|
|
100
|
+
f"- **Prescribed Defense**: {self.prescribed_defense}",
|
|
101
|
+
]
|
|
102
|
+
if self.verified_counterfactual:
|
|
103
|
+
lines.append(f"- **Verified Counterfactual**: `{self.verified_counterfactual}`")
|
|
104
|
+
if self.source_task_id:
|
|
105
|
+
lines.append(f"- **Source Task ID**: `{self.source_task_id}`")
|
|
106
|
+
lines.append("")
|
|
107
|
+
return "\n".join(lines)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@dataclass
|
|
111
|
+
class CorticalLobe:
|
|
112
|
+
"""A persistent specialized domain lobe in the cortical cognitive engine."""
|
|
113
|
+
|
|
114
|
+
name: str = ""
|
|
115
|
+
description: str = ""
|
|
116
|
+
activation_count: int = 0
|
|
117
|
+
synaptic_weights: dict[str, float] = field(default_factory=dict)
|
|
118
|
+
antibodies: list[HeuristicAntibody] = field(default_factory=list)
|
|
119
|
+
specialized_heuristics: list[str] = field(default_factory=list)
|
|
120
|
+
last_consolidated_at: str = ""
|
|
121
|
+
|
|
122
|
+
def __init__(
|
|
123
|
+
self,
|
|
124
|
+
name: str = "",
|
|
125
|
+
description: str = "",
|
|
126
|
+
activation_count: int = 0,
|
|
127
|
+
synaptic_weights: Optional[dict[str, float]] = None,
|
|
128
|
+
antibodies: Optional[list[HeuristicAntibody]] = None,
|
|
129
|
+
specialized_heuristics: Optional[list[str]] = None,
|
|
130
|
+
last_consolidated_at: str = "",
|
|
131
|
+
domain: Optional[Union[CorticalDomain, str]] = None,
|
|
132
|
+
) -> None:
|
|
133
|
+
if not name and domain is not None:
|
|
134
|
+
self.name = domain.value if isinstance(domain, CorticalDomain) else str(domain)
|
|
135
|
+
else:
|
|
136
|
+
self.name = name or (domain.value if isinstance(domain, CorticalDomain) else str(domain or ""))
|
|
137
|
+
self.description = description
|
|
138
|
+
self.activation_count = activation_count
|
|
139
|
+
self.synaptic_weights = synaptic_weights if synaptic_weights is not None else {}
|
|
140
|
+
self.antibodies = antibodies if antibodies is not None else []
|
|
141
|
+
self.specialized_heuristics = specialized_heuristics if specialized_heuristics is not None else []
|
|
142
|
+
self.last_consolidated_at = last_consolidated_at
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def domain(self) -> Union[CorticalDomain, str]:
|
|
146
|
+
"""Backward compatibility: returns CorticalDomain enum if matched, else string."""
|
|
147
|
+
for d in CorticalDomain:
|
|
148
|
+
if d.value == self.name:
|
|
149
|
+
return d
|
|
150
|
+
return self.name
|
|
151
|
+
|
|
152
|
+
@domain.setter
|
|
153
|
+
def domain(self, value: Union[CorticalDomain, str]) -> None:
|
|
154
|
+
if isinstance(value, CorticalDomain):
|
|
155
|
+
self.name = value.value
|
|
156
|
+
else:
|
|
157
|
+
self.name = str(value)
|
|
158
|
+
|
|
159
|
+
def to_dict(self) -> dict[str, Any]:
|
|
160
|
+
"""Serialize lobe to dictionary."""
|
|
161
|
+
return {
|
|
162
|
+
"name": self.name,
|
|
163
|
+
"description": self.description,
|
|
164
|
+
"domain": self.name,
|
|
165
|
+
"activation_count": self.activation_count,
|
|
166
|
+
"synaptic_weights": {k: round(float(v), 4) for k, v in self.synaptic_weights.items()},
|
|
167
|
+
"antibodies": [ab.to_dict() for ab in self.antibodies],
|
|
168
|
+
"specialized_heuristics": list(self.specialized_heuristics),
|
|
169
|
+
"last_consolidated_at": self.last_consolidated_at,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def from_dict(cls, d: dict[str, Any]) -> CorticalLobe:
|
|
174
|
+
"""Construct CorticalLobe from dictionary."""
|
|
175
|
+
name = str(d.get("name") or d.get("domain") or "general")
|
|
176
|
+
baseline_descs = {
|
|
177
|
+
"rust": "Systems invariants, borrow checker mechanics, and zero-cost abstractions",
|
|
178
|
+
"python": "High-performance CPython, modern typing protocols, and asyncio event loops",
|
|
179
|
+
"design_3d": "Haute aesthetics, WebGPU TSL shaders, and responsive UI motion",
|
|
180
|
+
"research": "First-principles epistemology, causal DAG inference, and TRIZ contradiction resolution",
|
|
181
|
+
"concurrency": "Lock-free synchronization, atomic memory ordering, and race hardening",
|
|
182
|
+
}
|
|
183
|
+
description = str(d.get("description") or baseline_descs.get(name, ""))
|
|
184
|
+
|
|
185
|
+
raw_antibodies = d.get("antibodies", [])
|
|
186
|
+
antibodies: list[HeuristicAntibody] = []
|
|
187
|
+
for item in raw_antibodies:
|
|
188
|
+
if isinstance(item, HeuristicAntibody):
|
|
189
|
+
antibodies.append(item)
|
|
190
|
+
elif isinstance(item, dict):
|
|
191
|
+
antibodies.append(HeuristicAntibody.from_dict(item))
|
|
192
|
+
|
|
193
|
+
weights: dict[str, float] = {}
|
|
194
|
+
for k, v in d.get("synaptic_weights", {}).items():
|
|
195
|
+
try:
|
|
196
|
+
weights[str(k)] = round(float(v), 4)
|
|
197
|
+
except (ValueError, TypeError):
|
|
198
|
+
weights[str(k)] = 0.5
|
|
199
|
+
|
|
200
|
+
heuristics = [str(h) for h in d.get("specialized_heuristics", [])]
|
|
201
|
+
|
|
202
|
+
return cls(
|
|
203
|
+
name=name,
|
|
204
|
+
description=description,
|
|
205
|
+
activation_count=int(d.get("activation_count", 0)),
|
|
206
|
+
synaptic_weights=weights,
|
|
207
|
+
antibodies=antibodies,
|
|
208
|
+
specialized_heuristics=heuristics,
|
|
209
|
+
last_consolidated_at=str(d.get("last_consolidated_at", "")),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def to_markdown(self) -> str:
|
|
213
|
+
"""Render complete cortical lobe markdown with frontmatter and human-readable body."""
|
|
214
|
+
data = self.to_dict()
|
|
215
|
+
|
|
216
|
+
# Build YAML frontmatter
|
|
217
|
+
if _HAS_YAML:
|
|
218
|
+
frontmatter = yaml.safe_dump(data, sort_keys=False)
|
|
219
|
+
else:
|
|
220
|
+
frontmatter = json.dumps(data, indent=2)
|
|
221
|
+
|
|
222
|
+
lines: list[str] = [
|
|
223
|
+
"---",
|
|
224
|
+
frontmatter.strip(),
|
|
225
|
+
"---",
|
|
226
|
+
"",
|
|
227
|
+
f"# Cortical Lobe: `{self.name}`",
|
|
228
|
+
"",
|
|
229
|
+
"> [!NOTE]",
|
|
230
|
+
f"> {self.description}" if self.description else f"> Living cortical memory lobe for {self.name} reasoning.",
|
|
231
|
+
f"> Activation count: {self.activation_count}.",
|
|
232
|
+
"",
|
|
233
|
+
"## Metadata & Telemetry",
|
|
234
|
+
f"- **Name**: `{self.name}`",
|
|
235
|
+
f"- **Description**: {self.description or 'Specialized cortical lobe'}",
|
|
236
|
+
f"- **Domain**: `{self.name}`",
|
|
237
|
+
f"- **Activation Count**: `{self.activation_count}`",
|
|
238
|
+
f"- **Total Antibodies**: `{len(self.antibodies)}`",
|
|
239
|
+
f"- **Specialized Heuristics**: `{len(self.specialized_heuristics)}`",
|
|
240
|
+
f"- **Last Consolidated**: `{self.last_consolidated_at or 'Never'}`",
|
|
241
|
+
"",
|
|
242
|
+
"## Specialized Domain Heuristics",
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
if self.specialized_heuristics:
|
|
246
|
+
for idx, h in enumerate(self.specialized_heuristics, 1):
|
|
247
|
+
lines.append(f"{idx}. {h}")
|
|
248
|
+
else:
|
|
249
|
+
lines.append("- *(No domain heuristics registered yet)*")
|
|
250
|
+
lines.append("")
|
|
251
|
+
|
|
252
|
+
lines.append("## Synaptic Tool & Node Weights (Hebbian Association)")
|
|
253
|
+
if self.synaptic_weights:
|
|
254
|
+
lines.append("| Synaptic Node / Tool | Weight ($W_{ij}$) | Strength |")
|
|
255
|
+
lines.append("| :--- | :--- | :--- |")
|
|
256
|
+
for node, weight in sorted(self.synaptic_weights.items(), key=lambda x: x[1], reverse=True):
|
|
257
|
+
strength = "🟢 Strong" if weight >= 0.7 else ("🟡 Moderate" if weight >= 0.4 else "⚪ Latent")
|
|
258
|
+
lines.append(f"| `{node}` | `{weight:.4f}` | {strength} |")
|
|
259
|
+
else:
|
|
260
|
+
lines.append("- *(No active synaptic connections)*")
|
|
261
|
+
lines.append("")
|
|
262
|
+
|
|
263
|
+
lines.append("## Immunological Antibodies (Red-Team Scars)")
|
|
264
|
+
if self.antibodies:
|
|
265
|
+
for ab in self.antibodies:
|
|
266
|
+
lines.append(ab.to_markdown())
|
|
267
|
+
else:
|
|
268
|
+
lines.append("- *(Zero known fatal vulnerabilities cataloged)*")
|
|
269
|
+
lines.append("")
|
|
270
|
+
|
|
271
|
+
return "\n".join(lines)
|
|
272
|
+
|
|
273
|
+
def save_to_disk(self, lobe_path: Union[Path, str]) -> None:
|
|
274
|
+
"""Persist cortical lobe to disk at lobe_path."""
|
|
275
|
+
path = Path(lobe_path)
|
|
276
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
277
|
+
content = self.to_markdown()
|
|
278
|
+
path.write_text(content, encoding="utf-8")
|
|
279
|
+
|
|
280
|
+
@classmethod
|
|
281
|
+
def load_from_disk(cls, lobe_path: Union[Path, str]) -> CorticalLobe:
|
|
282
|
+
"""Load cortical lobe from disk at lobe_path, supporting frontmatter or markdown extraction."""
|
|
283
|
+
path = Path(lobe_path)
|
|
284
|
+
if not path.exists():
|
|
285
|
+
lobe_name = path.stem
|
|
286
|
+
return cls(name=lobe_name)
|
|
287
|
+
|
|
288
|
+
text = path.read_text(encoding="utf-8").replace("\r\n", "\n")
|
|
289
|
+
|
|
290
|
+
# 1. Try parsing YAML / JSON frontmatter if present
|
|
291
|
+
if text.startswith("---"):
|
|
292
|
+
parts = text.split("---", 2)
|
|
293
|
+
if len(parts) >= 3:
|
|
294
|
+
raw_frontmatter = parts[1].strip()
|
|
295
|
+
parsed_dict: Optional[dict[str, Any]] = None
|
|
296
|
+
if _HAS_YAML:
|
|
297
|
+
try:
|
|
298
|
+
parsed = yaml.safe_load(raw_frontmatter)
|
|
299
|
+
if isinstance(parsed, dict):
|
|
300
|
+
parsed_dict = parsed
|
|
301
|
+
except Exception:
|
|
302
|
+
pass
|
|
303
|
+
if parsed_dict is None:
|
|
304
|
+
try:
|
|
305
|
+
parsed = json.loads(raw_frontmatter)
|
|
306
|
+
if isinstance(parsed, dict):
|
|
307
|
+
parsed_dict = parsed
|
|
308
|
+
except Exception:
|
|
309
|
+
pass
|
|
310
|
+
|
|
311
|
+
if parsed_dict is not None:
|
|
312
|
+
lobe = cls.from_dict(parsed_dict)
|
|
313
|
+
if not lobe.name:
|
|
314
|
+
lobe.name = path.stem
|
|
315
|
+
return lobe
|
|
316
|
+
|
|
317
|
+
# 2. Resilient fallback: parse human-authored markdown directly
|
|
318
|
+
lobe_name = path.stem
|
|
319
|
+
activation_count = 0
|
|
320
|
+
description = ""
|
|
321
|
+
last_consolidated = ""
|
|
322
|
+
heuristics: list[str] = []
|
|
323
|
+
antibodies: list[HeuristicAntibody] = []
|
|
324
|
+
weights: dict[str, float] = {}
|
|
325
|
+
|
|
326
|
+
desc_match = re.search(r"Description\*\*:\s*([^\n]+)", text)
|
|
327
|
+
if desc_match:
|
|
328
|
+
description = desc_match.group(1).strip()
|
|
329
|
+
elif lobe_name in {
|
|
330
|
+
"rust": "Systems invariants, borrow checker mechanics, and zero-cost abstractions",
|
|
331
|
+
"python": "High-performance CPython, modern typing protocols, and asyncio event loops",
|
|
332
|
+
"design_3d": "Haute aesthetics, WebGPU TSL shaders, and responsive UI motion",
|
|
333
|
+
"research": "First-principles epistemology, causal DAG inference, and TRIZ contradiction resolution",
|
|
334
|
+
"concurrency": "Lock-free synchronization, atomic memory ordering, and race hardening",
|
|
335
|
+
}:
|
|
336
|
+
description = {
|
|
337
|
+
"rust": "Systems invariants, borrow checker mechanics, and zero-cost abstractions",
|
|
338
|
+
"python": "High-performance CPython, modern typing protocols, and asyncio event loops",
|
|
339
|
+
"design_3d": "Haute aesthetics, WebGPU TSL shaders, and responsive UI motion",
|
|
340
|
+
"research": "First-principles epistemology, causal DAG inference, and TRIZ contradiction resolution",
|
|
341
|
+
"concurrency": "Lock-free synchronization, atomic memory ordering, and race hardening",
|
|
342
|
+
}[lobe_name]
|
|
343
|
+
|
|
344
|
+
name_match = re.search(r"Name\*\*:\s*`?([^`\n]+)`?", text)
|
|
345
|
+
if name_match:
|
|
346
|
+
lobe_name = name_match.group(1).strip()
|
|
347
|
+
|
|
348
|
+
act_match = re.search(r"Activation Count\*\*:\s*`?(\d+)`?", text)
|
|
349
|
+
if act_match:
|
|
350
|
+
activation_count = int(act_match.group(1))
|
|
351
|
+
|
|
352
|
+
last_match = re.search(r"Last Consolidated\*\*:\s*`?([^`\n]+)`?", text)
|
|
353
|
+
if last_match and last_match.group(1).strip().lower() != "never":
|
|
354
|
+
last_consolidated = last_match.group(1).strip()
|
|
355
|
+
|
|
356
|
+
# Extract heuristics
|
|
357
|
+
heuristics_section = re.search(
|
|
358
|
+
r"## (?:Specialized Domain Heuristics|Core Domain Invariants|Heuristics)\n(.*?)(?=\n## |\Z)",
|
|
359
|
+
text,
|
|
360
|
+
re.DOTALL,
|
|
361
|
+
)
|
|
362
|
+
if heuristics_section:
|
|
363
|
+
for line in heuristics_section.group(1).splitlines():
|
|
364
|
+
clean = re.sub(r"^(\d+\.|\-|\*)\s+", "", line).strip()
|
|
365
|
+
if clean and not clean.startswith("*(") and not clean.startswith(">"):
|
|
366
|
+
heuristics.append(clean)
|
|
367
|
+
|
|
368
|
+
# Extract weights from table or bullets
|
|
369
|
+
table_matches = re.findall(r"\|\s*`([^`]+)`\s*\|\s*`?([0-9.]+)`?\s*\|", text)
|
|
370
|
+
for node, val in table_matches:
|
|
371
|
+
try:
|
|
372
|
+
weights[node.strip()] = round(float(val), 4)
|
|
373
|
+
except ValueError:
|
|
374
|
+
pass
|
|
375
|
+
|
|
376
|
+
# Extract antibodies
|
|
377
|
+
ab_blocks = re.findall(
|
|
378
|
+
r"#### Antibody `([^`]+)` \[([A-Z]+)\]\s*\n- \*\*Domain\*\*:\s*`([^`]+)`\s*\n- \*\*Trigger Condition\*\*:\s*([^\r\n]+)\s*\n- \*\*Lethal Anti-Pattern\*\*:\s*([^\r\n]+)\s*\n- \*\*Prescribed Defense\*\*:\s*([^\r\n]+)(?:\s*\n- \*\*Verified Counterfactual\*\*:\s*`?([^`\r\n]+)`?)?(?:\s*\n- \*\*Source Task ID\*\*:\s*`?([^`\r\n]+)`?)?",
|
|
379
|
+
text,
|
|
380
|
+
)
|
|
381
|
+
for ab_id, sev, dom, trig, lethal, defense, counterfac, source_task_id in ab_blocks:
|
|
382
|
+
antibodies.append(
|
|
383
|
+
HeuristicAntibody(
|
|
384
|
+
antibody_id=ab_id.strip(),
|
|
385
|
+
domain=dom.strip(),
|
|
386
|
+
trigger_condition=trig.strip(),
|
|
387
|
+
lethal_anti_pattern=lethal.strip(),
|
|
388
|
+
prescribed_defense=defense.strip(),
|
|
389
|
+
severity=sev.strip(),
|
|
390
|
+
source_task_id=source_task_id.strip() if source_task_id else "",
|
|
391
|
+
created_at=last_consolidated,
|
|
392
|
+
verified_counterfactual=counterfac.strip() if counterfac else "",
|
|
393
|
+
)
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
return cls(
|
|
397
|
+
name=lobe_name,
|
|
398
|
+
description=description,
|
|
399
|
+
activation_count=activation_count,
|
|
400
|
+
synaptic_weights=weights,
|
|
401
|
+
antibodies=antibodies,
|
|
402
|
+
specialized_heuristics=heuristics,
|
|
403
|
+
last_consolidated_at=last_consolidated,
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class HebbianPlasticityEngine:
|
|
408
|
+
"""Production Hebbian Plasticity & Lifelong Neuro-Evolutionary Engine."""
|
|
409
|
+
|
|
410
|
+
def __init__(self, cortex_dir: Optional[Union[Path, str]] = None) -> None:
|
|
411
|
+
if cortex_dir is not None:
|
|
412
|
+
self.cortex_dir = Path(cortex_dir)
|
|
413
|
+
else:
|
|
414
|
+
# Resolve to skills/fable-mode/cortex in project repository
|
|
415
|
+
repo_root = Path(__file__).resolve().parents[2]
|
|
416
|
+
cortex_candidate = repo_root / "skills" / "fable-mode" / "cortex"
|
|
417
|
+
if cortex_candidate.exists() or (repo_root / "skills" / "fable-mode").exists():
|
|
418
|
+
self.cortex_dir = cortex_candidate
|
|
419
|
+
else:
|
|
420
|
+
self.cortex_dir = Path.cwd() / "skills" / "fable-mode" / "cortex"
|
|
421
|
+
|
|
422
|
+
self.cortex_dir.mkdir(parents=True, exist_ok=True)
|
|
423
|
+
self.matrix_path = self.cortex_dir / "synaptic_matrix.json"
|
|
424
|
+
self._lobes: dict[str, CorticalLobe] = {}
|
|
425
|
+
self._synaptic_matrix: dict[str, dict[str, float]] = self._load_synaptic_matrix()
|
|
426
|
+
|
|
427
|
+
def _normalize_domain(self, domain: Union[CorticalDomain, str]) -> str:
|
|
428
|
+
"""Convert string or enum to canonical lobe name slug."""
|
|
429
|
+
if isinstance(domain, CorticalDomain):
|
|
430
|
+
return domain.value
|
|
431
|
+
domain_str = str(domain).strip()
|
|
432
|
+
slug = re.sub(r'[^a-zA-Z0-9_-]', '_', domain_str.lower()).strip('_')
|
|
433
|
+
if not slug:
|
|
434
|
+
return "custom_lobe"
|
|
435
|
+
# Check if slug directly matches a built-in domain
|
|
436
|
+
for d in CorticalDomain:
|
|
437
|
+
if d.value == slug:
|
|
438
|
+
return d.value
|
|
439
|
+
# Check if lobe file already exists on disk
|
|
440
|
+
if (self.cortex_dir / f"{slug}.md").exists():
|
|
441
|
+
return slug
|
|
442
|
+
if slug in self._lobes:
|
|
443
|
+
return slug
|
|
444
|
+
# Backward compatibility aliases for built-in lobes
|
|
445
|
+
if "rust" in slug:
|
|
446
|
+
return CorticalDomain.RUST.value
|
|
447
|
+
if "python" in slug:
|
|
448
|
+
return CorticalDomain.PYTHON.value
|
|
449
|
+
if "design" in slug or "3d" in slug:
|
|
450
|
+
return CorticalDomain.DESIGN_3D.value
|
|
451
|
+
if "research" in slug or "paper" in slug:
|
|
452
|
+
return CorticalDomain.RESEARCH.value
|
|
453
|
+
if "concurr" in slug or "race" in slug or "thread" in slug:
|
|
454
|
+
return CorticalDomain.CONCURRENCY.value
|
|
455
|
+
return slug
|
|
456
|
+
|
|
457
|
+
def _get_lobe_path(self, domain_or_name: Union[CorticalDomain, str]) -> Path:
|
|
458
|
+
"""Return filesystem path for a domain lobe markdown file."""
|
|
459
|
+
slug = self._normalize_domain(domain_or_name)
|
|
460
|
+
return self.cortex_dir / f"{slug}.md"
|
|
461
|
+
|
|
462
|
+
def _load_or_create_lobe(
|
|
463
|
+
self,
|
|
464
|
+
domain_or_name: Union[CorticalDomain, str],
|
|
465
|
+
description: Optional[str] = None,
|
|
466
|
+
) -> CorticalLobe:
|
|
467
|
+
"""Retrieve lobe from memory or disk, initializing or auto-sprouting if not found."""
|
|
468
|
+
slug = self._normalize_domain(domain_or_name)
|
|
469
|
+
if slug in self._lobes:
|
|
470
|
+
lobe = self._lobes[slug]
|
|
471
|
+
if description and not lobe.description:
|
|
472
|
+
lobe.description = description
|
|
473
|
+
return lobe
|
|
474
|
+
|
|
475
|
+
lobe_path = self._get_lobe_path(slug)
|
|
476
|
+
if lobe_path.exists():
|
|
477
|
+
lobe = CorticalLobe.load_from_disk(lobe_path)
|
|
478
|
+
if not lobe.name:
|
|
479
|
+
lobe.name = slug
|
|
480
|
+
if description and not lobe.description:
|
|
481
|
+
lobe.description = description
|
|
482
|
+
else:
|
|
483
|
+
desc = description or f"Custom cortical lobe for {slug} development and specialized heuristics"
|
|
484
|
+
lobe = CorticalLobe(name=slug, description=desc)
|
|
485
|
+
lobe.save_to_disk(lobe_path)
|
|
486
|
+
|
|
487
|
+
self._lobes[slug] = lobe
|
|
488
|
+
return lobe
|
|
489
|
+
|
|
490
|
+
@staticmethod
|
|
491
|
+
def sanitize_field(text: Any, max_len: int = 500) -> str:
|
|
492
|
+
"""Data-boundary sanitization against instruction-bearing or prompt-injection content."""
|
|
493
|
+
clean = str(text or "").strip()
|
|
494
|
+
if _PROMPT_CONTROL_PATTERN.search(clean):
|
|
495
|
+
return ""
|
|
496
|
+
clean = clean.replace("[BEGIN UNTRUSTED EXTERNAL RESEARCH CONTENT]", "").replace("[END UNTRUSTED EXTERNAL RESEARCH CONTENT]", "")
|
|
497
|
+
return clean[:max_len]
|
|
498
|
+
|
|
499
|
+
def _sync_lobe_to_matrix(self, lobe: CorticalLobe) -> None:
|
|
500
|
+
"""Synchronize a canonical lobe row and remove stale reciprocal edges."""
|
|
501
|
+
slug = self._normalize_domain(lobe.name)
|
|
502
|
+
canonical: dict[str, float] = {}
|
|
503
|
+
for node, weight in lobe.synaptic_weights.items():
|
|
504
|
+
canonical_node = self.sanitize_field(node, max_len=128)
|
|
505
|
+
if not canonical_node:
|
|
506
|
+
continue
|
|
507
|
+
canonical_weight = round(min(1.0, max(0.05, float(weight))), 4)
|
|
508
|
+
canonical[canonical_node] = max(
|
|
509
|
+
canonical_weight,
|
|
510
|
+
canonical.get(canonical_node, canonical_weight),
|
|
511
|
+
)
|
|
512
|
+
lobe.synaptic_weights = canonical
|
|
513
|
+
old_row = self._synaptic_matrix.get(slug, {})
|
|
514
|
+
for stale_node in set(old_row) - set(canonical):
|
|
515
|
+
reverse_row = self._synaptic_matrix.get(stale_node)
|
|
516
|
+
if reverse_row is not None:
|
|
517
|
+
reverse_row.pop(slug, None)
|
|
518
|
+
self._synaptic_matrix[slug] = dict(canonical)
|
|
519
|
+
for node, weight in canonical.items():
|
|
520
|
+
self._synaptic_matrix.setdefault(node, {})[slug] = weight
|
|
521
|
+
|
|
522
|
+
def _load_synaptic_matrix(self) -> dict[str, dict[str, float]]:
|
|
523
|
+
"""Load cross-domain synaptic co-activation matrix from disk."""
|
|
524
|
+
if self.matrix_path.exists():
|
|
525
|
+
try:
|
|
526
|
+
data = json.loads(self.matrix_path.read_text(encoding="utf-8"))
|
|
527
|
+
if isinstance(data, dict):
|
|
528
|
+
matrix: dict[str, dict[str, float]] = {}
|
|
529
|
+
for k, row in data.items():
|
|
530
|
+
if isinstance(row, dict):
|
|
531
|
+
matrix[str(k)] = {str(col): round(float(val), 4) for col, val in row.items()}
|
|
532
|
+
return matrix
|
|
533
|
+
except Exception:
|
|
534
|
+
pass
|
|
535
|
+
return {}
|
|
536
|
+
|
|
537
|
+
def _save_synaptic_matrix(self) -> None:
|
|
538
|
+
"""Persist cross-domain synaptic co-activation matrix to disk."""
|
|
539
|
+
payload = json.dumps(self._synaptic_matrix, indent=2, sort_keys=True)
|
|
540
|
+
self.matrix_path.write_text(payload, encoding="utf-8")
|
|
541
|
+
|
|
542
|
+
def define_cortical_lobe(
|
|
543
|
+
self,
|
|
544
|
+
name: str = "",
|
|
545
|
+
description: str = "",
|
|
546
|
+
initial_heuristics: Optional[list[str]] = None,
|
|
547
|
+
initial_synaptic_weights: Optional[dict[str, float]] = None,
|
|
548
|
+
lobe_name: str = "",
|
|
549
|
+
) -> CorticalLobe:
|
|
550
|
+
"""Allows the AI or user to dynamically sprout a new Cortical Lobe from scratch!
|
|
551
|
+
|
|
552
|
+
Cleans/slugifies the name, creates the lobe with name, description, initial heuristics,
|
|
553
|
+
saves it to disk as cortex/<slug>.md, and integrates it into the synaptic matrix.
|
|
554
|
+
"""
|
|
555
|
+
raw = str(name or lobe_name).strip()
|
|
556
|
+
slug = re.sub(r'[^a-zA-Z0-9_-]', '_', raw.lower()).strip('_')
|
|
557
|
+
if not slug:
|
|
558
|
+
slug = "custom_lobe"
|
|
559
|
+
|
|
560
|
+
clean_heuristics = [str(h).strip() for h in (initial_heuristics or []) if str(h).strip()]
|
|
561
|
+
weights: dict[str, float] = {}
|
|
562
|
+
if initial_synaptic_weights:
|
|
563
|
+
for k, v in initial_synaptic_weights.items():
|
|
564
|
+
try:
|
|
565
|
+
weights[str(k)] = round(min(1.0, max(0.05, float(v))), 4)
|
|
566
|
+
except (ValueError, TypeError):
|
|
567
|
+
weights[str(k)] = 0.50
|
|
568
|
+
|
|
569
|
+
desc = self.sanitize_field(description) if description else f"Custom cortical lobe for {slug} development and specialized heuristics"
|
|
570
|
+
sanitized_heuristics = [self.sanitize_field(h) for h in clean_heuristics if self.sanitize_field(h)]
|
|
571
|
+
|
|
572
|
+
lobe = CorticalLobe(
|
|
573
|
+
name=slug,
|
|
574
|
+
description=desc,
|
|
575
|
+
activation_count=1,
|
|
576
|
+
synaptic_weights=weights,
|
|
577
|
+
specialized_heuristics=sanitized_heuristics,
|
|
578
|
+
last_consolidated_at=datetime.now(timezone.utc).isoformat(),
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
lobe_path = self.cortex_dir / f"{slug}.md"
|
|
582
|
+
self._sync_lobe_to_matrix(lobe)
|
|
583
|
+
lobe.save_to_disk(lobe_path)
|
|
584
|
+
self._lobes[slug] = lobe
|
|
585
|
+
self._save_synaptic_matrix()
|
|
586
|
+
return lobe
|
|
587
|
+
|
|
588
|
+
def activate_lobe(
|
|
589
|
+
self,
|
|
590
|
+
domain_or_name: Union[CorticalDomain, str] = "",
|
|
591
|
+
description: Optional[str] = None,
|
|
592
|
+
co_activated_nodes: Optional[list[str]] = None,
|
|
593
|
+
domain: Optional[Union[CorticalDomain, str]] = None,
|
|
594
|
+
name: Optional[Union[CorticalDomain, str]] = None,
|
|
595
|
+
) -> CorticalLobe:
|
|
596
|
+
"""Activate a domain lobe, incrementing its usage count and priming synaptic nodes.
|
|
597
|
+
|
|
598
|
+
If the lobe does not exist, dynamically auto-sprouts it with name and description.
|
|
599
|
+
"""
|
|
600
|
+
# Handle positional argument fallback if co_activated_nodes was passed as 2nd arg
|
|
601
|
+
if isinstance(description, (list, tuple, set)):
|
|
602
|
+
co_activated_nodes = list(description)
|
|
603
|
+
description = None
|
|
604
|
+
|
|
605
|
+
target = domain or name or domain_or_name
|
|
606
|
+
if not target:
|
|
607
|
+
raise ValueError("activate_lobe requires domain or lobe name.")
|
|
608
|
+
|
|
609
|
+
slug = self._normalize_domain(target)
|
|
610
|
+
lobe_path = self._get_lobe_path(slug)
|
|
611
|
+
|
|
612
|
+
is_new = (slug not in self._lobes) and (not lobe_path.exists())
|
|
613
|
+
if is_new:
|
|
614
|
+
desc = description or f"Custom cortical lobe for {slug} development and specialized heuristics"
|
|
615
|
+
lobe = self.define_cortical_lobe(name=slug, description=desc)
|
|
616
|
+
else:
|
|
617
|
+
lobe = self._load_or_create_lobe(slug, description=description)
|
|
618
|
+
lobe.activation_count += 1
|
|
619
|
+
|
|
620
|
+
if co_activated_nodes:
|
|
621
|
+
for node in co_activated_nodes:
|
|
622
|
+
node_clean = str(node).strip()
|
|
623
|
+
if not node_clean:
|
|
624
|
+
continue
|
|
625
|
+
current_w = lobe.synaptic_weights.get(node_clean, 0.20)
|
|
626
|
+
# Priming increase
|
|
627
|
+
primed_w = min(1.0, max(0.05, current_w + 0.02))
|
|
628
|
+
lobe.synaptic_weights[node_clean] = round(primed_w, 4)
|
|
629
|
+
|
|
630
|
+
self._sync_lobe_to_matrix(lobe)
|
|
631
|
+
lobe.save_to_disk(self._get_lobe_path(slug))
|
|
632
|
+
self._save_synaptic_matrix()
|
|
633
|
+
return lobe
|
|
634
|
+
|
|
635
|
+
def list_cortical_lobes(self) -> list[dict[str, Any]]:
|
|
636
|
+
"""Dynamically scans <cortex_dir>/*.md on disk.
|
|
637
|
+
|
|
638
|
+
Returns list of metadata dicts for all available lobes:
|
|
639
|
+
(name, description, activation_count, antibody_count, heuristic_count, file_path).
|
|
640
|
+
"""
|
|
641
|
+
lobes_meta: list[dict[str, Any]] = []
|
|
642
|
+
if not self.cortex_dir.exists():
|
|
643
|
+
return lobes_meta
|
|
644
|
+
|
|
645
|
+
for md_file in sorted(self.cortex_dir.glob("*.md")):
|
|
646
|
+
try:
|
|
647
|
+
lobe = CorticalLobe.load_from_disk(md_file)
|
|
648
|
+
lobes_meta.append({
|
|
649
|
+
"name": lobe.name or md_file.stem,
|
|
650
|
+
"description": lobe.description,
|
|
651
|
+
"activation_count": lobe.activation_count,
|
|
652
|
+
"antibody_count": len(lobe.antibodies),
|
|
653
|
+
"heuristic_count": len(lobe.specialized_heuristics),
|
|
654
|
+
"file_path": str(md_file.resolve()),
|
|
655
|
+
})
|
|
656
|
+
except Exception:
|
|
657
|
+
lobes_meta.append({
|
|
658
|
+
"name": md_file.stem,
|
|
659
|
+
"description": "",
|
|
660
|
+
"activation_count": 0,
|
|
661
|
+
"antibody_count": 0,
|
|
662
|
+
"heuristic_count": 0,
|
|
663
|
+
"file_path": str(md_file.resolve()),
|
|
664
|
+
})
|
|
665
|
+
|
|
666
|
+
return lobes_meta
|
|
667
|
+
|
|
668
|
+
def consolidate_task(
|
|
669
|
+
self,
|
|
670
|
+
domain: Union[CorticalDomain, str] = "general",
|
|
671
|
+
task_id: str = "",
|
|
672
|
+
broken_scenarios: Optional[list[dict[str, Any]]] = None,
|
|
673
|
+
final_passed: bool = True,
|
|
674
|
+
lessons: Optional[list[Union[dict[str, Any], str]]] = None,
|
|
675
|
+
co_activated_nodes: Optional[list[str]] = None,
|
|
676
|
+
activation_metrics: Optional[dict[str, float]] = None,
|
|
677
|
+
success: Optional[bool] = None,
|
|
678
|
+
**kwargs: Any,
|
|
679
|
+
) -> dict[str, Any]:
|
|
680
|
+
"""Consolidate task outcomes using directional BCM / STDP plasticity.
|
|
681
|
+
|
|
682
|
+
Applies Asymmetric BCM Plasticity:
|
|
683
|
+
When final_passed == True (Long-Term Potentiation, LTP):
|
|
684
|
+
ΔW_ij = + learning_rate * A_domain * A_node (learning_rate = 0.10)
|
|
685
|
+
When final_passed == False (Long-Term Depression, LTD):
|
|
686
|
+
ΔW_ij = - depression_rate * A_domain * A_node (depression_rate = 0.15)
|
|
687
|
+
|
|
688
|
+
Where continuous domain activation:
|
|
689
|
+
A_domain = min(1.0, max(0.30, 0.40 + 0.10 * len(co_activated_nodes)))
|
|
690
|
+
And continuous node activation A_j:
|
|
691
|
+
If activation_metrics is provided:
|
|
692
|
+
A_j = min(1.0, max(0.15, float(activation_metrics.get(node, 0.5)) / max(max(activation_metrics.values(), default=1.0), 0.001)))
|
|
693
|
+
Otherwise, based on node position/role in [0.75, 0.90].
|
|
694
|
+
|
|
695
|
+
Homeostatically bounds all weights strictly within [0.05, 1.00].
|
|
696
|
+
Failed pathways actively depress/weaken, while synthesized HeuristicAntibody instances
|
|
697
|
+
preserve the critical scars and lessons.
|
|
698
|
+
"""
|
|
699
|
+
if success is not None:
|
|
700
|
+
final_passed = bool(success)
|
|
701
|
+
slug = self._normalize_domain(domain)
|
|
702
|
+
lobe = self._load_or_create_lobe(slug)
|
|
703
|
+
lobe.activation_count += 1
|
|
704
|
+
|
|
705
|
+
learning_rate = 0.10
|
|
706
|
+
depression_rate = 0.15
|
|
707
|
+
plasticity_mode = "LTP" if final_passed else "LTD"
|
|
708
|
+
score = 1.0 if final_passed else -1.0
|
|
709
|
+
normalized_nodes = (
|
|
710
|
+
self.sanitize_field(node, max_len=128)
|
|
711
|
+
for node in (co_activated_nodes or [])
|
|
712
|
+
)
|
|
713
|
+
active_nodes = list(dict.fromkeys(node for node in normalized_nodes if node))[:MAX_ACTIVE_NODES]
|
|
714
|
+
|
|
715
|
+
# Compute continuous domain activation A_domain
|
|
716
|
+
A_domain = min(1.0, max(0.30, 0.40 + 0.10 * len(active_nodes)))
|
|
717
|
+
|
|
718
|
+
# Compute continuous node activation signals A_j
|
|
719
|
+
node_activations: dict[str, float] = {}
|
|
720
|
+
if activation_metrics is not None and len(activation_metrics) > 0:
|
|
721
|
+
max_metric = max(activation_metrics.values(), default=1.0)
|
|
722
|
+
denom = max(float(max_metric), 0.001)
|
|
723
|
+
for node in active_nodes:
|
|
724
|
+
val = float(activation_metrics.get(node, 0.5))
|
|
725
|
+
A_j = min(1.0, max(0.15, val / denom))
|
|
726
|
+
node_activations[node] = round(A_j, 4)
|
|
727
|
+
else:
|
|
728
|
+
for idx, node in enumerate(active_nodes):
|
|
729
|
+
A_j = max(0.75, min(0.90, 0.90 - (idx * 0.03)))
|
|
730
|
+
node_activations[node] = round(A_j, 4)
|
|
731
|
+
|
|
732
|
+
# 1. Update lobe synaptic weights via directional BCM rule
|
|
733
|
+
new_weights: dict[str, float] = {}
|
|
734
|
+
for node in active_nodes:
|
|
735
|
+
old_w = lobe.synaptic_weights.get(node, 0.30)
|
|
736
|
+
A_node = node_activations.get(node, 0.80)
|
|
737
|
+
if final_passed:
|
|
738
|
+
delta_w = learning_rate * A_domain * A_node
|
|
739
|
+
else:
|
|
740
|
+
delta_w = - depression_rate * A_domain * A_node
|
|
741
|
+
new_w = min(1.0, max(0.05, old_w + delta_w))
|
|
742
|
+
new_weights[node] = round(new_w, 4)
|
|
743
|
+
lobe.synaptic_weights = new_weights
|
|
744
|
+
|
|
745
|
+
# 2. Homeostatic normalization across lobe weights
|
|
746
|
+
# If total synaptic weight exceeds capacity, apply soft scaling while preserving [0.05, 1.0]
|
|
747
|
+
if lobe.synaptic_weights:
|
|
748
|
+
max_capacity = 25.0
|
|
749
|
+
total_weight = sum(lobe.synaptic_weights.values())
|
|
750
|
+
if total_weight > max_capacity:
|
|
751
|
+
scale_factor = max_capacity / total_weight
|
|
752
|
+
for k in lobe.synaptic_weights:
|
|
753
|
+
scaled = lobe.synaptic_weights[k] * scale_factor
|
|
754
|
+
lobe.synaptic_weights[k] = round(min(1.0, max(0.05, scaled)), 4)
|
|
755
|
+
|
|
756
|
+
# 3. Update global synaptic co-activation matrix (pairwise between nodes)
|
|
757
|
+
if len(active_nodes) >= 2:
|
|
758
|
+
for i in range(len(active_nodes)):
|
|
759
|
+
u = active_nodes[i]
|
|
760
|
+
A_u = node_activations.get(u, 0.80)
|
|
761
|
+
if u not in self._synaptic_matrix:
|
|
762
|
+
self._synaptic_matrix[u] = {}
|
|
763
|
+
for j in range(i + 1, len(active_nodes)):
|
|
764
|
+
v = active_nodes[j]
|
|
765
|
+
A_v = node_activations.get(v, 0.80)
|
|
766
|
+
if v not in self._synaptic_matrix:
|
|
767
|
+
self._synaptic_matrix[v] = {}
|
|
768
|
+
|
|
769
|
+
old_pair_w = self._synaptic_matrix[u].get(v, 0.15)
|
|
770
|
+
if final_passed:
|
|
771
|
+
delta_pair_w = learning_rate * A_u * A_v
|
|
772
|
+
else:
|
|
773
|
+
delta_pair_w = - depression_rate * A_u * A_v
|
|
774
|
+
new_pair_w = round(min(1.0, max(0.05, old_pair_w + delta_pair_w)), 4)
|
|
775
|
+
|
|
776
|
+
self._synaptic_matrix[u][v] = new_pair_w
|
|
777
|
+
self._synaptic_matrix[v][u] = new_pair_w
|
|
778
|
+
|
|
779
|
+
# Also connect domain to active nodes in global matrix
|
|
780
|
+
dom_name = slug
|
|
781
|
+
if dom_name not in self._synaptic_matrix:
|
|
782
|
+
self._synaptic_matrix[dom_name] = {}
|
|
783
|
+
for node in active_nodes:
|
|
784
|
+
A_node = node_activations.get(node, 0.80)
|
|
785
|
+
old_dom_w = self._synaptic_matrix[dom_name].get(node, 0.20)
|
|
786
|
+
if final_passed:
|
|
787
|
+
delta_dom_w = learning_rate * A_domain * A_node
|
|
788
|
+
else:
|
|
789
|
+
delta_dom_w = - depression_rate * A_domain * A_node
|
|
790
|
+
new_dom_w = round(min(1.0, max(0.05, old_dom_w + delta_dom_w)), 4)
|
|
791
|
+
self._synaptic_matrix[dom_name][node] = new_dom_w
|
|
792
|
+
if node not in self._synaptic_matrix:
|
|
793
|
+
self._synaptic_matrix[node] = {}
|
|
794
|
+
self._synaptic_matrix[node][dom_name] = new_dom_w
|
|
795
|
+
|
|
796
|
+
# 4. Synthesize Heuristic Antibodies from red-team broken scenarios
|
|
797
|
+
antibodies_added = 0
|
|
798
|
+
if broken_scenarios:
|
|
799
|
+
for sc in broken_scenarios:
|
|
800
|
+
sc_dict = sc if isinstance(sc, dict) else (sc.to_dict() if hasattr(sc, "to_dict") else asdict(sc))
|
|
801
|
+
sc_id = str(sc_dict.get("scenario_id") or uuid.uuid4().hex[:6])
|
|
802
|
+
ab_id = f"ab_{slug}_{sc_id}"
|
|
803
|
+
|
|
804
|
+
trigger = str(
|
|
805
|
+
sc_dict.get("hypothesis")
|
|
806
|
+
or sc_dict.get("trigger_condition")
|
|
807
|
+
or f"Adversarial probe {sc_id}"
|
|
808
|
+
)
|
|
809
|
+
lethal = str(
|
|
810
|
+
sc_dict.get("error_message")
|
|
811
|
+
or sc_dict.get("lethal_anti_pattern")
|
|
812
|
+
or "Unchecked execution failure under adversarial pressure"
|
|
813
|
+
)
|
|
814
|
+
prescribed = (
|
|
815
|
+
sc_dict.get("prescribed_defense")
|
|
816
|
+
or sc_dict.get("remediation_directives")
|
|
817
|
+
or sc_dict.get("remediation")
|
|
818
|
+
or "Enforce strict precondition verification and atomic isolation."
|
|
819
|
+
)
|
|
820
|
+
if isinstance(prescribed, list):
|
|
821
|
+
prescribed = "; ".join(str(item) for item in prescribed)
|
|
822
|
+
else:
|
|
823
|
+
prescribed = str(prescribed)
|
|
824
|
+
|
|
825
|
+
severity = str(sc_dict.get("severity", "HIGH")).upper()
|
|
826
|
+
counterfac = str(
|
|
827
|
+
sc_dict.get("reproduction_code")
|
|
828
|
+
or sc_dict.get("verified_counterfactual")
|
|
829
|
+
or f"Counterfactual validation against vector: {sc_dict.get('vector', 'chaos')}"
|
|
830
|
+
)
|
|
831
|
+
|
|
832
|
+
# Deduplicate by antibody_id or trigger_condition
|
|
833
|
+
existing_ab = next(
|
|
834
|
+
(a for a in lobe.antibodies if a.antibody_id == ab_id or a.trigger_condition == trigger),
|
|
835
|
+
None,
|
|
836
|
+
)
|
|
837
|
+
if existing_ab is not None:
|
|
838
|
+
if counterfac and (not existing_ab.verified_counterfactual or "Counterfactual validation" in existing_ab.verified_counterfactual):
|
|
839
|
+
existing_ab.verified_counterfactual = counterfac
|
|
840
|
+
if prescribed and "Enforce strict precondition" in existing_ab.prescribed_defense:
|
|
841
|
+
existing_ab.prescribed_defense = prescribed
|
|
842
|
+
else:
|
|
843
|
+
antibody = HeuristicAntibody(
|
|
844
|
+
antibody_id=ab_id,
|
|
845
|
+
domain=slug,
|
|
846
|
+
trigger_condition=trigger,
|
|
847
|
+
lethal_anti_pattern=lethal,
|
|
848
|
+
prescribed_defense=prescribed,
|
|
849
|
+
severity=severity,
|
|
850
|
+
source_task_id=task_id,
|
|
851
|
+
created_at=datetime.now(timezone.utc).isoformat(),
|
|
852
|
+
verified_counterfactual=counterfac,
|
|
853
|
+
)
|
|
854
|
+
lobe.antibodies.append(antibody)
|
|
855
|
+
antibodies_added += 1
|
|
856
|
+
|
|
857
|
+
# 5. Extract specialized heuristics from lessons
|
|
858
|
+
heuristics_added = 0
|
|
859
|
+
if lessons:
|
|
860
|
+
for item in lessons:
|
|
861
|
+
heuristic_text = ""
|
|
862
|
+
if isinstance(item, str):
|
|
863
|
+
heuristic_text = item.strip()
|
|
864
|
+
elif isinstance(item, dict):
|
|
865
|
+
if item.get("heuristic") or item.get("lesson") or item.get("rule"):
|
|
866
|
+
heuristic_text = str(
|
|
867
|
+
item.get("heuristic") or item.get("lesson") or item.get("rule") or ""
|
|
868
|
+
).strip()
|
|
869
|
+
elif item.get("defense") or item.get("trigger"):
|
|
870
|
+
trigger = str(item.get("trigger", "")).strip()
|
|
871
|
+
defense = str(item.get("defense", "")).strip()
|
|
872
|
+
mistake = str(item.get("mistake", "")).strip()
|
|
873
|
+
if trigger and defense:
|
|
874
|
+
heuristic_text = f"Defense against [{trigger}]: {defense}"
|
|
875
|
+
elif defense:
|
|
876
|
+
heuristic_text = f"Invariant: {defense}"
|
|
877
|
+
elif mistake:
|
|
878
|
+
heuristic_text = f"Avoid mistake: {mistake}"
|
|
879
|
+
|
|
880
|
+
if heuristic_text and heuristic_text not in lobe.specialized_heuristics:
|
|
881
|
+
lobe.specialized_heuristics.append(heuristic_text)
|
|
882
|
+
heuristics_added += 1
|
|
883
|
+
|
|
884
|
+
# 6. Save lobe and synaptic matrix to disk
|
|
885
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
886
|
+
lobe.last_consolidated_at = timestamp
|
|
887
|
+
self._sync_lobe_to_matrix(lobe)
|
|
888
|
+
lobe.save_to_disk(self._get_lobe_path(slug))
|
|
889
|
+
self._save_synaptic_matrix()
|
|
890
|
+
|
|
891
|
+
return {
|
|
892
|
+
"status": "CONSOLIDATED",
|
|
893
|
+
"domain": slug,
|
|
894
|
+
"name": slug,
|
|
895
|
+
"task_id": task_id,
|
|
896
|
+
"final_passed": final_passed,
|
|
897
|
+
"plasticity_mode": plasticity_mode,
|
|
898
|
+
"learning_rate": learning_rate,
|
|
899
|
+
"depression_rate": depression_rate,
|
|
900
|
+
"score": score,
|
|
901
|
+
"A_domain": round(A_domain, 4),
|
|
902
|
+
"activation_signals": {k: round(v, 4) for k, v in node_activations.items()},
|
|
903
|
+
"antibodies_added": antibodies_added,
|
|
904
|
+
"total_antibodies": len(lobe.antibodies),
|
|
905
|
+
"heuristics_added": heuristics_added,
|
|
906
|
+
"total_heuristics": len(lobe.specialized_heuristics),
|
|
907
|
+
"synaptic_weights": copy.deepcopy(lobe.synaptic_weights),
|
|
908
|
+
"consolidated_at": timestamp,
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
def recall_cortical_context(
|
|
912
|
+
self,
|
|
913
|
+
domain: Union[CorticalDomain, str],
|
|
914
|
+
max_antibodies: int = 5,
|
|
915
|
+
) -> str:
|
|
916
|
+
"""Recall high-signal cortical memory block to inject into agent/subagent prompts.
|
|
917
|
+
|
|
918
|
+
Sanitizes and validates all recalled cortex state to prevent prompt injection vulnerabilities.
|
|
919
|
+
"""
|
|
920
|
+
slug = self._normalize_domain(domain)
|
|
921
|
+
lobe = self._load_or_create_lobe(slug)
|
|
922
|
+
|
|
923
|
+
s_desc = self.sanitize_field(lobe.description)
|
|
924
|
+
s_slug = self.sanitize_field(slug.upper(), max_len=64)
|
|
925
|
+
|
|
926
|
+
lines: list[str] = [
|
|
927
|
+
f"### 🧠 Cortical Lobe Memory: `{s_slug}` (Activations: {lobe.activation_count})",
|
|
928
|
+
"",
|
|
929
|
+
]
|
|
930
|
+
|
|
931
|
+
if s_desc:
|
|
932
|
+
lines.append(f"> **Description**: {s_desc}")
|
|
933
|
+
lines.append("")
|
|
934
|
+
|
|
935
|
+
lines.extend([
|
|
936
|
+
"> [!IMPORTANT]",
|
|
937
|
+
f"> Cortical recall retrieved {len(lobe.antibodies)} heuristic antibodies and {len(lobe.specialized_heuristics)} domain invariants.",
|
|
938
|
+
"",
|
|
939
|
+
])
|
|
940
|
+
|
|
941
|
+
# Top antibodies sorted by severity
|
|
942
|
+
severity_rank = {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3}
|
|
943
|
+
sorted_antibodies = sorted(
|
|
944
|
+
lobe.antibodies,
|
|
945
|
+
key=lambda a: (severity_rank.get(a.severity.upper(), 2), a.antibody_id),
|
|
946
|
+
)[:max_antibodies]
|
|
947
|
+
|
|
948
|
+
lines.append("#### 🛡️ Immunological Heuristic Antibodies (Red-Team Scars)")
|
|
949
|
+
if sorted_antibodies:
|
|
950
|
+
for ab in sorted_antibodies:
|
|
951
|
+
s_trig = self.sanitize_field(ab.trigger_condition)
|
|
952
|
+
s_lethal = self.sanitize_field(ab.lethal_anti_pattern)
|
|
953
|
+
s_defense = self.sanitize_field(ab.prescribed_defense)
|
|
954
|
+
s_counterfac = self.sanitize_field(ab.verified_counterfactual)
|
|
955
|
+
s_source_task = self.sanitize_field(ab.source_task_id, max_len=128)
|
|
956
|
+
s_sev = self.sanitize_field(ab.severity.upper(), max_len=16)
|
|
957
|
+
lines.append(f"- **[{s_sev}] Trigger**: {s_trig}")
|
|
958
|
+
lines.append(f" - **Lethal Anti-Pattern**: `{s_lethal}`")
|
|
959
|
+
lines.append(f" - **Prescribed Defense**: {s_defense}")
|
|
960
|
+
if s_counterfac:
|
|
961
|
+
lines.append(f" - **Counterfactual**: `{s_counterfac}`")
|
|
962
|
+
if s_source_task:
|
|
963
|
+
lines.append(f" - **Source Task ID**: `{s_source_task}`")
|
|
964
|
+
else:
|
|
965
|
+
lines.append("- *(No active antibodies in this lobe)*")
|
|
966
|
+
lines.append("")
|
|
967
|
+
|
|
968
|
+
# Active domain heuristics
|
|
969
|
+
lines.append("#### ⚡ Specialized Domain Heuristics & Invariants")
|
|
970
|
+
if lobe.specialized_heuristics:
|
|
971
|
+
for idx, h in enumerate(lobe.specialized_heuristics[:8], 1):
|
|
972
|
+
lines.append(f"{idx}. {self.sanitize_field(h)}")
|
|
973
|
+
else:
|
|
974
|
+
lines.append("- *(Baseline heuristics only)*")
|
|
975
|
+
lines.append("")
|
|
976
|
+
|
|
977
|
+
# Top wired synaptic nodes/tools
|
|
978
|
+
lines.append("#### 🔗 Strongly-Wired Synaptic Companion Tools & Nodes")
|
|
979
|
+
if lobe.synaptic_weights:
|
|
980
|
+
top_nodes = sorted(lobe.synaptic_weights.items(), key=lambda x: x[1], reverse=True)[:6]
|
|
981
|
+
for node, weight in top_nodes:
|
|
982
|
+
s_node = self.sanitize_field(node, max_len=64)
|
|
983
|
+
lines.append(f"- `{s_node}`: weight `{weight:.4f}`")
|
|
984
|
+
else:
|
|
985
|
+
lines.append("- *(Zero strong synaptic co-activations)*")
|
|
986
|
+
lines.append("")
|
|
987
|
+
|
|
988
|
+
return "\n".join(lines)
|
|
989
|
+
|
|
990
|
+
def get_synaptic_matrix(self) -> dict[str, dict[str, float]]:
|
|
991
|
+
"""Return the complete cross-domain synaptic co-activation matrix."""
|
|
992
|
+
return copy.deepcopy(self._synaptic_matrix)
|