Architecture
How Shield's six safety layers and packages fit together.
Shield is organized as a set of focused Go packages. The engine package is the central coordinator. All other packages define interfaces, entities, and subsystem logic that compose around it.
Layered safety model
┌──────────────────────────────────────────────────────────────────┐
│ engine.Engine │
│ ScanInput / ScanOutput / Stop │
├──────────────────────────────────────────────────────────────────┤
│ Six cognitive safety layers │
│ │
│ Layer 1: INSTINCTS (<10ms) Injection, Jailbreak, Exfil │
│ Layer 2: AWARENESS (<50ms) PII, Topic, Intent, Sentiment │
│ Layer 3: BOUNDARIES (<5ms) Hard topic/action/data limits │
│ Layer 4: VALUES (<100ms) Toxicity, Brand, Honesty │
│ Layer 5: JUDGMENT (<500ms) Grounding, Relevance, Compliance│
│ Layer 6: REFLEXES (<10ms) Custom condition→action rules │
│ │
│ Each layer can short-circuit: if instincts detect injection │
│ with high confidence, deeper layers are skipped. │
├──────────────────────┬───────────────────────────────────────────┤
│ plugin.Registry │ SafetyProfile composition │
│ OnScanStarted │ Instincts + Awareness + Boundaries + │
│ OnScanCompleted │ Values + Judgment + Reflexes │
│ OnInstinctTriggered │ → compose into named profiles │
│ (15 total hooks) │ → assign to apps/tenants │
├──────────────────────┴───────────────────────────────────────────┤
│ store.Store │
│ (composite: scan.Store + instinct.Store + awareness.Store + │
│ boundary.Store + values.Store + judgment.Store + reflex.Store + │
│ profile.Store + policy.Store + pii.Store + compliance.Store + │
│ Migrate/Ping/Close) │
└──────────────────────────────────────────────────────────────────┘Engine construction
engine.New accepts option functions:
eng, err := engine.New(
engine.WithStore(pgStore), // optional: composite Store
engine.WithConfig(shield.Config{ // optional: override defaults
EnableShortCircuit: true,
ScanConcurrency: 10,
}),
engine.WithPlugin(metricsPlugin), // optional: lifecycle hooks
engine.WithLogger(slog.Default()), // optional: structured logger
)All components are interfaces — swap any with your own implementation.
Scan execution flow
When content is scanned, the engine processes it through six layers:
-
Instincts — Pre-conscious, immediate threat detection. Prompt injection, jailbreak attempts, and data exfiltration are detected here. Fastest layer (
<10ms). Can short-circuit to skip deeper layers. -
Awareness — Perception layer. PII detection, topic classification, sentiment analysis, intent detection, and language identification. Produces findings that inform later layers.
-
Boundaries — Hard binary limits. Topics, actions, or data patterns that are absolutely forbidden. No thresholds, no gradients — content either passes or is immediately blocked.
-
Values — Ethical evaluation. Toxicity detection, brand safety checks, honesty assessment, and respect evaluation. Configurable thresholds and severity levels.
-
Judgment — Contextual risk assessment. The slowest but most sophisticated layer. Grounding verification (hallucination detection), relevance scoring, consistency checking, and compliance assessment. Requires context.
-
Reflexes — Policy-driven condition-action rules. Rate limiting, escalation logic, pattern-based triggers, and custom rules. The final layer before a decision is produced.
Tenant isolation
shield.WithTenant(ctx, id) and shield.WithApp(ctx, id) inject identifiers into the context. These are extracted at every layer:
- Store — all queries include
WHERE app_id = ?filters - Engine — scope is applied to every scan result
- API — the Forge request context provides tenant/app identifiers
Cross-tenant access is structurally impossible: even if a caller passes a scan ID from another tenant, the store layer returns ErrScanNotFound.
Plugin system
Plugins implement the plugin.Plugin base interface (just Name() string) and then opt in to specific lifecycle hooks by implementing additional interfaces:
type Plugin interface {
Name() string
}
// Opt-in hooks (implement any subset):
type ScanStarted interface {
OnScanStarted(ctx context.Context, scanID id.ScanID, direction string, text string) error
}
type ScanCompleted interface { /* ... */ }
type InstinctTriggered interface { /* ... */ }
type BoundaryEnforced interface { /* ... */ }
// ... 15 hooks totalThe plugin.Registry type-caches plugins at registration time, so emit calls iterate only over plugins that implement the relevant hook. Errors from hooks are logged but never propagated.
Built-in plugins:
observability.MetricsExtension— 14 counters for all lifecycle eventsaudithook.Extension— bridges lifecycle events to an audit trail backend
Package index
| Package | Import path | Purpose |
|---|---|---|
shield | github.com/xraph/shield | Root — Entity, Config, scope helpers, errors |
id | .../id | TypeID-based entity identifiers (13 prefixes) |
engine | .../engine | Core layered safety engine |
scan | .../scan | Input, Finding, Result, Decision types |
instinct | .../instinct | Pre-conscious threat detection |
awareness | .../awareness | Perception — PII, topic, intent detection |
boundary | .../boundary | Hard safety limits |
values | .../values | Ethical evaluation rules |
judgment | .../judgment | Contextual risk assessment |
reflex | .../reflex | Condition-action response rules |
profile | .../profile | SafetyProfile composition |
policy | .../policy | Administrative governance |
pii | .../pii | PII vault with AES-256-GCM encryption |
compliance | .../compliance | Regulatory compliance reporting |
plugin | .../plugin | Plugin interfaces and Registry |
observability | .../observability | Metrics plugin (14 counters) |
audit_hook | .../audit_hook | Audit trail plugin |
store | .../store | Composite persistence interface |
extension | .../extension | Forge framework extension adapter |