Foundation Perimeter ValidationService Implementation
Context
Foundation Perimeter implements a Four-Zone Architecture for BEAM-native AI systems. The ValidationService is the core component that manages validation caching, performance monitoring, and contract enforcement across all zones.
Task
Implement Foundation.Perimeter.ValidationService
as a GenServer that provides high-performance validation with caching, telemetry integration, and Foundation-specific optimizations.
Requirements
Architecture
- GenServer implementation with proper OTP supervision
- ETS-based validation caching with TTL support
- Performance monitoring and telemetry integration
- Foundation-specific enforcement levels per zone
- Circuit breaker protection against validation failures
Test-Driven Implementation
Follow Foundation’s event-driven testing philosophy - no Process.sleep/1
allowed. Use Foundation.UnifiedTestFoundation
with appropriate isolation mode.
Performance Targets
- Zone 1 (External): <15ms average validation time
- Zone 2 (Strategic): <5ms average validation time
- Cache hit rate: >80% for repeated validations
- Concurrent validation support with minimal contention
Implementation Specification
Module Structure
defmodule Foundation.Perimeter.ValidationService do
@moduledoc """
Central validation service for Foundation Perimeter system.
Manages validation caching, performance monitoring, and contract enforcement.
"""
use GenServer
require Logger
alias Foundation.Perimeter.{ContractRegistry, ErrorHandler}
alias Foundation.Telemetry
defstruct [
:validation_cache,
:performance_stats,
:enforcement_config,
:contract_cache
]
end
API Functions Required
start_link/1
- Start service with configurationvalidate/4
- Synchronous validation with cachingvalidate_async/4
- Asynchronous validation for non-blocking operationsget_performance_stats/0
- Retrieve performance metricsupdate_enforcement_config/1
- Runtime configuration updatesclear_cache/0
- Manual cache clearing
State Management
@type state :: %__MODULE__{
validation_cache: :ets.tid(),
performance_stats: performance_stats(),
enforcement_config: enforcement_config(),
contract_cache: map()
}
@type performance_stats :: %{
total_validations: non_neg_integer(),
cache_hits: non_neg_integer(),
cache_misses: non_neg_integer(),
average_validation_time: float(),
error_rate: float()
}
@type enforcement_config :: %{
external_level: enforcement_level(),
service_level: enforcement_level(),
coupling_level: enforcement_level(),
core_level: enforcement_level(),
cache_ttl: pos_integer(),
max_cache_size: pos_integer()
}
@type enforcement_level :: :none | :log | :warn | :strict
Core Functionality
Validation with Caching
def validate(contract_module, contract_name, data, opts \\ []) do
GenServer.call(__MODULE__, {:validate, contract_module, contract_name, data, opts})
end
def handle_call({:validate, contract_module, contract_name, data, opts}, _from, state) do
start_time = System.monotonic_time(:microsecond)
case perform_validation_with_cache(contract_module, contract_name, data, opts, state) do
{:ok, result} = success ->
end_time = System.monotonic_time(:microsecond)
validation_time = end_time - start_time
new_state = update_performance_stats(state, :success, validation_time)
Telemetry.emit([:foundation, :perimeter, :validation, :success], %{
duration: validation_time
}, %{
contract_module: contract_module,
contract_name: contract_name
})
{:reply, success, new_state}
{:error, _reason} = error ->
end_time = System.monotonic_time(:microsecond)
validation_time = end_time - start_time
new_state = update_performance_stats(state, :error, validation_time)
Telemetry.emit([:foundation, :perimeter, :validation, :error], %{
duration: validation_time
}, %{
contract_module: contract_module,
contract_name: contract_name
})
{:reply, error, new_state}
end
end
Cache Management
defp perform_validation_with_cache(contract_module, contract_name, data, opts, state) do
cache_key = generate_cache_key(contract_module, contract_name, data)
enforcement_level = get_enforcement_level(contract_module, state.enforcement_config)
case enforcement_level do
:none ->
{:ok, data} # No validation in none mode
level when level in [:strict, :warn, :log] ->
case check_cache(cache_key, state) do
{:hit, result} ->
Telemetry.increment([:foundation, :perimeter, :cache_hit])
{:ok, result}
:miss ->
Telemetry.increment([:foundation, :perimeter, :cache_miss])
case perform_validation(contract_module, contract_name, data, opts) do
{:ok, result} = success ->
store_in_cache(cache_key, result, state)
success
error ->
error
end
end
end
end
Testing Requirements
Test Structure
defmodule Foundation.Perimeter.ValidationServiceTest do
use Foundation.UnifiedTestFoundation, :registry
import Foundation.AsyncTestHelpers
alias Foundation.Perimeter.ValidationService
alias Foundation.Perimeter.Error
@moduletag :perimeter_testing
@moduletag timeout: 15_000
describe "ValidationService functionality" do
test "validates external contracts with caching", %{test_context: ctx} do
# Start ValidationService in test context
{:ok, service_pid} = start_supervised({ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]})
# Test contract and data
contract_module = Foundation.Perimeter.External.TestContracts
contract_name = :test_contract
valid_data = %{name: "test", value: 42}
# First validation should miss cache
assert_telemetry_event [:foundation, :perimeter, :cache_miss], %{count: 1} do
assert {:ok, validated} = ValidationService.validate(contract_module, contract_name, valid_data)
assert validated.name == "test"
end
# Second validation should hit cache
assert_telemetry_event [:foundation, :perimeter, :cache_hit], %{count: 1} do
assert {:ok, validated} = ValidationService.validate(contract_module, contract_name, valid_data)
assert validated.name == "test"
end
# Verify performance tracking
stats = ValidationService.get_performance_stats()
assert stats.total_validations >= 2
assert stats.cache_hits >= 1
assert stats.cache_misses >= 1
end
test "handles validation errors correctly", %{test_context: ctx} do
{:ok, _service_pid} = start_supervised({ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]})
contract_module = Foundation.Perimeter.External.TestContracts
contract_name = :test_contract
invalid_data = %{name: "", value: "not_a_number"}
# Should emit error telemetry
assert_telemetry_event [:foundation, :perimeter, :validation, :error],
%{duration: duration} when duration > 0 do
assert {:error, %Error{}} = ValidationService.validate(contract_module, contract_name, invalid_data)
end
# Error rate should be tracked
stats = ValidationService.get_performance_stats()
assert stats.error_rate > 0
end
test "enforces zone-specific validation levels", %{test_context: ctx} do
{:ok, _service_pid} = start_supervised({ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]})
# Configure strict enforcement for external
ValidationService.update_enforcement_config(%{
external_level: :strict,
service_level: :none
})
external_contract = Foundation.Perimeter.External.TestContracts
service_contract = Foundation.Perimeter.Services.TestContracts
invalid_data = %{invalid: "data"}
# External should fail validation
assert {:error, _} = ValidationService.validate(external_contract, :test_contract, invalid_data)
# Service should bypass validation (none level)
assert {:ok, ^invalid_data} = ValidationService.validate(service_contract, :test_contract, invalid_data)
end
end
describe "ValidationService performance" do
test "meets performance targets for zone validation", %{test_context: ctx} do
{:ok, _service_pid} = start_supervised({ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]})
external_contract = Foundation.Perimeter.External.TestContracts
strategic_contract = Foundation.Perimeter.Services.TestContracts
valid_data = %{name: "test", value: 42}
# Measure Zone 1 (External) performance
{external_time, {:ok, _}} = :timer.tc(fn ->
ValidationService.validate(external_contract, :test_contract, valid_data)
end)
# Measure Zone 2 (Strategic) performance
{strategic_time, {:ok, _}} = :timer.tc(fn ->
ValidationService.validate(strategic_contract, :test_contract, valid_data)
end)
# Convert to milliseconds
external_ms = external_time / 1000
strategic_ms = strategic_time / 1000
# Assert performance targets
assert external_ms < 15.0, "Zone 1 validation took #{external_ms}ms, should be <15ms"
assert strategic_ms < 5.0, "Zone 2 validation took #{strategic_ms}ms, should be <5ms"
end
test "cache hit rate exceeds target under load", %{test_context: ctx} do
{:ok, _service_pid} = start_supervised({ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]})
contract_module = Foundation.Perimeter.External.TestContracts
contract_name = :test_contract
valid_data = %{name: "test", value: 42}
# Perform many validations with same data
for _i <- 1..100 do
assert {:ok, _} = ValidationService.validate(contract_module, contract_name, valid_data)
end
stats = ValidationService.get_performance_stats()
cache_hit_rate = stats.cache_hits / (stats.cache_hits + stats.cache_misses)
assert cache_hit_rate > 0.8, "Cache hit rate #{Float.round(cache_hit_rate * 100, 1)}% should be >80%"
end
end
describe "ValidationService supervision" do
test "integrates with Foundation supervision tree", %{test_context: ctx} do
# Start under test supervisor
sup_spec = {ValidationService, [
name: :"validation_service_#{ctx.test_id}",
registry: ctx.registry_name
]}
{:ok, service_pid} = start_supervised(sup_spec)
assert Process.alive?(service_pid)
# Test functionality
contract_module = Foundation.Perimeter.External.TestContracts
valid_data = %{name: "test", value: 42}
assert {:ok, _} = ValidationService.validate(contract_module, :test_contract, valid_data)
# Test restart behavior
ref = Process.monitor(service_pid)
Process.exit(service_pid, :kill)
# Wait for restart
assert_receive {:DOWN, ^ref, :process, ^service_pid, :killed}, 2000
# Should restart and be functional
wait_for(fn ->
case ValidationService.validate(contract_module, :test_contract, valid_data) do
{:ok, _} -> true
_ -> nil
end
end, 5000)
end
end
end
Test Support Modules
Create these supporting test modules:
defmodule Foundation.Perimeter.External.TestContracts do
use Foundation.Perimeter
external_contract :test_contract do
field :name, :string, required: true, length: 1..100
field :value, :integer, required: true, range: 1..1000
end
end
defmodule Foundation.Perimeter.Services.TestContracts do
use Foundation.Perimeter
strategic_boundary :test_contract do
field :name, :string, required: true
field :value, :integer, required: true
end
end
Success Criteria
- All tests pass with zero
Process.sleep/1
usage - Performance targets met: Zone 1 <15ms, Zone 2 <5ms
- Cache hit rate >80% under load testing
- Proper OTP supervision integration with restart capability
- Telemetry events emitted for all validation operations
- Memory efficiency with bounded cache growth
- Concurrent validation support without contention issues
Files to Create
lib/foundation/perimeter/validation_service.ex
- Main implementationtest/foundation/perimeter/validation_service_test.exs
- Comprehensive test suitetest/support/perimeter_test_contracts.ex
- Test support contracts
Follow Foundation’s testing standards: event-driven coordination, proper isolation, deterministic assertions, and comprehensive error handling.