Lifeblood. Hexagonal Architecture

Architecture diagram matching the actual codebase. Solid items are implemented and dogfood-verified. Faded dashed items are planned but not yet built. Every port interface has a concrete implementation. All hexagonal boundaries enforced by tests.

11 assemblies + 3 standalone adapters
Self-analyze graph (live counts in STATUS.md)
1,191 tests / CI green (37 [SkippableFact] runtime-gated)
C# + C + TypeScript + Python
Cross-module: Proven
Every port wired
Incremental re-analyze (file + csproj + asmdef)
File-level edges
MCP tools — read + write side
Truth envelope
Unity reachability
Roslyn bidirectional
ISymbolResolver + IInvariantProvider
RoslynSemanticView
BCL ownership
Native usage + timing
Queryable invariants in tree
UTF-16 BOM-aware JSON import
UTF-8-pinned MCP stdio
Caller-owned analyze scope policy
SearchResult.MatchKind
Enum members first-class
dotnet tool
Left side. Language Adapters

Language Adapters swappable

Roslyn / C#Reference adapter. Proven type/call/cross-module resolution. Topological sort + CompilationReference. Generics, typeof, attributes.
libclang / CBeta (v0.7.7). Standalone native extractor under adapters/native-clang. Reads compile_commands.json. Surfaces translation units, functions, globals, fields, type shells, enum members, macros, includes, callback-table rows and cells. Partial-parse tolerant.
TypeScriptStandalone Node.js. ts.createProgram + TypeChecker. High-confidence. Self-analyzing.
PythonStandalone ast-based. Zero dependencies. Classes, functions, imports, inheritance. Self-analyzing.
JSON GraphUniversal protocol. Import + export with full metadata round-trip.
CommunityGo, Rust. Build via JSON protocol. Guides ready.

Infrastructure Ports sealed

IFileSystemReadAllText, ReadLines, OpenRead, FileExists, DirectoryExists, FindFiles, GetLastWriteTimeUtc. Impl: PhysicalFileSystem.
IProgressSinkReport(phase, current, total), Log(message). Impl: ConsoleProgressSink (stderr).
IRuleProviderLoadRules(path) → ArchitectureRule[]. Impl: RulesLoader (JSON deserialization).

Composition Roots

Lifeblood.CLIdotnet tool: lifeblood. analyze, context, export. CI exit codes.
Lifeblood.Server.Mcpdotnet tool: lifeblood-mcp. Stdio JSON-RPC. MCP tool surface (read + write side; live counts in STATUS.md). Bidirectional Roslyn. RoslynSemanticView shared by reference across consumers. Truth envelope on every read-side response (INV-ENVELOPE-001).
 
Inbound Ports
IWorkspaceAnalyzerproject → SemanticGraph
IModuleDiscoveryroot → ModuleInfo[]
IGraphImporterstream → GraphDocument
IGraphExportergraph → stream
ICompilationHostdiagnostics, compile-check, refs
ICodeExecutorcode → result + output
IWorkspaceRefactoringrename → edits, format

Application Layer

AnalyzeWorkspaceUseCase
GenerateContextUseCase
Every port interface wired

Domain

Semantic Graph

Symbol, Edge, Evidence
GraphBuilder, GraphValidator
GraphDocument

Pure. Immutable. Zero dependencies.

Analysis

Coupling, BlastRadius, Cycles
Tiers, RuleValidator

Outbound Ports
IAgentContextGeneratorgraph → AgentContextPack
IMcpGraphProviderLookup, Deps, BlastRadius, FileImpact
IInstructionFileGeneratorgraph → markdown
ISymbolResolvername / id → SymbolResolutionResult (with wrong-namespace fallback, v0.6.3)
ISemanticSearchProvidertokenized name + xmldoc ranked-OR
IDeadCodeAnalyzerexperimental / advisory (INV-DEADCODE-001)
IPartialViewBuildertype → combined partial source
IInvariantProviderCLAUDE.md → queryable invariants
Lifeblood.Analysis (optional addon) CouplingAnalyzer, BlastRadiusAnalyzer, CircularDependencyDetector, TierClassifier, RuleValidator. All stateless. Depends only on Domain.
Enforced invariants (tested AND queryable via lifeblood_invariant_check) Domain: zero deps. Application: Domain only. No adapter-to-adapter refs. No connector-to-adapter refs. ScriptHost zero ProjectReferences (INV-SCRIPTHOST-001). Composition roots use an explicit allowlist (INV-COMPROOT-001). Graph immutable. Output deterministic. 11 frozen ADRs. Live test / tool / port / invariant / self-analyze counts in STATUS.md. CI jobs: build, TypeScript adapter, Python adapter, dogfood. Golden repos and fixtures for all 4 adapters (C# via Roslyn golden repos, C via native-clang fixtures, TypeScript golden repo, Python golden repo). Incremental re-analyze (file + csproj + asmdef, INV-UNITY-002). Caller-owned scope policy on incremental analyze: rejects on detected drift unless allowFullFallback is opted in; wire shape carries mode + requestedMode + fallbackReason + canRetryFull + suggestedRetry (INV-ANALYZE-FALLBACK-001). File-level edges. Enum members are first-class graph symbols with constantValue (INV-EXTRACT-ENUMMEMBER-001). BCL ownership decided once at discovery (INV-BCL-001..005). ISymbolResolver routes every read-side handler with kind correction (INV-RESOLVER-001..006); Rule 4 short-name fallback never crosses containing types or kinds for member-kind inputs (INV-RESOLVER-007). SearchResult.MatchKind structurally reports which scoring bucket drove the rank (INV-SEARCH-MATCHKIND-001). RoslynSemanticView shared by reference (INV-VIEW-001..003). Truth envelope on every read-side response (INV-ENVELOPE-001). Unity reachability port (INV-UNITY-001) with full Editor reflection roster + type-via-child propagation. Authority report + forwarder classifier (INV-AUTHORITY-001, INV-FORWARDER-001). Native usage and timing on every analyze response (INV-USAGE-001..PROBE-002). Typed architectural invariants under docs/invariants/ tree, aggregated dynamically by IInvariantProvider (INV-INVARIANT-001). lifeblood_dead_code ships experimental / advisory with three known false-positive classes (INV-DEADCODE-001).
Right side. AI Connectors

AI Connectors swappable

Right-side connectors expose semantic truth to AI agents and tools.

AgentContextGeneratorHigh-value files, boundaries, reading order, hotspots, dependency matrix, violations.
InstructionFileGeneratorCLAUDE.md / AGENTS.md sections with module boundaries and architecture rules.
LifebloodMcpProviderSymbol lookup, dependencies, dependants, blast radius, file impact, short-name resolution.
LifebloodSymbolResolverReference ISymbolResolver implementation. Routes every read-side handler through canonical → truncated method → bare short name → extracted short name from qualified input (wrong-namespace fallback, v0.6.3). Deterministic primary file path picker for partial types.
LifebloodSemanticSearchProviderRanked search over symbol names, qualified names, and xmldoc summaries. Tokenized ranked-OR (v0.6.3).
LifebloodInvariantProviderTree-walking runtime parser. Aggregates <root>/CLAUDE.md + <root>/AGENTS.md + every *.md under docs/invariants/. Five authoring shapes recognised (A/B/C/D/E). Exposes 90 architectural invariants as queryable structured data via lifeblood_invariant_check (INV-INVARIANT-001).
LifebloodPartialViewBuilderCombined source view across every partial declaration of a type.
LifebloodAuthorityReporterSingle graph walk produces implementedInterfaceCount, ownedPublicSurface, per-interface usage, forwarderRatio. Powers lifeblood_authority_report + lifeblood_port_health (INV-AUTHORITY-001, INV-FORWARDER-001).
LifebloodResponseDecoratorBuilds the truth envelope on every read-side response. Per-tool classification table sourced from ToolRegistry (INV-ENVELOPE-001).
UnityReachabilityAdapterMonoBehaviour magic methods + full Unity Editor reflection roster (RuntimeInitializeOnLoadMethod, MenuItem, SettingsProvider, Shortcut, BurstCompile, NUnit lifecycle, ...) + type-via-child propagation (INV-UNITY-001, INV-UNITY-002).
UnityAssemblyResolverProbes Library/ScriptAssemblies, Library/Bee/artifacts, Library/PackageCache for execute-time DLL injection so scripts can touch UnityEngine types (INV-EXECUTE-001).
LifebloodDeadCodeAnalyzerv0.6.4: five extractor false-positive classes fixed. v0.6.5: three more (ctor, field-initializer, accessor). v0.6.7: Unity reachability injection cuts MonoBehaviour-magic FPs 97% on real Unity workspaces. v0.7.0+: LB-FP-003 Editor reflection roster. summarize/maxResults pagination via LB-FR-024. See INV-DEADCODE-001.
MCP Server (stdio)JSON-RPC 2.0. Read + write tool surface (live counts in STATUS.md). Bidirectional Roslyn. Connect from Claude Code or any MCP client.
REST / LSP BridgeIDE extensions and web services. Not yet started.

What comes out

Verified, capability-aware context for AI systems.

Context pack JSONstructured AI-consumable output
Instruction file markdownCLAUDE.md architecture sections
MCP interactive queriesTools over stdio — read + write side
Exported graph.jsonportable semantic graph + metadata
CLI analysis reportsymbols, edges, violations, cycles
Code executionCSharpScript.RunAsync via MCP
Diagnostics + compile checkRoslyn compiler-as-a-service
Find references + renameworkspace-aware refactoring

Quality gates

Golden reposC# (HexagonalApp, CycleRepo), TS (mini-app), Python (mini-app). Assert specific types + edges.
Self-dogfoodEvery push: analyze own codebase, validate rules, export graph, cross-language proof.
Architecture invariant testsDomain zero deps, Application→Domain only, no adapter↔adapter, no connector→adapter.
Adapters (left)Roslyn is the C# reference with cross-module resolution. libclang is the C reference (beta, v0.7.7), reading compile_commands.json and emitting Lifeblood-shape graph JSON. TypeScript and Python are standalone adapters. JSON graph is the universal bridge. Community adapters (Go, Rust) have contribution guides.
Core (center)Pure domain + application orchestration. Port interfaces (live count in STATUS.md). All sealed with concrete implementations. GraphDocument carries version, language, and adapter capabilities. All invariants enforced by tests AND queryable at runtime via lifeblood_invariant_check.
Connectors (right)Context packs, instruction files, MCP server with interactive tool surface, CLI with CI exit codes. They depend inward on Application ports, never on adapters. Packaged as dotnet tools.