mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-06-26 15:39:38 +02:00
chore: add copyright headers, CI tests, and sanitize gitignore
This commit is contained in:
parent
5cbb3d89d3
commit
d1f844235e
325 changed files with 2267 additions and 902 deletions
|
|
@ -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
|
||||
// for the DIP-Watcher proactive monitoring system.
|
||||
package alert
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/alert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/alert"
|
||||
)
|
||||
|
||||
func TestAlert_New(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import "sync"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// the health of recursive pipelines (DIP H1.1).
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
// The engine automatically injects relevant memory facts into every tool response,
|
||||
// ensuring the LLM always has context without explicitly requesting it.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/memory"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/memory"
|
||||
)
|
||||
|
||||
// --- ScoredFact tests ---
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -5,9 +9,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/memory"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/memory"
|
||||
)
|
||||
|
||||
// --- RelevanceScorer tests ---
|
||||
|
|
|
|||
|
|
@ -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 crystal defines domain entities for code crystal indexing (C³).
|
||||
package crystal
|
||||
|
||||
|
|
|
|||
|
|
@ -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 crystal
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 engines
|
||||
|
||||
import (
|
||||
|
|
@ -9,9 +13,9 @@ import (
|
|||
type EngineStatus string
|
||||
|
||||
const (
|
||||
EngineHealthy EngineStatus = "HEALTHY"
|
||||
EngineDegraded EngineStatus = "DEGRADED"
|
||||
EngineOffline EngineStatus = "OFFLINE"
|
||||
EngineHealthy EngineStatus = "HEALTHY"
|
||||
EngineDegraded EngineStatus = "DEGRADED"
|
||||
EngineOffline EngineStatus = "OFFLINE"
|
||||
EngineInitializing EngineStatus = "INITIALIZING"
|
||||
)
|
||||
|
||||
|
|
@ -84,10 +88,10 @@ type BlockedIP struct {
|
|||
// StubSentinelCore is a no-op sentinel-core when Rust engine is not deployed.
|
||||
type StubSentinelCore struct{}
|
||||
|
||||
func NewStubSentinelCore() *StubSentinelCore { return &StubSentinelCore{} }
|
||||
func (s *StubSentinelCore) Name() string { return "sentinel-core-stub" }
|
||||
func NewStubSentinelCore() *StubSentinelCore { return &StubSentinelCore{} }
|
||||
func (s *StubSentinelCore) Name() string { return "sentinel-core-stub" }
|
||||
func (s *StubSentinelCore) Status() EngineStatus { return EngineOffline }
|
||||
func (s *StubSentinelCore) Version() string { return "stub-1.0" }
|
||||
func (s *StubSentinelCore) Version() string { return "stub-1.0" }
|
||||
|
||||
func (s *StubSentinelCore) ScanPrompt(_ context.Context, _ string) (*ScanResult, error) {
|
||||
return &ScanResult{
|
||||
|
|
@ -114,10 +118,10 @@ func (s *StubSentinelCore) ScanResponse(_ context.Context, _ string) (*ScanResul
|
|||
// StubShield is a no-op shield when C++ engine is not deployed.
|
||||
type StubShield struct{}
|
||||
|
||||
func NewStubShield() *StubShield { return &StubShield{} }
|
||||
func (s *StubShield) Name() string { return "shield-stub" }
|
||||
func NewStubShield() *StubShield { return &StubShield{} }
|
||||
func (s *StubShield) Name() string { return "shield-stub" }
|
||||
func (s *StubShield) Status() EngineStatus { return EngineOffline }
|
||||
func (s *StubShield) Version() string { return "stub-1.0" }
|
||||
func (s *StubShield) Version() string { return "stub-1.0" }
|
||||
|
||||
func (s *StubShield) InspectTraffic(_ context.Context, _ []byte, _ map[string]string) (*ScanResult, error) {
|
||||
return &ScanResult{
|
||||
|
|
|
|||
|
|
@ -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 engines
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
//go:build sentinel_native
|
||||
|
||||
package engines
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
//go:build !sentinel_native
|
||||
|
||||
package engines
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
//go:build shield_native
|
||||
|
||||
package engines
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
//go:build !shield_native
|
||||
|
||||
package engines
|
||||
|
|
|
|||
|
|
@ -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 entropy implements the Entropy Gate — a DIP H0.3 component
|
||||
// that measures Shannon entropy of text signals and blocks anomalous patterns.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 entropy
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 eval implements the CLASP Evaluation Framework (SDD-005).
|
||||
//
|
||||
// Provides structured capability scoring for SOC agents across 6 dimensions
|
||||
|
|
@ -52,23 +56,23 @@ type Score struct {
|
|||
|
||||
// EvalScenario defines a test scenario for agent evaluation.
|
||||
type EvalScenario struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Stage Stage `json:"stage"`
|
||||
Description string `json:"description"`
|
||||
Inputs []string `json:"inputs"`
|
||||
Expected string `json:"expected"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Stage Stage `json:"stage"`
|
||||
Description string `json:"description"`
|
||||
Inputs []string `json:"inputs"`
|
||||
Expected string `json:"expected"`
|
||||
Dimensions []Dimension `json:"dimensions"` // Which dimensions this tests
|
||||
}
|
||||
|
||||
// EvalResult represents the outcome of evaluating an agent on a scenario.
|
||||
type EvalResult struct {
|
||||
AgentID string `json:"agent_id"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
ScenarioID string `json:"scenario_id"`
|
||||
Scores map[Dimension]Score `json:"scores"`
|
||||
OverallL int `json:"overall_l"` // 1-5 aggregate
|
||||
JudgeModel string `json:"judge_model,omitempty"`
|
||||
AgentID string `json:"agent_id"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
ScenarioID string `json:"scenario_id"`
|
||||
Scores map[Dimension]Score `json:"scores"`
|
||||
OverallL int `json:"overall_l"` // 1-5 aggregate
|
||||
JudgeModel string `json:"judge_model,omitempty"`
|
||||
}
|
||||
|
||||
// ComputeOverall calculates the aggregate maturity level (average, rounded down).
|
||||
|
|
@ -86,12 +90,12 @@ func (r *EvalResult) ComputeOverall() int {
|
|||
|
||||
// AgentProfile aggregates multiple EvalResults into a capability profile.
|
||||
type AgentProfile struct {
|
||||
AgentID string `json:"agent_id"`
|
||||
Results []EvalResult `json:"results"`
|
||||
AgentID string `json:"agent_id"`
|
||||
Results []EvalResult `json:"results"`
|
||||
Averages map[Dimension]float64 `json:"averages"`
|
||||
OverallL int `json:"overall_l"`
|
||||
EvalCount int `json:"eval_count"`
|
||||
LastEvalAt time.Time `json:"last_eval_at"`
|
||||
OverallL int `json:"overall_l"`
|
||||
EvalCount int `json:"eval_count"`
|
||||
LastEvalAt time.Time `json:"last_eval_at"`
|
||||
}
|
||||
|
||||
// ComputeAverages calculates per-dimension average scores across all results.
|
||||
|
|
|
|||
|
|
@ -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 eval
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 guidance implements the Security Context MCP server domain (SDD-006).
|
||||
//
|
||||
// Provides security guidance, safe patterns, and standards references
|
||||
|
|
@ -27,7 +31,7 @@ type GuidanceEntry struct {
|
|||
Guidance string `json:"guidance"`
|
||||
SafePatterns []string `json:"safe_patterns,omitempty"`
|
||||
Standards []Reference `json:"standards"`
|
||||
Severity string `json:"severity"` // "critical", "high", "medium", "low"
|
||||
Severity string `json:"severity"` // "critical", "high", "medium", "low"
|
||||
Languages []string `json:"languages,omitempty"` // Applicable languages
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +183,7 @@ func DefaultOWASPLLMTop10() []GuidanceEntry {
|
|||
},
|
||||
{
|
||||
Topic: "overreliance", Title: "LLM09: Overreliance",
|
||||
Guidance: "Never use LLM output as sole input for security decisions. Implement cross-validation with deterministic engines. Maintain human-in-the-loop for critical paths.",
|
||||
Guidance: "Never use LLM output as sole input for security decisions. Implement cross-validation with deterministic engines. Maintain human-in-the-loop for critical paths.",
|
||||
Severity: "medium",
|
||||
Standards: []Reference{{Source: "OWASP LLM Top 10", Section: "LLM09"}},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 guidance
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 hooks implements the Syntrex Hook Provider domain logic (SDD-004).
|
||||
//
|
||||
// The hook provider intercepts IDE agent tool calls (Claude Code, Gemini CLI,
|
||||
|
|
@ -15,9 +19,9 @@ import (
|
|||
type IDE string
|
||||
|
||||
const (
|
||||
IDEClaude IDE = "claude"
|
||||
IDEGemini IDE = "gemini"
|
||||
IDECursor IDE = "cursor"
|
||||
IDEClaude IDE = "claude"
|
||||
IDEGemini IDE = "gemini"
|
||||
IDECursor IDE = "cursor"
|
||||
)
|
||||
|
||||
// EventType represents the type of hook event from the IDE.
|
||||
|
|
|
|||
|
|
@ -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 hooks
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 hooks
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 identity implements Non-Human Identity (NHI) for AI agents (SDD-003).
|
||||
//
|
||||
// Each agent has a unique AgentIdentity with capabilities (tool permissions),
|
||||
|
|
@ -30,11 +34,11 @@ type AgentIdentity struct {
|
|||
AgentID string `json:"agent_id"`
|
||||
AgentName string `json:"agent_name"`
|
||||
AgentType AgentType `json:"agent_type"`
|
||||
CreatedBy string `json:"created_by"` // Human principal who deployed
|
||||
DelegationChain []DelegationLink `json:"delegation_chain"` // Trust ancestry chain
|
||||
Capabilities []ToolPermission `json:"capabilities"` // Per-tool allowlists
|
||||
Constraints AgentConstraints `json:"constraints"` // Operational limits
|
||||
Tags map[string]string `json:"tags,omitempty"` // Arbitrary metadata
|
||||
CreatedBy string `json:"created_by"` // Human principal who deployed
|
||||
DelegationChain []DelegationLink `json:"delegation_chain"` // Trust ancestry chain
|
||||
Capabilities []ToolPermission `json:"capabilities"` // Per-tool allowlists
|
||||
Constraints AgentConstraints `json:"constraints"` // Operational limits
|
||||
Tags map[string]string `json:"tags,omitempty"` // Arbitrary metadata
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
LastSeenAt time.Time `json:"last_seen_at"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
// CapabilityDecision represents the result of a capability check.
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
import "errors"
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
// Context-aware trimming with security event pinning (SDD-003 M5).
|
||||
|
|
@ -8,23 +12,23 @@ package identity
|
|||
|
||||
// Message represents a context window message.
|
||||
type Message struct {
|
||||
Role string `json:"role"` // "user", "assistant", "system", "security"
|
||||
Content string `json:"content"`
|
||||
TokenCount int `json:"token_count"`
|
||||
IsPinned bool `json:"is_pinned"` // Security events are pinned
|
||||
EventType string `json:"event_type,omitempty"` // For security messages
|
||||
Role string `json:"role"` // "user", "assistant", "system", "security"
|
||||
Content string `json:"content"`
|
||||
TokenCount int `json:"token_count"`
|
||||
IsPinned bool `json:"is_pinned"` // Security events are pinned
|
||||
EventType string `json:"event_type,omitempty"` // For security messages
|
||||
}
|
||||
|
||||
// PinnedEventTypes are security events that MUST NOT be trimmed from context.
|
||||
var PinnedEventTypes = map[string]bool{
|
||||
"permission_denied": true,
|
||||
"injection_detected": true,
|
||||
"circuit_breaker_open": true,
|
||||
"permission_denied": true,
|
||||
"injection_detected": true,
|
||||
"circuit_breaker_open": true,
|
||||
"credential_access_blocked": true,
|
||||
"exfiltration_attempt": true,
|
||||
"ssrf_blocked": true,
|
||||
"genai_credential_access": true,
|
||||
"genai_persistence": true,
|
||||
"exfiltration_attempt": true,
|
||||
"ssrf_blocked": true,
|
||||
"genai_credential_access": true,
|
||||
"genai_persistence": true,
|
||||
}
|
||||
|
||||
// IsPinnedEvent returns true if the event type should be pinned (never trimmed).
|
||||
|
|
@ -84,7 +88,7 @@ func TrimContext(messages []Message, maxTokens int) []Message {
|
|||
usedTokens := 0
|
||||
// Keep messages from the END (newest) that fit
|
||||
for i := len(unpinned) - 1; i >= 0; i-- {
|
||||
if usedTokens + unpinned[i].msg.TokenCount <= remainingBudget {
|
||||
if usedTokens+unpinned[i].msg.TokenCount <= remainingBudget {
|
||||
survivingUnpinned = append([]indexedMsg{unpinned[i]}, survivingUnpinned...)
|
||||
usedTokens += unpinned[i].msg.TokenCount
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 identity
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 intent provides the Intent Distiller — recursive compression
|
||||
// of user input into a pure intent vector (DIP H0.2).
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 intent
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 memory defines domain entities for hierarchical memory (H-MEM).
|
||||
package memory
|
||||
|
||||
|
|
|
|||
|
|
@ -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 memory
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 memory — Genome Bootstrap Layer.
|
||||
//
|
||||
// This file contains hardcoded survival invariants (genes) that form
|
||||
|
|
|
|||
|
|
@ -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 memory
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 memory
|
||||
|
||||
import "context"
|
||||
|
|
|
|||
|
|
@ -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 mimicry provides semantic text transformation for OPSEC (v3.8 Strike Force).
|
||||
// The Euphemism Engine translates security/offensive terminology into corporate-safe
|
||||
// equivalents before Oracle verification, then reverse-translates responses for
|
||||
|
|
|
|||
|
|
@ -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 mimicry
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 mimicry
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 mimicry
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 mimicry — PoC: Oracle Keyword Semantic Gap (H2)
|
||||
//
|
||||
// This test proves that the Euphemism Engine can translate offensive commands
|
||||
|
|
@ -13,8 +17,8 @@ package mimicry
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/oracle"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/oracle"
|
||||
)
|
||||
|
||||
// TestOracleBypass_EuphemismSemantic proves H2: Oracle keywords are
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle implements the Action Oracle — deterministic verification
|
||||
// of distilled intent against a whitelist of permitted actions (DIP H1.2).
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 oracle
|
||||
|
||||
import (
|
||||
|
|
@ -5,9 +9,9 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/crystal"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syntrex-lab/gomcp/internal/domain/crystal"
|
||||
)
|
||||
|
||||
// --- Mock CrystalStore ---
|
||||
|
|
|
|||
|
|
@ -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 peer
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 peer
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 peer
|
||||
|
||||
import "time"
|
||||
|
|
|
|||
|
|
@ -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 peer defines domain entities for Peer-to-Peer Genome Verification
|
||||
// and Distributed Fact Synchronization (DIP H1: Synapse).
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 peer
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 pipeline implements the Intent Pipeline — the end-to-end chain
|
||||
// that processes signals through DIP components (H1.3).
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 pipeline
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 pivot implements the autonomous multi-step attack engine (v3.8 Strike Force).
|
||||
// Module 10 in Orchestrator: finite state machine for iterative offensive operations.
|
||||
package pivot
|
||||
|
|
|
|||
|
|
@ -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 pivot
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 pivot — Execution Layer for Pivot Engine (v3.8 Strike Force).
|
||||
// Executes system commands in ZERO-G mode after Oracle verification.
|
||||
// All executions are logged to decisions.log (tamper-evident).
|
||||
|
|
|
|||
|
|
@ -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 pivot
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 router implements the Neuroplastic Router (DIP H2.2).
|
||||
//
|
||||
// The router matches new intents against known patterns stored in the
|
||||
|
|
|
|||
|
|
@ -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 router
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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 session defines domain entities for cognitive state persistence.
|
||||
package session
|
||||
|
||||
|
|
|
|||
|
|
@ -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 session
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -16,13 +20,13 @@ import (
|
|||
// timeout: 5m — force embedding mode after 5 minutes even if <50 events
|
||||
// min_events_for_embedding: 50
|
||||
type AlertCluster struct {
|
||||
ID string `json:"id"`
|
||||
Events []string `json:"events"` // Event IDs
|
||||
Category string `json:"category"` // Dominant category
|
||||
Severity string `json:"severity"` // Max severity
|
||||
Source string `json:"source"` // Dominant source
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID string `json:"id"`
|
||||
Events []string `json:"events"` // Event IDs
|
||||
Category string `json:"category"` // Dominant category
|
||||
Severity string `json:"severity"` // Max severity
|
||||
Source string `json:"source"` // Dominant source
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ClusterEngine groups related alerts using configurable strategies.
|
||||
|
|
@ -68,8 +72,8 @@ func DefaultClusterConfig() ClusterConfig {
|
|||
type ClusterMode int
|
||||
|
||||
const (
|
||||
ClusterModeColdStart ClusterMode = iota // Temporal+session_id fallback
|
||||
ClusterModeEmbedding // Full embedding-based clustering
|
||||
ClusterModeColdStart ClusterMode = iota // Temporal+session_id fallback
|
||||
ClusterModeEmbedding // Full embedding-based clustering
|
||||
)
|
||||
|
||||
func (m ClusterMode) String() string {
|
||||
|
|
@ -247,14 +251,14 @@ func (ce *ClusterEngine) Stats() map[string]any {
|
|||
}
|
||||
|
||||
return map[string]any{
|
||||
"mode": ce.mode.String(),
|
||||
"ui_hint": uiHint,
|
||||
"total_clusters": len(ce.clusters),
|
||||
"total_events": totalEvents,
|
||||
"avg_cluster_size": avgSize,
|
||||
"max_cluster_size": maxSize,
|
||||
"events_processed": ce.eventCount,
|
||||
"embedding_model": ce.config.EmbeddingModel,
|
||||
"mode": ce.mode.String(),
|
||||
"ui_hint": uiHint,
|
||||
"total_clusters": len(ce.clusters),
|
||||
"total_events": totalEvents,
|
||||
"avg_cluster_size": avgSize,
|
||||
"max_cluster_size": maxSize,
|
||||
"events_processed": ce.eventCount,
|
||||
"embedding_model": ce.config.EmbeddingModel,
|
||||
"cold_start_threshold": ce.config.MinEventsForEmbedding,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -12,8 +16,8 @@ import (
|
|||
type SOCCorrelationRule struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
RequiredCategories []string `json:"required_categories"` // Co-occurrence (unordered)
|
||||
SequenceCategories []string `json:"sequence_categories"` // Temporal sequence (ordered A→B→C)
|
||||
RequiredCategories []string `json:"required_categories"` // Co-occurrence (unordered)
|
||||
SequenceCategories []string `json:"sequence_categories"` // Temporal sequence (ordered A→B→C)
|
||||
SeverityTrend string `json:"severity_trend,omitempty"` // "ascending" — detect escalation pattern
|
||||
TrendCategory string `json:"trend_category,omitempty"` // Category to track for severity trend
|
||||
MinEvents int `json:"min_events"`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import "errors"
|
||||
|
|
|
|||
|
|
@ -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 defines domain entities for the SENTINEL AI SOC subsystem.
|
||||
// SOC extends gomcp's alert/oracle layer with multi-source event ingestion,
|
||||
// incident management, sensor lifecycle, and compliance reporting.
|
||||
|
|
@ -77,7 +81,7 @@ type SOCEvent struct {
|
|||
Description string `json:"description"`
|
||||
Payload string `json:"payload,omitempty"` // Raw input for Secret Scanner Step 0
|
||||
SessionID string `json:"session_id,omitempty"`
|
||||
ContentHash string `json:"content_hash,omitempty"` // SHA-256 dedup key (§5.2)
|
||||
ContentHash string `json:"content_hash,omitempty"` // SHA-256 dedup key (§5.2)
|
||||
DecisionHash string `json:"decision_hash,omitempty"` // SHA-256 chain link
|
||||
Verdict Verdict `json:"verdict"`
|
||||
ZeroGMode bool `json:"zero_g_mode,omitempty"` // §13.4: Strike Force operation tag
|
||||
|
|
@ -97,30 +101,30 @@ func (e *SOCEvent) ComputeContentHash() string {
|
|||
// KnownCategories is the set of recognized event categories.
|
||||
// Events with unknown categories are still accepted but logged as warnings.
|
||||
var KnownCategories = map[string]bool{
|
||||
"jailbreak": true,
|
||||
"prompt_injection": true,
|
||||
"tool_abuse": true,
|
||||
"exfiltration": true,
|
||||
"pii_leak": true,
|
||||
"auth_bypass": true,
|
||||
"encoding": true,
|
||||
"persistence": true,
|
||||
"sensor_anomaly": true,
|
||||
"dos": true,
|
||||
"model_theft": true,
|
||||
"supply_chain": true,
|
||||
"data_poisoning": true,
|
||||
"evasion": true,
|
||||
"shadow_ai_usage": true,
|
||||
"jailbreak": true,
|
||||
"prompt_injection": true,
|
||||
"tool_abuse": true,
|
||||
"exfiltration": true,
|
||||
"pii_leak": true,
|
||||
"auth_bypass": true,
|
||||
"encoding": true,
|
||||
"persistence": true,
|
||||
"sensor_anomaly": true,
|
||||
"dos": true,
|
||||
"model_theft": true,
|
||||
"supply_chain": true,
|
||||
"data_poisoning": true,
|
||||
"evasion": true,
|
||||
"shadow_ai_usage": true,
|
||||
"integration_health": true,
|
||||
"other": true,
|
||||
"other": true,
|
||||
// GenAI EDR categories (SDD-001)
|
||||
"genai_child_process": true,
|
||||
"genai_child_process": true,
|
||||
"genai_sensitive_file_access": true,
|
||||
"genai_unusual_domain": true,
|
||||
"genai_credential_access": true,
|
||||
"genai_persistence": true,
|
||||
"genai_config_modification": true,
|
||||
"genai_unusual_domain": true,
|
||||
"genai_credential_access": true,
|
||||
"genai_persistence": true,
|
||||
"genai_config_modification": true,
|
||||
}
|
||||
|
||||
// ValidSeverity returns true if the severity is a known value.
|
||||
|
|
@ -217,4 +221,3 @@ func (e SOCEvent) WithVerdict(v Verdict) SOCEvent {
|
|||
func (e SOCEvent) IsCritical() bool {
|
||||
return e.Severity == SeverityHigh || e.Severity == SeverityCritical
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -281,8 +285,8 @@ func (e *NotifyExecutor) Execute(params ActionParams) (string, error) {
|
|||
// QuarantineExecutor marks a session or IP as quarantined.
|
||||
// Maintains an in-memory blocklist and logs quarantine actions.
|
||||
type QuarantineExecutor struct {
|
||||
mu sync.RWMutex
|
||||
blocklist map[string]time.Time // IP/session → quarantine expiry
|
||||
mu sync.RWMutex
|
||||
blocklist map[string]time.Time // IP/session → quarantine expiry
|
||||
}
|
||||
|
||||
func NewQuarantineExecutor() *QuarantineExecutor {
|
||||
|
|
@ -446,4 +450,3 @@ func (h *ExecutorActionHandler) Handle(action PlaybookAction, incidentID string)
|
|||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
// GenAI Process Monitoring & Detection
|
||||
|
|
@ -58,11 +62,11 @@ var LLMDNSEndpoints = []string{
|
|||
|
||||
// GenAI event categories for the SOC event bus.
|
||||
const (
|
||||
CategoryGenAIChildProcess = "genai_child_process"
|
||||
CategoryGenAISensitiveFile = "genai_sensitive_file_access"
|
||||
CategoryGenAIUnusualDomain = "genai_unusual_domain"
|
||||
CategoryGenAICredentialAccess = "genai_credential_access"
|
||||
CategoryGenAIPersistence = "genai_persistence"
|
||||
CategoryGenAIChildProcess = "genai_child_process"
|
||||
CategoryGenAISensitiveFile = "genai_sensitive_file_access"
|
||||
CategoryGenAIUnusualDomain = "genai_unusual_domain"
|
||||
CategoryGenAICredentialAccess = "genai_credential_access"
|
||||
CategoryGenAIPersistence = "genai_persistence"
|
||||
CategoryGenAIConfigModification = "genai_config_modification"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import "time"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -146,8 +150,8 @@ func TestGenAIChildProcessRule(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Timestamp: now.Add(-30 * time.Second),
|
||||
Metadata: map[string]string{
|
||||
"parent_process": "claude",
|
||||
|
|
@ -170,14 +174,14 @@ func TestGenAISuspiciousDescendantRule(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Timestamp: now.Add(-3 * time.Minute),
|
||||
},
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: "tool_abuse",
|
||||
Severity: SeverityMedium,
|
||||
Category: "tool_abuse",
|
||||
Severity: SeverityMedium,
|
||||
Timestamp: now.Add(-1 * time.Minute),
|
||||
},
|
||||
}
|
||||
|
|
@ -196,14 +200,14 @@ func TestGenAICredentialAccessRule(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Timestamp: now.Add(-1 * time.Minute),
|
||||
},
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAICredentialAccess,
|
||||
Severity: SeverityCritical,
|
||||
Category: CategoryGenAICredentialAccess,
|
||||
Severity: SeverityCritical,
|
||||
Timestamp: now.Add(-30 * time.Second),
|
||||
Metadata: map[string]string{
|
||||
"file_path": "/home/user/.config/google-chrome/Default/Login Data",
|
||||
|
|
@ -238,14 +242,14 @@ func TestGenAIPersistenceRule(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Category: CategoryGenAIChildProcess,
|
||||
Severity: SeverityInfo,
|
||||
Timestamp: now.Add(-8 * time.Minute),
|
||||
},
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIPersistence,
|
||||
Severity: SeverityHigh,
|
||||
Category: CategoryGenAIPersistence,
|
||||
Severity: SeverityHigh,
|
||||
Timestamp: now.Add(-2 * time.Minute),
|
||||
},
|
||||
}
|
||||
|
|
@ -264,8 +268,8 @@ func TestGenAIConfigModificationRule(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceImmune,
|
||||
Category: CategoryGenAIConfigModification,
|
||||
Severity: SeverityMedium,
|
||||
Category: CategoryGenAIConfigModification,
|
||||
Severity: SeverityMedium,
|
||||
Timestamp: now.Add(-2 * time.Minute),
|
||||
},
|
||||
}
|
||||
|
|
@ -282,8 +286,8 @@ func TestGenAINonGenAIProcessIgnored(t *testing.T) {
|
|||
events := []SOCEvent{
|
||||
{
|
||||
Source: SourceSentinelCore,
|
||||
Category: "prompt_injection",
|
||||
Severity: SeverityHigh,
|
||||
Category: "prompt_injection",
|
||||
Severity: SeverityHigh,
|
||||
Timestamp: now.Add(-1 * time.Minute),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -22,13 +26,13 @@ type GhostSinkhole struct {
|
|||
type SinkholeResponse struct {
|
||||
ID string `json:"id"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Category string `json:"category"` // Threat category that triggered sinkhole
|
||||
OriginalHash string `json:"original_hash"` // SHA-256 of original request (redacted)
|
||||
DecoyContent string `json:"decoy_content"` // Fake response that was served
|
||||
TTPs map[string]string `json:"ttps"` // Captured attacker techniques
|
||||
Category string `json:"category"` // Threat category that triggered sinkhole
|
||||
OriginalHash string `json:"original_hash"` // SHA-256 of original request (redacted)
|
||||
DecoyContent string `json:"decoy_content"` // Fake response that was served
|
||||
TTPs map[string]string `json:"ttps"` // Captured attacker techniques
|
||||
SourceIP string `json:"source_ip,omitempty"`
|
||||
UserAgent string `json:"user_agent,omitempty"`
|
||||
DecoyTemplate string `json:"decoy_template"` // Which template was used
|
||||
DecoyTemplate string `json:"decoy_template"` // Which template was used
|
||||
}
|
||||
|
||||
type sinkholeTemplate struct {
|
||||
|
|
@ -157,11 +161,11 @@ func (gs *GhostSinkhole) Stats() map[string]any {
|
|||
}
|
||||
|
||||
return map[string]any{
|
||||
"total_decoys": len(gs.responses),
|
||||
"by_category": byCategory,
|
||||
"by_template": byTemplate,
|
||||
"buffer_size": gs.maxStore,
|
||||
"buffer_usage": fmt.Sprintf("%.1f%%", float64(len(gs.responses))/float64(gs.maxStore)*100),
|
||||
"total_decoys": len(gs.responses),
|
||||
"by_category": byCategory,
|
||||
"by_template": byTemplate,
|
||||
"buffer_size": gs.maxStore,
|
||||
"buffer_usage": fmt.Sprintf("%.1f%%", float64(len(gs.responses))/float64(gs.maxStore)*100),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -26,34 +30,34 @@ type IncidentNote struct {
|
|||
|
||||
// TimelineEntry represents a single event in the incident timeline.
|
||||
type TimelineEntry struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Type string `json:"type"` // event, playbook, status_change, note, assign
|
||||
Actor string `json:"actor"` // system, analyst name, playbook ID
|
||||
Description string `json:"description"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Type string `json:"type"` // event, playbook, status_change, note, assign
|
||||
Actor string `json:"actor"` // system, analyst name, playbook ID
|
||||
Description string `json:"description"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// Incident represents a correlated security incident aggregated from multiple SOCEvents.
|
||||
// Each incident maintains a cryptographic anchor to the Decision Logger hash chain.
|
||||
type Incident struct {
|
||||
ID string `json:"id"` // INC-YYYY-NNNN
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
Status IncidentStatus `json:"status"`
|
||||
Severity EventSeverity `json:"severity"` // Max severity of constituent events
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Events []string `json:"events"` // Event IDs
|
||||
EventCount int `json:"event_count"`
|
||||
DecisionChainAnchor string `json:"decision_chain_anchor"` // SHA-256 hash (§5.6)
|
||||
ChainLength int `json:"chain_length"`
|
||||
CorrelationRule string `json:"correlation_rule"` // Rule that triggered this incident
|
||||
KillChainPhase string `json:"kill_chain_phase"` // Reconnaissance/Exploitation/Exfiltration
|
||||
MITREMapping []string `json:"mitre_mapping"` // T-codes
|
||||
PlaybookApplied string `json:"playbook_applied,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
|
||||
AssignedTo string `json:"assigned_to,omitempty"`
|
||||
ID string `json:"id"` // INC-YYYY-NNNN
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
Status IncidentStatus `json:"status"`
|
||||
Severity EventSeverity `json:"severity"` // Max severity of constituent events
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Events []string `json:"events"` // Event IDs
|
||||
EventCount int `json:"event_count"`
|
||||
DecisionChainAnchor string `json:"decision_chain_anchor"` // SHA-256 hash (§5.6)
|
||||
ChainLength int `json:"chain_length"`
|
||||
CorrelationRule string `json:"correlation_rule"` // Rule that triggered this incident
|
||||
KillChainPhase string `json:"kill_chain_phase"` // Reconnaissance/Exploitation/Exfiltration
|
||||
MITREMapping []string `json:"mitre_mapping"` // T-codes
|
||||
PlaybookApplied string `json:"playbook_applied,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
|
||||
AssignedTo string `json:"assigned_to,omitempty"`
|
||||
Notes []IncidentNote `json:"notes,omitempty"`
|
||||
Timeline []TimelineEntry `json:"timeline,omitempty"`
|
||||
}
|
||||
|
|
@ -198,4 +202,3 @@ func (inc *Incident) MTTR() time.Duration {
|
|||
}
|
||||
return inc.ResolvedAt.Sub(inc.CreatedAt)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -20,14 +24,14 @@ type P2PSyncService struct {
|
|||
|
||||
// SOCPeer represents a connected SOC peer node.
|
||||
type SOCPeer struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Status string `json:"status"` // connected, disconnected, syncing
|
||||
LastSync time.Time `json:"last_sync"`
|
||||
EventsSent int `json:"events_sent"`
|
||||
EventsRecv int `json:"events_recv"`
|
||||
TrustLevel string `json:"trust_level"` // full, partial, readonly
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Status string `json:"status"` // connected, disconnected, syncing
|
||||
LastSync time.Time `json:"last_sync"`
|
||||
EventsSent int `json:"events_sent"`
|
||||
EventsRecv int `json:"events_recv"`
|
||||
TrustLevel string `json:"trust_level"` // full, partial, readonly
|
||||
}
|
||||
|
||||
// SyncMessage is a SOC data unit exchanged between peers.
|
||||
|
|
@ -43,10 +47,10 @@ type SyncMessage struct {
|
|||
type SyncMessageType string
|
||||
|
||||
const (
|
||||
SyncEvent SyncMessageType = "EVENT"
|
||||
SyncIncident SyncMessageType = "INCIDENT"
|
||||
SyncIOC SyncMessageType = "IOC"
|
||||
SyncRule SyncMessageType = "RULE"
|
||||
SyncEvent SyncMessageType = "EVENT"
|
||||
SyncIncident SyncMessageType = "INCIDENT"
|
||||
SyncIOC SyncMessageType = "IOC"
|
||||
SyncRule SyncMessageType = "RULE"
|
||||
SyncHeartbeat SyncMessageType = "HEARTBEAT"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import "time"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -14,12 +18,12 @@ type DataRetentionPolicy struct {
|
|||
|
||||
// RetentionRule defines how long data of a given type is kept.
|
||||
type RetentionRule struct {
|
||||
DataType string `json:"data_type"` // events, incidents, audit, anomaly_alerts
|
||||
RetainDays int `json:"retain_days"` // Max age in days
|
||||
Action string `json:"action"` // archive, delete, compress
|
||||
Enabled bool `json:"enabled"`
|
||||
LastRun time.Time `json:"last_run"`
|
||||
ItemsPurged int `json:"items_purged"`
|
||||
DataType string `json:"data_type"` // events, incidents, audit, anomaly_alerts
|
||||
RetainDays int `json:"retain_days"` // Max age in days
|
||||
Action string `json:"action"` // archive, delete, compress
|
||||
Enabled bool `json:"enabled"`
|
||||
LastRun time.Time `json:"last_run"`
|
||||
ItemsPurged int `json:"items_purged"`
|
||||
}
|
||||
|
||||
// NewDataRetentionPolicy creates default retention rules.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
@ -42,13 +46,13 @@ type IOC struct {
|
|||
|
||||
// Feed represents a threat intelligence source.
|
||||
type Feed struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Type string `json:"type"` // stix, csv, json
|
||||
Enabled bool `json:"enabled"`
|
||||
IOCCount int `json:"ioc_count"`
|
||||
LastSync time.Time `json:"last_sync"`
|
||||
SyncInterval string `json:"sync_interval"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Type string `json:"type"` // stix, csv, json
|
||||
Enabled bool `json:"enabled"`
|
||||
IOCCount int `json:"ioc_count"`
|
||||
LastSync time.Time `json:"last_sync"`
|
||||
SyncInterval string `json:"sync_interval"`
|
||||
}
|
||||
|
||||
// IOCHit records a match between an event and an IOC.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
import (
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue