import React, { useState } from 'react'; import { ShieldCheck, Plus, Play, Trash2, AlertTriangle, CheckCircle2, XCircle, Sliders, Filter, Code2, FileCheck2 } from 'lucide-react'; import { api } from '../api/client'; export default function PolicyRulesLab({ rules, currentWorkspace, onCreateRule, onDeleteRule, onValidate, loading }) { const [showAddModal, setShowAddModal] = useState(false); const [ruleName, setRuleName] = useState(''); const [ruleType, setRuleType] = useState('CONFIDENCE_THRESHOLD'); const [conditionVal, setConditionVal] = useState('0.85'); const [isBlocking, setIsBlocking] = useState(true); const [lintResults, setLintResults] = useState(null); const [validating, setValidating] = useState(false); const handleCreate = async (e) => { e.preventDefault(); if (!ruleName.trim()) return; let condition = {}; if (ruleType === 'CONFIDENCE_THRESHOLD') { condition = { min_confidence: parseFloat(conditionVal) || 0.85 }; } else if (ruleType === 'REGEX_FORMAT') { condition = { pattern: conditionVal }; } else { condition = { field: conditionVal }; } await onCreateRule(ruleName.trim(), ruleType, condition, isBlocking); setRuleName(''); setShowAddModal(false); }; const runLinter = async () => { if (!currentWorkspace?.id) return; setValidating(true); try { const res = await onValidate(); setLintResults(res); } finally { setValidating(false); } }; return (
{/* Policy Rules Lab Header */}

Policy as Code (CI Linting Engine)

Automated quality gates and regulatory guardrails executed before knowledge merges.

{/* Lint Results Suite (GitHub Actions Style) */} {lintResults && (
CI Check Suite Summary
{lintResults.has_violations ? `FAILED: ${lintResults.violations_count} Violations` : 'ALL CHECKS PASSED'}
{(lintResults.validations || []).map((val, idx) => (
{val.severity === 'PASS' ? ( ) : ( )}
{val.rule_name} {val.message}
{val.severity}
))}
)} {/* Active Rules Grid */}
{rules.map((rule) => (
{rule.name} {rule.is_blocking ? 'BLOCKING GATE' : 'ADVISORY'}
Type: {rule.rule_type}
{JSON.stringify(rule.condition || {})}
ID: {rule.id.slice(0, 8)}
))}
{/* Add Rule Modal */} {showAddModal && (

Add Validation Policy Rule

setRuleName(e.target.value)} className="w-full bg-[#141B2D] border border-slate-700/80 rounded-lg px-3 py-2 text-xs text-slate-200 focus:outline-none focus:ring-1 focus:ring-emerald-500" />
setConditionVal(e.target.value)} className="w-full bg-[#141B2D] border border-slate-700/80 rounded-lg px-3 py-2 text-xs font-mono text-slate-200 focus:outline-none focus:ring-1 focus:ring-emerald-500" />
setIsBlocking(e.target.checked)} className="rounded border-slate-700 text-emerald-600 focus:ring-emerald-500 bg-[#141B2D]" />
)}
); }