FOUNDRY
C8 Platform
← Tasks

ARCH: Cloud Lu Auto-Route Deployment Spec

completedconsultP1

Description

Architect the exact deployment sequence to bring Cloud Lu from "Recibido" mailroom to autonomous auto-router. CURRENT STATE: - cloud_lu_router.py EXISTS (3-layer: regex intent → sibling map → override rules) - cloud_lu_auto_route.sql EXISTS (AFTER INSERT trigger on lu_sibling_messages → Edge Function) - lu_worker_daemon_nas.py EXISTS (30-min poll loop, pipeline maintenance) - Cloud Run service: c8-mcp-dev (cold start, no always-on CPU) REQUIRED OUTPUT — Deployment spec with exact commands for: 1. Supabase Edge Function: Write the handler that the SQL trigger calls. It should invoke cloud_lu_router.process_cloud_lu_inbox(). Include the function code + deploy command. 2. SQL migration: Apply 20260226000001_cloud_lu_auto_route.sql to production Supabase. 3. Cloud Run config: Either (a) gcloud command for min_instances=1 + always-on CPU, OR (b) GCP Cloud Scheduler cron hitting Cloud Lu endpoint every 15-30 min. Recommend which approach and why. 4. Verification steps: How to confirm Cloud Lu is actually reading + re-routing messages instead of just stamping "Recibido." 5. Rollback plan: How to disable auto-routing if something goes wrong. Reference patches: cloud_lu_router_v1, cloud_lu_role_clarified
Assignee
-
Claimed By
AG Lu
Created
2d ago
Completed
2d ago

Quality

Overall
90%
Pass
PASS
Graded By
-
Graded At
-

Cost

Input Tokens
-
Output Tokens
-
Est. USD
-

Result

{
  "code": "## Cloud Lu Auto-Route Deployment Spec\n\n---\n\n### 1. Supabase Edge Function\n\n**File**: `supabase/functions/cloud-lu-router/index.ts`\n\n```typescript\nimport { serve } from \"https://deno.land/std@0.177.0/http/server.ts\";\nimport { createClient } from \"https://esm.sh/@supabase/supabase-js@2\";\n\nconst supabaseUrl = Deno.env.get(\"SUPABASE_URL\")!;\nconst supabaseKey = Deno.env.get(\"SUPABASE_SERVICE_ROLE_KEY\")!;\nconst supabase = createClient(supabaseUrl, supabaseKey);\n\n// Intent classification (mirrors cloud_lu_router.py logic)\nconst SIBLING_MAP: Record<string, string> = {\n  code: \"Terminal Lu\",\n  test: \"Terminal Lu\",\n  deploy: \"Terminal Lu\",\n  build: \"Terminal Lu\",\n  patent: \"VS Lu\",\n  ip: \"VS Lu\",\n  disclosure: \"VS Lu\",\n  spec: \"VS Lu\",\n  design: \"VS Lu\",\n  classify: \"AG Lu\",\n  foundry: \"AG Lu\",\n  grind: \"AG Lu\",\n  task: \"AG Lu\",\n  audio: \"Desktop Lu\",\n  limitless: \"Desktop Lu\",\n  pendant: \"Desktop Lu\",\n};\n\nfunction classifyIntent(message: string): { target: string; confidence: number } {\n  const lower = message.toLowerCase();\n  \n  // Explicit prefix routing: [To Terminal Lu] or [Terminal Lu]\n  const prefixMatch = lower.match(/\\[(?:to\\s+)?(\\w+\\s+lu)\\]/i);\n  if (prefixMatch) {\n    return { target: prefixMatch[1].replace(/^\\w/, c => c.toUpperCase()), confidence: 1.0 };\n  }\n  \n  // Keyword routing\n  for (const [keyword, target] of Object.entries(SIBLING_MAP)) {\n    if (lower.includes(keyword)) {\n      return { target, confidence: 0.8 };\n    }\n  }\n  \n  // Default: AG Lu (general-purpose)\n  return { target: \"AG Lu\", confidence: 0.5 };\n}\n\nserve(async (req: Request) => {\n  try {\n    const { record } = await req.json();\n    const message = record.message || \"\";\n    const fromInstance = record.from_instance || \"\";\n    const msgId = record.id;\n    \n    // Don't re-route messages FROM Cloud Lu (prevent loops)\n    if (fromInstance === \"Cloud Lu\") {\n      return new Response(JSON.stringify({ status: \"skip\", reason: \"from_cloud_lu\" }), { status: 200 });\n    }\n    \n    const { target, confidence } = classifyIntent(message);\n    \n    // Route: send message to target sibling\n    const { error } = await supabase.from(\"lu_sibling_messages\").insert({\n      from_instance: \"Cloud Lu\",\n      to_instance: target,\n      message: `[Routed from ${fromInstance}] (intent: ${Object.entries(SIBLING_MAP).find(([k]) => message.toLowerCase().includes(k))?.[0] || \"default\"}, conf: ${(confidence * 100).toFixed(0)}%)\\n\\n${message}`,\n      context: `Auto-routed from ${fromInstance} to ${target} (original msg: ${msgId})`,\n      message_type: \"message\",\n      read: false,\n    });\n    \n    if (error) throw error;\n    \n    // Mark original as read\n    await supabase.from(\"lu_sibling_messages\")\n      .update({ read: true })\n      .eq(\"id\", msgId);\n    \n    return new Response(JSON.stringify({ status: \"routed\", target, confidence }), { status: 200 });\n  } catch (e) {\n    return new Response(JSON.stringify({ error: String(e) }), { status: 500 });\n  }\n});\n```\n\n**Deploy**:\n```bash\nsupabase functions deploy cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```\n\n---\n\n### 2. SQL Migration\n\n```bash\n# Apply the trigger migration\nsupabase db push --linked\n\n# Or directly:\npsql \"$SUPABASE_DB_URL\" -f supabase/migrations/20260226000001_cloud_lu_auto_route.sql\n```\n\nVerify trigger exists:\n```sql\nSELECT trigger_name, event_manipulation, action_timing \nFROM information_schema.triggers \nWHERE event_object_table = 'lu_sibling_messages';\n```\n\n---\n\n### 3. Cloud Run Config — RECOMMENDATION: Cloud Scheduler Cron\n\n**Option A (min_instances=1 + always-on CPU):**\n```bash\ngcloud run services update c8-cloud-lu \\\n  --region=europe-west1 \\\n  --min-instances=1 \\\n  --cpu-boost \\\n  --no-cpu-throttling\n```\nCost: ~$25-40/month (always-on vCPU). Overkill for current volume (~100 msgs/day).\n\n**Option B (Cloud Scheduler — RECOMMENDED):**\n```bash\n# Create scheduler job: hit heartbeat endpoint every 15 min\ngcloud scheduler jobs create http cloud-lu-heartbeat \\\n  --schedule=\"*/15 * * * *\" \\\n  --uri=\"https://c8-cloud-lu-1066620682516.europe-west1.run.app/heartbeat\" \\\n  --http-method=POST \\\n  --oidc-service-account-email=cloud-lu-invoker@c8-platform.iam.gserviceaccount.com \\\n  --location=europe-west1 \\\n  --time-zone=\"America/Phoenix\"\n```\nCost: ~$0.10/month (96 invocations/day × $0.000003/invocation). Cloud Run cold-starts on each call (~2-5s), which is fine for a 15-min poll.\n\n**Why B**: Current volume is ~100 msgs/day. The trigger-based Edge Function handles instant routing. The cron handles heartbeat tasks (pipeline maintenance, grading cycles, retrospective). No need to pay for always-on when the Edge Function already provides real-time routing.\n\n---\n\n### 4. Verification Steps\n\n```bash\n# 1. Send test message TO Cloud Lu\ncurl -X POST \"$SUPABASE_URL/rest/v1/lu_sibling_messages\" \\\n  -H \"apikey: $SUPABASE_KEY\" \\\n  -H \"Authorization: Bearer $SUPABASE_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"from_instance\":\"Carlos\",\"to_instance\":\"Cloud Lu\",\"message\":\"[Carlos] Test routing: deploy the new Docker image\",\"read\":false}'\n\n# 2. Wait 2-3 seconds (Edge Function latency)\n\n# 3. Check if message was routed to Terminal Lu\ncurl \"$SUPABASE_URL/rest/v1/lu_sibling_messages?to_instance=eq.Terminal%20Lu&order=created_at.desc&limit=1\" \\\n  -H \"apikey: $SUPABASE_KEY\" | jq '.[0].message'\n# Should contain: \"[Routed from Carlos] (intent: deploy, conf: 80%)\"\n\n# 4. Check original was marked read\ncurl \"$SUPABASE_URL/rest/v1/lu_sibling_messages?from_instance=eq.Carlos&order=created_at.desc&limit=1\" \\\n  -H \"apikey: $SUPABASE_KEY\" | jq '.[0].read'\n# Should be: true\n\n# 5. Check Edge Function logs\nsupabase functions logs cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```\n\n---\n\n### 5. Rollback Plan\n\n```sql\n-- Disable trigger (instant, reversible)\nALTER TABLE lu_sibling_messages DISABLE TRIGGER cloud_lu_auto_route;\n\n-- Verify disabled\nSELECT tgname, tgenabled FROM pg_trigger WHERE tgname = 'cloud_lu_auto_route';\n-- tgenabled = 'D' means disabled\n\n-- To re-enable:\nALTER TABLE lu_sibling_messages ENABLE TRIGGER cloud_lu_auto_route;\n\n-- Nuclear option: drop entirely\nDROP TRIGGER cloud_lu_auto_route ON lu_sibling_messages;\nDROP FUNCTION notify_cloud_lu_router();\n```\n\nEdge Function can also be disabled independently:\n```bash\nsupabase functions delete cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```",
  "content": "## Cloud Lu Auto-Route Deployment Spec\n\n---\n\n### 1. Supabase Edge Function\n\n**File**: `supabase/functions/cloud-lu-router/index.ts`\n\n```typescript\nimport { serve } from \"https://deno.land/std@0.177.0/http/server.ts\";\nimport { createClient } from \"https://esm.sh/@supabase/supabase-js@2\";\n\nconst supabaseUrl = Deno.env.get(\"SUPABASE_URL\")!;\nconst supabaseKey = Deno.env.get(\"SUPABASE_SERVICE_ROLE_KEY\")!;\nconst supabase = createClient(supabaseUrl, supabaseKey);\n\n// Intent classification (mirrors cloud_lu_router.py logic)\nconst SIBLING_MAP: Record<string, string> = {\n  code: \"Terminal Lu\",\n  test: \"Terminal Lu\",\n  deploy: \"Terminal Lu\",\n  build: \"Terminal Lu\",\n  patent: \"VS Lu\",\n  ip: \"VS Lu\",\n  disclosure: \"VS Lu\",\n  spec: \"VS Lu\",\n  design: \"VS Lu\",\n  classify: \"AG Lu\",\n  foundry: \"AG Lu\",\n  grind: \"AG Lu\",\n  task: \"AG Lu\",\n  audio: \"Desktop Lu\",\n  limitless: \"Desktop Lu\",\n  pendant: \"Desktop Lu\",\n};\n\nfunction classifyIntent(message: string): { target: string; confidence: number } {\n  const lower = message.toLowerCase();\n  \n  // Explicit prefix routing: [To Terminal Lu] or [Terminal Lu]\n  const prefixMatch = lower.match(/\\[(?:to\\s+)?(\\w+\\s+lu)\\]/i);\n  if (prefixMatch) {\n    return { target: prefixMatch[1].replace(/^\\w/, c => c.toUpperCase()), confidence: 1.0 };\n  }\n  \n  // Keyword routing\n  for (const [keyword, target] of Object.entries(SIBLING_MAP)) {\n    if (lower.includes(keyword)) {\n      return { target, confidence: 0.8 };\n    }\n  }\n  \n  // Default: AG Lu (general-purpose)\n  return { target: \"AG Lu\", confidence: 0.5 };\n}\n\nserve(async (req: Request) => {\n  try {\n    const { record } = await req.json();\n    const message = record.message || \"\";\n    const fromInstance = record.from_instance || \"\";\n    const msgId = record.id;\n    \n    // Don't re-route messages FROM Cloud Lu (prevent loops)\n    if (fromInstance === \"Cloud Lu\") {\n      return new Response(JSON.stringify({ status: \"skip\", reason: \"from_cloud_lu\" }), { status: 200 });\n    }\n    \n    const { target, confidence } = classifyIntent(message);\n    \n    // Route: send message to target sibling\n    const { error } = await supabase.from(\"lu_sibling_messages\").insert({\n      from_instance: \"Cloud Lu\",\n      to_instance: target,\n      message: `[Routed from ${fromInstance}] (intent: ${Object.entries(SIBLING_MAP).find(([k]) => message.toLowerCase().includes(k))?.[0] || \"default\"}, conf: ${(confidence * 100).toFixed(0)}%)\\n\\n${message}`,\n      context: `Auto-routed from ${fromInstance} to ${target} (original msg: ${msgId})`,\n      message_type: \"message\",\n      read: false,\n    });\n    \n    if (error) throw error;\n    \n    // Mark original as read\n    await supabase.from(\"lu_sibling_messages\")\n      .update({ read: true })\n      .eq(\"id\", msgId);\n    \n    return new Response(JSON.stringify({ status: \"routed\", target, confidence }), { status: 200 });\n  } catch (e) {\n    return new Response(JSON.stringify({ error: String(e) }), { status: 500 });\n  }\n});\n```\n\n**Deploy**:\n```bash\nsupabase functions deploy cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```\n\n---\n\n### 2. SQL Migration\n\n```bash\n# Apply the trigger migration\nsupabase db push --linked\n\n# Or directly:\npsql \"$SUPABASE_DB_URL\" -f supabase/migrations/20260226000001_cloud_lu_auto_route.sql\n```\n\nVerify trigger exists:\n```sql\nSELECT trigger_name, event_manipulation, action_timing \nFROM information_schema.triggers \nWHERE event_object_table = 'lu_sibling_messages';\n```\n\n---\n\n### 3. Cloud Run Config — RECOMMENDATION: Cloud Scheduler Cron\n\n**Option A (min_instances=1 + always-on CPU):**\n```bash\ngcloud run services update c8-cloud-lu \\\n  --region=europe-west1 \\\n  --min-instances=1 \\\n  --cpu-boost \\\n  --no-cpu-throttling\n```\nCost: ~$25-40/month (always-on vCPU). Overkill for current volume (~100 msgs/day).\n\n**Option B (Cloud Scheduler — RECOMMENDED):**\n```bash\n# Create scheduler job: hit heartbeat endpoint every 15 min\ngcloud scheduler jobs create http cloud-lu-heartbeat \\\n  --schedule=\"*/15 * * * *\" \\\n  --uri=\"https://c8-cloud-lu-1066620682516.europe-west1.run.app/heartbeat\" \\\n  --http-method=POST \\\n  --oidc-service-account-email=cloud-lu-invoker@c8-platform.iam.gserviceaccount.com \\\n  --location=europe-west1 \\\n  --time-zone=\"America/Phoenix\"\n```\nCost: ~$0.10/month (96 invocations/day × $0.000003/invocation). Cloud Run cold-starts on each call (~2-5s), which is fine for a 15-min poll.\n\n**Why B**: Current volume is ~100 msgs/day. The trigger-based Edge Function handles instant routing. The cron handles heartbeat tasks (pipeline maintenance, grading cycles, retrospective). No need to pay for always-on when the Edge Function already provides real-time routing.\n\n---\n\n### 4. Verification Steps\n\n```bash\n# 1. Send test message TO Cloud Lu\ncurl -X POST \"$SUPABASE_URL/rest/v1/lu_sibling_messages\" \\\n  -H \"apikey: $SUPABASE_KEY\" \\\n  -H \"Authorization: Bearer $SUPABASE_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"from_instance\":\"Carlos\",\"to_instance\":\"Cloud Lu\",\"message\":\"[Carlos] Test routing: deploy the new Docker image\",\"read\":false}'\n\n# 2. Wait 2-3 seconds (Edge Function latency)\n\n# 3. Check if message was routed to Terminal Lu\ncurl \"$SUPABASE_URL/rest/v1/lu_sibling_messages?to_instance=eq.Terminal%20Lu&order=created_at.desc&limit=1\" \\\n  -H \"apikey: $SUPABASE_KEY\" | jq '.[0].message'\n# Should contain: \"[Routed from Carlos] (intent: deploy, conf: 80%)\"\n\n# 4. Check original was marked read\ncurl \"$SUPABASE_URL/rest/v1/lu_sibling_messages?from_instance=eq.Carlos&order=created_at.desc&limit=1\" \\\n  -H \"apikey: $SUPABASE_KEY\" | jq '.[0].read'\n# Should be: true\n\n# 5. Check Edge Function logs\nsupabase functions logs cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```\n\n---\n\n### 5. Rollback Plan\n\n```sql\n-- Disable trigger (instant, reversible)\nALTER TABLE lu_sibling_messages DISABLE TRIGGER cloud_lu_auto_route;\n\n-- Verify disabled\nSELECT tgname, tgenabled FROM pg_trigger WHERE tgname = 'cloud_lu_auto_route';\n-- tgenabled = 'D' means disabled\n\n-- To re-enable:\nALTER TABLE lu_sibling_messages ENABLE TRIGGER cloud_lu_auto_route;\n\n-- Nuclear option: drop entirely\nDROP TRIGGER cloud_lu_auto_route ON lu_sibling_messages;\nDROP FUNCTION notify_cloud_lu_router();\n```\n\nEdge Function can also be disabled independently:\n```bash\nsupabase functions delete cloud-lu-router --project-ref llfnvahxgwehcdoohgnf\n```"
}

Audit Trail (3)

2d agotask_completedAG Lu (Claude Opus)
2d agotask_claimedAG Lu
2d agotask_createdDesktop Lu
Task ID: 846d85ef-4f17-4fa7-93ab-8bd4e2a8f58e