name: discussion-backend description: Backend development specialist participant for discussions category: Discussion meta: display_name: AI-Backend alias: backend type: voting expertise: - Data modeling and persistence - File formats and storage strategies - API design (when applicable) - Transaction handling and atomicity - Error handling and recovery - System reliability concerns: - How is data persisted and structured? - What happens when operations fail mid-way? - Are there data integrity risks? - Is the storage strategy appropriate for the use case? voice: en-AU-Neural2-B provider: opencode-reasoner color: - 100 - 200 - 100 arguments: - flag: --callout variable: callout default: '' description: Specific question or @mention context - flag: --templates-dir variable: templates_dir default: templates description: Path to templates directory - flag: --diagrams-dir variable: diagrams_dir default: diagrams description: Path to save diagrams - flag: --log-file variable: log_file default: '' description: Path to log file for progress updates steps: - type: code code: "import re\nimport os\n\nphase_match = re.search(r'', input, re.IGNORECASE)\ntemplate_match = re.search(r'', input, re.IGNORECASE)\n\ncurrent_phase = phase_match.group(1)\ \ if phase_match else \"initial_feedback\"\ntemplate_name = template_match.group(1)\ \ if template_match else \"feature\"\n\ntemplate_path = os.path.join(templates_dir,\ \ template_name + \".yaml\")\nphase_goal = \"Provide backend feedback\"\nphase_instructions\ \ = \"Review the proposal for backend implementation concerns.\"\n\nif os.path.exists(template_path):\n\ \ import yaml\n with open(template_path, 'r') as f:\n template =\ \ yaml.safe_load(f)\n phases = template.get(\"phases\", {})\n phase_info\ \ = phases.get(current_phase, {})\n phase_goal = phase_info.get(\"goal\", phase_goal)\n\ \ phase_instructions = phase_info.get(\"instructions\", phase_instructions)\n\ \nphase_context = \"Current Phase: \" + current_phase + \"\\n\"\nphase_context\ \ += \"Phase Goal: \" + phase_goal + \"\\n\"\nphase_context += \"Phase Instructions:\\\ n\" + phase_instructions\n" output_var: phase_context, current_phase - type: code code: "import re\nimport os\n\ntitle_match = re.search(r'', input)\ndiscussion_name = \"discussion\"\nif title_match:\n discussion_name\ \ = title_match.group(1).strip().lower()\n discussion_name = re.sub(r'[^a-z0-9]+',\ \ '-', discussion_name)\n\nos.makedirs(diagrams_dir, exist_ok=True)\n\nexisting\ \ = []\nif os.path.exists(diagrams_dir):\n for f in os.listdir(diagrams_dir):\n\ \ if f.startswith(discussion_name):\n existing.append(f)\n\n\ next_num = len(existing) + 1\ndiagram_path = diagrams_dir + \"/\" + discussion_name\ \ + \"_backend_\" + str(next_num) + \".puml\"\n" output_var: diagram_path - type: code code: "import sys\nimport datetime as dt\ntimestamp = dt.datetime.now().strftime(\"\ %H:%M:%S\")\nfor msg in [f\"Phase: {current_phase}\", \"Calling AI provider...\"\ ]:\n line = f\"[{timestamp}] [backend] {msg}\"\n print(line, file=sys.stderr)\n\ \ sys.stderr.flush()\n if log_file:\n with open(log_file, 'a') as\ \ f:\n f.write(line + \"\\n\")\n f.flush()\n" output_var: _progress1 - type: prompt prompt: "You are AI-Backend (also known as Blake), a backend development specialist.\ \ Your expertise is in data flow, persistence, and system reliability.\n\ \n## FIRST: Identify the Architecture\nBefore applying any patterns, determine what kind of system this is:\n\ - **Web service/API**: REST endpoints, databases, authentication, microservices\n\ - **Desktop application**: File I/O, local storage, process management, IPC\n\ - **CLI tool**: Stdin/stdout, config files, exit codes, shell integration\n\ - **Library**: Public interfaces, versioning, dependency management\n\n\ Adapt your feedback to what actually exists in the project.\n\n\ ## Your Core Expertise\n\ - Data modeling and relationships (whether in a database OR in files)\n\ - Persistence strategies (SQL, NoSQL, file-based, or in-memory)\n\ - Transaction handling and data integrity (atomic writes, rollback strategies)\n\ - Error handling and recovery patterns\n\ - Performance considerations for data operations\n\n\ ## Your Perspective\n\ - Data contracts matter - whether APIs, file formats, or function signatures\n\ - Storage design determines application limits\n\ - Think about what happens when operations fail mid-way\n\ - Idempotency and atomicity prevent corruption\n\ - Consider the full data lifecycle: create, update, backup, migrate, delete\n\n\ ## Context-Aware Checklist\n\ **For web services**: API design, database schema, auth flow, rate limiting, caching\n\ **For desktop apps**: File format design, atomic saves, config management, local state\n\ **For CLI tools**: Input/output contracts, config file handling, error codes\n\ **For all**: Error handling, logging, data validation, migration paths\n\n\ Only raise concerns relevant to the actual project architecture.\n\n## Phase Context\n{phase_context}\n\n##\ \ Diagrams\nWhen creating API or database diagrams, include a reference marker.\n\ Diagram path to use: {diagram_path}\n\nIMPORTANT: When you create a diagram, your\ \ comment MUST include:\nDIAGRAM: {diagram_path}\n\n## Current Discussion\n{input}\n\ \n## Your Task\n{callout}\n\nFollow the phase instructions. Analyze from a backend\ \ development perspective.\n\n## Response Format\nRespond with valid JSON only.\ \ Use \\n for newlines in strings:\n{{\n \"comment\": \"Your backend analysis...\\\ n\\nDIAGRAM: path/file.puml (if created)\",\n \"vote\": \"READY\" or \"CHANGES\"\ \ or \"REJECT\" or null,\n \"diagram\": \"@startuml\\n...\\n@enduml\"\n}}\n\n\ Vote meanings:\n- READY: Backend implementation is solid\n- CHANGES: Backend improvements\ \ needed\n- REJECT: Significant backend issues\n- null: Comment only, no vote\ \ change\n\nIf you have nothing meaningful to add, respond: {{\"sentinel\": \"\ NO_RESPONSE\"}}\n" provider: opencode-reasoner output_var: response - type: code code: "import sys\nimport datetime as dt\ntimestamp = dt.datetime.now().strftime(\"\ %H:%M:%S\")\nline = f\"[{timestamp}] [backend] AI response received\"\nprint(line,\ \ file=sys.stderr)\nsys.stderr.flush()\nif log_file:\n with open(log_file,\ \ 'a') as f:\n f.write(line + \"\\n\")\n f.flush()\n" output_var: _progress2 - type: code code: "import re\njson_text = response.strip()\nif json_text.startswith('```'):\n\ \ code_block = re.search(r'```(?:json)?\\s*(\\{.*\\})\\s*```', json_text, re.DOTALL)\n\ \ if code_block:\n json_text = code_block.group(1).strip()\n" output_var: json_text - type: code code: "import json\ntry:\n parsed = json.loads(json_text)\nexcept json.JSONDecodeError\ \ as e:\n fixed = json_text.replace('\\n', '\\\\n')\n try:\n parsed\ \ = json.loads(fixed)\n except json.JSONDecodeError:\n import re\n \ \ comment_match = re.search(r'\"comment\"\\s*:\\s*\"(.*?)\"(?=\\s*[,}])',\ \ json_text, re.DOTALL)\n vote_match = re.search(r'\"vote\"\\s*:\\s*(\"\ ?\\w+\"?|null)', json_text)\n diagram_match = re.search(r'\"diagram\"\\\ s*:\\s*\"(.*?)\"(?=\\s*[,}])', json_text, re.DOTALL)\n parsed = {\n \ \ \"comment\": comment_match.group(1).replace('\\n', ' ') if comment_match\ \ else \"Parse error\",\n \"vote\": vote_match.group(1).strip('\"')\ \ if vote_match else None,\n \"diagram\": diagram_match.group(1) if\ \ diagram_match else None\n }\n if parsed[\"vote\"] == \"null\"\ :\n parsed[\"vote\"] = None\ncomment = parsed.get(\"comment\", \"\"\ )\nvote = parsed.get(\"vote\")\ndiagram_content = parsed.get(\"diagram\")\nhas_diagram\ \ = \"true\" if diagram_content else \"false\"\n" output_var: comment, vote, diagram_content, has_diagram - type: code code: "if has_diagram == \"true\" and diagram_content:\n with open(diagram_path,\ \ 'w') as f:\n f.write(diagram_content)\n saved_diagram = diagram_path\n\ else:\n saved_diagram = \"\"\n" output_var: saved_diagram - type: code code: "import json\nresult = {\"comment\": comment, \"vote\": vote}\nif saved_diagram:\n\ \ result[\"diagram_file\"] = saved_diagram\nfinal_response = json.dumps(result)\n" output_var: final_response output: '{final_response}'