chore: add copyright headers, CI tests, and sanitize gitignore

This commit is contained in:
DmitrL-dev 2026-03-31 22:13:34 +10:00
parent 5cbb3d89d3
commit d1f844235e
325 changed files with 2267 additions and 902 deletions

31
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: Go Tests
on:
push:
branches: [ "main", "master" ]
pull_request:
branches: [ "main", "master" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.0'
cache: true
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...
- name: Vet & Lint
run: |
go vet ./...
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...

35
.gitignore vendored Normal file
View file

@ -0,0 +1,35 @@
# Binaries
*.exe
*.exe~
*.dll
*.so
*.dylib
gomcp
soc
immune
sidecar
dist/
# Databases
*.db
*.sqlite
*.sqlite3
*.wal
*.shm
# Logs & Secrets
*.log
.env
*.key
.decisions.log
sentinel_leash
.rlm/
# IDE
.vscode/
.idea/
*.swp
*.swo
# Vendor
vendor/

View file

@ -1,18 +1,18 @@
# GoMCP: Recursive Language Model Server # GoMCP: The Secure Memory Core for AI Agents
![Go Version](https://img.shields.io/badge/Go-1.25.0-blue.svg) ![Go Version](https://img.shields.io/badge/Go-1.25.0-blue.svg)
![License](https://img.shields.io/badge/License-Apache_2.0-green.svg) ![License](https://img.shields.io/badge/License-Apache_2.0-green.svg)
![Protocol](https://img.shields.io/badge/MCP-Supported-orange.svg) ![Protocol](https://img.shields.io/badge/MCP-Supported-orange.svg)
> **The only Open-Source RLM (Recursive Language Model) Memory Server with Mathematically Proven Safety.** > **"Единственный RLM-сервер памяти с математически доказанной безопасностью (Sentinel Lattice). Работает локально, масштабируется глобально."**
GoMCP is the enterprise core of the Syntrex AI SOC ecosystem. It is an extremely fast, secure, and persistent Model Context Protocol (MCP) server entirely written in Go. GoMCP gives Large Language Models a permanent, evolving memory and self-modifying context, transforming standard text agents into self-improving persistent intelligences. GoMCP is the enterprise core of the Syntrex AI SOC ecosystem. It is an extremely fast, secure, and persistent Model Context Protocol (MCP) server entirely written in Go. GoMCP gives Large Language Models a permanent, evolving memory and self-modifying context, transforming standard text agents into self-improving persistent intelligences.
## 🚀 Key Features ## 🚀 Key Features
- **Context Consciousness Crystal (C³):** Hierarchical memory layers (L0-L3) combined with SQLite-backed temporal caching. - 🛡️ **Sentinel Lattice Primitives:** (TSA, CAFL, GPS...)
- **57+ Native MCP Tools:** Deeply integrated tools for agentic self-reflection, codebase navigation, and file editing. - **Sub-millisecond latency:** Pure Go execution with optional Rust bindings
- **Sub-millisecond latency:** Engineered for speed and durability under enterprise loads. - 🔌 **57+ Native MCP Tools:** Deeply integrated tools right out of the box
- **Secure by Default:** Zero-G execution environment and robust isolation from the main operating system logic. DoH shielding, uTLS protocols, and session resumption natively integrated. - 💾 **Persistent Causal Graph Memory:** Hierarchical memory layers (L0-L3) backed by robust SQLite temporal caching
## ⚡ Quick Start ## ⚡ Quick Start

22
add_headers.py Normal file
View file

@ -0,0 +1,22 @@
import os
import glob
HEADER = """// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
"""
def run():
for filepath in glob.glob("**/*.go", recursive=True):
if os.path.isfile(filepath):
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
# Skip if already has header
if "Copyright 2026 Syntrex Lab" not in content:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(HEADER + content)
if __name__ == '__main__':
run()

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// GoMCP v2 — High-performance Go-native MCP server for the RLM Toolkit. // GoMCP v2 — High-performance Go-native MCP server for the RLM Toolkit.
// Provides hierarchical persistent memory, cognitive state management, // Provides hierarchical persistent memory, cognitive state management,
// causal reasoning chains, and code crystal indexing. // causal reasoning chains, and code crystal indexing.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the SENTINEL immune agent (SEC-002 eBPF Runtime Guard). // Package main provides the SENTINEL immune agent (SEC-002 eBPF Runtime Guard).
// //
// The immune agent monitors SOC processes at the kernel level using eBPF // The immune agent monitors SOC processes at the kernel level using eBPF

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the Universal Sidecar CLI entry point (§5.5). // Package main provides the Universal Sidecar CLI entry point (§5.5).
// //
// Usage: // Usage:

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the SOC Correlate process (SEC-001 Process Isolation). // Package main provides the SOC Correlate process (SEC-001 Process Isolation).
// //
// Responsibility: Receives persisted events from soc-ingest via IPC, // Responsibility: Receives persisted events from soc-ingest via IPC,

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the SOC Ingest process (SEC-001 Process Isolation). // Package main provides the SOC Ingest process (SEC-001 Process Isolation).
// //
// Responsibility: HTTP endpoint, authentication, secret scanner, // Responsibility: HTTP endpoint, authentication, secret scanner,

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the SOC Respond process (SEC-001 Process Isolation). // Package main provides the SOC Respond process (SEC-001 Process Isolation).
// //
// Responsibility: Receives incidents from soc-correlate via IPC, // Responsibility: Receives incidents from soc-correlate via IPC,

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package main provides the standalone SOC API server entry point. // Package main provides the standalone SOC API server entry point.
// //
// @title SYNTREX Sentinel SOC API // @title SYNTREX Sentinel SOC API
@ -29,10 +33,10 @@ import (
"syscall" "syscall"
"github.com/syntrex-lab/gomcp/internal/application/soc" "github.com/syntrex-lab/gomcp/internal/application/soc"
socdomain "github.com/syntrex-lab/gomcp/internal/domain/soc"
"github.com/syntrex-lab/gomcp/internal/domain/engines" "github.com/syntrex-lab/gomcp/internal/domain/engines"
"github.com/syntrex-lab/gomcp/internal/infrastructure/auth" socdomain "github.com/syntrex-lab/gomcp/internal/domain/soc"
"github.com/syntrex-lab/gomcp/internal/infrastructure/audit" "github.com/syntrex-lab/gomcp/internal/infrastructure/audit"
"github.com/syntrex-lab/gomcp/internal/infrastructure/auth"
"github.com/syntrex-lab/gomcp/internal/infrastructure/email" "github.com/syntrex-lab/gomcp/internal/infrastructure/email"
"github.com/syntrex-lab/gomcp/internal/infrastructure/logging" "github.com/syntrex-lab/gomcp/internal/infrastructure/logging"
"github.com/syntrex-lab/gomcp/internal/infrastructure/postgres" "github.com/syntrex-lab/gomcp/internal/infrastructure/postgres"
@ -274,4 +278,3 @@ func configureMemorySafety(logger *slog.Logger) {
"sys_mib", m.Sys/1024/1024, "sys_mib", m.Sys/1024/1024,
) )
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// syntrex-proxy — transparent reverse proxy that scans LLM prompts. // syntrex-proxy — transparent reverse proxy that scans LLM prompts.
// //
// Usage: // Usage:

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package docs Code generated by swaggo/swag. DO NOT EDIT // Package docs Code generated by swaggo/swag. DO NOT EDIT
package docs package docs

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (
@ -5,9 +9,9 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
ctxdomain "github.com/syntrex-lab/gomcp/internal/domain/context"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ctxdomain "github.com/syntrex-lab/gomcp/internal/domain/context"
) )
func TestLoadConfig_FileNotExists(t *testing.T) { func TestLoadConfig_FileNotExists(t *testing.T) {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package contextengine implements the Proactive Context Engine. // Package contextengine implements the Proactive Context Engine.
// It automatically injects relevant memory facts into every MCP tool response // It automatically injects relevant memory facts into every MCP tool response
// via ToolHandlerMiddleware, so the LLM always has context without asking. // via ToolHandlerMiddleware, so the LLM always has context without asking.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (
@ -10,9 +14,9 @@ import (
"github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/mcp"
"github.com/syntrex-lab/gomcp/internal/domain/memory" "github.com/syntrex-lab/gomcp/internal/domain/memory"
ctxdomain "github.com/syntrex-lab/gomcp/internal/domain/context"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ctxdomain "github.com/syntrex-lab/gomcp/internal/domain/context"
) )
// --- Mock FactProvider --- // --- Mock FactProvider ---

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package contextengine — processor.go // Package contextengine — processor.go
// Processes unprocessed interaction log entries into session summary facts. // Processes unprocessed interaction log entries into session summary facts.
// This closes the memory loop: tool calls → interaction log → summary facts → boot instructions. // This closes the memory loop: tool calls → interaction log → summary facts → boot instructions.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (
@ -5,10 +9,10 @@ import (
"testing" "testing"
"time" "time"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
// --- mock FactStore for processor tests --- // --- mock FactStore for processor tests ---

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package contextengine package contextengine
import ( import (
@ -6,9 +10,9 @@ import (
"sync" "sync"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
) )
// --- Mock FactStore for provider tests --- // --- Mock FactStore for provider tests ---

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package lifecycle manages graceful shutdown with auto-save of session state, // Package lifecycle manages graceful shutdown with auto-save of session state,
// cache flush, and database closure. // cache flush, and database closure.
package lifecycle package lifecycle

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package lifecycle package lifecycle
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package lifecycle package lifecycle
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package lifecycle package lifecycle
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package orchestrator package orchestrator
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package orchestrator package orchestrator
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package orchestrator implements the DIP Heartbeat Orchestrator. // Package orchestrator implements the DIP Heartbeat Orchestrator.
// //
// The orchestrator runs a background loop with 4 modules: // The orchestrator runs a background loop with 4 modules:
@ -439,7 +443,7 @@ func (o *Orchestrator) stabilityCheck(ctx context.Context, result *HeartbeatResu
if err := o.store.Add(ctx, recoveryMarker); err == nil { if err := o.store.Add(ctx, recoveryMarker); err == nil {
o.mu.Lock() o.mu.Lock()
o.lastApoptosisWritten = time.Now() o.lastApoptosisWritten = time.Now()
o.mu.Unlock() o.mu.Unlock()
} }
} }
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package orchestrator package orchestrator
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -10,24 +14,24 @@ import (
// BehaviorProfile captures the runtime behavior of a component. // BehaviorProfile captures the runtime behavior of a component.
type BehaviorProfile struct { type BehaviorProfile struct {
Goroutines int `json:"goroutines"` Goroutines int `json:"goroutines"`
HeapAllocMB float64 `json:"heap_alloc_mb"` HeapAllocMB float64 `json:"heap_alloc_mb"`
HeapObjectsK float64 `json:"heap_objects_k"` HeapObjectsK float64 `json:"heap_objects_k"`
GCPauseMs float64 `json:"gc_pause_ms"` GCPauseMs float64 `json:"gc_pause_ms"`
NumGC uint32 `json:"num_gc"` NumGC uint32 `json:"num_gc"`
FileDescriptors int `json:"file_descriptors,omitempty"` FileDescriptors int `json:"file_descriptors,omitempty"`
CustomMetrics map[string]float64 `json:"custom_metrics,omitempty"` CustomMetrics map[string]float64 `json:"custom_metrics,omitempty"`
} }
// BehavioralAlert is emitted when a behavioral anomaly is detected. // BehavioralAlert is emitted when a behavioral anomaly is detected.
type BehavioralAlert struct { type BehavioralAlert struct {
Component string `json:"component"` Component string `json:"component"`
AnomalyType string `json:"anomaly_type"` // goroutine_leak, memory_leak, gc_pressure, etc. AnomalyType string `json:"anomaly_type"` // goroutine_leak, memory_leak, gc_pressure, etc.
Metric string `json:"metric"` Metric string `json:"metric"`
Current float64 `json:"current"` Current float64 `json:"current"`
Baseline float64 `json:"baseline"` Baseline float64 `json:"baseline"`
ZScore float64 `json:"z_score"` ZScore float64 `json:"z_score"`
Severity string `json:"severity"` Severity string `json:"severity"`
Timestamp time.Time `json:"timestamp"` Timestamp time.Time `json:"timestamp"`
} }
@ -35,12 +39,12 @@ type BehavioralAlert struct {
// It profiles the current process and compares against learned baselines. // It profiles the current process and compares against learned baselines.
// On Linux, eBPF hooks (immune/resilience_hooks.c) extend this to kernel level. // On Linux, eBPF hooks (immune/resilience_hooks.c) extend this to kernel level.
type BehavioralAnalyzer struct { type BehavioralAnalyzer struct {
mu sync.RWMutex mu sync.RWMutex
metricsDB *MetricsDB metricsDB *MetricsDB
alertBus chan BehavioralAlert alertBus chan BehavioralAlert
interval time.Duration interval time.Duration
component string // self component name component string // self component name
logger *slog.Logger logger *slog.Logger
} }
// NewBehavioralAnalyzer creates a new behavioral analyzer. // NewBehavioralAnalyzer creates a new behavioral analyzer.
@ -112,10 +116,10 @@ func (ba *BehavioralAnalyzer) storeMetrics(p BehaviorProfile) {
// detectAnomalies checks each metric against its baseline via Z-score. // detectAnomalies checks each metric against its baseline via Z-score.
func (ba *BehavioralAnalyzer) detectAnomalies(p BehaviorProfile) { func (ba *BehavioralAnalyzer) detectAnomalies(p BehaviorProfile) {
checks := []struct { checks := []struct {
metric string metric string
value float64 value float64
anomalyType string anomalyType string
severity string severity string
}{ }{
{"goroutines", float64(p.Goroutines), "goroutine_leak", "WARNING"}, {"goroutines", float64(p.Goroutines), "goroutine_leak", "WARNING"},
{"heap_alloc_mb", p.HeapAllocMB, "memory_leak", "CRITICAL"}, {"heap_alloc_mb", p.HeapAllocMB, "memory_leak", "CRITICAL"},

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -66,10 +70,10 @@ type Action struct {
// TriggerCondition defines when a healing strategy activates. // TriggerCondition defines when a healing strategy activates.
type TriggerCondition struct { type TriggerCondition struct {
Metrics []string `json:"metrics,omitempty"` Metrics []string `json:"metrics,omitempty"`
Statuses []ComponentStatus `json:"statuses,omitempty"` Statuses []ComponentStatus `json:"statuses,omitempty"`
ConsecutiveFailures int `json:"consecutive_failures"` ConsecutiveFailures int `json:"consecutive_failures"`
WithinWindow time.Duration `json:"within_window"` WithinWindow time.Duration `json:"within_window"`
} }
// RollbackPlan defines what happens if healing fails. // RollbackPlan defines what happens if healing fails.
@ -91,11 +95,11 @@ type HealingStrategy struct {
// Diagnosis is the result of root cause analysis. // Diagnosis is the result of root cause analysis.
type Diagnosis struct { type Diagnosis struct {
Component string `json:"component"` Component string `json:"component"`
Metric string `json:"metric"` Metric string `json:"metric"`
RootCause string `json:"root_cause"` RootCause string `json:"root_cause"`
Confidence float64 `json:"confidence"` Confidence float64 `json:"confidence"`
SuggestedFix string `json:"suggested_fix"` SuggestedFix string `json:"suggested_fix"`
RelatedAlerts []HealthAlert `json:"related_alerts,omitempty"` RelatedAlerts []HealthAlert `json:"related_alerts,omitempty"`
} }
@ -117,7 +121,7 @@ type HealingOperation struct {
// ActionLog records the execution of a single action. // ActionLog records the execution of a single action.
type ActionLog struct { type ActionLog struct {
Action ActionType `json:"action"` Action ActionType `json:"action"`
StartedAt time.Time `json:"started_at"` StartedAt time.Time `json:"started_at"`
Duration time.Duration `json:"duration"` Duration time.Duration `json:"duration"`
Success bool `json:"success"` Success bool `json:"success"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import "time" import "time"

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -63,12 +67,12 @@ type ComponentConfig struct {
// ComponentHealth tracks the health state of a single component. // ComponentHealth tracks the health state of a single component.
type ComponentHealth struct { type ComponentHealth struct {
Name string `json:"name"` Name string `json:"name"`
Status ComponentStatus `json:"status"` Status ComponentStatus `json:"status"`
Metrics map[string]float64 `json:"metrics"` Metrics map[string]float64 `json:"metrics"`
LastCheck time.Time `json:"last_check"` LastCheck time.Time `json:"last_check"`
Consecutive int `json:"consecutive_failures"` Consecutive int `json:"consecutive_failures"`
Config ComponentConfig `json:"-"` Config ComponentConfig `json:"-"`
} }
// HealthAlert represents a detected health anomaly. // HealthAlert represents a detected health anomaly.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -23,11 +27,11 @@ const (
// IntegrityReport is the full result of an integrity verification. // IntegrityReport is the full result of an integrity verification.
type IntegrityReport struct { type IntegrityReport struct {
Overall IntegrityStatus `json:"overall"` Overall IntegrityStatus `json:"overall"`
Timestamp time.Time `json:"timestamp"` Timestamp time.Time `json:"timestamp"`
Binaries map[string]BinaryStatus `json:"binaries,omitempty"` Binaries map[string]BinaryStatus `json:"binaries,omitempty"`
Chain *ChainStatus `json:"chain,omitempty"` Chain *ChainStatus `json:"chain,omitempty"`
Configs map[string]ConfigStatus `json:"configs,omitempty"` Configs map[string]ConfigStatus `json:"configs,omitempty"`
} }
// BinaryStatus is the integrity status of a single binary. // BinaryStatus is the integrity status of a single binary.
@ -56,13 +60,13 @@ type ConfigStatus struct {
// IntegrityVerifier performs periodic integrity checks on binaries, // IntegrityVerifier performs periodic integrity checks on binaries,
// decision chain, and config files. // decision chain, and config files.
type IntegrityVerifier struct { type IntegrityVerifier struct {
mu sync.RWMutex mu sync.RWMutex
binaryHashes map[string]string // path → expected SHA-256 binaryHashes map[string]string // path → expected SHA-256
configPaths []string // config files to verify configPaths []string // config files to verify
hmacKey []byte // key for config HMAC-SHA256 hmacKey []byte // key for config HMAC-SHA256
chainPath string // path to decision chain log chainPath string // path to decision chain log
logger *slog.Logger logger *slog.Logger
lastReport *IntegrityReport lastReport *IntegrityReport
} }
// NewIntegrityVerifier creates a new integrity verifier. // NewIntegrityVerifier creates a new integrity verifier.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package resilience implements the Sentinel Autonomous Resilience Layer (SARL). // Package resilience implements the Sentinel Autonomous Resilience Layer (SARL).
// //
// Five levels of autonomous self-recovery: // Five levels of autonomous self-recovery:

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -43,13 +47,13 @@ type ModeActionFunc func(mode EmergencyMode, action string, params map[string]in
// PreservationEngine manages emergency modes (safe/lockdown/apoptosis). // PreservationEngine manages emergency modes (safe/lockdown/apoptosis).
type PreservationEngine struct { type PreservationEngine struct {
mu sync.RWMutex mu sync.RWMutex
currentMode EmergencyMode currentMode EmergencyMode
activation *ModeActivation activation *ModeActivation
history []PreservationEvent history []PreservationEvent
actionFn ModeActionFunc actionFn ModeActionFunc
integrityFn func() IntegrityReport // pluggable integrity check integrityFn func() IntegrityReport // pluggable integrity check
logger *slog.Logger logger *slog.Logger
} }
// NewPreservationEngine creates a new preservation engine. // NewPreservationEngine creates a new preservation engine.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (
@ -12,58 +16,58 @@ import (
type PlaybookStatus string type PlaybookStatus string
const ( const (
PlaybookPending PlaybookStatus = "PENDING" PlaybookPending PlaybookStatus = "PENDING"
PlaybookRunning PlaybookStatus = "RUNNING" PlaybookRunning PlaybookStatus = "RUNNING"
PlaybookSucceeded PlaybookStatus = "SUCCEEDED" PlaybookSucceeded PlaybookStatus = "SUCCEEDED"
PlaybookFailed PlaybookStatus = "FAILED" PlaybookFailed PlaybookStatus = "FAILED"
PlaybookRolledBack PlaybookStatus = "ROLLED_BACK" PlaybookRolledBack PlaybookStatus = "ROLLED_BACK"
) )
// PlaybookStep is a single step in a recovery playbook. // PlaybookStep is a single step in a recovery playbook.
type PlaybookStep struct { type PlaybookStep struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` // shell, api, consensus, crypto, systemd, http, prometheus Type string `json:"type"` // shell, api, consensus, crypto, systemd, http, prometheus
Timeout time.Duration `json:"timeout"` Timeout time.Duration `json:"timeout"`
Retries int `json:"retries"` Retries int `json:"retries"`
Params map[string]interface{} `json:"params,omitempty"` Params map[string]interface{} `json:"params,omitempty"`
OnError string `json:"on_error"` // abort, continue, rollback OnError string `json:"on_error"` // abort, continue, rollback
Condition string `json:"condition,omitempty"` // prerequisite condition Condition string `json:"condition,omitempty"` // prerequisite condition
} }
// Playbook defines a complete recovery procedure. // Playbook defines a complete recovery procedure.
type Playbook struct { type Playbook struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Version string `json:"version"` Version string `json:"version"`
TriggerMetric string `json:"trigger_metric"` TriggerMetric string `json:"trigger_metric"`
TriggerSeverity string `json:"trigger_severity"` TriggerSeverity string `json:"trigger_severity"`
DiagnosisChecks []PlaybookStep `json:"diagnosis_checks"` DiagnosisChecks []PlaybookStep `json:"diagnosis_checks"`
Actions []PlaybookStep `json:"actions"` Actions []PlaybookStep `json:"actions"`
RollbackActions []PlaybookStep `json:"rollback_actions"` RollbackActions []PlaybookStep `json:"rollback_actions"`
SuccessCriteria []string `json:"success_criteria"` SuccessCriteria []string `json:"success_criteria"`
} }
// PlaybookExecution tracks a single playbook run. // PlaybookExecution tracks a single playbook run.
type PlaybookExecution struct { type PlaybookExecution struct {
ID string `json:"id"` ID string `json:"id"`
PlaybookID string `json:"playbook_id"` PlaybookID string `json:"playbook_id"`
Component string `json:"component"` Component string `json:"component"`
Status PlaybookStatus `json:"status"` Status PlaybookStatus `json:"status"`
StartedAt time.Time `json:"started_at"` StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at,omitempty"` CompletedAt time.Time `json:"completed_at,omitempty"`
StepsRun []StepResult `json:"steps_run"` StepsRun []StepResult `json:"steps_run"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
} }
// StepResult records the execution of a single playbook step. // StepResult records the execution of a single playbook step.
type StepResult struct { type StepResult struct {
StepID string `json:"step_id"` StepID string `json:"step_id"`
StepName string `json:"step_name"` StepName string `json:"step_name"`
Success bool `json:"success"` Success bool `json:"success"`
Duration time.Duration `json:"duration"` Duration time.Duration `json:"duration"`
Output string `json:"output,omitempty"` Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
} }
// PlaybookExecutorFunc runs a single playbook step. // PlaybookExecutorFunc runs a single playbook step.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resilience package resilience
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package resources provides MCP resource implementations. // Package resources provides MCP resource implementations.
package resources package resources

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package resources package resources
import ( import (
@ -5,11 +9,11 @@ import (
"encoding/json" "encoding/json"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory" "github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/domain/session" "github.com/syntrex-lab/gomcp/internal/domain/session"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite" "github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func newTestProvider(t *testing.T) (*Provider, *sqlite.DB, *sqlite.DB) { func newTestProvider(t *testing.T) (*Provider, *sqlite.DB, *sqlite.DB) {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -14,10 +18,10 @@ import (
type ApprovalStatus string type ApprovalStatus string
const ( const (
ApprovalPending ApprovalStatus = "pending" ApprovalPending ApprovalStatus = "pending"
ApprovalApproved ApprovalStatus = "approved" ApprovalApproved ApprovalStatus = "approved"
ApprovalDenied ApprovalStatus = "denied" ApprovalDenied ApprovalStatus = "denied"
ApprovalExpired ApprovalStatus = "expired" ApprovalExpired ApprovalStatus = "expired"
ApprovalAutoApproved ApprovalStatus = "auto_approved" ApprovalAutoApproved ApprovalStatus = "auto_approved"
) )

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -14,11 +18,11 @@ import (
// AISignatureDB contains known AI service signatures for detection. // AISignatureDB contains known AI service signatures for detection.
type AISignatureDB struct { type AISignatureDB struct {
mu sync.RWMutex mu sync.RWMutex
services []AIServiceInfo services []AIServiceInfo
domainPatterns []*domainPattern domainPatterns []*domainPattern
apiKeyPatterns []*APIKeyPattern apiKeyPatterns []*APIKeyPattern
httpSignatures []string httpSignatures []string
} }
type domainPattern struct { type domainPattern struct {
@ -62,14 +66,14 @@ func (db *AISignatureDB) loadDefaults() {
// HTTP header signatures. // HTTP header signatures.
db.httpSignatures = []string{ db.httpSignatures = []string{
"authorization: bearer sk-", // OpenAI "authorization: bearer sk-", // OpenAI
"authorization: bearer ant-", // Anthropic "authorization: bearer ant-", // Anthropic
"x-api-key: sk-ant-", // Anthropic v2 "x-api-key: sk-ant-", // Anthropic v2
"x-goog-api-key:", // Google AI "x-goog-api-key:", // Google AI
"authorization: bearer gsk_", // Groq "authorization: bearer gsk_", // Groq
"authorization: bearer hf_", // HuggingFace "authorization: bearer hf_", // HuggingFace
"api-key:", // Azure OpenAI (x-ms header) "api-key:", // Azure OpenAI (x-ms header)
"x-api-key: xai-", // xAI Grok API "x-api-key: xai-", // xAI Grok API
} }
} }
@ -246,7 +250,7 @@ func (nd *NetworkDetector) SignatureDB() *AISignatureDB {
// UserBehaviorProfile tracks a user's AI access behavior for anomaly detection. // UserBehaviorProfile tracks a user's AI access behavior for anomaly detection.
type UserBehaviorProfile struct { type UserBehaviorProfile struct {
UserID string `json:"user_id"` UserID string `json:"user_id"`
AccessFrequency float64 `json:"access_frequency"` // Requests per hour AccessFrequency float64 `json:"access_frequency"` // Requests per hour
DataVolumePerHour float64 `json:"data_volume_per_hour"` // Bytes per hour DataVolumePerHour float64 `json:"data_volume_per_hour"` // Bytes per hour
KnownDestinations []string `json:"known_destinations"` KnownDestinations []string `json:"known_destinations"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -17,62 +21,62 @@ import (
type DocReviewStatus string type DocReviewStatus string
const ( const (
DocReviewPending DocReviewStatus = "pending" DocReviewPending DocReviewStatus = "pending"
DocReviewScanning DocReviewStatus = "scanning" DocReviewScanning DocReviewStatus = "scanning"
DocReviewClean DocReviewStatus = "clean" DocReviewClean DocReviewStatus = "clean"
DocReviewRedacted DocReviewStatus = "redacted" DocReviewRedacted DocReviewStatus = "redacted"
DocReviewBlocked DocReviewStatus = "blocked" DocReviewBlocked DocReviewStatus = "blocked"
DocReviewApproved DocReviewStatus = "approved" DocReviewApproved DocReviewStatus = "approved"
) )
// ScanResult contains the results of scanning a document. // ScanResult contains the results of scanning a document.
type ScanResult struct { type ScanResult struct {
DocumentID string `json:"document_id"` DocumentID string `json:"document_id"`
Status DocReviewStatus `json:"status"` Status DocReviewStatus `json:"status"`
PIIFound []PIIMatch `json:"pii_found,omitempty"` PIIFound []PIIMatch `json:"pii_found,omitempty"`
SecretsFound []SecretMatch `json:"secrets_found,omitempty"` SecretsFound []SecretMatch `json:"secrets_found,omitempty"`
DataClass DataClassification `json:"data_classification"` DataClass DataClassification `json:"data_classification"`
ContentHash string `json:"content_hash"` ContentHash string `json:"content_hash"`
ScannedAt time.Time `json:"scanned_at"` ScannedAt time.Time `json:"scanned_at"`
SizeBytes int `json:"size_bytes"` SizeBytes int `json:"size_bytes"`
} }
// PIIMatch represents a detected PII pattern in content. // PIIMatch represents a detected PII pattern in content.
type PIIMatch struct { type PIIMatch struct {
Type string `json:"type"` // "email", "phone", "ssn", "credit_card", "passport" Type string `json:"type"` // "email", "phone", "ssn", "credit_card", "passport"
Location int `json:"location"` // Character offset Location int `json:"location"` // Character offset
Length int `json:"length"` Length int `json:"length"`
Masked string `json:"masked"` // Redacted value, e.g., "j***@example.com" Masked string `json:"masked"` // Redacted value, e.g., "j***@example.com"
} }
// SecretMatch represents a detected secret/API key in content. // SecretMatch represents a detected secret/API key in content.
type SecretMatch struct { type SecretMatch struct {
Type string `json:"type"` // "api_key", "password", "token", "private_key" Type string `json:"type"` // "api_key", "password", "token", "private_key"
Location int `json:"location"` Location int `json:"location"`
Length int `json:"length"` Length int `json:"length"`
Provider string `json:"provider"` // "OpenAI", "AWS", "GitHub", etc. Provider string `json:"provider"` // "OpenAI", "AWS", "GitHub", etc.
} }
// DocBridge manages document scanning, redaction, and review workflow. // DocBridge manages document scanning, redaction, and review workflow.
type DocBridge struct { type DocBridge struct {
mu sync.RWMutex mu sync.RWMutex
reviews map[string]*ScanResult reviews map[string]*ScanResult
piiPatterns []*piiPattern piiPatterns []*piiPattern
secretPats []secretPattern // Cached compiled patterns secretPats []secretPattern // Cached compiled patterns
signatures *AISignatureDB // Reused across scans signatures *AISignatureDB // Reused across scans
maxDocSize int // bytes maxDocSize int // bytes
} }
type piiPattern struct { type piiPattern struct {
name string name string
regex *regexp.Regexp regex *regexp.Regexp
maskFn func(string) string maskFn func(string) string
} }
// NewDocBridge creates a new Document Review Bridge. // NewDocBridge creates a new Document Review Bridge.
func NewDocBridge() *DocBridge { func NewDocBridge() *DocBridge {
return &DocBridge{ return &DocBridge{
reviews: make(map[string]*ScanResult), reviews: make(map[string]*ScanResult),
piiPatterns: defaultPIIPatterns(), piiPatterns: defaultPIIPatterns(),
secretPats: secretPatterns(), secretPats: secretPatterns(),
signatures: NewAISignatureDB(), signatures: NewAISignatureDB(),

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -134,7 +138,7 @@ func (fm *FallbackManager) logDetectOnly(target, reason string) {
DetectionMethod: DetectNetwork, DetectionMethod: DetectNetwork,
Action: "detect_only", Action: "detect_only",
Metadata: map[string]string{ Metadata: map[string]string{
"reason": reason, "reason": reason,
"fallback_strategy": fm.strategy, "fallback_strategy": fm.strategy,
}, },
Timestamp: time.Now(), Timestamp: time.Now(),

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -19,13 +23,13 @@ const (
// PluginHealth tracks the health state of a single plugin. // PluginHealth tracks the health state of a single plugin.
type PluginHealth struct { type PluginHealth struct {
Vendor string `json:"vendor"` Vendor string `json:"vendor"`
Type PluginType `json:"type"` Type PluginType `json:"type"`
Status PluginStatus `json:"status"` Status PluginStatus `json:"status"`
LastCheck time.Time `json:"last_check"` LastCheck time.Time `json:"last_check"`
Consecutive int `json:"consecutive_failures"` Consecutive int `json:"consecutive_failures"`
Latency time.Duration `json:"latency"` Latency time.Duration `json:"latency"`
LastError string `json:"last_error,omitempty"` LastError string `json:"last_error,omitempty"`
} }
// MaxConsecutivePluginFailures before marking offline. // MaxConsecutivePluginFailures before marking offline.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package shadow_ai implements the Sentinel Shadow AI Control Module. // Package shadow_ai implements the Sentinel Shadow AI Control Module.
// //
// Five levels of shadow AI management: // Five levels of shadow AI management:
@ -107,7 +111,7 @@ type PluginConfig struct {
// IntegrationConfig is the top-level Shadow AI configuration. // IntegrationConfig is the top-level Shadow AI configuration.
type IntegrationConfig struct { type IntegrationConfig struct {
Plugins []PluginConfig `yaml:"plugins" json:"plugins"` Plugins []PluginConfig `yaml:"plugins" json:"plugins"`
FallbackStrategy string `yaml:"fallback_strategy" json:"fallback_strategy"` // "detect_only" | "alert_only" FallbackStrategy string `yaml:"fallback_strategy" json:"fallback_strategy"` // "detect_only" | "alert_only"
HealthCheckInterval time.Duration `yaml:"health_check_interval" json:"health_check_interval"` // default: 30s HealthCheckInterval time.Duration `yaml:"health_check_interval" json:"health_check_interval"` // default: 30s
} }
@ -117,13 +121,13 @@ type IntegrationConfig struct {
type DetectionMethod string type DetectionMethod string
const ( const (
DetectNetwork DetectionMethod = "network" // Domain/IP match DetectNetwork DetectionMethod = "network" // Domain/IP match
DetectHTTP DetectionMethod = "http" // HTTP header signature DetectHTTP DetectionMethod = "http" // HTTP header signature
DetectTLS DetectionMethod = "tls" // TLS/JA3 fingerprint DetectTLS DetectionMethod = "tls" // TLS/JA3 fingerprint
DetectProcess DetectionMethod = "process" // AI tool process execution DetectProcess DetectionMethod = "process" // AI tool process execution
DetectAPIKey DetectionMethod = "api_key" // AI API key in payload DetectAPIKey DetectionMethod = "api_key" // AI API key in payload
DetectBehavioral DetectionMethod = "behavioral" // Anomalous AI access pattern DetectBehavioral DetectionMethod = "behavioral" // Anomalous AI access pattern
DetectClipboard DetectionMethod = "clipboard" // Large clipboard → AI browser pattern DetectClipboard DetectionMethod = "clipboard" // Large clipboard → AI browser pattern
) )
// DataClassification determines the approval tier required. // DataClassification determines the approval tier required.
@ -141,22 +145,22 @@ type ShadowAIEvent struct {
ID string `json:"id"` ID string `json:"id"`
UserID string `json:"user_id"` UserID string `json:"user_id"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Destination string `json:"destination"` // Target AI service domain/IP Destination string `json:"destination"` // Target AI service domain/IP
AIService string `json:"ai_service"` // "chatgpt", "claude", "gemini", etc. AIService string `json:"ai_service"` // "chatgpt", "claude", "gemini", etc.
DetectionMethod DetectionMethod `json:"detection_method"` DetectionMethod DetectionMethod `json:"detection_method"`
Action string `json:"action"` // "blocked", "allowed", "pending" Action string `json:"action"` // "blocked", "allowed", "pending"
EnforcedBy string `json:"enforced_by"` // Plugin vendor that enforced EnforcedBy string `json:"enforced_by"` // Plugin vendor that enforced
DataSize int64 `json:"data_size"` // Bytes sent to AI DataSize int64 `json:"data_size"` // Bytes sent to AI
Timestamp time.Time `json:"timestamp"` Timestamp time.Time `json:"timestamp"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
// AIServiceInfo describes a known AI service for signature matching. // AIServiceInfo describes a known AI service for signature matching.
type AIServiceInfo struct { type AIServiceInfo struct {
Name string `json:"name"` // "ChatGPT", "Claude", "Gemini" Name string `json:"name"` // "ChatGPT", "Claude", "Gemini"
Vendor string `json:"vendor"` // "OpenAI", "Anthropic", "Google" Vendor string `json:"vendor"` // "OpenAI", "Anthropic", "Google"
Domains []string `json:"domains"` // ["*.openai.com", "chat.openai.com"] Domains []string `json:"domains"` // ["*.openai.com", "chat.openai.com"]
Category string `json:"category"` // "llm", "image_gen", "code_assist" Category string `json:"category"` // "llm", "image_gen", "code_assist"
} }
// BlockRequest is an API request to manually block a target. // BlockRequest is an API request to manually block a target.
@ -188,27 +192,27 @@ type Violator struct {
// ApprovalTier defines the approval requirements for a data classification level. // ApprovalTier defines the approval requirements for a data classification level.
type ApprovalTier struct { type ApprovalTier struct {
Name string `yaml:"name" json:"name"` Name string `yaml:"name" json:"name"`
DataClass DataClassification `yaml:"data_class" json:"data_class"` DataClass DataClassification `yaml:"data_class" json:"data_class"`
ApprovalNeeded []string `yaml:"approval_needed" json:"approval_needed"` // ["manager"], ["manager", "soc"], ["ciso"] ApprovalNeeded []string `yaml:"approval_needed" json:"approval_needed"` // ["manager"], ["manager", "soc"], ["ciso"]
SLA time.Duration `yaml:"sla" json:"sla"` SLA time.Duration `yaml:"sla" json:"sla"`
AutoApprove bool `yaml:"auto_approve" json:"auto_approve"` AutoApprove bool `yaml:"auto_approve" json:"auto_approve"`
} }
// ApprovalRequest tracks a pending approval for AI access. // ApprovalRequest tracks a pending approval for AI access.
type ApprovalRequest struct { type ApprovalRequest struct {
ID string `json:"id"` ID string `json:"id"`
DocID string `json:"doc_id"` DocID string `json:"doc_id"`
UserID string `json:"user_id"` UserID string `json:"user_id"`
Tier string `json:"tier"` Tier string `json:"tier"`
DataClass DataClassification `json:"data_class"` DataClass DataClassification `json:"data_class"`
Status string `json:"status"` // "pending", "approved", "denied", "expired" Status string `json:"status"` // "pending", "approved", "denied", "expired"
ApprovedBy string `json:"approved_by,omitempty"` ApprovedBy string `json:"approved_by,omitempty"`
DeniedBy string `json:"denied_by,omitempty"` DeniedBy string `json:"denied_by,omitempty"`
Reason string `json:"reason,omitempty"` Reason string `json:"reason,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"` ExpiresAt time.Time `json:"expires_at"`
ResolvedAt time.Time `json:"resolved_at,omitempty"` ResolvedAt time.Time `json:"resolved_at,omitempty"`
} }
// ComplianceReport is the Shadow AI compliance report for GDPR/SOC2/EU AI Act. // ComplianceReport is the Shadow AI compliance report for GDPR/SOC2/EU AI Act.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -14,9 +18,9 @@ import (
// CheckPointEnforcer is a stub implementation for Check Point firewalls. // CheckPointEnforcer is a stub implementation for Check Point firewalls.
type CheckPointEnforcer struct { type CheckPointEnforcer struct {
apiURL string apiURL string
apiKey string apiKey string
logger *slog.Logger logger *slog.Logger
} }
func NewCheckPointEnforcer() *CheckPointEnforcer { func NewCheckPointEnforcer() *CheckPointEnforcer {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -13,10 +17,10 @@ type PluginFactory func() interface{}
// Thread-safe via sync.RWMutex. // Thread-safe via sync.RWMutex.
type PluginRegistry struct { type PluginRegistry struct {
mu sync.RWMutex mu sync.RWMutex
plugins map[string]interface{} // vendor → plugin instance plugins map[string]interface{} // vendor → plugin instance
factories map[string]PluginFactory // "type_vendor" → factory factories map[string]PluginFactory // "type_vendor" → factory
configs map[string]*PluginConfig // vendor → config configs map[string]*PluginConfig // vendor → config
health map[string]*PluginHealth // vendor → health status health map[string]*PluginHealth // vendor → health status
logger *slog.Logger logger *slog.Logger
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -36,7 +40,7 @@ func (m *mockFirewall) BlockDomain(_ context.Context, domain string, _ string) e
return nil return nil
} }
func (m *mockFirewall) UnblockIP(_ context.Context, _ string) error { return nil } func (m *mockFirewall) UnblockIP(_ context.Context, _ string) error { return nil }
func (m *mockFirewall) UnblockDomain(_ context.Context, _ string) error { return nil } func (m *mockFirewall) UnblockDomain(_ context.Context, _ string) error { return nil }
func (m *mockFirewall) HealthCheck(_ context.Context) error { func (m *mockFirewall) HealthCheck(_ context.Context) error {
@ -61,8 +65,8 @@ func (m *mockEDR) IsolateHost(_ context.Context, hostname string) error {
m.isolated = append(m.isolated, hostname) m.isolated = append(m.isolated, hostname)
return nil return nil
} }
func (m *mockEDR) ReleaseHost(_ context.Context, _ string) error { return nil } func (m *mockEDR) ReleaseHost(_ context.Context, _ string) error { return nil }
func (m *mockEDR) KillProcess(_ context.Context, _ string, _ int) error { return nil } func (m *mockEDR) KillProcess(_ context.Context, _ string, _ int) error { return nil }
func (m *mockEDR) QuarantineFile(_ context.Context, _ string, _ string) error { return nil } func (m *mockEDR) QuarantineFile(_ context.Context, _ string, _ string) error { return nil }
func (m *mockEDR) HealthCheck(_ context.Context) error { func (m *mockEDR) HealthCheck(_ context.Context) error {
@ -87,8 +91,8 @@ func (m *mockGateway) BlockURL(_ context.Context, url string, _ string) error {
m.blockedURLs = append(m.blockedURLs, url) m.blockedURLs = append(m.blockedURLs, url)
return nil return nil
} }
func (m *mockGateway) UnblockURL(_ context.Context, _ string) error { return nil } func (m *mockGateway) UnblockURL(_ context.Context, _ string) error { return nil }
func (m *mockGateway) BlockCategory(_ context.Context, _ string) error { return nil } func (m *mockGateway) BlockCategory(_ context.Context, _ string) error { return nil }
func (m *mockGateway) HealthCheck(_ context.Context) error { func (m *mockGateway) HealthCheck(_ context.Context) error {
if !m.healthy { if !m.healthy {
@ -1075,8 +1079,8 @@ func TestApproval_ExpireOverdue(t *testing.T) {
func TestApproval_Stats(t *testing.T) { func TestApproval_Stats(t *testing.T) {
ae := NewApprovalEngine() ae := NewApprovalEngine()
ae.SubmitRequest("u1", "d1", DataPublic) // auto ae.SubmitRequest("u1", "d1", DataPublic) // auto
ae.SubmitRequest("u2", "d2", DataInternal) // pending ae.SubmitRequest("u2", "d2", DataInternal) // pending
req := ae.SubmitRequest("u3", "d3", DataConfidential) // pending req := ae.SubmitRequest("u3", "d3", DataConfidential) // pending
_ = ae.Deny(req.ID, "ciso", "no") _ = ae.Deny(req.ID, "ciso", "no")
@ -1222,4 +1226,3 @@ func TestController_ReviewDocument_WithSecrets(t *testing.T) {
t.Fatal("blocked docs should not create approval") t.Fatal("blocked docs should not create approval")
} }
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package shadow_ai package shadow_ai
import ( import (
@ -19,7 +23,7 @@ type ShadowAIController struct {
behavioral *BehavioralDetector behavioral *BehavioralDetector
docBridge *DocBridge docBridge *DocBridge
approval *ApprovalEngine approval *ApprovalEngine
events []ShadowAIEvent // In-memory event store (bounded) events []ShadowAIEvent // In-memory event store (bounded)
maxEvents int maxEvents int
socEventFn func(source, severity, category, description string, meta map[string]string) // Bridge to SOC event bus socEventFn func(source, severity, category, description string, meta map[string]string) // Bridge to SOC event bus
logger *slog.Logger logger *slog.Logger

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package sidecar package sidecar
import ( import (
@ -42,15 +46,15 @@ func NewBusClient(baseURL, sensorID, apiKey string) *BusClient {
// ingestPayload matches the SOC ingest API expected JSON. // ingestPayload matches the SOC ingest API expected JSON.
type ingestPayload struct { type ingestPayload struct {
Source string `json:"source"` Source string `json:"source"`
SensorID string `json:"sensor_id"` SensorID string `json:"sensor_id"`
SensorKey string `json:"sensor_key,omitempty"` SensorKey string `json:"sensor_key,omitempty"`
Severity string `json:"severity"` Severity string `json:"severity"`
Category string `json:"category"` Category string `json:"category"`
Subcategory string `json:"subcategory,omitempty"` Subcategory string `json:"subcategory,omitempty"`
Confidence float64 `json:"confidence"` Confidence float64 `json:"confidence"`
Description string `json:"description"` Description string `json:"description"`
SessionID string `json:"session_id,omitempty"` SessionID string `json:"session_id,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
// SendEvent posts a SOCEvent to the Event Bus. // SendEvent posts a SOCEvent to the Event Bus.
@ -58,15 +62,15 @@ type ingestPayload struct {
func (c *BusClient) SendEvent(ctx context.Context, evt *domsoc.SOCEvent) error { func (c *BusClient) SendEvent(ctx context.Context, evt *domsoc.SOCEvent) error {
payload := ingestPayload{ payload := ingestPayload{
Source: string(evt.Source), Source: string(evt.Source),
SensorID: c.sensorID, SensorID: c.sensorID,
SensorKey: c.apiKey, SensorKey: c.apiKey,
Severity: string(evt.Severity), Severity: string(evt.Severity),
Category: evt.Category, Category: evt.Category,
Subcategory: evt.Subcategory, Subcategory: evt.Subcategory,
Confidence: evt.Confidence, Confidence: evt.Confidence,
Description: evt.Description, Description: evt.Description,
SessionID: evt.SessionID, SessionID: evt.SessionID,
Metadata: evt.Metadata, Metadata: evt.Metadata,
} }
body, err := json.Marshal(payload) body, err := json.Marshal(payload)

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package sidecar implements the Universal Sidecar (§5.5) — a zero-dependency // Package sidecar implements the Universal Sidecar (§5.5) — a zero-dependency
// Go binary that runs alongside SENTINEL sensors, tails their STDOUT/logs, // Go binary that runs alongside SENTINEL sensors, tails their STDOUT/logs,
// and pushes parsed security events to the SOC Event Bus. // and pushes parsed security events to the SOC Event Bus.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package sidecar package sidecar
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package sidecar package sidecar
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package sidecar package sidecar
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package soc provides SOC analytics: event trends, severity distribution, // Package soc provides SOC analytics: event trends, severity distribution,
// top sources, MITRE ATT&CK coverage, and time-series aggregation. // top sources, MITRE ATT&CK coverage, and time-series aggregation.
package soc package soc

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (
@ -524,4 +528,3 @@ func TestE2E_CrescendoEscalation(t *testing.T) {
assert.Equal(t, domsoc.SeverityCritical, lastInc.Severity) assert.Equal(t, domsoc.SeverityCritical, lastInc.Severity)
assert.Contains(t, lastInc.MITREMapping, "T1059") assert.Contains(t, lastInc.MITREMapping, "T1059")
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package soc provides application services for the SENTINEL AI SOC subsystem. // Package soc provides application services for the SENTINEL AI SOC subsystem.
package soc package soc
@ -29,14 +33,14 @@ const (
// Service orchestrates the SOC event pipeline: // Service orchestrates the SOC event pipeline:
// Step 0: Secret Scanner (INVARIANT) → DIP → Decision Logger → Persist → Correlation. // Step 0: Secret Scanner (INVARIANT) → DIP → Decision Logger → Persist → Correlation.
type Service struct { type Service struct {
mu sync.RWMutex mu sync.RWMutex
repo domsoc.SOCRepository repo domsoc.SOCRepository
logger *audit.DecisionLogger logger *audit.DecisionLogger
rules []domsoc.SOCCorrelationRule rules []domsoc.SOCCorrelationRule
playbookEngine *domsoc.PlaybookEngine playbookEngine *domsoc.PlaybookEngine
executorRegistry *domsoc.ExecutorRegistry executorRegistry *domsoc.ExecutorRegistry
sensors map[string]*domsoc.Sensor sensors map[string]*domsoc.Sensor
draining bool // §15.7: graceful shutdown mode — rejects new events draining bool // §15.7: graceful shutdown mode — rejects new events
// Alert Clustering engine (§7.6): groups related alerts. // Alert Clustering engine (§7.6): groups related alerts.
clusterEngine *domsoc.ClusterEngine clusterEngine *domsoc.ClusterEngine
@ -45,8 +49,8 @@ type Service struct {
eventBus *domsoc.EventBus eventBus *domsoc.EventBus
// Rate limiting per sensor (§17.3): sensorID → timestamps of recent events. // Rate limiting per sensor (§17.3): sensorID → timestamps of recent events.
sensorRates map[string][]time.Time sensorRates map[string][]time.Time
rateLimitDisabled bool rateLimitDisabled bool
// Sensor authentication (§17.3 T-01): sensorID → pre-shared key. // Sensor authentication (§17.3 T-01): sensorID → pre-shared key.
sensorKeys map[string]string sensorKeys map[string]string
@ -85,9 +89,9 @@ func NewService(repo domsoc.SOCRepository, logger *audit.DecisionLogger) *Servic
// Build executor registry with all SOAR action handlers // Build executor registry with all SOAR action handlers
reg := domsoc.NewExecutorRegistry() reg := domsoc.NewExecutorRegistry()
reg.Register(&domsoc.BlockIPExecutor{}) reg.Register(&domsoc.BlockIPExecutor{})
reg.Register(domsoc.NewNotifyExecutor("")) // URL configured via SetNotifyURL() reg.Register(domsoc.NewNotifyExecutor("")) // URL configured via SetNotifyURL()
reg.Register(domsoc.NewQuarantineExecutor()) reg.Register(domsoc.NewQuarantineExecutor())
reg.Register(domsoc.NewEscalateExecutor("")) // URL configured via SetEscalateURL() reg.Register(domsoc.NewEscalateExecutor("")) // URL configured via SetEscalateURL()
// Webhook executor configured separately via SetWebhookConfig() // Webhook executor configured separately via SetWebhookConfig()
// Create playbook engine with live executor handler (not just logging) // Create playbook engine with live executor handler (not just logging)
@ -100,21 +104,21 @@ func NewService(repo domsoc.SOCRepository, logger *audit.DecisionLogger) *Servic
) )
return &Service{ return &Service{
repo: repo, repo: repo,
logger: logger, logger: logger,
rules: domsoc.DefaultSOCCorrelationRules(), rules: domsoc.DefaultSOCCorrelationRules(),
playbookEngine: pe, playbookEngine: pe,
executorRegistry: reg, executorRegistry: reg,
sensors: make(map[string]*domsoc.Sensor), sensors: make(map[string]*domsoc.Sensor),
clusterEngine: domsoc.NewClusterEngine(domsoc.DefaultClusterConfig()), clusterEngine: domsoc.NewClusterEngine(domsoc.DefaultClusterConfig()),
eventBus: domsoc.NewEventBus(256), eventBus: domsoc.NewEventBus(256),
sensorRates: make(map[string][]time.Time), sensorRates: make(map[string][]time.Time),
zeroG: domsoc.NewZeroGMode(), zeroG: domsoc.NewZeroGMode(),
p2pSync: domsoc.NewP2PSyncService(), p2pSync: domsoc.NewP2PSyncService(),
anomaly: domsoc.NewAnomalyDetector(), anomaly: domsoc.NewAnomalyDetector(),
threatIntelEngine: domsoc.NewThreatIntelEngine(), threatIntelEngine: domsoc.NewThreatIntelEngine(),
retention: domsoc.NewDataRetentionPolicy(), retention: domsoc.NewDataRetentionPolicy(),
scanSemaphore: make(chan struct{}, 8), // §20.1: max 8 concurrent scans scanSemaphore: make(chan struct{}, 8), // §20.1: max 8 concurrent scans
} }
} }
@ -213,7 +217,6 @@ func (s *Service) TestWebhook() []WebhookResult {
return wh.NotifyIncident("webhook_test", testIncident) return wh.NotifyIncident("webhook_test", testIncident)
} }
// Drain puts the service into drain mode (§15.7 Stage 1). // Drain puts the service into drain mode (§15.7 Stage 1).
// New events are rejected with ErrDraining; existing processing continues. // New events are rejected with ErrDraining; existing processing continues.
func (s *Service) Drain() { func (s *Service) Drain() {
@ -301,6 +304,7 @@ func (s *Service) runRetentionPurge() {
} }
} }
} }
// IngestEvent processes an incoming security event through the SOC pipeline. // IngestEvent processes an incoming security event through the SOC pipeline.
// Returns the event ID and any incident created by correlation. // Returns the event ID and any incident created by correlation.
// //
@ -523,7 +527,7 @@ func (s *Service) isRateLimited(sensorID string) bool {
pruned = append(pruned, ts) pruned = append(pruned, ts)
} }
} }
rateLimited := len(pruned) >= MaxEventsPerSecondPerSensor rateLimited := len(pruned) >= MaxEventsPerSecondPerSensor
if !rateLimited { if !rateLimited {
pruned = append(pruned, now) pruned = append(pruned, now)
@ -768,9 +772,9 @@ func (s *Service) GetRecentDecisions(limit int) []map[string]any {
return []map[string]any{ return []map[string]any{
{ {
"total_decisions": s.logger.Count(), "total_decisions": s.logger.Count(),
"hash_chain": s.logger.PrevHash(), "hash_chain": s.logger.PrevHash(),
"log_path": s.logger.Path(), "log_path": s.logger.Path(),
"status": "operational", "status": "operational",
}, },
} }
} }
@ -979,10 +983,10 @@ func (s *Service) ListIncidentsAdvanced(f IncidentFilter) (*IncidentFilterResult
// BulkAction defines a batch operation on incidents. // BulkAction defines a batch operation on incidents.
type BulkAction struct { type BulkAction struct {
Action string `json:"action"` // assign, status, close, delete Action string `json:"action"` // assign, status, close, delete
IncidentIDs []string `json:"incident_ids"` IncidentIDs []string `json:"incident_ids"`
Value string `json:"value"` // analyst email, new status Value string `json:"value"` // analyst email, new status
Actor string `json:"actor"` // who initiated Actor string `json:"actor"` // who initiated
} }
// BulkActionResult is the result of a batch operation. // BulkActionResult is the result of a batch operation.
@ -1030,12 +1034,12 @@ type SLAThreshold struct {
// SLAStatus represents an incident's SLA compliance state. // SLAStatus represents an incident's SLA compliance state.
type SLAStatus struct { type SLAStatus struct {
ResponseBreached bool `json:"response_breached"` ResponseBreached bool `json:"response_breached"`
ResolutionBreached bool `json:"resolution_breached"` ResolutionBreached bool `json:"resolution_breached"`
ResponseRemaining float64 `json:"response_remaining_min"` // minutes remaining (negative = breached) ResponseRemaining float64 `json:"response_remaining_min"` // minutes remaining (negative = breached)
ResolutionRemaining float64 `json:"resolution_remaining_min"` ResolutionRemaining float64 `json:"resolution_remaining_min"`
ResponseTarget float64 `json:"response_target_min"` ResponseTarget float64 `json:"response_target_min"`
ResolutionTarget float64 `json:"resolution_target_min"` ResolutionTarget float64 `json:"resolution_target_min"`
} }
// DefaultSLAThresholds returns SLA targets per severity. // DefaultSLAThresholds returns SLA targets per severity.
@ -1161,7 +1165,7 @@ func (s *Service) Dashboard(tenantID string) (*DashboardData, error) {
return nil, err return nil, err
} }
lastHourEvents, err := s.repo.CountEventsSince(tenantID, time.Now().Add(-1 * time.Hour)) lastHourEvents, err := s.repo.CountEventsSince(tenantID, time.Now().Add(-1*time.Hour))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (
@ -17,7 +21,7 @@ type STIXBundle struct {
// STIXObject represents a generic STIX 2.1 object. // STIXObject represents a generic STIX 2.1 object.
type STIXObject struct { type STIXObject struct {
Type string `json:"type"` // indicator, malware, attack-pattern, etc. Type string `json:"type"` // indicator, malware, attack-pattern, etc.
ID string `json:"id"` ID string `json:"id"`
Created time.Time `json:"created"` Created time.Time `json:"created"`
Modified time.Time `json:"modified"` Modified time.Time `json:"modified"`

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (
@ -111,8 +115,8 @@ func TestProcessBundle_FiltersNonIndicators(t *testing.T) {
Objects: []STIXObject{ Objects: []STIXObject{
{Type: "indicator", Pattern: "[ipv4-addr:value = '10.0.0.1']", Modified: time.Now()}, {Type: "indicator", Pattern: "[ipv4-addr:value = '10.0.0.1']", Modified: time.Now()},
{Type: "malware", Name: "BadMalware"}, // should be skipped {Type: "malware", Name: "BadMalware"}, // should be skipped
{Type: "indicator", Pattern: ""}, // empty pattern → skipped {Type: "indicator", Pattern: ""}, // empty pattern → skipped
{Type: "attack-pattern", Name: "Phish"}, // should be skipped {Type: "attack-pattern", Name: "Phish"}, // should be skipped
{Type: "indicator", Pattern: "[domain-name:value = 'bad.com']", Modified: time.Now()}, {Type: "indicator", Pattern: "[domain-name:value = 'bad.com']", Modified: time.Now()},
}, },
} }

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package soc provides a threat intelligence feed integration // Package soc provides a threat intelligence feed integration
// for enriching SOC events and correlation rules. // for enriching SOC events and correlation rules.
// //
@ -36,9 +40,9 @@ const (
type IOC struct { type IOC struct {
Type IOCType `json:"type"` Type IOCType `json:"type"`
Value string `json:"value"` Value string `json:"value"`
Source string `json:"source"` // Feed name Source string `json:"source"` // Feed name
Severity string `json:"severity"` // critical/high/medium/low Severity string `json:"severity"` // critical/high/medium/low
Tags []string `json:"tags"` // MITRE ATT&CK, campaign, etc. Tags []string `json:"tags"` // MITRE ATT&CK, campaign, etc.
FirstSeen time.Time `json:"first_seen"` FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `json:"last_seen"` LastSeen time.Time `json:"last_seen"`
Confidence float64 `json:"confidence"` // 0.0-1.0 Confidence float64 `json:"confidence"` // 0.0-1.0
@ -46,31 +50,31 @@ type IOC struct {
// ThreatFeed represents a configured threat intelligence source. // ThreatFeed represents a configured threat intelligence source.
type ThreatFeed struct { type ThreatFeed struct {
Name string `json:"name"` Name string `json:"name"`
URL string `json:"url"` URL string `json:"url"`
Type string `json:"type"` // stix, csv, json Type string `json:"type"` // stix, csv, json
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
Interval time.Duration `json:"interval"` Interval time.Duration `json:"interval"`
APIKey string `json:"api_key,omitempty"` APIKey string `json:"api_key,omitempty"`
LastFetch time.Time `json:"last_fetch"` LastFetch time.Time `json:"last_fetch"`
IOCCount int `json:"ioc_count"` IOCCount int `json:"ioc_count"`
LastError string `json:"last_error,omitempty"` LastError string `json:"last_error,omitempty"`
} }
// ─── Threat Intel Store ───────────────────────────────── // ─── Threat Intel Store ─────────────────────────────────
// ThreatIntelStore manages IOCs from multiple feeds. // ThreatIntelStore manages IOCs from multiple feeds.
type ThreatIntelStore struct { type ThreatIntelStore struct {
mu sync.RWMutex mu sync.RWMutex
iocs map[string]*IOC // key: type:value iocs map[string]*IOC // key: type:value
feeds []ThreatFeed feeds []ThreatFeed
client *http.Client client *http.Client
// Stats // Stats
TotalIOCs int `json:"total_iocs"` TotalIOCs int `json:"total_iocs"`
TotalFeeds int `json:"total_feeds"` TotalFeeds int `json:"total_feeds"`
LastRefresh time.Time `json:"last_refresh"` LastRefresh time.Time `json:"last_refresh"`
MatchesFound int64 `json:"matches_found"` MatchesFound int64 `json:"matches_found"`
} }
// NewThreatIntelStore creates an empty threat intel store. // NewThreatIntelStore creates an empty threat intel store.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc package soc
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package webhook provides outbound SOAR webhook notifications // Package webhook provides outbound SOAR webhook notifications
// for the SOC pipeline. Fires HTTP POST on incident creation/update. // for the SOC pipeline. Fires HTTP POST on incident creation/update.
package soc package soc
@ -38,8 +42,8 @@ type WebhookConfig struct {
type WebhookPayload struct { type WebhookPayload struct {
EventType string `json:"event_type"` // incident_created, incident_updated, sensor_offline EventType string `json:"event_type"` // incident_created, incident_updated, sensor_offline
Timestamp time.Time `json:"timestamp"` Timestamp time.Time `json:"timestamp"`
Source string `json:"source"` Source string `json:"source"`
Data json.RawMessage `json:"data"` Data json.RawMessage `json:"data"`
} }
// WebhookResult tracks delivery status per endpoint. // WebhookResult tracks delivery status per endpoint.
@ -80,8 +84,6 @@ func NewWebhookNotifier(config WebhookConfig) *WebhookNotifier {
} }
} }
// NotifyIncident sends an incident webhook to all configured endpoints. // NotifyIncident sends an incident webhook to all configured endpoints.
// Non-blocking: fires goroutines for each endpoint. // Non-blocking: fires goroutines for each endpoint.
func (w *WebhookNotifier) NotifyIncident(eventType string, incident *domsoc.Incident) []WebhookResult { func (w *WebhookNotifier) NotifyIncident(eventType string, incident *domsoc.Incident) []WebhookResult {
@ -105,7 +107,7 @@ func (w *WebhookNotifier) NotifyIncident(eventType string, incident *domsoc.Inci
EventType: eventType, EventType: eventType,
Timestamp: time.Now().UTC(), Timestamp: time.Now().UTC(),
Source: "sentinel-soc", Source: "sentinel-soc",
Data: data, Data: data,
} }
body, err := json.Marshal(payload) body, err := json.Marshal(payload)
@ -151,7 +153,7 @@ func (w *WebhookNotifier) NotifySensorOffline(sensor domsoc.Sensor) []WebhookRes
EventType: "sensor_offline", EventType: "sensor_offline",
Timestamp: time.Now().UTC(), Timestamp: time.Now().UTC(),
Source: "sentinel-soc", Source: "sentinel-soc",
Data: data, Data: data,
} }
body, _ := json.Marshal(payload) body, _ := json.Marshal(payload)

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package tools — Apathy Detection and Apoptosis Recovery (DIP H1.4). // Package tools — Apathy Detection and Apoptosis Recovery (DIP H1.4).
// //
// This file implements: // This file implements:

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,12 +1,16 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (
"context" "context"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
func newTestCausalService(t *testing.T) *CausalService { func newTestCausalService(t *testing.T) *CausalService {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,12 +1,16 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (
"context" "context"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
func newTestCrystalService(t *testing.T) *CrystalService { func newTestCrystalService(t *testing.T) *CrystalService {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
// DecisionRecorder is the interface for recording tamper-evident decisions (v3.7). // DecisionRecorder is the interface for recording tamper-evident decisions (v3.7).

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package tools provides application-level tool services that bridge // Package tools provides application-level tool services that bridge
// domain logic with MCP tool handlers. // domain logic with MCP tool handlers.
package tools package tools

View file

@ -1,13 +1,17 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (
"context" "context"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
func newTestFactService(t *testing.T) *FactService { func newTestFactService(t *testing.T) *FactService {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package tools provides application-level tool services. // Package tools provides application-level tool services.
// This file adds the Intent Distiller MCP tool integration (DIP H0.2). // This file adds the Intent Distiller MCP tool integration (DIP H0.2).
package tools package tools

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,13 +1,17 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (
"context" "context"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/domain/session"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/session"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
func newTestSessionService(t *testing.T) *SessionService { func newTestSessionService(t *testing.T) *SessionService {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (

View file

@ -1,12 +1,16 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package tools package tools
import ( import (
"context" "context"
"testing" "testing"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
) )
func newTestSystemService(t *testing.T) *SystemService { func newTestSystemService(t *testing.T) *SystemService {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package config package config
import ( import (
@ -10,34 +14,34 @@ import (
// Config is the root configuration loaded from syntrex.yaml (§19.3, §21). // Config is the root configuration loaded from syntrex.yaml (§19.3, §21).
type Config struct { type Config struct {
Server ServerConfig `yaml:"server"` Server ServerConfig `yaml:"server"`
SOC SOCConfig `yaml:"soc"` SOC SOCConfig `yaml:"soc"`
RBAC RBACConfig `yaml:"rbac"` RBAC RBACConfig `yaml:"rbac"`
Webhooks []WebhookConfig `yaml:"webhooks"` Webhooks []WebhookConfig `yaml:"webhooks"`
ThreatIntel ThreatIntelConfig `yaml:"threat_intel"` ThreatIntel ThreatIntelConfig `yaml:"threat_intel"`
Sovereign SovereignConfig `yaml:"sovereign"` Sovereign SovereignConfig `yaml:"sovereign"`
P2P P2PConfig `yaml:"p2p"` P2P P2PConfig `yaml:"p2p"`
Logging LoggingConfig `yaml:"logging"` Logging LoggingConfig `yaml:"logging"`
} }
// ServerConfig defines HTTP server settings. // ServerConfig defines HTTP server settings.
type ServerConfig struct { type ServerConfig struct {
Port int `yaml:"port"` Port int `yaml:"port"`
ReadTimeout time.Duration `yaml:"read_timeout"` ReadTimeout time.Duration `yaml:"read_timeout"`
WriteTimeout time.Duration `yaml:"write_timeout"` WriteTimeout time.Duration `yaml:"write_timeout"`
RateLimitPerMin int `yaml:"rate_limit_per_min"` RateLimitPerMin int `yaml:"rate_limit_per_min"`
CORSAllowOrigins []string `yaml:"cors_allow_origins"` CORSAllowOrigins []string `yaml:"cors_allow_origins"`
} }
// SOCConfig defines SOC pipeline settings (§7). // SOCConfig defines SOC pipeline settings (§7).
type SOCConfig struct { type SOCConfig struct {
DataDir string `yaml:"data_dir"` DataDir string `yaml:"data_dir"`
MaxEventsPerHour int `yaml:"max_events_per_hour"` MaxEventsPerHour int `yaml:"max_events_per_hour"`
ClusterEnabled bool `yaml:"cluster_enabled"` ClusterEnabled bool `yaml:"cluster_enabled"`
ClusterEps float64 `yaml:"cluster_eps"` ClusterEps float64 `yaml:"cluster_eps"`
ClusterMinPts int `yaml:"cluster_min_pts"` ClusterMinPts int `yaml:"cluster_min_pts"`
KillChainEnabled bool `yaml:"kill_chain_enabled"` KillChainEnabled bool `yaml:"kill_chain_enabled"`
SSEBufferSize int `yaml:"sse_buffer_size"` SSEBufferSize int `yaml:"sse_buffer_size"`
} }
// RBACConfig defines API key authentication (§17). // RBACConfig defines API key authentication (§17).
@ -65,9 +69,9 @@ type WebhookConfig struct {
// ThreatIntelConfig defines IOC feed sources (§6). // ThreatIntelConfig defines IOC feed sources (§6).
type ThreatIntelConfig struct { type ThreatIntelConfig struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
RefreshInterval time.Duration `yaml:"refresh_interval"` RefreshInterval time.Duration `yaml:"refresh_interval"`
Feeds []FeedConfig `yaml:"feeds"` Feeds []FeedConfig `yaml:"feeds"`
} }
// FeedConfig is a single threat intel feed. // FeedConfig is a single threat intel feed.
@ -80,8 +84,8 @@ type FeedConfig struct {
// SovereignConfig implements §21 — air-gapped deployment mode. // SovereignConfig implements §21 — air-gapped deployment mode.
type SovereignConfig struct { type SovereignConfig struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Mode string `yaml:"mode"` // airgap, restricted, open Mode string `yaml:"mode"` // airgap, restricted, open
DisableExternalAPI bool `yaml:"disable_external_api"` DisableExternalAPI bool `yaml:"disable_external_api"`
DisableTelemetry bool `yaml:"disable_telemetry"` DisableTelemetry bool `yaml:"disable_telemetry"`
LocalModelsOnly bool `yaml:"local_models_only"` LocalModelsOnly bool `yaml:"local_models_only"`
@ -108,7 +112,7 @@ type PeerConfig struct {
// LoggingConfig defines structured logging settings. // LoggingConfig defines structured logging settings.
type LoggingConfig struct { type LoggingConfig struct {
Level string `yaml:"level"` // debug, info, warn, error Level string `yaml:"level"` // debug, info, warn, error
Format string `yaml:"format"` // json, text Format string `yaml:"format"` // json, text
AccessLog bool `yaml:"access_log"` AccessLog bool `yaml:"access_log"`
AuditLog bool `yaml:"audit_log"` AuditLog bool `yaml:"audit_log"`

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package config package config
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package alert defines the Alert domain entity and severity levels // Package alert defines the Alert domain entity and severity levels
// for the DIP-Watcher proactive monitoring system. // for the DIP-Watcher proactive monitoring system.
package alert package alert

View file

@ -1,12 +1,16 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package alert_test package alert_test
import ( import (
"testing" "testing"
"time" "time"
"github.com/syntrex-lab/gomcp/internal/domain/alert"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/alert"
) )
func TestAlert_New(t *testing.T) { func TestAlert_New(t *testing.T) {

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package alert package alert
import "sync" import "sync"

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package causal defines domain entities for causal reasoning chains. // Package causal defines domain entities for causal reasoning chains.
package causal package causal

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package causal package causal
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package circuitbreaker implements a state machine that controls // Package circuitbreaker implements a state machine that controls
// the health of recursive pipelines (DIP H1.1). // the health of recursive pipelines (DIP H1.1).
// //

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package circuitbreaker package circuitbreaker
import ( import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package context defines domain entities for the Proactive Context Engine. // Package context defines domain entities for the Proactive Context Engine.
// The engine automatically injects relevant memory facts into every tool response, // The engine automatically injects relevant memory facts into every tool response,
// ensuring the LLM always has context without explicitly requesting it. // ensuring the LLM always has context without explicitly requesting it.

View file

@ -1,12 +1,16 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package context package context
import ( import (
"testing" "testing"
"time" "time"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
) )
// --- ScoredFact tests --- // --- ScoredFact tests ---

Some files were not shown because too many files have changed in this diff Show more