From 45a433c0eb63cae1322203ee14292f1c427a09c9 Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Thu, 29 Jan 2026 01:26:17 +0000
Subject: feat: Add Red Team UI to makima/frontend contract creation (#45)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Add redTeamEnabled and redTeamPrompt state to contracts page
- Add "Enable Red Team Monitoring" checkbox with description
- Add conditional "Custom Review Criteria" textarea when enabled
- Include redTeamEnabled/redTeamPrompt in CreateContractRequest
- Reset red team fields when canceling contract creation
- Add redTeamEnabled to ContractSummary and Contract types
- Add redTeamEnabled/redTeamPrompt to CreateContractRequest type
- Add Red Team badge (🔍) to ContractList for enabled contracts

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
---
 makima/frontend/src/routes/contracts.tsx | 59 ++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

(limited to 'makima/frontend/src/routes/contracts.tsx')

diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx
index 9891f29..bb66215 100644
--- a/makima/frontend/src/routes/contracts.tsx
+++ b/makima/frontend/src/routes/contracts.tsx
@@ -93,6 +93,8 @@ function ContractsPageContent() {
   const [contractTypes, setContractTypes] = useState<ContractTypeTemplate[]>([]);
   const [contractTypesLoading, setContractTypesLoading] = useState(false);
   const [localOnly, setLocalOnly] = useState(false);
+  const [redTeamEnabled, setRedTeamEnabled] = useState(false);
+  const [redTeamPrompt, setRedTeamPrompt] = useState("");
 
   // Fetch contract types when modal opens - merges built-in types with user templates
   useEffect(() => {
@@ -266,6 +268,8 @@ function ContractsPageContent() {
       contractType: contractType,
       initialPhase: initialPhase !== defaultPhaseForType ? initialPhase : undefined,
       localOnly: localOnly || undefined,
+      redTeamEnabled: redTeamEnabled || undefined,
+      redTeamPrompt: redTeamEnabled && redTeamPrompt.trim() ? redTeamPrompt.trim() : undefined,
     };
 
     try {
@@ -341,6 +345,8 @@ function ContractsPageContent() {
     setRepoUrl("");
     setRepoPath("");
     setLocalOnly(false);
+    setRedTeamEnabled(false);
+    setRedTeamPrompt("");
     setCreateError(null);
   }, []);
 
@@ -712,6 +718,59 @@ function ContractsPageContent() {
                   </p>
                 </div>
 
+                {/* Red Team Monitoring */}
+                <div className="border-t border-[rgba(117,170,252,0.2)] pt-4">
+                  <div className="flex items-center gap-3">
+                    <button
+                      type="button"
+                      onClick={() => setRedTeamEnabled(!redTeamEnabled)}
+                      className={`w-5 h-5 flex items-center justify-center border transition-colors ${
+                        redTeamEnabled
+                          ? "bg-[#0f3c78] border-[#75aafc] text-[#dbe7ff]"
+                          : "bg-[#0d1b2d] border-[#3f6fb3] text-transparent"
+                      }`}
+                    >
+                      {redTeamEnabled && (
+                        <svg
+                          xmlns="http://www.w3.org/2000/svg"
+                          width="12"
+                          height="12"
+                          viewBox="0 0 24 24"
+                          fill="none"
+                          stroke="currentColor"
+                          strokeWidth="3"
+                          strokeLinecap="round"
+                          strokeLinejoin="round"
+                        >
+                          <polyline points="20 6 9 17 4 12" />
+                        </svg>
+                      )}
+                    </button>
+                    <label
+                      className="font-mono text-sm text-[#dbe7ff] cursor-pointer select-none"
+                      onClick={() => setRedTeamEnabled(!redTeamEnabled)}
+                    >
+                      Enable Red Team Monitoring
+                    </label>
+                  </div>
+                  <p className="font-mono text-xs text-[#8b949e] pl-8">
+                    Spawns a parallel task to monitor work output for quality and compliance.
+                  </p>
+                  {redTeamEnabled && (
+                    <div className="mt-3 pl-8">
+                      <label className="block font-mono text-xs text-[#75aafc] uppercase mb-2">
+                        Custom Review Criteria (Optional)
+                      </label>
+                      <textarea
+                        value={redTeamPrompt}
+                        onChange={(e) => setRedTeamPrompt(e.target.value)}
+                        placeholder="e.g., 'Focus on security best practices' or 'Ensure all functions have tests'"
+                        className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] text-sm font-mono h-20 resize-none focus:border-[#75aafc] focus:outline-none"
+                      />
+                    </div>
+                  )}
+                </div>
+
                 {/* Repository Configuration */}
                 <div className="border-t border-[rgba(117,170,252,0.2)] pt-4">
                   <label className="block font-mono text-xs text-[#75aafc] uppercase mb-3">
-- 
cgit v1.2.3

