Download src/validators/governance-validator.go from Snapkitty/icp-dag-crystallizer: direct link, hf CLI and curl.
- Browser
- Download file 20.9 kB
-
https://huggingface.co/Snapkitty/icp-dag-crystallizer/resolve/main/src/validators/governance-validator.go
- Command line
-
hf download hf://Snapkitty/icp-dag-crystallizer/src/validators/governance-validator.go
-
curl -L -o governance-validator.go https://huggingface.co/Snapkitty/icp-dag-crystallizer/resolve/main/src/validators/governance-validator.go
20.9 kB
| // SPDX-License-Identifier: LicenseRef-Sovereign-Leviathan-SL-AGPL3-001 | |
| // Licensing: see LICENSE in the repository root. | |
| // governance-validator.go - ICP-DAG Governance Protocol Implementation | |
| // Validates agent communication against Integrity Constraint Protocol | |
| // Min 600 LOC validation rules for I2, I3, I4, I5, I9, I10 | |
| package main | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "sort" | |
| "sync" | |
| "time" | |
| ) | |
| // ClaimState represents the verification state of a claim | |
| type ClaimState string | |
| const ( | |
| Unknown ClaimState = "Unknown" | |
| Verified ClaimState = "Verified" | |
| Contradicted ClaimState = "Contradicted" | |
| Pending ClaimState = "Pending" | |
| ) | |
| // Claim represents an assertion made by an agent | |
| type Claim struct { | |
| ID string `json:"id"` | |
| Agent string `json:"agent"` | |
| Content string `json:"content"` | |
| State ClaimState `json:"state"` | |
| Timestamp uint64 `json:"timestamp"` | |
| } | |
| // Proof represents verification of claims forming a chain | |
| type Proof struct { | |
| ClaimID string `json:"claim_id"` | |
| ProofChain []string `json:"proof_chain"` // Ordered claim IDs | |
| VerifierAgent string `json:"verifier_agent"` | |
| IsValid bool `json:"is_valid"` | |
| } | |
| // Decision represents consensus decision backed by proofs | |
| type Decision struct { | |
| DecisionID string `json:"decision_id"` | |
| Agent string `json:"agent"` | |
| SupportingProofs []string `json:"supporting_proofs"` | |
| ConflictingProofs []string `json:"conflicting_proofs"` | |
| Authorized bool `json:"authorized"` | |
| Timestamp uint64 `json:"timestamp"` | |
| } | |
| // Execution represents action based on authorized decision | |
| type Execution struct { | |
| ExecID string `json:"exec_id"` | |
| Agent string `json:"agent"` | |
| DecisionID string `json:"decision_id"` | |
| Executed bool `json:"executed"` | |
| Timestamp uint64 `json:"timestamp"` | |
| } | |
| // AgentMessage represents inter-agent communication | |
| type AgentMessage struct { | |
| Sender string `json:"sender"` | |
| Receiver string `json:"receiver"` | |
| Claim Claim `json:"claim"` | |
| MessageID string `json:"message_id"` | |
| DependsOn []string `json:"depends_on"` // Message IDs this depends on | |
| } | |
| // ProtocolViolation records a rule violation | |
| type ProtocolViolation struct { | |
| ViolationType string `json:"violation_type"` | |
| Description string `json:"description"` | |
| AffectedEntity string `json:"affected_entity"` | |
| RuleID string `json:"rule_id"` | |
| Timestamp uint64 `json:"timestamp"` | |
| } | |
| // DAGStructure represents agent dependency graph | |
| type DAGStructure struct { | |
| Nodes []string `json:"nodes"` | |
| Edges [][2]string `json:"edges"` | |
| IsAcyclic bool `json:"is_acyclic"` | |
| Cycles [][]string `json:"cycles"` | |
| TopologicalSort []string `json:"topological_sort"` | |
| } | |
| // ClaimAnalysis summarizes claim states | |
| type ClaimAnalysis struct { | |
| TotalClaims int `json:"total_claims"` | |
| VerifiedClaims int `json:"verified_claims"` | |
| UnknownClaims int `json:"unknown_claims"` | |
| ContradictedClaims int `json:"contradicted_claims"` | |
| PendingClaims int `json:"pending_claims"` | |
| StateInconsistencies []string `json:"state_inconsistencies"` | |
| } | |
| // ExecutionChain traces execution to supporting claims | |
| type ExecutionChain struct { | |
| ChainID string `json:"chain_id"` | |
| ExecutionID string `json:"execution_id"` | |
| DecisionID string `json:"decision_id"` | |
| Proofs []string `json:"proofs"` | |
| Claims []string `json:"claims"` | |
| IsValidChain bool `json:"is_valid_chain"` | |
| ChainLength int `json:"chain_length"` | |
| } | |
| // ValidationReport complete validation results | |
| type ValidationReport struct { | |
| Violations []ProtocolViolation `json:"violations"` | |
| IsValid bool `json:"is_valid"` | |
| DAGStructure DAGStructure `json:"dag_structure"` | |
| ClaimAnalysis ClaimAnalysis `json:"claim_analysis"` | |
| ExecutionChains []ExecutionChain `json:"execution_chains"` | |
| ValidationTime string `json:"validation_time"` | |
| ViolationSummary map[string]int `json:"violation_summary"` | |
| } | |
| // ICPDAGValidator implements ICP-DAG validation logic | |
| type ICPDAGValidator struct { | |
| claims map[string]*Claim | |
| proofs map[string]*Proof | |
| decisions map[string]*Decision | |
| executions map[string]*Execution | |
| messages []*AgentMessage | |
| violations []ProtocolViolation | |
| mu sync.RWMutex | |
| } | |
| // NewICPDAGValidator creates validator instance | |
| func NewICPDAGValidator() *ICPDAGValidator { | |
| return &ICPDAGValidator{ | |
| claims: make(map[string]*Claim), | |
| proofs: make(map[string]*Proof), | |
| decisions: make(map[string]*Decision), | |
| executions: make(map[string]*Execution), | |
| messages: make([]*AgentMessage, 0), | |
| violations: make([]ProtocolViolation, 0), | |
| } | |
| } | |
| // RegisterClaim adds claim to validation system | |
| func (v *ICPDAGValidator) RegisterClaim(claim *Claim) { | |
| v.mu.Lock() | |
| defer v.mu.Unlock() | |
| v.claims[claim.ID] = claim | |
| } | |
| // RegisterProof adds proof to validation system | |
| func (v *ICPDAGValidator) RegisterProof(proof *Proof) { | |
| v.mu.Lock() | |
| defer v.mu.Unlock() | |
| v.proofs[proof.ClaimID] = proof | |
| } | |
| // RegisterDecision adds decision to validation system | |
| func (v *ICPDAGValidator) RegisterDecision(decision *Decision) { | |
| v.mu.Lock() | |
| defer v.mu.Unlock() | |
| v.decisions[decision.DecisionID] = decision | |
| } | |
| // RegisterExecution adds execution to validation system | |
| func (v *ICPDAGValidator) RegisterExecution(execution *Execution) { | |
| v.mu.Lock() | |
| defer v.mu.Unlock() | |
| v.executions[execution.ExecID] = execution | |
| } | |
| // RegisterMessage adds inter-agent message to validation system | |
| func (v *ICPDAGValidator) RegisterMessage(message *AgentMessage) { | |
| v.mu.Lock() | |
| defer v.mu.Unlock() | |
| v.messages = append(v.messages, message) | |
| } | |
| // validateI3UnknownClaims - Rule I3: Unknown claims cannot authorize | |
| func (v *ICPDAGValidator) validateI3UnknownClaims() { | |
| for decisionID, decision := range v.decisions { | |
| for _, proofID := range decision.SupportingProofs { | |
| if proof, exists := v.proofs[proofID]; exists { | |
| for _, claimID := range proof.ProofChain { | |
| if claim, exists := v.claims[claimID]; exists { | |
| if claim.State == Unknown { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I3_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Unknown claim %s used in proof chain for decision %s", | |
| claimID, decisionID, | |
| ), | |
| AffectedEntity: claimID, | |
| RuleID: "I3", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // validateI4ContradictedClaims - Rule I4: Contradicted claims cannot authorize | |
| func (v *ICPDAGValidator) validateI4ContradictedClaims() { | |
| for decisionID, decision := range v.decisions { | |
| // Check supporting proofs for contradicted claims | |
| for _, proofID := range decision.SupportingProofs { | |
| if proof, exists := v.proofs[proofID]; exists { | |
| for _, claimID := range proof.ProofChain { | |
| if claim, exists := v.claims[claimID]; exists { | |
| if claim.State == Contradicted { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I4_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Contradicted claim %s used in proof for decision %s", | |
| claimID, decisionID, | |
| ), | |
| AffectedEntity: claimID, | |
| RuleID: "I4", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Check for conflicting proofs alongside supporting proofs | |
| if len(decision.SupportingProofs) > 0 && len(decision.ConflictingProofs) > 0 { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I4_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Decision %s has both supporting and conflicting proofs", | |
| decisionID, | |
| ), | |
| AffectedEntity: decisionID, | |
| RuleID: "I4", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| } | |
| // validateI5ExecutionChain - Rule I5: Execution needs authorized decision | |
| func (v *ICPDAGValidator) validateI5ExecutionChain() { | |
| for execID, execution := range v.executions { | |
| if !execution.Executed { | |
| continue | |
| } | |
| decision, decisionExists := v.decisions[execution.DecisionID] | |
| if !decisionExists { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I5_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Execution %s references non-existent decision %s", | |
| execID, execution.DecisionID, | |
| ), | |
| AffectedEntity: execID, | |
| RuleID: "I5", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| continue | |
| } | |
| if !decision.Authorized { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I5_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Execution %s uses unauthorized decision %s", | |
| execID, execution.DecisionID, | |
| ), | |
| AffectedEntity: execID, | |
| RuleID: "I5", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| continue | |
| } | |
| // Verify all supporting proofs are valid | |
| for _, proofID := range decision.SupportingProofs { | |
| if proof, exists := v.proofs[proofID]; exists { | |
| if !proof.IsValid { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I5_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Execution %s depends on invalid proof %s", | |
| execID, proofID, | |
| ), | |
| AffectedEntity: execID, | |
| RuleID: "I5", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| // Verify claims in proof chain are verified | |
| for _, claimID := range proof.ProofChain { | |
| if claim, exists := v.claims[claimID]; exists { | |
| if claim.State != Verified { | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I5_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Execution %s depends on non-verified claim %s (state: %s)", | |
| execID, claimID, claim.State, | |
| ), | |
| AffectedEntity: execID, | |
| RuleID: "I5", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // validateI9ClaimConsistency - Rule I9: Claim state consistency | |
| func (v *ICPDAGValidator) validateI9ClaimConsistency() ClaimAnalysis { | |
| analysis := ClaimAnalysis{ | |
| TotalClaims: len(v.claims), | |
| StateInconsistencies: make([]string, 0), | |
| } | |
| claimStateMap := make(map[string]map[ClaimState]bool) | |
| for claimID, claim := range v.claims { | |
| if _, exists := claimStateMap[claimID]; !exists { | |
| claimStateMap[claimID] = make(map[ClaimState]bool) | |
| } | |
| claimStateMap[claimID][claim.State] = true | |
| switch claim.State { | |
| case Verified: | |
| analysis.VerifiedClaims++ | |
| case Unknown: | |
| analysis.UnknownClaims++ | |
| case Contradicted: | |
| analysis.ContradictedClaims++ | |
| case Pending: | |
| analysis.PendingClaims++ | |
| } | |
| } | |
| // Check for state inconsistencies | |
| for claimID, states := range claimStateMap { | |
| hasUnknown := states[Unknown] | |
| hasVerified := states[Verified] | |
| hasContradicted := states[Contradicted] | |
| // Cannot be Unknown AND Verified | |
| if hasUnknown && hasVerified { | |
| analysis.StateInconsistencies = append(analysis.StateInconsistencies, claimID) | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I9_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Claim %s has simultaneous Unknown and Verified states", | |
| claimID, | |
| ), | |
| AffectedEntity: claimID, | |
| RuleID: "I9", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| // Cannot be Verified AND Contradicted | |
| if hasVerified && hasContradicted { | |
| analysis.StateInconsistencies = append(analysis.StateInconsistencies, claimID) | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I9_VIOLATION", | |
| Description: fmt.Sprintf( | |
| "Claim %s has simultaneous Verified and Contradicted states", | |
| claimID, | |
| ), | |
| AffectedEntity: claimID, | |
| RuleID: "I9", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| return analysis | |
| } | |
| // validateAcyclicity - Rules I2 & I10: DAG acyclicity detection | |
| func (v *ICPDAGValidator) validateAcyclicity() DAGStructure { | |
| dag := DAGStructure{ | |
| Nodes: make([]string, 0), | |
| Edges: make([][2]string, 0), | |
| Cycles: make([][]string, 0), | |
| } | |
| // Build dependency graph from messages | |
| graph := make(map[string][]string) | |
| agents := make(map[string]bool) | |
| for _, msg := range v.messages { | |
| agents[msg.Sender] = true | |
| agents[msg.Receiver] = true | |
| graph[msg.Sender] = append(graph[msg.Sender], msg.Receiver) | |
| // Add message dependencies | |
| for _, depID := range msg.DependsOn { | |
| for _, depMsg := range v.messages { | |
| if depMsg.MessageID == depID { | |
| graph[depMsg.Sender] = append(graph[depMsg.Sender], msg.Sender) | |
| } | |
| } | |
| } | |
| } | |
| for agent := range agents { | |
| dag.Nodes = append(dag.Nodes, agent) | |
| } | |
| sort.Strings(dag.Nodes) | |
| for from, tos := range graph { | |
| for _, to := range tos { | |
| dag.Edges = append(dag.Edges, [2]string{from, to}) | |
| } | |
| } | |
| // Detect cycles using DFS | |
| cycles := v.detectCyclesDFS(graph) | |
| dag.Cycles = cycles | |
| dag.IsAcyclic = len(cycles) == 0 | |
| // Topological sort if acyclic | |
| if dag.IsAcyclic { | |
| dag.TopologicalSort = v.topologicalSort(graph) | |
| } | |
| return dag | |
| } | |
| // detectCyclesDFS detects cycles in directed graph | |
| func (v *ICPDAGValidator) detectCyclesDFS(graph map[string][]string) [][]string { | |
| visited := make(map[string]int) // 0: unvisited, 1: visiting, 2: visited | |
| cycles := make([][]string, 0) | |
| path := make([]string, 0) | |
| var dfs func(node string) | |
| dfs = func(node string) { | |
| visited[node] = 1 // Mark as visiting | |
| path = append(path, node) | |
| if neighbors, exists := graph[node]; exists { | |
| for _, neighbor := range neighbors { | |
| if visited[neighbor] == 1 { | |
| // Back edge found - cycle detected | |
| cycleStart := -1 | |
| for i, n := range path { | |
| if n == neighbor { | |
| cycleStart = i | |
| break | |
| } | |
| } | |
| if cycleStart != -1 { | |
| cycle := make([]string, len(path)-cycleStart) | |
| copy(cycle, path[cycleStart:]) | |
| cycles = append(cycles, cycle) | |
| } | |
| } else if visited[neighbor] == 0 { | |
| dfs(neighbor) | |
| } | |
| } | |
| } | |
| path = path[:len(path)-1] | |
| visited[node] = 2 // Mark as visited | |
| } | |
| for node := range graph { | |
| if visited[node] == 0 { | |
| dfs(node) | |
| } | |
| } | |
| return cycles | |
| } | |
| // topologicalSort performs Kahn's algorithm | |
| func (v *ICPDAGValidator) topologicalSort(graph map[string][]string) []string { | |
| inDegree := make(map[string]int) | |
| allNodes := make(map[string]bool) | |
| for from, tos := range graph { | |
| allNodes[from] = true | |
| if _, exists := inDegree[from]; !exists { | |
| inDegree[from] = 0 | |
| } | |
| for _, to := range tos { | |
| allNodes[to] = true | |
| inDegree[to]++ | |
| } | |
| } | |
| queue := make([]string, 0) | |
| for node := range allNodes { | |
| if inDegree[node] == 0 { | |
| queue = append(queue, node) | |
| } | |
| } | |
| result := make([]string, 0) | |
| for len(queue) > 0 { | |
| node := queue[0] | |
| queue = queue[1:] | |
| result = append(result, node) | |
| if neighbors, exists := graph[node]; exists { | |
| for _, neighbor := range neighbors { | |
| inDegree[neighbor]-- | |
| if inDegree[neighbor] == 0 { | |
| queue = append(queue, neighbor) | |
| } | |
| } | |
| } | |
| } | |
| return result | |
| } | |
| // buildExecutionChains traces execution→decision→proof→claim chains | |
| func (v *ICPDAGValidator) buildExecutionChains() []ExecutionChain { | |
| chains := make([]ExecutionChain, 0) | |
| for execID, execution := range v.executions { | |
| chain := ExecutionChain{ | |
| ChainID: fmt.Sprintf("chain_%s", execID), | |
| ExecutionID: execID, | |
| DecisionID: execution.DecisionID, | |
| Proofs: make([]string, 0), | |
| Claims: make([]string, 0), | |
| } | |
| if decision, exists := v.decisions[execution.DecisionID]; exists { | |
| chain.Proofs = append(chain.Proofs, decision.SupportingProofs...) | |
| for _, proofID := range chain.Proofs { | |
| if proof, exists := v.proofs[proofID]; exists { | |
| chain.Claims = append(chain.Claims, proof.ProofChain...) | |
| } | |
| } | |
| // Validate chain | |
| chain.IsValidChain = decision.Authorized | |
| if chain.IsValidChain { | |
| for _, proofID := range chain.Proofs { | |
| if proof, exists := v.proofs[proofID]; exists && !proof.IsValid { | |
| chain.IsValidChain = false | |
| break | |
| } | |
| } | |
| } | |
| if chain.IsValidChain { | |
| for _, claimID := range chain.Claims { | |
| if claim, exists := v.claims[claimID]; exists && claim.State != Verified { | |
| chain.IsValidChain = false | |
| break | |
| } | |
| } | |
| } | |
| } | |
| chain.ChainLength = len(chain.Proofs) + len(chain.Claims) | |
| chains = append(chains, chain) | |
| } | |
| return chains | |
| } | |
| // Validate performs complete validation | |
| func (v *ICPDAGValidator) Validate() ValidationReport { | |
| v.mu.Lock() | |
| v.violations = make([]ProtocolViolation, 0) | |
| v.mu.Unlock() | |
| // Run all validations | |
| v.validateI3UnknownClaims() | |
| v.validateI4ContradictedClaims() | |
| v.validateI5ExecutionChain() | |
| claimAnalysis := v.validateI9ClaimConsistency() | |
| dagStructure := v.validateAcyclicity() | |
| // Check acyclicity rules | |
| if !dagStructure.IsAcyclic { | |
| for _, cycle := range dagStructure.Cycles { | |
| cycleStr := fmt.Sprintf("%v", cycle) | |
| v.violations = append(v.violations, ProtocolViolation{ | |
| ViolationType: "I2_I10_VIOLATION", | |
| Description: fmt.Sprintf("Cycle detected in DAG: %s", cycleStr), | |
| AffectedEntity: cycleStr, | |
| RuleID: "I2_I10", | |
| Timestamp: uint64(time.Now().Unix()), | |
| }) | |
| } | |
| } | |
| executionChains := v.buildExecutionChains() | |
| isValid := len(v.violations) == 0 | |
| // Build violation summary | |
| violationSummary := make(map[string]int) | |
| for _, v := range v.violations { | |
| violationSummary[v.RuleID]++ | |
| } | |
| return ValidationReport{ | |
| Violations: v.violations, | |
| IsValid: isValid, | |
| DAGStructure: dagStructure, | |
| ClaimAnalysis: claimAnalysis, | |
| ExecutionChains: executionChains, | |
| ValidationTime: time.Now().Format(time.RFC3339), | |
| ViolationSummary: violationSummary, | |
| } | |
| } | |
| // String formats validation report for output | |
| func (r ValidationReport) String() string { | |
| output := fmt.Sprintf("=== ICP-DAG Governance Protocol Validation Report ===\n\n") | |
| output += fmt.Sprintf("Overall Status: ") | |
| if r.IsValid { | |
| output += "VALID\n" | |
| } else { | |
| output += "INVALID\n" | |
| } | |
| output += fmt.Sprintf("Total Violations: %d\n", len(r.Violations)) | |
| output += fmt.Sprintf("Validation Time: %s\n\n", r.ValidationTime) | |
| if len(r.Violations) > 0 { | |
| output += "--- Protocol Violations ---\n" | |
| for idx, v := range r.Violations { | |
| output += fmt.Sprintf("%d. [%s] %s\n", idx+1, v.RuleID, v.ViolationType) | |
| output += fmt.Sprintf(" Entity: %s\n", v.AffectedEntity) | |
| output += fmt.Sprintf(" Desc: %s\n\n", v.Description) | |
| } | |
| } | |
| output += fmt.Sprintf("--- Claim Analysis ---\n") | |
| output += fmt.Sprintf("Total Claims: %d\n", r.ClaimAnalysis.TotalClaims) | |
| output += fmt.Sprintf("Verified: %d\n", r.ClaimAnalysis.VerifiedClaims) | |
| output += fmt.Sprintf("Unknown: %d\n", r.ClaimAnalysis.UnknownClaims) | |
| output += fmt.Sprintf("Contradicted: %d\n", r.ClaimAnalysis.ContradictedClaims) | |
| output += fmt.Sprintf("State Inconsistencies: %d\n\n", len(r.ClaimAnalysis.StateInconsistencies)) | |
| output += fmt.Sprintf("--- DAG Structure ---\n") | |
| output += fmt.Sprintf("Nodes: %d\n", len(r.DAGStructure.Nodes)) | |
| output += fmt.Sprintf("Edges: %d\n", len(r.DAGStructure.Edges)) | |
| output += fmt.Sprintf("Acyclic: %v\n", r.DAGStructure.IsAcyclic) | |
| if len(r.DAGStructure.Cycles) > 0 { | |
| output += fmt.Sprintf("Cycles Found: %d\n", len(r.DAGStructure.Cycles)) | |
| } | |
| output += fmt.Sprintf("\n--- Execution Chains ---\n") | |
| output += fmt.Sprintf("Total Chains: %d\n", len(r.ExecutionChains)) | |
| for _, chain := range r.ExecutionChains { | |
| output += fmt.Sprintf(" %s: %d proofs, %d claims, Valid: %v\n", | |
| chain.ChainID, len(chain.Proofs), len(chain.Claims), chain.IsValidChain) | |
| } | |
| return output | |
| } | |
| // JSON returns JSON representation of report | |
| func (r ValidationReport) JSON() (string, error) { | |
| data, err := json.MarshalIndent(r, "", " ") | |
| if err != nil { | |
| return "", err | |
| } | |
| return string(data), nil | |
| } | |
| // Example usage | |
| func main() { | |
| validator := NewICPDAGValidator() | |
| // Example 1: Valid authorization chain | |
| verifiedClaim := &Claim{ | |
| ID: "claim_1", | |
| Agent: "governance_board", | |
| Content: "Policy approved", | |
| State: Verified, | |
| Timestamp: 1000, | |
| } | |
| validator.RegisterClaim(verifiedClaim) | |
| proof := &Proof{ | |
| ClaimID: "proof_1", | |
| ProofChain: []string{"claim_1"}, | |
| VerifierAgent: "validator", | |
| IsValid: true, | |
| } | |
| validator.RegisterProof(proof) | |
| decision := &Decision{ | |
| DecisionID: "dec_1", | |
| Agent: "consensus", | |
| SupportingProofs: []string{"proof_1"}, | |
| ConflictingProofs: []string{}, | |
| Authorized: true, | |
| Timestamp: 1001, | |
| } | |
| validator.RegisterDecision(decision) | |
| execution := &Execution{ | |
| ExecID: "exec_1", | |
| Agent: "executor", | |
| DecisionID: "dec_1", | |
| Executed: true, | |
| Timestamp: 1002, | |
| } | |
| validator.RegisterExecution(execution) | |
| // Validate | |
| report := validator.Validate() | |
| fmt.Println(report.String()) | |
| // JSON output | |
| jsonReport, _ := report.JSON() | |
| fmt.Println("\n" + jsonReport) | |
| } | |